MCPcopy Create free account
hub / github.com/DeusData/codebase-memory-mcp / cbm_safe_getenv

Function cbm_safe_getenv

src/foundation/platform.c:371–436  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

369}
370
371const char *cbm_safe_getenv(const char *name, char *buf, size_t buf_sz, const char *fallback) {
372 if (!name || !name[0] || !buf || buf_sz == 0) {
373 return NULL;
374 }
375 buf[0] = '\0';
376#ifdef _WIN32
377 /* #996 Layer 2: _environ holds ANSI-code-page bytes, NOT UTF-8. A
378 * non-ASCII value (USERPROFILE of C:\Users\Kovács János, or a Greek/CJK
379 * CBM_CACHE_DIR) arrives here either mojibake'd or with unrepresentable
380 * characters replaced by '?', which is INVALID in Windows paths — every
381 * downstream wide-safe file API then fails no matter how correct it is.
382 * Read the value wide and convert to genuine UTF-8, matching the
383 * UTF-8-path convention the rest of the codebase (cbm_fopen, _wmkdir,
384 * SQLite VFS) already assumes. */
385 {
386 wchar_t wname[CBM_SZ_256];
387 int wn = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, name, -1, wname, CBM_SZ_256);
388 if (wn > 0) {
389 SetLastError(ERROR_SUCCESS);
390 DWORD needed = GetEnvironmentVariableW(wname, NULL, 0U);
391 DWORD environment_error = GetLastError();
392 if (needed == 0U) {
393 if (environment_error == ERROR_ENVVAR_NOT_FOUND) {
394 return fallback ? platform_copy_environment_value(buf, buf_sz, fallback) : NULL;
395 }
396 /* An existing empty variable is distinct from a missing one. */
397 return buf;
398 }
399 wchar_t *wval = calloc((size_t)needed, sizeof(*wval));
400 if (!wval) {
401 return NULL;
402 }
403 SetLastError(ERROR_SUCCESS);
404 DWORD got = GetEnvironmentVariableW(wname, wval, needed);
405 DWORD read_error = GetLastError();
406 if (got >= needed || (got == 0U && read_error != ERROR_SUCCESS)) {
407 free(wval);
408 return NULL;
409 }
410 char *utf8 = cbm_wide_to_utf8(wval);
411 free(wval);
412 if (!utf8) {
413 return NULL;
414 }
415 const char *copied = platform_copy_environment_value(buf, buf_sz, utf8);
416 free(utf8);
417 return copied;
418 }
419 return NULL;
420 }
421#else
422 char **env = CBM_ENVIRON;
423 if (env) {
424 size_t nlen = strlen(name);
425 for (; *env; env++) {
426 if (strncmp(*env, name, nlen) == 0 && (*env)[nlen] == '=') {
427 return platform_copy_environment_value(buf, buf_sz, *env + nlen + SKIP_ONE);
428 }

Callers 15

main_daemon_endpoint_newFunction · 0.85
main_session_contextFunction · 0.85
mainFunction · 0.85
cbm_detect_shell_rcFunction · 0.85
find_in_pathFunction · 0.85
cbm_claude_config_dirFunction · 0.85

Calls 2

cbm_wide_to_utf8Function · 0.85

Tested by 1

prune_fixture_setupFunction · 0.68