GNOME Bugzilla – Bug 786685
file: use unsigned int when shifting 31 bits
Last modified: 2017-08-23 15:50:42 UTC
.
Created attachment 358243 [details] [review] file: use unsigned int when shifting 31 bits In C, as numbers are signed integers by default, it is an Undefined Behaviour to left shift a signed integer by 31 bits (when the integer size is 32 bits which is the common size where nautilus runs). So explicitly use unsigned integer. This issue was found by UBsan: nautilus/src/nautilus-file.c:312:14: runtime error: left shift of 1 by 31 places cannot be represented in type 'int' nautilus/src/nautilus-file.c:4273:11: runtime error: left shift of 1 by 31 places cannot be represented in type 'int' nautilus/src/nautilus-file.c:366:18: runtime error: left shift of 1 by 31 places cannot be represented in type 'int'
Review of attachment 358243 [details] [review]: For correctness sake, I’m not sure that the default signedness is defined by the standard, but sure.
(In reply to Ernestas Kulik from comment #2) > Review of attachment 358243 [details] [review] [review]: > > For correctness sake, I’m not sure that the default signedness is defined by > the standard, but sure. ISO/IEC 9899:1999 (E) §6.4.4.5: The type of an integer constant is the first of the corresponding list in which its value can be represented. int is indeed the first one in the table, so I must have confused it with the default signedness of the char type.
(In reply to Ernestas Kulik from comment #2) > Review of attachment 358243 [details] [review] [review]: > > For correctness sake, I’m not sure that the default signedness is defined by > the standard, but sure. From C11 6.5.7#3: The integer promotions are performed on each of the operands. The type of the result is that of the promoted left operand. If the value of the right operand is negative or is greater than or equal to the width of the promoted left operand, the behavior is undefined. Also C11 6.3.1.1#2: The following may be used in an expression wherever an int or unsigned int may be used: — An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int. — A bit-field of type _Bool, int, signed int, or unsigned int. If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. 58) All other types are unchanged by the integer promotions. So in short, if the number fits in int, it is promoted to int, else to unsigned int, and higher sizes. For the same reason, a char literal has a size of int when used in expressions. So they are signed int by default if it fits.
Attachment 358243 [details] pushed as 3ec65ac - file: use unsigned int when shifting 31 bits