Menu

#100 isdigit() called with negative numbers

closed-fixed
nobody
None
5
2013-04-08
2013-03-25
James Teh
No

There are several places in eSpeak where isdigit() can be called with a negative number. isdigit() should only be called with valid unsigned chars, even though it accepts an int. This usually isn't a problem, but it does cause debug assertions in MSVCRT. I'm not sure why this happens.

1. Speak the following string in English: "\ud7a4s" (where \ud7a4 means the character U+d7a4).
In this case, TranslateRoman passes a negative number to isdigit() (around line 983 of numbers.cpp).
2. Compile the dictionary for the "ro" language.
In this case, copy_rule_string passes a negative number to isdigit() (around line 1159 of compiledict.cpp).
3. I've also seen this happen in compile_line (around line 545 of compiledict.cpp), but I'm not sure how to reproduce that.

Discussion

  • Jonathan Duddington

    In all 3 cases, isdigit() is called with a value which is of type char. This should be correct.

    Presumably MSVCRT reports the error if the char value has bit 7 set. I think this is an error in MSVCRT.

    I suppose I'll need to replace isdigit() with my own version.

     
  • James Teh

    James Teh - 2013-03-25

    char is signed. i think you want unsigned char, not char. Casting an 8 bit char to an int yields a negative int. For example, observe the following code:
    char c = 0xff;
    int i = c;
    printf("%d\n", i);
    The result will be -1, not 255. If you change c to an unsigned char, you will get 255 as expected. Of course, you could also cast to avoid having to change all of your types.

     
  • Jonathan Duddington

    • status: open --> closed-fixed
     

Log in to post a comment.

Auth0 Logo