cb424d7448
verify-patch-sanity.py validates every active recipe .patch has internally- consistent hunk line counts — catching the 'malformed patch at line N' failure at commit/CI/preflight time instead of hours into a cook. This cycle hit that class three times (qtwaylandscanner, sddm, xwayland), each only discovered when cookbook tried to apply the patch. Running it across the repo found 29 latent malformed patches (validated against GNU patch: e.g. relibc/P3-sysv-ipc reproduces 'malformed patch at line 22'). They were harmless only because they sit in vendored recipes (baked, not re- applied) — but would fail on any version-bump re-derivation. --fix recounts the hunk headers (body untouched) and repaired all 29. Wired into build-preflight.sh (Phase 1.0D) and redbear-ci.yml, with a unit test (test-patch-sanity.sh). Skips archived/legacy trees and unvalidatable formats (empty placeholders, bare-@@ git hunks).
178 lines
5.8 KiB
C
178 lines
5.8 KiB
C
// RUN: %clang_analyze_cc1 -verify %s \
|
|
// RUN: -analyzer-checker=core \
|
|
// RUN: -analyzer-checker=debug.ExprInspection \
|
|
// RUN: -analyzer-checker=unix.StdCLibraryFunctions \
|
|
// RUN: -analyzer-checker=apiModeling.Errno \
|
|
// RUN: -analyzer-checker=unix.Errno \
|
|
// RUN: -analyzer-config unix.StdCLibraryFunctions:ModelPOSIX=true
|
|
|
|
#include "Inputs/errno_var.h"
|
|
#include "Inputs/std-c-library-functions-POSIX.h"
|
|
|
|
#define NULL ((void *) 0)
|
|
|
|
void clang_analyzer_warnIfReached();
|
|
void clang_analyzer_eval(int);
|
|
|
|
int unsafe_errno_read(int sock, void *data, int data_size) {
|
|
if (send(sock, data, data_size, 0) != data_size) {
|
|
if (errno == 1) {
|
|
// expected-warning@-1{{An undefined value may be read from 'errno'}}
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int errno_lseek(int fildes, off_t offset) {
|
|
off_t result = lseek(fildes, offset, 0);
|
|
if (result == (off_t)-1) {
|
|
// Failure path.
|
|
// check if the function is modeled
|
|
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
|
|
return 2;
|
|
}
|
|
if (result != offset) {
|
|
// Not success path (?)
|
|
// not sure if this is a valid case, allow to check 'errno'
|
|
if (errno == 1) { // no warning
|
|
return 1;
|
|
}
|
|
clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
|
|
}
|
|
if (result == offset) {
|
|
// The checker does not differentiate for this case.
|
|
// In general case no relation exists between the arg 2 and the returned
|
|
// value, only for SEEK_SET.
|
|
if (errno == 1) { // no warning
|
|
return 1;
|
|
}
|
|
clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void errno_mkstemp(char *template) {
|
|
int FD = mkstemp(template);
|
|
if (FD >= 0) {
|
|
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
|
|
close(FD);
|
|
} else {
|
|
clang_analyzer_eval(FD == -1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
|
|
if (errno) {} // no warning
|
|
}
|
|
}
|
|
|
|
void errno_mkdtemp(char *template) {
|
|
char *Dir = mkdtemp(template);
|
|
if (Dir == NULL) {
|
|
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
|
|
if (errno) {} // no warning
|
|
} else {
|
|
clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}
|
|
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
|
|
}
|
|
}
|
|
|
|
typedef char* CHAR_PTR;
|
|
void errno_mkdtemp2(CHAR_PTR template) {
|
|
CHAR_PTR Dir = mkdtemp(template);
|
|
if (Dir == NULL) {
|
|
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
|
|
if (errno) {} // no warning
|
|
} else {
|
|
clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}
|
|
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
|
|
}
|
|
}
|
|
|
|
typedef char const* CONST_CHAR_PTR;
|
|
void errno_mkdtemp3(CHAR_PTR template) {
|
|
CONST_CHAR_PTR Dir = mkdtemp(template);
|
|
if (Dir == NULL) {
|
|
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
|
|
if (errno) {} // no warning
|
|
} else {
|
|
clang_analyzer_eval(Dir == template); // expected-warning{{TRUE}}
|
|
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
|
|
}
|
|
}
|
|
|
|
void errno_getcwd_buf_nonnull(char *Buf, size_t Sz) {
|
|
if (Buf == NULL)
|
|
return;
|
|
char *Path = getcwd(Buf, Sz);
|
|
if (Sz == 0) {
|
|
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(Path == NULL); // expected-warning{{TRUE}}
|
|
if (errno) {} // no warning
|
|
} else if (Path == NULL) {
|
|
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
|
|
if (errno) {} // no warning
|
|
} else {
|
|
clang_analyzer_eval(Path == Buf); // expected-warning{{TRUE}}
|
|
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
|
|
}
|
|
}
|
|
|
|
void errno_getcwd_buf_null() {
|
|
// POSIX does not mention this case but many implementations (Linux, FreeBSD) work this way.
|
|
char *Path = getcwd(NULL, 1);
|
|
if (Path == NULL) {
|
|
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
|
|
if (errno) {} // no warning
|
|
} else {
|
|
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
|
|
}
|
|
}
|
|
|
|
void errno_execv(char *Path, char * Argv[]) {
|
|
int Ret = execv(Path, Argv);
|
|
clang_analyzer_eval(Ret == -1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
|
|
if (errno) {} // no warning
|
|
}
|
|
|
|
void errno_execvp(char *File, char * Argv[]) {
|
|
int Ret = execvp(File, Argv);
|
|
clang_analyzer_eval(Ret == -1); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
|
|
if (errno) {} // no warning
|
|
}
|
|
|
|
void errno_popen(void) {
|
|
FILE *F = popen("xxx", "r");
|
|
if (!F) {
|
|
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
|
|
if (errno) {} // no-warning
|
|
} else {
|
|
if (errno) {} // expected-warning{{An undefined value may be read from 'errno' [unix.Errno]}}
|
|
pclose(F);
|
|
}
|
|
}
|
|
|
|
void errno_pclose(void) {
|
|
FILE *F = popen("xx", "w");
|
|
if (!F)
|
|
return;
|
|
int Ret = pclose(F);
|
|
if (Ret == -1) {
|
|
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
|
|
if (errno) {} // no-warning
|
|
} else {
|
|
clang_analyzer_eval(Ret >= 0); // expected-warning{{TRUE}}
|
|
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
|
|
}
|
|
}
|
|
|
|
void errno_realpath(char *Path, char *Buf) {
|
|
char *Ret = realpath(Path, Buf);
|
|
if (!Ret) {
|
|
clang_analyzer_eval(errno != 0); // expected-warning{{TRUE}}
|
|
if (errno) {} // no-warning
|
|
} else {
|
|
if (errno) {} // expected-warning{{An undefined value may be read from 'errno'}}
|
|
}
|
|
}
|