This was what i discovered:
I am trying to parse a JSON that looks like this:
Code: Select all
{
"mantHistoryInfo": [
{
"code": "AFC-1094-C0",
"maxRate": 0.0,
"minRate": 0.0,
"phase": 0,
"timeSlot": "2024-01-01T00:00",
"value": 0.0
},
{
"code": "AFC-1094-C0",
"maxRate": 30.0,
"minRate": 0.0,
"phase": 0,
"timeSlot": "2024-01-04T18:00",
"value": 0.000459
}
]
}
So i downloaded the latest version of YAJL and tried again. The parser was not crashing anymore but it was not working as intended because the YAJL_GET_NUMBER function was returning the value 4.000 instead of 0.000459.
I immediatly thought that this was strange, it seemed like the bugfix was not working but the user Jeron in the topic that i linked above said that for him the bugfix had resolved the issue.
So what i did was look in the source code and tried to figure out what was going on.
This is the piece of code that was causing problems:
Code: Select all
if YAJL_IS_NUMBER(node);
init_gconv();
str = yajl_iconv_toLocal( gConv: nv.number.R );
mem.yajl_iconv_string += 1;
monitor;
retval = %dec(%str(str):30:9);
on-error 105;
// Remove the RNX0105 (error converting numeric)
QMHRCVPM( RCVM0100
: %size(RCVM0100)
: 'RCVM0100'
: '*'
: 0
: '*ESCAPE'
: *blanks
: 0
: '*REMOVE'
: x'0000000800000000');
eval(h) retval = atof(str);
endmon;
yajl_iconv_string_free(str);
mem.yajl_iconv_string -= 1;
else;
retval = 0;
endif;
return retval;
This explained everything. I am italian and my IBM i has italian locales. The "atof" function is locale-dependent, meaning that if it's used in an "italian" environment it must receive the string "0,000459" to work correctly.
This even explained why the other user had no more complaints, he is probably using a US locale where the decimal separator is the "dot".
To fix my bug i followed the IBM guide on how to "force" a specific locale when doing stuff that is locale-sensitive.
Even if my program is working now, i still think that this can be considered a "bug" of the parser. That is because the JSON grammar does not allow for ambiguity, the notation for numbers is such that only the "dot" che be used as a decimal separator. For this reason when the parser calls the atof function it can safely assume that the "locale" in which the number is written is the POSIX / US locale, and for this reason it should enforce that locale just how the IBM guide explains to do.
Otherwise the parser does not work "out of the box" for people that use different locales, but only for those who use the point as the decimal separator.