@@ -3120,44 +3120,82 @@ Check for misuses of stream APIs. Check for misuses of stream APIs: ``fopen, fcl
3120
3120
3121
3121
alpha.unix .Stream (C)
3122
3122
"""""""""""""""""""""
3123
- Check stream handling functions: ``fopen, tmpfile, fclose, fread, fwrite, fseek, ftell, rewind, fgetpos, ``
3124
- ``fsetpos, clearerr, feof, ferror, fileno ``.
3123
+ Check C stream handling functions:
3124
+ ``fopen, fdopen, freopen, tmpfile, fclose, fread, fwrite, fgetc, fgets, fputc, fputs, fprintf, fscanf, ungetc, getdelim, getline, fseek, fseeko, ftell, ftello, fflush, rewind, fgetpos, fsetpos, clearerr, feof, ferror, fileno ``.
3125
+
3126
+ The checker maintains information about the C stream objects (``FILE * ``) and
3127
+ can detect error conditions related to use of streams. The following conditions
3128
+ are detected:
3129
+
3130
+ * The ``FILE * `` pointer passed to the function is NULL (the single exception is
3131
+ ``fflush `` where NULL is allowed).
3132
+ * Use of stream after close.
3133
+ * Opened stream is not closed.
3134
+ * Read from a stream after end-of-file. (This is not a fatal error but reported
3135
+ by the checker. Stream remains in EOF state and the read operation fails.)
3136
+ * Use of stream when the file position is indeterminate after a previous failed
3137
+ operation. Some functions (like ``ferror ``, ``clearerr ``, ``fseek ``) are
3138
+ allowed in this state.
3139
+ * Invalid 3rd ("``whence ``") argument to ``fseek ``.
3140
+
3141
+ The checker does not track the correspondence between integer file descriptors
3142
+ and ``FILE * `` pointers. Operations on standard streams like ``stdin `` are not
3143
+ treated specially and are therefore often not recognized (because these streams
3144
+ are usually not opened explicitly by the program, and are global variables).
3125
3145
3126
3146
.. code-block :: c
3127
3147
3128
- void test () {
3148
+ void test1 () {
3129
3149
FILE *p = fopen("foo", "r");
3130
3150
} // warn: opened file is never closed
3131
3151
3132
- void test () {
3152
+ void test2 () {
3133
3153
FILE *p = fopen("foo", "r");
3134
3154
fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
3135
3155
fclose(p);
3136
3156
}
3137
3157
3138
- void test () {
3158
+ void test3 () {
3139
3159
FILE *p = fopen("foo", "r");
3160
+ if (p) {
3161
+ fseek(p, 1, 3); // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
3162
+ fclose(p);
3163
+ }
3164
+ }
3140
3165
3141
- if (p)
3142
- fseek(p, 1, 3);
3143
- // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
3166
+ void test4() {
3167
+ FILE *p = fopen("foo", "r");
3168
+ if (!p)
3169
+ return;
3144
3170
3145
3171
fclose(p);
3172
+ fclose(p); // warn: stream already closed
3146
3173
}
3147
3174
3148
- void test () {
3175
+ void test5 () {
3149
3176
FILE *p = fopen("foo", "r");
3177
+ if (!p)
3178
+ return;
3179
+
3180
+ fgetc(p);
3181
+ if (!ferror(p))
3182
+ fgetc(p); // warn: possible read after end-of-file
3183
+
3150
3184
fclose(p);
3151
- fclose(p); // warn: already closed
3152
3185
}
3153
3186
3154
- void test() {
3155
- FILE *p = tmpfile();
3156
- ftell(p); // warn: stream pointer might be NULL
3187
+ void test6() {
3188
+ FILE *p = fopen("foo", "r");
3189
+ if (!p)
3190
+ return;
3191
+
3192
+ fgetc(p);
3193
+ if (!feof(p))
3194
+ fgetc(p); // warn: file position may be indeterminate after I/O error
3195
+
3157
3196
fclose(p);
3158
3197
}
3159
3198
3160
-
3161
3199
.. _alpha-unix-cstring-BufferOverlap :
3162
3200
3163
3201
alpha.unix .cstring .BufferOverlap (C)
0 commit comments