1
- // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.unix.Stream,debug.ExprInspection -verify %s
1
+ // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix, alpha.unix.Stream,debug.ExprInspection -verify %s
2
2
3
3
#include "Inputs/system-header-simulator.h"
4
4
#include "Inputs/system-header-simulator-for-malloc.h"
@@ -35,24 +35,26 @@ void test_getline_null_size() {
35
35
fclose (F1 );
36
36
}
37
37
38
- void test_getline_null_buffer_bad_size () {
38
+ void test_getline_null_buffer_size_gt0 () {
39
39
FILE * F1 = tmpfile ();
40
40
if (!F1 )
41
41
return ;
42
42
char * buffer = NULL ;
43
43
size_t n = 8 ;
44
- getline (& buffer , & n , F1 ); // expected-warning {{Line pointer might be null while n value is not zero}}
44
+ getline (& buffer , & n , F1 ); // ok since posix 2018
45
+ free (buffer );
45
46
fclose (F1 );
46
47
}
47
48
48
- void test_getline_null_buffer_bad_size_2 (size_t n ) {
49
+ void test_getline_null_buffer_size_gt0_2 (size_t n ) {
49
50
FILE * F1 = tmpfile ();
50
51
if (!F1 )
51
52
return ;
52
53
char * buffer = NULL ;
53
54
if (n > 0 ) {
54
- getline (& buffer , & n , F1 ); // expected-warning {{Line pointer might be null while n value is not zero}}
55
+ getline (& buffer , & n , F1 ); // ok since posix 2018
55
56
}
57
+ free (buffer );
56
58
fclose (F1 );
57
59
}
58
60
@@ -67,6 +69,58 @@ void test_getline_null_buffer_unknown_size(size_t n) {
67
69
free (buffer );
68
70
}
69
71
72
+ void test_getline_null_buffer_undef_size () {
73
+ FILE * F1 = tmpfile ();
74
+ if (!F1 )
75
+ return ;
76
+
77
+ char * buffer = NULL ;
78
+ size_t n ;
79
+
80
+ getline (& buffer , & n , F1 ); // ok since posix 2018
81
+ fclose (F1 );
82
+ free (buffer );
83
+ }
84
+
85
+ void test_getline_buffer_size_0 () {
86
+ FILE * F1 = tmpfile ();
87
+ if (!F1 )
88
+ return ;
89
+
90
+ char * buffer = malloc (10 );
91
+ size_t n = 0 ;
92
+ if (buffer != NULL )
93
+ getline (& buffer , & n , F1 ); // ok, the buffer is enough for 0 character
94
+ fclose (F1 );
95
+ free (buffer );
96
+ }
97
+
98
+ void test_getline_buffer_bad_size () {
99
+ FILE * F1 = tmpfile ();
100
+ if (!F1 )
101
+ return ;
102
+
103
+ char * buffer = malloc (10 );
104
+ size_t n = 100 ;
105
+ if (buffer != NULL )
106
+ getline (& buffer , & n , F1 ); // expected-warning {{The buffer from the first argument is smaller than the size specified by the second parameter}}
107
+ fclose (F1 );
108
+ free (buffer );
109
+ }
110
+
111
+ void test_getline_buffer_smaller_size () {
112
+ FILE * F1 = tmpfile ();
113
+ if (!F1 )
114
+ return ;
115
+
116
+ char * buffer = malloc (100 );
117
+ size_t n = 10 ;
118
+ if (buffer != NULL )
119
+ getline (& buffer , & n , F1 ); // ok, there is enough space for 10 characters
120
+ fclose (F1 );
121
+ free (buffer );
122
+ }
123
+
70
124
void test_getline_null_buffer () {
71
125
FILE * F1 = tmpfile ();
72
126
if (!F1 )
@@ -101,24 +155,26 @@ void test_getdelim_null_size() {
101
155
fclose (F1 );
102
156
}
103
157
104
- void test_getdelim_null_buffer_bad_size () {
158
+ void test_getdelim_null_buffer_size_gt0 () {
105
159
FILE * F1 = tmpfile ();
106
160
if (!F1 )
107
161
return ;
108
162
char * buffer = NULL ;
109
163
size_t n = 8 ;
110
- getdelim (& buffer , & n , ';' , F1 ); // expected-warning {{Line pointer might be null while n value is not zero}}
164
+ getdelim (& buffer , & n , ';' , F1 ); // ok since posix 2018
165
+ free (buffer );
111
166
fclose (F1 );
112
167
}
113
168
114
- void test_getdelim_null_buffer_bad_size_2 (size_t n ) {
169
+ void test_getdelim_null_buffer_size_gt0_2 (size_t n ) {
115
170
FILE * F1 = tmpfile ();
116
171
if (!F1 )
117
172
return ;
118
173
char * buffer = NULL ;
119
174
if (n > 0 ) {
120
- getdelim (& buffer , & n , ' ' , F1 ); // expected-warning {{Line pointer might be null while n value is not zero}}
175
+ getdelim (& buffer , & n , ' ' , F1 ); // ok since posix 2018
121
176
}
177
+ free (buffer );
122
178
fclose (F1 );
123
179
}
124
180
@@ -289,18 +345,21 @@ void test_getline_not_null(char **buffer, size_t *size) {
289
345
}
290
346
}
291
347
292
- void test_getline_size_0 (size_t size ) {
348
+ void test_getline_size_constraint (size_t size ) {
293
349
FILE * file = fopen ("file.txt" , "r" );
294
350
if (file == NULL ) {
295
351
return ;
296
352
}
297
353
298
354
size_t old_size = size ;
299
- char * buffer = NULL ;
300
- ssize_t r = getline (& buffer , & size , file );
301
- if (r >= 0 ) {
302
- // Since buffer is NULL, old_size should be 0. Otherwise, there would be UB.
303
- clang_analyzer_eval (old_size == 0 ); // expected-warning{{TRUE}}
355
+ char * buffer = malloc (10 );
356
+ if (buffer != NULL ) {
357
+ ssize_t r = getline (& buffer , & size , file );
358
+ if (r >= 0 ) {
359
+ // Since buffer has a size of 10, old_size must be less than or equal to 10.
360
+ // Otherwise, there would be UB.
361
+ clang_analyzer_eval (old_size <= 10 ); // expected-warning{{TRUE}}
362
+ }
304
363
}
305
364
fclose (file );
306
365
free (buffer );
@@ -334,7 +393,9 @@ void test_getline_negative_buffer() {
334
393
335
394
char * buffer = NULL ;
336
395
size_t n = -1 ;
337
- getline (& buffer , & n , file ); // expected-warning {{Line pointer might be null while n value is not zero}}
396
+ getline (& buffer , & n , file ); // ok since posix 2018
397
+ free (buffer );
398
+ fclose (file );
338
399
}
339
400
340
401
void test_getline_negative_buffer_2 (char * buffer ) {
@@ -348,5 +409,6 @@ void test_getline_negative_buffer_2(char *buffer) {
348
409
if (ret > 0 ) {
349
410
clang_analyzer_eval (ret < n ); // expected-warning {{TRUE}}
350
411
}
412
+ free (buffer );
351
413
fclose (file );
352
414
}
0 commit comments