Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug with integer parsing in MD_StringIsCStyleInt and MD_CStyleIntFromString #26

Open
EeroMutka opened this issue Nov 1, 2024 · 0 comments

Comments

@EeroMutka
Copy link

Calling MD_StringIsCStyleInt(MD_S8Lit("0")) returns false and MD_CStyleIntFromString(MD_S8Lit("012345")) returns 5349.

Both functions handle radix parsing incorrectly. If the parser encounters a leading zero, but no "x" or "b", then you will get incorrect results.

Here are the functions after my fix:

MD_FUNCTION MD_b32
MD_StringIsCStyleInt(MD_String8 string)
{
    MD_u8 *ptr = string.str;
    MD_u8 *opl = string.str + string.size;
    
    // consume sign
    for (;ptr < opl && (*ptr == '+' || *ptr == '-'); ptr += 1);
    
    // radix from prefix
    MD_u32 radix = 10;
    if (ptr + 1 < opl && *ptr == '0')
    {
        MD_u8 c1 = ptr[1];
        if (c1 == 'x')
        {
            ptr += 2;
            radix = 0x10;
        }
        else if (c1 == 'b')
        {
            ptr += 2;
            radix = 2;
        }
    }
    
    // check integer "digits"
    MD_String8 digits_substr = MD_S8Range(ptr, opl);
    MD_b32 result = MD_StringIsU64(digits_substr, radix);
    
    return(result);
}
MD_FUNCTION MD_i64
MD_CStyleIntFromString(MD_String8 string)
{
    MD_u64 p = 0;
    
    // consume sign
    MD_i64 sign = +1;
    if (p < string.size)
    {
        MD_u8 c = string.str[p];
        if (c == '-')
        {
            sign = -1;
            p += 1;
        }
        else if (c == '+')
        {
            p += 1;
        }
    }
    
    // radix from prefix
    MD_u32 radix = 10;
    if (p + 1 < string.size && string.str[p] == '0')
    {
        MD_u8 c1 = string.str[p + 1];
        if (c1 == 'x')
        {
            p += 2;
            radix = 0x10;
        }
        else if (c1 == 'b')
        {
            p += 2;
            radix = 2;
        }
    }
    
    // consume integer "digits"
    MD_String8 digits_substr = MD_S8Skip(string, p);
    MD_u64 n = MD_U64FromString(digits_substr, radix);
    
    // combine result
    MD_i64 result = sign*n;
    return(result);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant