fix(pipeline): resolve relative import files without a raw allocation

Resolve the exact File an explicit relative import names through
cbm_repo_rel_join into stack buffers instead of the allocating relative
resolver, so the raw allocator count of pass_pkgmap.c does not grow
(memory-core ratchet). The helper refuses a path above the repository
root and honours php_only like the other strategies in
resolve_import_strategies, which main gained after the base of this
branch.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
This commit is contained in:
Martin Vogel committed 2026-10-20 03:32:28 +02:00
1 parent 55e8479516
commit 0baad9450f
1 file changed
+38 -14
+38 -14
View File
@@ -2115,6 +2115,37 @@ static const cbm_gbuf_node_t *resolve_sibling_file(const cbm_pipeline_ctx_t *ctx
return found;
}
/* The File an explicit relative import (`./x`, `../x`) names exactly, for
* files whose File QN differs from the module QN Strategy 1 tries
* (`../styles/global.css`, `../layouts/Layout.astro`, #2558). Resolved in
* stack buffers by cbm_repo_rel_join, which refuses a path above the
* repository root. */
static const cbm_gbuf_node_t *resolve_relative_file(const cbm_pipeline_ctx_t *ctx,
const char *source_rel, const char *module_path,
bool php_only) {
if (!source_rel || !module_path || module_path[0] != '.' ||
!(module_path[1] == '/' || (module_path[1] == '.' && module_path[2] == '/'))) {
return NULL;
}
char dir[PKGMAP_PATH_BUF];
int dir_len = snprintf(dir, sizeof(dir), "%s", source_rel);
if (dir_len < 0 || (size_t)dir_len >= sizeof(dir)) {
return NULL;
}
char *slash = strrchr(dir, '/');
if (slash) {
*slash = '\0';
} else {
dir[0] = '\0';
}
char path[PKGMAP_PATH_BUF];
if (!cbm_repo_rel_join(dir, module_path, path, sizeof(path))) {
return NULL;
}
const cbm_gbuf_node_t *file = cbm_pipeline_file_node(ctx->gbuf, ctx->project_name, path);
return file && (!php_only || node_in_php_file(file)) ? file : NULL;
}
/* ── PHP PSR-4 class imports (#1186) ──────────────────────────────── */
typedef enum {
@@ -2389,20 +2420,13 @@ static const cbm_gbuf_node_t *resolve_import_strategies(
}
}
/* Relative non-module files can have a File QN that does not match the
* module QN above. Resolve the exact file after module and sibling lookup. */
if (imp->module_path[0] == '.' &&
(imp->module_path[1] == '/' ||
(imp->module_path[1] == '.' && imp->module_path[2] == '/'))) {
char *resolved = cbm_pipeline_resolve_relative_import(source_rel, imp->module_path);
if (resolved) {
const cbm_gbuf_node_t *file =
cbm_pipeline_file_node(ctx->gbuf, ctx->project_name, resolved);
free(resolved);
if (file) {
return file;
}
}
/* Strategy 1c: relative non-module files can have a File QN that does not
* match the module QN above. Resolve the exact file after module and
* sibling lookup. */
const cbm_gbuf_node_t *rel_file =
resolve_relative_file(ctx, source_rel, imp->module_path, php_only);
if (rel_file) {
return rel_file;
}
/* Strategy 2: namespace map. `using App.Utils`, `import com.example.Foo`,