fix(portability+format): Windows pkgmap stat; clang-format distilled passes

- pass_pkgmap: lstat/S_ISLNK are POSIX-only and undeclared on the MSYS2
  Windows build. Guard them under #ifndef _WIN32 (plain stat on Windows,
  where symlinks aren't a concern here). Fixes the Windows build break
  introduced by the workspace-manifest walker.
- Run clang-format-20 over str_util.c, store.c, mcp.c, pipeline.c,
  pass_route_nodes.c, pass_pkgmap.c so the recently-landed pkgmap / route /
  security passes satisfy the lint gate.
This commit is contained in:
Martin Vogel
2026-05-30 19:34:27 +02:00
parent 9e2bb92895
commit fcf98acf8d
6 changed files with 35 additions and 21 deletions
+8 -4
View File
@@ -271,13 +271,17 @@ bool cbm_validate_shell_arg(const char *s) {
}
bool cbm_validate_project_name(const char *name) {
if (!name || !*name) return false;
if (!name || !*name)
return false;
/* Reject directory traversal */
if (strcmp(name, "..") == 0 || strstr(name, "..") != NULL) return false;
if (strcmp(name, "..") == 0 || strstr(name, "..") != NULL)
return false;
/* Reject path separators */
if (strchr(name, '/') || strchr(name, '\\')) return false;
if (strchr(name, '/') || strchr(name, '\\'))
return false;
/* Reject leading dot (hidden files / relative refs) */
if (name[0] == '.') return false;
if (name[0] == '.')
return false;
/* Allow only alphanumeric, dash, underscore, dot */
for (const char *p = name; *p; p++) {
if (!(((*p >= 'a') && (*p <= 'z')) || ((*p >= 'A') && (*p <= 'Z')) ||
+2 -1
View File
@@ -822,7 +822,8 @@ static int collect_db_project_names(const char *dir_path, char *out, size_t out_
if (!is_project_db_file(n, len)) {
continue;
}
if ((size_t)offset >= out_sz) break; /* bounds check before write */
if ((size_t)offset >= out_sz)
break; /* bounds check before write */
if (count > 0 && offset < (int)out_sz - MCP_SEPARATOR) {
out[offset++] = ',';
}
+11 -4
View File
@@ -775,8 +775,7 @@ static bool is_pkgmap_manifest_basename(const char *basename) {
* matched by the shared cbm_should_skip_dir helper so we don't walk
* node_modules, .git, build, etc. Returns the number of manifests
* parsed, accumulated across the whole walk. */
static int pkgmap_walk_dir(const char *abs_dir, const char *rel_dir,
cbm_pkg_entries_t *entries) {
static int pkgmap_walk_dir(const char *abs_dir, const char *rel_dir, cbm_pkg_entries_t *entries) {
DIR *dir = opendir(abs_dir);
if (!dir) {
return 0;
@@ -797,12 +796,20 @@ static int pkgmap_walk_dir(const char *abs_dir, const char *rel_dir,
snprintf(rel_path, sizeof(rel_path), "%s", name);
}
struct stat st;
#ifdef _WIN32
/* Windows has no lstat/S_ISLNK; symlinks aren't a concern for the
* MSYS2 build, so a plain stat is sufficient here. */
if (stat(abs_path, &st) != 0) {
continue;
}
#else
if (lstat(abs_path, &st) != 0) {
continue;
}
if (S_ISLNK(st.st_mode)) {
continue;
}
#endif
if (S_ISDIR(st.st_mode)) {
if (cbm_should_skip_dir(name, CBM_MODE_FULL)) {
continue;
@@ -902,8 +909,8 @@ CBMHashTable *cbm_pkgmap_build_from_repo(const char *repo_path, const cbm_file_i
int from_walk = cbm_pkgmap_scan_repo(repo_path, &entries);
cbm_log_info("pkgmap.scan", "manifests_from_files", pkgmap_itoa(from_files),
"manifests_from_walk", pkgmap_itoa(from_walk),
"entries", pkgmap_itoa(entries.count));
"manifests_from_walk", pkgmap_itoa(from_walk), "entries",
pkgmap_itoa(entries.count));
CBMHashTable *map = cbm_pkgmap_build(&entries, SKIP_ONE, project_name);
cbm_pkg_entries_free(&entries);
return map;
+6 -6
View File
@@ -974,8 +974,9 @@ static void sveltekit_file_visitor(const cbm_gbuf_node_t *node, void *userdata)
/* Find every DEFINES edge from this file to a Function or Variable. */
const cbm_gbuf_edge_t **edges = NULL;
int edge_count = 0;
if (cbm_gbuf_find_edges_by_source_type(ctx->gb, node->id, "DEFINES", &edges, &edge_count) != 0
|| edge_count == 0) {
if (cbm_gbuf_find_edges_by_source_type(ctx->gb, node->id, "DEFINES", &edges, &edge_count) !=
0 ||
edge_count == 0) {
return;
}
@@ -1018,16 +1019,15 @@ static void sveltekit_file_visitor(const cbm_gbuf_node_t *node, void *userdata)
char route_props[CBM_SZ_256];
snprintf(route_props, sizeof(route_props),
"{\"method\":\"%s\",\"framework\":\"sveltekit\"}", method);
int64_t route_id = cbm_gbuf_upsert_node(ctx->gb, "Route", route_path, route_qn, "", 0, 0,
route_props);
int64_t route_id =
cbm_gbuf_upsert_node(ctx->gb, "Route", route_path, route_qn, "", 0, 0, route_props);
if (route_id == 0) {
continue;
}
ctx->routes_created++;
char hprops[CBM_SZ_256];
snprintf(hprops, sizeof(hprops),
"{\"handler\":\"%s\",\"framework\":\"sveltekit\"%s}",
snprintf(hprops, sizeof(hprops), "{\"handler\":\"%s\",\"framework\":\"sveltekit\"%s}",
child->qualified_name ? child->qualified_name : child->name,
is_actions ? ",\"via\":\"actions_object\"" : "");
cbm_gbuf_insert_edge(ctx->gb, child->id, route_id, "HANDLES", hprops);
+2 -3
View File
@@ -598,9 +598,8 @@ static int run_parallel_pipeline(cbm_pipeline_t *p, cbm_pipeline_ctx_t *ctx,
* stays NULL and the fused resolver simply no-ops cross-file resolution
* (per-file LSP already ran during extract). */
char cbm_lsp_cross_env[CBM_SZ_16];
const bool run_cross_lsp =
cbm_safe_getenv("CBM_DISABLE_LSP_CROSS", cbm_lsp_cross_env, sizeof(cbm_lsp_cross_env),
NULL) == NULL;
const bool run_cross_lsp = cbm_safe_getenv("CBM_DISABLE_LSP_CROSS", cbm_lsp_cross_env,
sizeof(cbm_lsp_cross_env), NULL) == NULL;
if (!run_cross_lsp) {
cbm_log_info("lsp_cross.skipped", "reason", "CBM_DISABLE_LSP_CROSS env set");
}
+6 -3
View File
@@ -1772,8 +1772,10 @@ int cbm_store_find_nodes_by_qn_suffix(cbm_store_t *s, const char *project, const
void cbm_store_node_degree(cbm_store_t *s, int64_t node_id, int *in_deg, int *out_deg) {
if (!s) {
if (in_deg) *in_deg = 0;
if (out_deg) *out_deg = 0;
if (in_deg)
*in_deg = 0;
if (out_deg)
*out_deg = 0;
return;
}
*in_deg = 0;
@@ -2319,7 +2321,8 @@ static void where_add_like_hints(const char *column, const char *pattern, char *
continue;
int pool_was_full = (pool->count >= ST_LIKE_POOL_MAX);
like_pool_add(pool, lp);
if (pool_was_full) continue; /* lp was freed — skip bind */
if (pool_was_full)
continue; /* lp was freed — skip bind */
snprintf(bind_buf, sizeof(bind_buf), "%s LIKE ?%d", column, *bind_idx + SKIP_ONE);
*wlen = where_append(where, where_sz, *wlen, nparams, bind_buf);
where_bind_text(binds, bind_idx, lp);