After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 786685 - file: use unsigned int when shifting 31 bits
file: use unsigned int when shifting 31 bits
Status: RESOLVED FIXED
Product: nautilus
Classification: Core
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: Nautilus Maintainers
Nautilus Maintainers
Depends on:
Blocks:
 
 
Reported: 2017-08-23 14:50 UTC by Mohammed Sadiq
Modified: 2017-08-23 15:50 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
file: use unsigned int when shifting 31 bits (1.30 KB, patch)
2017-08-23 14:50 UTC, Mohammed Sadiq
committed Details | Review

Description Mohammed Sadiq 2017-08-23 14:50:41 UTC
.
Comment 1 Mohammed Sadiq 2017-08-23 14:50:48 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'
Comment 2 Ernestas Kulik 2017-08-23 14:53:52 UTC
Review of attachment 358243 [details] [review]:

For correctness sake, I’m not sure that the default signedness is defined by the standard, but sure.
Comment 3 Ernestas Kulik 2017-08-23 15:10:01 UTC
(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.
Comment 4 Mohammed Sadiq 2017-08-23 15:11:17 UTC
(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.
Comment 5 Ernestas Kulik 2017-08-23 15:50:36 UTC
Attachment 358243 [details] pushed as 3ec65ac - file: use unsigned int when shifting 31 bits