Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 21 additions & 18 deletions src/cli/windows_launcher_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#define CBM_WINDOWS_CURRENT_V1_SIZE 128U
#define CBM_WINDOWS_RELEASE_DESCRIPTOR_V1_SIZE 128U
#define CBM_WINDOWS_PAYLOAD_SHA256_BUF_LEN 65U
#ifndef CBM_WINDOWS_LAUNCHER_ABI_CURRENT
#define CBM_WINDOWS_LAUNCHER_ABI_CURRENT 1U
#endif
Expand All @@ -37,15 +38,15 @@ typedef struct {
uint32_t launcher_abi_min;
uint32_t launcher_abi_max;
uint64_t payload_size;
char payload_sha256[65];
char payload_sha256[CBM_WINDOWS_PAYLOAD_SHA256_BUF_LEN];
} cbm_windows_current_v1_t;

typedef struct {
uint32_t launcher_abi;
uint32_t payload_launcher_abi_min;
uint32_t payload_launcher_abi_max;
uint64_t payload_size;
char payload_sha256[65];
char payload_sha256[CBM_WINDOWS_PAYLOAD_SHA256_BUF_LEN];
} cbm_windows_release_descriptor_v1_t;

typedef enum {
Expand Down Expand Up @@ -77,17 +78,19 @@ cbm_windows_transition_plan_t cbm_windows_transition_plan(
/* Resolve the immutable generation pair using the canonical launcher's
* directory. A managed generation contains exactly these two executables:
* the payload and the launcher's hard-link backing. */
bool cbm_windows_generation_payload_path(const wchar_t *canonical_launcher_path,
const char payload_sha256[65], wchar_t *path_out,
size_t path_capacity);
bool cbm_windows_generation_launcher_path(const wchar_t *canonical_launcher_path,
const char payload_sha256[65], wchar_t *path_out,
size_t path_capacity);
bool cbm_windows_generation_payload_path(
const wchar_t *canonical_launcher_path,
const char payload_sha256[CBM_WINDOWS_PAYLOAD_SHA256_BUF_LEN], wchar_t *path_out,
size_t path_capacity);
bool cbm_windows_generation_launcher_path(
const wchar_t *canonical_launcher_path,
const char payload_sha256[CBM_WINDOWS_PAYLOAD_SHA256_BUF_LEN], wchar_t *path_out,
size_t path_capacity);
/* Derive the race-free retired state sibling shared by the uninstall payload
* (its own PID) and supervising launcher (the authenticated child PID). */
bool cbm_windows_retired_state_path(const wchar_t *canonical_launcher_path,
const char payload_sha256[65], uint32_t payload_pid,
wchar_t *path_out, size_t path_capacity);
const char payload_sha256[CBM_WINDOWS_PAYLOAD_SHA256_BUF_LEN],
uint32_t payload_pid, wchar_t *path_out, size_t path_capacity);

/* Match main's top-level dispatch. Tokens after a mode selector (cli,
* install, config, hook-augment, help/version) are opaque user input. */
Expand All @@ -104,7 +107,7 @@ typedef struct {
bool private_activation;
cbm_windows_launcher_action_t action;
uint64_t payload_size;
char expected_payload_sha256[65];
char expected_payload_sha256[CBM_WINDOWS_PAYLOAD_SHA256_BUF_LEN];
wchar_t canonical_launcher_path[CBM_WINDOWS_LAUNCHER_PATH_CAP];
/* Opaque one-shot authority retained only until startup validation has
* completed. Callers must use context_complete, never inspect it. */
Expand Down Expand Up @@ -144,13 +147,13 @@ bool cbm_windows_launcher_replace_atomic(const wchar_t *target_path, const wchar
bool cbm_windows_launcher_remove_posix(const wchar_t *target_path, char *error, size_t error_size);
/* Retire .cbm to its generation/PID-qualified sibling, then unlink canonical
* as the final uninstall commit. A failed unlink restores .cbm. */
bool cbm_windows_launcher_uninstall_commit(const wchar_t *canonical_launcher_path,
const char payload_sha256[65], char *error,
size_t error_size);
bool cbm_windows_generation_rollback_if_unreferenced(const wchar_t *canonical_launcher_path,
const char payload_sha256[65],
bool created_by_activation, char *error,
size_t error_size);
bool cbm_windows_launcher_uninstall_commit(
const wchar_t *canonical_launcher_path,
const char payload_sha256[CBM_WINDOWS_PAYLOAD_SHA256_BUF_LEN], char *error, size_t error_size);
bool cbm_windows_generation_rollback_if_unreferenced(
const wchar_t *canonical_launcher_path,
const char payload_sha256[CBM_WINDOWS_PAYLOAD_SHA256_BUF_LEN], bool created_by_activation,
char *error, size_t error_size);
bool cbm_windows_generations_prune(const wchar_t *canonical_launcher_path, size_t *removed_out,
char *error, size_t error_size);

Expand Down
4 changes: 3 additions & 1 deletion src/daemon/bootstrap.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,11 @@ cbm_daemon_ipc_endpoint_t *cbm_daemon_bootstrap_endpoint_new(const char *runtime
* directly (never through a shell), with exactly argv[0] plus the one hidden
* internal argument. It is detached from the launching client's lifetime and
* inherits no standard handles; logical client leases govern its lifetime. */
#include "../foundation/constants.h"

typedef struct {
const char *executable_path;
const char *argv[CBM_DAEMON_BOOTSTRAP_LAUNCH_ARGC + 1U];
const char *argv[CBM_DAEMON_BOOTSTRAP_LAUNCH_ARGC + SKIP_ONE];
size_t argc;
bool detached;
bool inherit_standard_handles;
Expand Down
4 changes: 3 additions & 1 deletion src/daemon/runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ bool cbm_daemon_runtime_request_activation_shutdown(
cbm_daemon_runtime_activation_action_t action, uint32_t timeout_ms,
cbm_daemon_runtime_activation_result_t *result_out);

#define CBM_DAEMON_SEMVER_SIZE 12U

typedef struct {
bool permanent;
bool stopping;
Expand All @@ -262,7 +264,7 @@ typedef struct {
uint8_t client_count; /* entries in client_pids, capped at the wire limit */
uint32_t client_pids[CBM_DAEMON_CONTROL_CLIENT_CAP];
char build_fingerprint[CBM_DAEMON_BUILD_FINGERPRINT_SIZE];
char semantic_version[12];
char semantic_version[CBM_DAEMON_SEMVER_SIZE];
} cbm_daemon_runtime_status_t;

typedef struct {
Expand Down
16 changes: 10 additions & 6 deletions src/foundation/sha256.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,17 @@
#include <stddef.h>
#include <stdint.h>

#define CBM_SHA256_DIGEST_LEN 32 /* raw digest bytes */
#define CBM_SHA256_HEX_LEN 64 /* lowercase hex chars (no NUL) */
#include "constants.h"

#define CBM_SHA256_STATE_WORDS CBM_SZ_8
#define CBM_SHA256_BLOCK_SIZE CBM_SZ_64
#define CBM_SHA256_DIGEST_LEN CBM_SZ_32 /* raw digest bytes */
#define CBM_SHA256_HEX_LEN CBM_SZ_64 /* lowercase hex chars (no NUL) */

typedef struct {
uint32_t state[8];
uint32_t state[CBM_SHA256_STATE_WORDS];
uint64_t bitlen;
uint8_t buf[64];
uint8_t buf[CBM_SHA256_BLOCK_SIZE];
size_t buflen;
} cbm_sha256_ctx;

Expand All @@ -24,7 +28,7 @@ void cbm_sha256_update(cbm_sha256_ctx *c, const void *data, size_t len);
void cbm_sha256_final(cbm_sha256_ctx *c, uint8_t out[CBM_SHA256_DIGEST_LEN]);

/* One-shot hash of a buffer to lowercase hex. `out` must hold
* CBM_SHA256_HEX_LEN + 1 bytes (hex chars + NUL). */
void cbm_sha256_hex(const void *data, size_t len, char out[CBM_SHA256_HEX_LEN + 1]);
* CBM_SHA256_HEX_LEN + SKIP_ONE bytes (hex chars + NUL). */
void cbm_sha256_hex(const void *data, size_t len, char out[CBM_SHA256_HEX_LEN + SKIP_ONE]);

#endif /* CBM_SHA256_H */
128 changes: 68 additions & 60 deletions src/pipeline/lsp_resolve.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ static inline const char *cbm_lsp_bare_segment(const char *name) {
* closes the `->` arrow (preceded by '-'); a bare '>' closes a template
* argument list ("identity<int>") and must NOT split, else the segment
* would be the empty string after the trailing '>'. */
if (*p == '.' || *p == ':' || (*p == '>' && p != name && p[-1] == '-')) {
if (*p == '.' || *p == ':' || (*p == '>' && p != name && p[-SKIP_ONE] == '-')) {
seg = p + SKIP_ONE;
}
}
Expand All @@ -81,7 +81,7 @@ static inline const char *cbm_pipeline_qn_class_method_tail(const char *qn) {
if (second == qn) {
return qn;
}
return second + 1;
return second + SKIP_ONE;
}
}
return qn;
Expand Down Expand Up @@ -110,6 +110,39 @@ static inline int cbm_pipeline_qn_class_method_tail_eq(const char *qn, const cha
return qt && tail && strcmp(qt, tail) == 0;
}

static inline const CBMResolvedCall *cbm_pipeline_find_lsp_resolution_tail(
const CBMResolvedCallArray *arr, const CBMCall *call) {
const char *call_tail = cbm_pipeline_qn_class_method_tail(call->enclosing_func_qn);
if (!call_tail) {
return NULL;
}

const CBMResolvedCall *best_tail = NULL;
for (int i = 0; i < arr->count; i++) {
const CBMResolvedCall *rc = &arr->items[i];
if (!rc->caller_qn || !rc->callee_qn) {
continue;
}
if (rc->confidence < CBM_LSP_CONFIDENCE_FLOOR) {
continue;
}
const char *short_name = strrchr(rc->callee_qn, '.');
short_name = short_name ? short_name + SKIP_ONE : rc->callee_qn;
const char *call_leaf = cbm_pipeline_call_callee_leaf(call->callee_name);
if (!call_leaf || strcmp(short_name, call_leaf) != 0) {
continue;
}
if (!cbm_pipeline_qn_class_method_tail_eq(rc->caller_qn, call_tail)) {
continue;
}
if (best_tail) {
return NULL;
}
best_tail = rc;
}
return best_tail;
}

/* Look up the highest-confidence LSP-resolved call entry whose caller QN
* matches the textual call's enclosing function and whose callee QN
* short-name matches the textual callee. Returns a pointer into `arr`
Expand Down Expand Up @@ -191,36 +224,7 @@ static inline const CBMResolvedCall *cbm_pipeline_find_lsp_resolution(
if (!allow_tail_match) {
return NULL;
}

const char *call_tail = cbm_pipeline_qn_class_method_tail(call->enclosing_func_qn);
if (!call_tail) {
return NULL;
}

const CBMResolvedCall *best_tail = NULL;
for (int i = 0; i < arr->count; i++) {
const CBMResolvedCall *rc = &arr->items[i];
if (!rc->caller_qn || !rc->callee_qn) {
continue;
}
if (rc->confidence < CBM_LSP_CONFIDENCE_FLOOR) {
continue;
}
const char *short_name = strrchr(rc->callee_qn, '.');
short_name = short_name ? short_name + SKIP_ONE : rc->callee_qn;
const char *call_leaf = cbm_pipeline_call_callee_leaf(call->callee_name);
if (!call_leaf || strcmp(short_name, call_leaf) != 0) {
continue;
}
if (!cbm_pipeline_qn_class_method_tail_eq(rc->caller_qn, call_tail)) {
continue;
}
if (best_tail) {
return NULL;
}
best_tail = rc;
}
return best_tail;
return cbm_pipeline_find_lsp_resolution_tail(arr, call);
}

/* Resolve an LSP-emitted callee_qn to a graph-buffer node.
Expand All @@ -237,34 +241,8 @@ static inline const CBMResolvedCall *cbm_pipeline_find_lsp_resolution(
* tail.
*
* Returns the matching node, or NULL if neither lookup hits. */
static inline const cbm_gbuf_node_t *cbm_pipeline_lsp_target_node(const cbm_gbuf_t *gbuf,
const char *project_name,
const char *callee_qn,
bool allow_tail_match) {
if (!gbuf || !callee_qn) {
return NULL;
}
const cbm_gbuf_node_t *direct = cbm_gbuf_find_by_qn(gbuf, callee_qn);
if (direct) {
return direct;
}
if (project_name && project_name[0]) {
size_t proj_len = strlen(project_name);
if (!(strncmp(callee_qn, project_name, proj_len) == 0 && callee_qn[proj_len] == '.')) {
char buf[CBM_SZ_1K];
int written = snprintf(buf, sizeof(buf), "%s.%s", project_name, callee_qn);
if (written > 0 && (size_t)written < sizeof(buf)) {
const cbm_gbuf_node_t *prefixed = cbm_gbuf_find_by_qn(gbuf, buf);
if (prefixed) {
return prefixed;
}
}
}
}
if (!allow_tail_match) {
return NULL;
}

static inline const cbm_gbuf_node_t *cbm_pipeline_lsp_target_tail_match(const cbm_gbuf_t *gbuf,
const char *callee_qn) {
const char *short_name = strrchr(callee_qn, '.');
short_name = short_name ? short_name + SKIP_ONE : callee_qn;
const char *callee_tail = cbm_pipeline_qn_class_method_tail(callee_qn);
Expand Down Expand Up @@ -297,4 +275,34 @@ static inline const cbm_gbuf_node_t *cbm_pipeline_lsp_target_node(const cbm_gbuf
return match;
}

static inline const cbm_gbuf_node_t *cbm_pipeline_lsp_target_node(const cbm_gbuf_t *gbuf,
const char *project_name,
const char *callee_qn,
bool allow_tail_match) {
if (!gbuf || !callee_qn) {
return NULL;
}
const cbm_gbuf_node_t *direct = cbm_gbuf_find_by_qn(gbuf, callee_qn);
if (direct) {
return direct;
}
if (project_name && project_name[0]) {
size_t proj_len = strlen(project_name);
if (!(strncmp(callee_qn, project_name, proj_len) == 0 && callee_qn[proj_len] == '.')) {
char buf[CBM_SZ_1K];
int written = snprintf(buf, sizeof(buf), "%s.%s", project_name, callee_qn);
if (written > 0 && (size_t)written < sizeof(buf)) {
const cbm_gbuf_node_t *prefixed = cbm_gbuf_find_by_qn(gbuf, buf);
if (prefixed) {
return prefixed;
}
}
}
}
if (!allow_tail_match) {
return NULL;
}
return cbm_pipeline_lsp_target_tail_match(gbuf, callee_qn);
}

#endif /* CBM_PIPELINE_LSP_RESOLVE_H */
15 changes: 8 additions & 7 deletions src/pipeline/pass_lsp_cross.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,9 @@ typedef struct {
* if none was built (or language has no cross-LSP entrypoint). */
static inline CBMTypeRegistry *cbm_pxc_registry_for_lang(const CBMCrossLspRegistries *r,
CBMLanguage lang) {
if (!r)
if (!r) {
return NULL;
}
switch (lang) {
case CBM_LANG_GO:
return r->go;
Expand Down Expand Up @@ -148,17 +149,17 @@ const struct CBMCargoManifest *cbm_pxc_get_rust_manifest(void);

/* Run the cross-file LSP resolver for non-TS languages. Appends
* resolved CALLS into r->resolved_calls (lives in r->arena). Caller
* owns source, module_qn, all_defs, imp_keys, imp_vals.
* NOTE: all_defs is read-only in practice but typed non-const to match
* owns source, module_qn, defs, imp_names, imp_qns.
* NOTE: defs is read-only in practice but typed non-const to match
* the existing cbm_run_X_lsp_cross callee signatures. */
void cbm_pxc_run_one(CBMLanguage lang, CBMFileResult *r, const char *source, int source_len,
const char *module_qn, CBMLSPDef *all_defs, int def_count,
const char **imp_keys, const char **imp_vals, int imp_count);
const char *module_qn, CBMLSPDef *defs, int def_count, const char **imp_names,
const char **imp_qns, int imp_count);

/* TS / JS / JSX / TSX variant with explicit dialect flags. */
void cbm_pxc_run_one_ts(CBMFileResult *r, const char *source, int source_len, const char *module_qn,
CBMLSPDef *all_defs, int def_count, const char **imp_keys,
const char **imp_vals, int imp_count, bool js_mode, bool jsx_mode,
CBMLSPDef *defs, int def_count, const char **imp_names,
const char **imp_qns, int imp_count, bool js_mode, bool jsx_mode,
bool dts_mode);

/* Per-file cross-LSP dispatch shared by the parallel resolve worker AND the
Expand Down
2 changes: 1 addition & 1 deletion src/store/store.c
Original file line number Diff line number Diff line change
Expand Up @@ -4131,7 +4131,7 @@ int cbm_store_bfs_multi(cbm_store_t *s, const int64_t *seed_ids, int seed_count,

int cap = ST_INIT_CAP_16;
int n = 0;
cbm_node_hop_t *visited = malloc(cap * sizeof(cbm_node_hop_t));
cbm_node_hop_t *visited = calloc(cap, sizeof(cbm_node_hop_t));
int scan_rc16;
while ((scan_rc16 = sqlite3_step(stmt)) == SQLITE_ROW) {
if (n > max_results) {
Expand Down
16 changes: 9 additions & 7 deletions src/ui/httpd.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
#define CBM_HTTP_MAX_BODY (1024 * 1024)
/* Default per-connection receive deadline. */
#define CBM_HTTP_RECV_DEADLINE_MS 5000
#include "../foundation/constants.h"

typedef struct cbm_httpd cbm_httpd_t; /* listener */
typedef struct cbm_http_conn cbm_http_conn_t; /* accepted connection */

Expand All @@ -51,14 +53,14 @@ typedef enum {
* Selected headers are copied for the routing/security layer ("" when
* absent). `body` is heap-allocated and NUL-terminated. */
typedef struct {
char method[16];
char path[2048];
char query[2048];
char method[CBM_SZ_16];
char path[CBM_SZ_2K];
char query[CBM_SZ_2K];
unsigned char http_minor; /* 0 for HTTP/1.0, 1 for HTTP/1.1 */
char origin[256];
char host[256];
char content_type[128];
char accept_language[256];
char origin[CBM_SZ_256];
char host[CBM_SZ_256];
char content_type[CBM_SZ_128];
char accept_language[CBM_SZ_256];
char *body;
size_t body_len;
} cbm_http_req_t;
Expand Down
Loading
Loading