brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.8 KiB · 86635ed Raw
323 lines · c
1// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix,debug.ExprInspection -verify %s2 3#include "Inputs/system-header-simulator.h"4#include "Inputs/system-header-simulator-for-malloc.h"5#include "Inputs/system-header-simulator-for-valist.h"6 7void clang_analyzer_eval(int);8void clang_analyzer_dump_int(int);9void clang_analyzer_dump_ptr(void*);10void clang_analyzer_warnIfReached();11 12void test_getline_null_lineptr() {13  FILE *F1 = tmpfile();14  if (!F1)15    return;16 17  char **buffer = NULL;18  size_t n = 0;19  getline(buffer, &n, F1); // expected-warning {{Line pointer might be NULL}}20  fclose(F1);21}22 23void test_getline_null_size() {24  FILE *F1 = tmpfile();25  if (!F1)26    return;27  char *buffer = NULL;28  getline(&buffer, NULL, F1); // expected-warning {{Size pointer might be NULL}}29  fclose(F1);30}31 32void test_getline_null_buffer_size_gt0() {33  FILE *F1 = tmpfile();34  if (!F1)35    return;36  char *buffer = NULL;37  size_t n = 8;38  getline(&buffer, &n, F1); // ok since posix 201839  free(buffer);40  fclose(F1);41}42 43void test_getline_null_buffer_size_gt0_2(size_t n) {44  FILE *F1 = tmpfile();45  if (!F1)46    return;47  char *buffer = NULL;48  if (n > 0) {49    getline(&buffer, &n, F1); // ok since posix 201850  }51  free(buffer);52  fclose(F1);53}54 55void test_getline_null_buffer_unknown_size(size_t n) {56  FILE *F1 = tmpfile();57  if (!F1)58    return;59  char *buffer = NULL;60 61  getline(&buffer, &n, F1);  // ok62  fclose(F1);63  free(buffer);64}65 66void test_getline_null_buffer_undef_size() {67  FILE *F1 = tmpfile();68  if (!F1)69    return;70 71  char *buffer = NULL;72  size_t n;73 74  getline(&buffer, &n, F1); // ok since posix 201875  fclose(F1);76  free(buffer);77}78 79void test_getline_buffer_size_0() {80  FILE *F1 = tmpfile();81  if (!F1)82    return;83 84  char *buffer = malloc(10);85  size_t n = 0;86  if (buffer != NULL)87    getline(&buffer, &n, F1); // ok, the buffer is enough for 0 character88  fclose(F1);89  free(buffer);90}91 92void test_getline_buffer_bad_size() {93  FILE *F1 = tmpfile();94  if (!F1)95    return;96 97  char *buffer = malloc(10);98  size_t n = 100;99  if (buffer != NULL)100    getline(&buffer, &n, F1); // expected-warning {{The buffer from the first argument is smaller than the size specified by the second parameter}}101  fclose(F1);102  free(buffer);103}104 105void test_getline_buffer_smaller_size() {106  FILE *F1 = tmpfile();107  if (!F1)108    return;109 110  char *buffer = malloc(100);111  size_t n = 10;112  if (buffer != NULL)113    getline(&buffer, &n, F1); // ok, there is enough space for 10 characters114  fclose(F1);115  free(buffer);116}117 118void test_getline_buffer_undef_size() {119  FILE *F1 = tmpfile();120  if (!F1)121    return;122 123  char *buffer = malloc(100);124  size_t n;125  if (buffer != NULL)126    getline(&buffer, &n, F1); // expected-warning {{The buffer from the first argument is not NULL, but the size specified by the second parameter is undefined}}127  fclose(F1);128  free(buffer);129}130 131 132void test_getline_null_buffer() {133  FILE *F1 = tmpfile();134  if (!F1)135    return;136  char *buffer = NULL;137  size_t n = 0;138  ssize_t r = getline(&buffer, &n, F1);139  // getline returns -1 on failure, number of char reads on success (>= 0)140  if (r < -1) {141    clang_analyzer_warnIfReached(); // must not happen142  } else {143    // The buffer could be allocated both on failure and success144    clang_analyzer_dump_int(n);      // expected-warning {{conj_$}}145    clang_analyzer_dump_ptr(buffer); // expected-warning {{conj_$}}146  }147  free(buffer);148  fclose(F1);149}150 151void test_getdelim_null_size() {152  FILE *F1 = tmpfile();153  if (!F1)154    return;155  char *buffer = NULL;156  getdelim(&buffer, NULL, ',', F1); // expected-warning {{Size pointer might be NULL}}157  fclose(F1);158}159 160void test_getdelim_null_buffer_size_gt0() {161  FILE *F1 = tmpfile();162  if (!F1)163    return;164  char *buffer = NULL;165  size_t n = 8;166  getdelim(&buffer, &n, ';', F1); // ok since posix 2018167  free(buffer);168  fclose(F1);169}170 171void test_getdelim_null_buffer_size_gt0_2(size_t n) {172  FILE *F1 = tmpfile();173  if (!F1)174    return;175  char *buffer = NULL;176  if (n > 0) {177    getdelim(&buffer, &n, ' ', F1);  // ok since posix 2018178  }179  free(buffer);180  fclose(F1);181}182 183void test_getdelim_null_buffer_unknown_size(size_t n) {184  FILE *F1 = tmpfile();185  if (!F1)186    return;187  char *buffer = NULL;188  getdelim(&buffer, &n, '-', F1);  // ok189  fclose(F1);190  free(buffer);191}192 193void test_getdelim_null_buffer() {194  FILE *F1 = tmpfile();195  if (!F1)196    return;197  char *buffer = NULL;198  size_t n = 0;199  ssize_t r = getdelim(&buffer, &n, '\r', F1);200  // getdelim returns -1 on failure, number of char reads on success (>= 0)201  if (r < -1) {202    clang_analyzer_warnIfReached(); // must not happen203  }204  else {205    // The buffer could be allocated both on failure and success206    clang_analyzer_dump_int(n);      // expected-warning {{conj_$}}207    clang_analyzer_dump_ptr(buffer); // expected-warning {{conj_$}}208  }209  free(buffer);210  fclose(F1);211}212 213void test_getline_while() {214  FILE *file = fopen("file.txt", "r");215  if (file == NULL) {216    return;217  }218 219  char *line = NULL;220  size_t len = 0;221  ssize_t read;222 223  while ((read = getline(&line, &len, file)) != -1) {224    printf("%s\n", line);225  }226 227  free(line);228  fclose(file);229}230 231void test_getline_return_check() {232  FILE *file = fopen("file.txt", "r");233  if (file == NULL) {234    return;235  }236 237  char *line = NULL;238  size_t len = 0;239  ssize_t r = getline(&line, &len, file);240 241  if (r != -1) {242    if (line[0] == '\0') {} // ok243  }244  free(line);245  fclose(file);246}247 248void test_getline_clear_eof() {249  FILE *file = fopen("file.txt", "r");250  if (file == NULL) {251    return;252  }253 254  size_t n = 10;255  char *buffer = malloc(n);256  ssize_t read = fread(buffer, n, 1, file);257  if (feof(file)) {258    clearerr(file);259    getline(&buffer, &n, file); // ok260  }261  fclose(file);262  free(buffer);263}264 265void test_getline_not_null(char **buffer, size_t *size) {266  FILE *file = fopen("file.txt", "r");267  if (file == NULL) {268    return;269  }270 271  getline(buffer, size, file);272  fclose(file);273 274  if (size == NULL || buffer == NULL) {275    clang_analyzer_warnIfReached(); // must not happen276  }277}278 279void test_getline_size_constraint(size_t size) {280  FILE *file = fopen("file.txt", "r");281  if (file == NULL) {282    return;283  }284 285  size_t old_size = size;286  char *buffer = malloc(10);287  if (buffer != NULL) {288    ssize_t r = getline(&buffer, &size, file);289    if (r >= 0) {290      // Since buffer has a size of 10, old_size must be less than or equal to 10.291      // Otherwise, there would be UB.292      clang_analyzer_eval(old_size <= 10); // expected-warning{{TRUE}}293    }294  }295  fclose(file);296  free(buffer);297}298 299void test_getline_negative_buffer() {300  FILE *file = fopen("file.txt", "r");301  if (file == NULL) {302    return;303  }304 305  char *buffer = NULL;306  size_t n = -1;307  getline(&buffer, &n, file); // ok since posix 2018308  free(buffer);309  fclose(file);310}311 312void test_getline_negative_buffer_2(char *buffer) {313  FILE *file = fopen("file.txt", "r");314  if (file == NULL) {315    return;316  }317 318  size_t n = -1;319  (void)getline(&buffer, &n, file); // ok320  free(buffer);321  fclose(file);322}323