The problem is that there are LOCALE settings where tolower() does things C programmers don't expect. I think tr_TR was one case, the handling of 'I' (Google "tr_tr locale bug" and you'll see lots of people hitting the same general problem). It isn't a problem of type safety, it's a problem that the same inputs might have different outputs for certain library functions when you change environment variables. I don't remember whether there were specific problems with other ctype functions, or if I just thought it was a good idea to be careful, once I realized the class of problem.
[My run-in with this issue was in development of fts2.c/fts3.c. I'm sure the same general series of events leads to similar local implementations in other projects :-).] -scott On Thu, Sep 17, 2015 at 7:03 AM, Jan Nijtmans <jan.nijtmans at gmail.com> wrote: > 2015-08-26 19:03 GMT+02:00 Ralf Junker <ralfjunker at gmx.de>: > > ext/misc/json1.c uses the following functions from the C library: > > > > isalnum(): http://www.sqlite.org/src/artifact/541004e47235cefc?ln=564 > > isspace(): http://www.sqlite.org/src/artifact/541004e47235cefc?ln=635 > > isdigit(): http://www.sqlite.org/src/artifact/541004e47235cefc?ln=829 > > > Shouldn't json1.c avoid them for the same reasons? > > Simpler is: cast the argument to (unsigned char), that > has the same effect (but is more efficient). > > Proposed patch below. > > Thanks! > > Regards, > Jan Nijtmans > ================================================== > --- ext/misc/json1.c > +++ ext/misc/json1.c > @@ -583,18 +583,18 @@ > char c; > u32 j; > int iThis; > int x; > JsonNode *pNode; > - while( isspace(pParse->zJson[i]) ){ i++; } > + while( isspace((unsigned char)pParse->zJson[i]) ){ i++; } > if( (c = pParse->zJson[i])==0 ) return 0; > if( c=='{' ){ > /* Parse object */ > iThis = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); > if( iThis<0 ) return -1; > for(j=i+1;;j++){ > - while( isspace(pParse->zJson[j]) ){ j++; } > + while( isspace((unsigned char)pParse->zJson[j]) ){ j++; } > x = jsonParseValue(pParse, j); > if( x<0 ){ > if( x==(-2) && pParse->nNode==(u32)iThis+1 ) return j+1; > return -1; > } > @@ -601,17 +601,17 @@ > if( pParse->oom ) return -1; > pNode = &pParse->aNode[pParse->nNode-1]; > if( pNode->eType!=JSON_STRING ) return -1; > pNode->jnFlags |= JNODE_LABEL; > j = x; > - while( isspace(pParse->zJson[j]) ){ j++; } > + while( isspace((unsigned char)pParse->zJson[j]) ){ j++; } > if( pParse->zJson[j]!=':' ) return -1; > j++; > x = jsonParseValue(pParse, j); > if( x<0 ) return -1; > j = x; > - while( isspace(pParse->zJson[j]) ){ j++; } > + while( isspace((unsigned char)pParse->zJson[j]) ){ j++; } > c = pParse->zJson[j]; > if( c==',' ) continue; > if( c!='}' ) return -1; > break; > } > @@ -620,18 +620,18 @@ > }else if( c=='[' ){ > /* Parse array */ > iThis = jsonParseAddNode(pParse, JSON_ARRAY, 0, 0); > if( iThis<0 ) return -1; > for(j=i+1;;j++){ > - while( isspace(pParse->zJson[j]) ){ j++; } > + while( isspace((unsigned char)pParse->zJson[j]) ){ j++; } > x = jsonParseValue(pParse, j); > if( x<0 ){ > if( x==(-3) && pParse->nNode==(u32)iThis+1 ) return j+1; > return -1; > } > j = x; > - while( isspace(pParse->zJson[j]) ){ j++; } > + while( isspace((unsigned char)pParse->zJson[j]) ){ j++; } > c = pParse->zJson[j]; > if( c==',' ) continue; > if( c!=']' ) return -1; > break; > } > @@ -656,21 +656,21 @@ > jsonParseAddNode(pParse, JSON_STRING, j+1-i, &pParse->zJson[i]); > if( !pParse->oom ) pParse->aNode[pParse->nNode-1].jnFlags = jnFlags; > return j+1; > }else if( c=='n' > && strncmp(pParse->zJson+i,"null",4)==0 > - && !isalnum(pParse->zJson[i+4]) ){ > + && !isalnum((unsigned char)pParse->zJson[i+4]) ){ > jsonParseAddNode(pParse, JSON_NULL, 0, 0); > return i+4; > }else if( c=='t' > && strncmp(pParse->zJson+i,"true",4)==0 > - && !isalnum(pParse->zJson[i+4]) ){ > + && !isalnum((unsigned char)pParse->zJson[i+4]) ){ > jsonParseAddNode(pParse, JSON_TRUE, 0, 0); > return i+4; > }else if( c=='f' > && strncmp(pParse->zJson+i,"false",5)==0 > - && !isalnum(pParse->zJson[i+5]) ){ > + && !isalnum((unsigned char)pParse->zJson[i+5]) ){ > jsonParseAddNode(pParse, JSON_FALSE, 0, 0); > return i+5; > }else if( c=='-' || (c>='0' && c<='9') ){ > /* Parse number */ > u8 seenDP = 0; > @@ -729,11 +729,11 @@ > if( zJson==0 ) return 1; > pParse->zJson = zJson; > i = jsonParseValue(pParse, 0); > if( pParse->oom ) i = -1; > if( i>0 ){ > - while( isspace(zJson[i]) ) i++; > + while( isspace((unsigned char)zJson[i]) ) i++; > if( zJson[i] ) i = -1; > } > if( i<=0 ){ > if( pCtx!=0 ){ > if( pParse->oom ){ > @@ -860,15 +860,15 @@ > pRoot->jnFlags |= JNODE_APPEND; > pParse->aNode[iLabel].jnFlags |= JNODE_RAW; > } > return pNode; > } > - }else if( zPath[0]=='[' && isdigit(zPath[1]) ){ > + }else if( zPath[0]=='[' && isdigit((unsigned char)zPath[1]) ){ > if( pRoot->eType!=JSON_ARRAY ) return 0; > i = 0; > zPath++; > - while( isdigit(zPath[0]) ){ > + while( isdigit((unsigned char)zPath[0]) ){ > i = i*10 + zPath[0] - '0'; > zPath++; > } > if( zPath[0]!=']' ){ > *pzErr = zPath; > _______________________________________________ > sqlite-users mailing list > sqlite-users at mailinglists.sqlite.org > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users >