Bug Summary

File:utils/utils.c
Warning:line 130, column 28
The result of the left shift is undefined because the left operand is negative

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name utils.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/var/lib/jenkins/workspace/scan-build-libcss -resource-dir /usr/lib/llvm-14/lib/clang/14.0.6 -D _BSD_SOURCE -D _DEFAULT_SOURCE -I /var/lib/jenkins/workspace/scan-build-libcss/include/ -I /var/lib/jenkins/workspace/scan-build-libcss/src -D _ALIGNED=__attribute__((aligned)) -D STMTEXPR=1 -D DEBUG -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.6/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -Og -Wwrite-strings -Wno-error -std=c99 -fconst-strings -fdebug-compilation-dir=/var/lib/jenkins/workspace/scan-build-libcss -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-display-progress -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /var/lib/jenkins/workspace/scan-build-libcss/clangScanBuildReports/2024-05-26-202032-2713686-1 -x c src/utils/utils.c
1/*
2 * This file is part of LibCSS.
3 * Licensed under the MIT License,
4 * http://www.opensource.org/licenses/mit-license.php
5 * Copyright 2007-9 John-Mark Bell <jmb@netsurf-browser.org>
6 */
7
8#include "utils/utils.h"
9
10css_fixed css__number_from_lwc_string(lwc_string *string,
11 bool_Bool int_only, size_t *consumed)
12{
13 if (string == NULL((void*)0) || lwc_string_length(string)({((string != ((void*)0)) ? (void) (0) : __assert_fail ("string != NULL"
, "src/utils/utils.c", 13, __extension__ __PRETTY_FUNCTION__)
); (string)->len;})
== 0
||
1
Assuming 'string' is not equal to NULL
2
'?' condition is true
3
Assuming the condition is false
5
Taking false branch
14 consumed == NULL((void*)0))
4
Assuming 'consumed' is not equal to NULL
15 return 0;
16
17 return css__number_from_string(
8
Calling 'css__number_from_string'
18 (uint8_t *)lwc_string_data(string)({((string != ((void*)0)) ? (void) (0) : __assert_fail ("string != NULL"
, "src/utils/utils.c", 18, __extension__ __PRETTY_FUNCTION__)
); (const char *)((string)+1);})
,
6
'?' condition is true
19 lwc_string_length(string)({((string != ((void*)0)) ? (void) (0) : __assert_fail ("string != NULL"
, "src/utils/utils.c", 19, __extension__ __PRETTY_FUNCTION__)
); (string)->len;})
,
7
'?' condition is true
20 int_only,
21 consumed);
22}
23
24css_fixed css__number_from_string(const uint8_t *data, size_t len,
25 bool_Bool int_only, size_t *consumed)
26{
27 const uint8_t *ptr = data;
28 int sign = 1;
29 int32_t intpart = 0;
30 int32_t fracpart = 0;
31 int32_t pwr = 1;
32
33 if (data
8.1
'data' is not equal to NULL
== NULL((void*)0) || len
8.2
'len' is not equal to 0
== 0 || consumed
8.3
'consumed' is not equal to NULL
== NULL((void*)0))
9
Taking false branch
34 return 0;
35
36 /* number = [+-]? ([0-9]+ | [0-9]* '.' [0-9]+) */
37
38 /* Extract sign, if any */
39 if (ptr[0] == '-') {
10
Assuming the condition is false
11
Taking false branch
40 sign = -1;
41 len--;
42 ptr++;
43 } else if (ptr[0] == '+') {
12
Assuming the condition is false
13
Taking false branch
44 len--;
45 ptr++;
46 }
47
48 /* Ensure we have either a digit or a '.' followed by a digit */
49 if (len
13.1
'len' is not equal to 0
== 0) {
14
Taking false branch
50 *consumed = 0;
51 return 0;
52 } else {
53 if (ptr[0] == '.') {
15
Assuming the condition is false
54 if (len == 1 || ptr[1] < '0' || '9' < ptr[1]) {
55 *consumed = 0;
56 return 0;
57 }
58 } else if (ptr[0] < '0' || '9' < ptr[0]) {
16
Assuming the condition is false
17
Assuming the condition is false
18
Taking false branch
59 *consumed = 0;
60 return 0;
61 }
62 }
63
64 /* Now extract intpart, assuming base 10 */
65 while (len
18.1
'len' is > 0
> 0
) {
21
Assuming 'len' is > 0
26
Assuming 'len' is > 0
32
Assuming 'len' is > 0
66 /* Stop on first non-digit */
67 if (ptr[0] < '0' || '9' < ptr[0])
19
Taking false branch
22
Assuming the condition is false
23
Assuming the condition is false
24
Taking false branch
27
Assuming the condition is false
28
Assuming the condition is false
29
Taking false branch
33
Assuming the condition is true
68 break;
69
70 /* Prevent overflow of 'intpart'; proper clamping below */
71 if (intpart < (1 << 22)) {
20
Taking true branch
25
Taking true branch
30
Assuming the condition is false
31
Taking false branch
72 intpart *= 10;
73 intpart += ptr[0] - '0';
74 }
75 ptr++;
76 len--;
77 }
78
79 /* And fracpart, again, assuming base 10 */
80 if (int_only == false0 && len > 1 && ptr[0] == '.' &&
34
Assuming 'int_only' is equal to false
35
Assuming 'len' is > 1
36
Assuming the condition is true
39
Taking true branch
81 ('0' <= ptr[1] && ptr[1] <= '9')) {
37
Assuming the condition is true
38
Assuming the condition is true
82 ptr++;
83 len--;
84
85 while (len
39.1
'len' is > 0
> 0
) {
42
Assuming 'len' is <= 0
43
Loop condition is false. Execution continues on line 97
86 if (ptr[0] < '0' || '9' < ptr[0])
40
Taking false branch
87 break;
88
89 if (pwr
40.1
'pwr' is < 1000000
< 1000000) {
41
Taking true branch
90 pwr *= 10;
91 fracpart *= 10;
92 fracpart += ptr[0] - '0';
93 }
94 ptr++;
95 len--;
96 }
97 fracpart = ((1 << 10) * fracpart + pwr/2) / pwr;
98 if (fracpart >= (1 << 10)) {
44
Assuming the condition is true
45
Taking true branch
99 intpart++;
46
Value assigned to 'intpart'
100 fracpart &= (1 << 10) - 1;
101 }
102 }
103
104 *consumed = ptr - data;
105
106 if (sign
46.1
'sign' is > 0
> 0) {
47
Taking true branch
107 /* If the result is larger than we can represent,
108 * then clamp to the maximum value we can store. */
109 if (intpart >= (1 << 21)) {
48
Assuming the condition is false
49
Taking false branch
110 intpart = (1 << 21) - 1;
111 fracpart = (1 << 10) - 1;
112 }
113 }
114 else {
115 /* If the negated result is smaller than we can represent
116 * then clamp to the minimum value we can store. */
117 if (intpart >= (1 << 21)) {
118 intpart = -(1 << 21);
119 fracpart = 0;
120 }
121 else {
122 intpart = -intpart;
123 if (fracpart) {
124 fracpart = (1 << 10) - fracpart;
125 intpart--;
126 }
127 }
128 }
129
130 return ((uint32_t)intpart << 10) | fracpart;
50
The result of the left shift is undefined because the left operand is negative
131}
132