mirror of
https://github.com/checkpoint-restore/criu
synced 2025-08-31 06:15:24 +00:00
compel: fix GCC 12 failure (out of bounds)
This is a confusing change as it seems the original code was just wrong. GCC 12 complains with: In function ‘__conv_val’, inlined from ‘std_strtoul’ at compel/plugins/std/string.c:202:7: compel/plugins/std/string.c:154:24: error: array subscript 97 is above array bounds of ‘const char[37]’ [-Werror=array-bounds] 154 | return &conv_tab[__tolower(c)] - conv_tab; | ^~~~~~~~~~~~~~~~~~~~~~~ compel/plugins/std/string.c: In function ‘std_strtoul’: compel/plugins/std/string.c:10:19: note: while referencing ‘conv_tab’ 10 | static const char conv_tab[] = "0123456789abcdefghijklmnopqrstuvwxyz"; | ^~~~~~~~ cc1: all warnings being treated as errors Which sounds correct. The array conv_tab has just 37 elements. If I understand the code correctly we are trying to convert anything that is character between a-z and A-Z to a number for cases where the base is larger than 10. For a base 11 conversion b|B should return 11. For a base 35 conversion z|Z should return 35. This is all for a strtoul() implementation. The original code was: static const char conv_tab[] = "0123456789abcdefghijklmnopqrstuvwxyz"; return &conv_tab[__tolower(c)] - conv_tab; and that seems wrong. If conv_tab would have been some kind of hash it could have worked, but '__tolower()' will always return something larger than 97 ('a') which will always overflow the array. But maybe I just don't get that part of the code. I replaced it with return __tolower(c) - 'a' + 10; which does the right thing: 'A' = 10, 'B' = 11 ... 'Z' = 35 Signed-off-by: Adrian Reber <areber@redhat.com>
This commit is contained in:
committed by
Andrei Vagin
parent
6be10a232d
commit
bf6975c3e5
@@ -151,7 +151,12 @@ static unsigned int __conv_val(unsigned char c)
|
||||
if (__isdigit(c))
|
||||
return c - '0';
|
||||
else if (__isalpha(c))
|
||||
return &conv_tab[__tolower(c)] - conv_tab;
|
||||
/**
|
||||
* If we want the value of something which __isalpha() == true
|
||||
* it has to be base > 10. 'A' = 10, 'B' = 11 ... 'Z' = 35
|
||||
*/
|
||||
return __tolower(c) - 'a' + 10;
|
||||
|
||||
return -1u;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user