NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: bin/42463: Bizarre behavior in awk with invalid numeric constants



The following reply was made to PR bin/42463; it has been noted by GNATS.

From: David Holland <dholland-bugs%netbsd.org@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: 
Subject: Re: bin/42463: Bizarre behavior in awk with invalid numeric constants
Date: Sun, 1 Jan 2017 00:44:38 +0000

 On Wed, Dec 16, 2009 at 09:10:00PM +0000, dholland%eecs.harvard.edu@localhost wrote:
  >    % awk </dev/null 'END { printf "%s\n", (0xblegh + 0) }'
  >    00
  >    % awk </dev/null 'END { printf "%s\n", (0xblegh + 3) }'
  >    03
  >    % awk </dev/null 'END { printf "%s\n", (0xblegh - 5) }'
  >    0-5
  > 
  > Huh?
 
 I figured out what going on here: the lexer isn't a C lexer where
 trailing letters are potentially part of a number, so it matches only
 the acceptable digits, calls those a number, and goes on. That means
 it gets the expression
 
    0 xblegh - 5
 
 which is to say, the string concatenation of 0 with (xblegh - 5), and
 since xblegh (a perfectly fine variable name) hasn't been assigned a
 value, it's 0, so we get a string concatenation of two numbers, which
 converts them to strings and pastes them together.
 
 This can be detected by assigning xblegh a value:
 
    % awk < /dev/null 'END { printf "%s\n", (0xblegh - 5) }' xblegh=8
    03
 
 In the case of gawk, because it accepts hex constants, it takes 0xb
 and what's left is the also unassigned variable "legh".
 
 This behavior certainly produces mystifying results and it might be
 good to have awk print a warning, like "Warning: no space between
 number and variable name".
 
 untested patch for that:
 
 Index: lex.c
 ===================================================================
 RCS file: /cvsroot/src/external/historical/nawk/dist/lex.c,v
 retrieving revision 1.2
 diff -u -p -r1.2 lex.c
 --- lex.c	26 Aug 2010 14:55:19 -0000	1.2
 +++ lex.c	1 Jan 2017 00:44:00 -0000
 @@ -151,6 +151,8 @@ int gettok(char **pbuf, int *psz)	/* get
  			  || c == '.' || c == '+' || c == '-')
  				*bp++ = c;
  			else {
 +				if (isalpha(c))
 +					WARNING( "no space between number and variable name" );
  				unput(c);
  				break;
  			}
 
 
 -- 
 David A. Holland
 dholland%netbsd.org@localhost
 


Home | Main Index | Thread Index | Old Index