Bug 725

Summary: busybox awk will wrongly cast integer to string causing functions to fail.
Product: Busybox Reporter: Andy Lord <bugzilla>
Component: OtherAssignee: unassigned
Status: RESOLVED FIXED    
Severity: normal CC: busybox-cvs
Priority: P5    
Version: 1.12.x   
Target Milestone: ---   
Hardware: Other   
OS: Linux   
Host: Target:
Build:

Description Andy Lord 2009-11-17 23:11:58 UTC
The busybox awk will infer a variable type from its RHS usage rather than the expression used to create it. Gawk does not have this problem. It sounds trivial, and arguably awk implementation dependent, but the following example
shows the full extent of the problem:

In the code below function a() returns 0, b() returns a() and c() returns b().
The a
Code (shell script)=====
awk '
function a() {
  return 0;
}

function b(tmp) {
        tmp= a();
        print "DBG:result="tmp;  #This line forces incorrect cast of tmpc to string
        return tmp;
}
function c(tmpc) {
        tmpc= b();
        return tmpc;
}

BEGIN {
  print "a():"(a()?"true":"false");
  print "b():"(b()?"true":"false");
  print "c():"(c()?"true":"false");
}
'
==============
Run test: echo | sh ./file.sh
==============
Expected output (as with gawk):
===============
# echo | /tmp/q.sh
a():false
DBG:result=0
b():false
DBG:result=0
c():false
================
Actual output : c() returns the string "0" rather than the number 0.
================
# echo | /tmp/q.sh
a():false
DBG:result=0
b():false
DBG:result=0
c():true
================
As noted in the code, it is the debug line that triggers the string cast.
This may may a lot of awk scripts behave (more) oddly than they would normally.

Workaround: Do not use boolean decision statements without operations, as the
0 may be case to a "0" at any point. 

eg. replace if(c()) with if(c()!=0) or (if(c()+0)), 

similarly, while() , (?:) etc.
=================
My speculation:
It looks like the interpreter, when in function c() is going to b() to determine its return type (integer or string), however it is using the 
debug print statement, rather than going to a().


Observed with busybox 1.12.3 on Linux 2.4.20 (Tomato WRT54G)
busybox 1.12.4 on Linux 2.6.15-sigma (NMT HDX 1000)
Comment 1 Andy Lord 2009-11-17 23:50:06 UTC
Nicer away to avoid. Always make sure numeric functions return an explicit numeric value (not implied).
eg 
function b() {
  tmp=a();
  print "a = "tmp;
  return tmp+0;
}
Comment 2 Denys Vlasenko 2009-11-29 23:10:31 UTC
Fixed in git:

[master 1284774] awk: fix an incorrect casting to string (bug 725). -44 bytes.

Will be in 1.16.x
Comment 3 Denys Vlasenko 2009-11-30 00:05:23 UTC
Fix for 1.15.2 is here:

http://busybox.net/downloads/fixes-1.15.2/busybox-1.15.2-awk.patch