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).
91 lines
2.5 KiB
C
91 lines
2.5 KiB
C
// RUN: %clang_analyze_cc1 \
|
|
// RUN: -analyzer-checker=security.PutenvStackArray \
|
|
// RUN: -verify %s
|
|
|
|
#include "Inputs/system-header-simulator.h"
|
|
void free(void *);
|
|
void *malloc(size_t);
|
|
int putenv(char *);
|
|
int snprintf(char *, size_t, const char *, ...);
|
|
|
|
int test_auto_var(const char *var) {
|
|
char env[1024];
|
|
(void)snprintf(env, sizeof(env), "TEST=%s", var);
|
|
return putenv(env); // expected-warning{{The 'putenv' function should not be called with arrays that have automatic storage}}
|
|
}
|
|
|
|
int test_static_var(const char *var) {
|
|
static char env[1024];
|
|
(void)snprintf(env, sizeof(env), "TEST=%s", var);
|
|
return putenv(env); // no-warning: static array is used
|
|
}
|
|
|
|
void test_heap_memory(const char *var) {
|
|
const char *env_format = "TEST=%s";
|
|
const size_t len = strlen(var) + strlen(env_format);
|
|
char *env = (char *)malloc(len);
|
|
if (env == NULL)
|
|
return;
|
|
if (putenv(env) != 0) // no-warning: env was dynamically allocated.
|
|
free(env);
|
|
}
|
|
|
|
typedef struct {
|
|
int A;
|
|
char Env[1024];
|
|
} Mem;
|
|
|
|
int test_auto_var_struct() {
|
|
Mem mem;
|
|
return putenv(mem.Env); // expected-warning{{The 'putenv' function should not be called with}}
|
|
}
|
|
|
|
int test_auto_var_subarray() {
|
|
char env[1024];
|
|
return putenv(env + 100); // expected-warning{{The 'putenv' function should not be called with}}
|
|
}
|
|
|
|
int f_test_auto_var_call(char *env) {
|
|
return putenv(env); // expected-warning{{The 'putenv' function should not be called with}}
|
|
}
|
|
|
|
int test_auto_var_call() {
|
|
char env[1024];
|
|
return f_test_auto_var_call(env);
|
|
}
|
|
|
|
int test_constant() {
|
|
char *env = "TEST";
|
|
return putenv(env); // no-warning: data is not on the stack
|
|
}
|
|
|
|
extern char *ext_env;
|
|
int test_extern() {
|
|
return putenv(ext_env); // no-warning: extern storage class.
|
|
}
|
|
|
|
void test_auto_var_reset() {
|
|
char env[] = "NAME=value";
|
|
putenv(env); // expected-warning{{The 'putenv' function should not be called with}}
|
|
// ... (do something)
|
|
// Even cases like this are likely a bug:
|
|
// It looks like that if one string was passed to putenv,
|
|
// it should not be deallocated at all, because when reading the
|
|
// environment variable a pointer into this string is returned.
|
|
// In this case, if another (or the same) thread reads variable "NAME"
|
|
// at this point and does not copy the returned string, the data may
|
|
// become invalid.
|
|
putenv((char *)"NAME=anothervalue");
|
|
}
|
|
|
|
void f_main(char *env) {
|
|
putenv(env); // no warning: string allocated in stack of 'main'
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
char env[] = "NAME=value";
|
|
putenv(env); // no warning: string allocated in stack of 'main'
|
|
f_main(env);
|
|
return 0;
|
|
}
|