ACPI AML decompiler w/ CFG recovery and structured pseudocode
29

Configure Feed

Select the types of activity you want to include in your feed.

Extend regression coverage w optional external AML corpus discovery and validation

+72 -6
+72 -6
test/t_corpus.c
··· 9 9 #include <dirent.h> 10 10 #include <errno.h> 11 11 #include <sys/stat.h> 12 + #include <unistd.h> 12 13 13 14 #ifndef TOBI_SRC_DIR 14 15 #define TOBI_SRC_DIR "." ··· 43 44 } 44 45 fclose(fp); 45 46 return 1; 47 + } 48 + 49 + static int write_blob(const char *path, const uint8_t *data, size_t len) { 50 + FILE *fp = fopen(path, "wb"); 51 + if (!fp) { 52 + fprintf(stderr, "open %s: %s\n", path, strerror(errno)); 53 + return 0; 54 + } 55 + if (len && fwrite(data, 1, len, fp) != len) { 56 + fclose(fp); 57 + return 0; 58 + } 59 + return fclose(fp) == 0; 46 60 } 47 61 48 62 static int stable_emit_blob(const char *label, const uint8_t *data, size_t len, int strict_should_pass) { ··· 112 126 return rc; 113 127 } 114 128 115 - static int walk_dir(const char *rel, size_t *count, size_t *bad_count) { 116 - char dir_path[512]; 117 - snprintf(dir_path, sizeof(dir_path), "%s/%s", TOBI_SRC_DIR, rel); 129 + static int has_aml_suffix(const char *name) { 130 + size_t len = strlen(name); 131 + return len >= 4u && strcmp(name + len - 4u, ".aml") == 0; 132 + } 133 + 134 + static int walk_dir_path(const char *dir_path, size_t *count, size_t *bad_count) { 118 135 DIR *dir = opendir(dir_path); 119 136 T_CHECK(dir != NULL); 120 137 struct dirent *de = NULL; ··· 122 139 if (de->d_name[0] == '.') { 123 140 continue; 124 141 } 125 - char path[768]; 126 - snprintf(path, sizeof(path), "%s/%s", dir_path, de->d_name); 142 + char path[1024]; 143 + int n = snprintf(path, sizeof(path), "%s/%s", dir_path, de->d_name); 144 + T_CHECK(n > 0 && (size_t)n < sizeof(path)); 127 145 struct stat st; 128 146 T_CHECK(stat(path, &st) == 0); 129 - if (S_ISREG(st.st_mode)) { 147 + if (S_ISDIR(st.st_mode)) { 148 + T_CHECK(walk_dir_path(path, count, bad_count) == 0); 149 + } else if (S_ISREG(st.st_mode) && has_aml_suffix(de->d_name)) { 130 150 int bad = strstr(de->d_name, "bad") != NULL; 131 151 T_CHECK(stable_emit(path, !bad) == 0); 132 152 (*count)++; ··· 139 159 return 0; 140 160 } 141 161 162 + static int walk_dir(const char *rel, size_t *count, size_t *bad_count) { 163 + char dir_path[512]; 164 + int n = snprintf(dir_path, sizeof(dir_path), "%s/%s", TOBI_SRC_DIR, rel); 165 + T_CHECK(n > 0 && (size_t)n < sizeof(dir_path)); 166 + return walk_dir_path(dir_path, count, bad_count); 167 + } 168 + 169 + static int walk_optional_external_dir(size_t *count, size_t *bad_count) { 170 + const char *dir = getenv("TOBI_AML_CORPUS"); 171 + if (!dir || !dir[0]) { 172 + dir = getenv("TOBI_CORPUS"); 173 + } 174 + if (!dir || !dir[0]) { 175 + return 0; 176 + } 177 + size_t before = *count; 178 + T_CHECK(walk_dir_path(dir, count, bad_count) == 0); 179 + T_CHECK(*count > before); 180 + return 0; 181 + } 182 + 183 + static int exercise_external_discovery(void) { 184 + char dir[] = "/tmp/tobi-corpus-XXXXXX"; 185 + T_CHECK(mkdtemp(dir) != NULL); 186 + char nested[256]; 187 + int n = snprintf(nested, sizeof(nested), "%s/nested", dir); 188 + T_CHECK(n > 0 && (size_t)n < sizeof(nested)); 189 + T_CHECK(mkdir(nested, 0700) == 0); 190 + char path[256]; 191 + n = snprintf(path, sizeof(path), "%s/m0.aml", nested); 192 + T_CHECK(n > 0 && (size_t)n < sizeof(path)); 193 + uint8_t m0[] = {0x14,0x0c,'M','T','H','0',0x01,0x70,0x0a,0x2a,0x60,0xa4,0x60}; 194 + T_CHECK(write_blob(path, m0, sizeof(m0))); 195 + size_t count = 0; 196 + size_t bad_count = 0; 197 + T_CHECK(walk_dir_path(dir, &count, &bad_count) == 0); 198 + T_CHECK(count == 1); 199 + T_CHECK(bad_count == 0); 200 + T_CHECK(unlink(path) == 0); 201 + T_CHECK(rmdir(nested) == 0); 202 + T_CHECK(rmdir(dir) == 0); 203 + return 0; 204 + } 205 + 142 206 int t_corpus(void) { 143 207 size_t count = 0; 144 208 size_t bad_count = 0; 209 + T_CHECK(exercise_external_discovery() == 0); 145 210 T_CHECK(walk_dir("sam", &count, &bad_count) == 0); 146 211 T_CHECK(walk_dir("fuzz/seed", &count, &bad_count) == 0); 212 + T_CHECK(walk_optional_external_dir(&count, &bad_count) == 0); 147 213 T_CHECK(count >= 9); 148 214 T_CHECK(bad_count >= 2); 149 215 return 0;