The C Standard, 7.23.9.3 paragraph 2 [ISO/IEC 9899:2024], defines the following behavior for fsetpos():
The
fsetposfunction sets thembstate_tobject (if any) and file position indicator for the stream pointed to bystreamaccording to the value of the object pointed to bypos, which shall be a value obtained from an earlier
Undefined behavior ;
...
successful call to the
fgetposfunction on a stream associated with the same file.
...
Invoking the fsetpos() function with any other values for pos is undefined behavior 181.
Noncompliant
...
Code Example
This noncompliant code example attempts to read three values from a file and then set the file position pointer back to the beginning of the file:
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h> int main(int argc, char *argv[]) { FILE *info = fopen( "widget.txt", "r"); int a,b,c; if(info == NULL) #include <string.h> int opener(FILE *file) { perror("Could not open file")int rc; return 0fpos_t offset; } if(fscanf(info,"%i %i %i", &a, &b, &c)!=3) { fprintf(stderr, "Expected but did not find three integers \n"); fclose(info);memset(&offset, 0, sizeof(offset)); if (file == NULL) { return 0-1; } else { /* Read in data printf("abc is %i%i%i\n",a,b,c); }from file */ intrc j=3; if(fsetpos(infofile, &j)!=0)offset); { if (rc perror("fsetpos failed"); fclose(info);!= 0 ) { return 0rc; } if(fscanf(info,"%i %i %i", &a, &b, &c)!=3) { fprintf(stderr, "Expected but did not find %i %i %i \n"); } else { printf("abc is %i%i%i \n",a,b,c); } fclose(info); return 0; } } |
Compliant Solution
return 0;
}
|
Only the return value of an fgetpos() call is a valid argument to fsetpos(); passing a value of type fpos_t that was created in any other way is undefined behavior 181.
Compliant Solution
In this compliant solution, the initial file position indicator is stored by first calling fgetpos(), which is used to restore the state to the beginning of the file in the later call to fsetpos():
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <stdio.h>
#include <string.h>
int opener(FILE *file) {
int rc | ||||
| Code Block | ||||
| ||||
int main(int argc, char argv[]) { FILE \*info = fopen( "widget.txt", "r"); fpos_t posoffset; int a,b,c; if (infofile == NULL) { perror("Could not open file") return -1; } rc = return 0fgetpos(file, &offset); } if if(fgetpos(info, &pos)\(rc != 0 ) { perror("fgetpos failed") return rc; } fclose(info); return 0; } if(fscanf(info,"%i %i %i", &a, &b, &c)\!=3) { fprintf(stderr, "Expected but did not find three integers \n"); fclose(info); return 0; } else { printf("abc is %i%i%i\n",a,b,c); } if(fsetpos(info, &pos)\!=0) { perror("fsetpos failed"); fclose(info); return 0; } if(fscanf(info,"%i %i %i", &a, &b, &c)\!=3) { fprintf(stderr, "Expected but did not find %i %i %i \n"); } else { printf("abc is %i%i%i \n",a,b,c); } fclose(info); return 0; } /* Read in data from file */ rc = fsetpos(file, &offset); if (rc != 0 ) { return rc; } return 0; } |
Risk Assessment
Misuse of the fsetpos() function can position a file position indicator to an unintended location in the file.
Rule | Severity | Likelihood | Detectable | Repairable | Priority | Level |
|---|---|---|---|---|---|---|
FIO44-C | Medium | Unlikely | No | No | P2 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
|---|---|---|---|---|---|---|---|---|---|
| CodeSonar |
| (customization) | Users can add a custom check for violations of this constraint. | ||||||
| Compass/ROSE | Can detect common violations of this rule. However, it cannot handle cases in which the value returned by | ||||||||
| Cppcheck Premium |
| premium-cert-fio44-c | |||||||
| Helix QAC |
| DF4841, DF4842, DF4843 | |||||||
| Klocwork |
| CERT.FSETPOS.VALUE | |||||||
| LDRA tool suite |
| 82 D | Fully implemented | ||||||
| Parasoft C/C++test |
| CERT_C-FIO44-a | Only use values for fsetpos() that are returned from fgetpos() | ||||||
| Polyspace Bug Finder |
| CERT C: Rule FIO44-C | Checks for invalid file position (rule partially covered) | ||||||
| PVS-Studio |
| V1035 |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
Key here (explains table format and definitions)
Taxonomy | Taxonomy item | Relationship |
|---|---|---|
| ISO/IEC TS 17961:2013 | Using a value for fsetpos other than a value returned from fgetpos [xfilepos] | Prior to 2018-01-12: CERT: Unspecified Relationship |
Bibliography
| [ISO/IEC 9899:2024] | 7.23.9.3, "The fsetpos Function" |
...