From c6896e2a7476b87a804b8afbd5ab957367e270bf Mon Sep 17 00:00:00 2001 From: "Darryl L. Miles" Date: Mon, 6 Jul 2026 16:47:35 +0000 Subject: [PATCH] =?UTF-8?q?oa:=20apply=20code-review=20feedback=20?= =?UTF-8?q?=E2=80=94=20strcpy=5Fs=20link=20fallback=20+=20argv=20cleanup?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to review-master-upstream-20249999-oa-dcff2f64-6535a4e1.md: - strcpy_s: add an inline fallback implementation right after the declaration, guarded by #ifndef __STDC_LIB_EXT1__. glibc never defines that macro and does not provide the C11 Annex K interfaces, so the bare declaration was an unresolved symbol at link time; the fallback makes magicOA.o self-contained (strcpy_s becomes a defined symbol) while a real Annex K libc still wins. - magicInit.cpp / magicOA.cpp: use `char argvbuf[] = "tclsh"` for the mutable argv string instead of `char[32]` + snprintf. --- oa/magicInit.cpp | 5 ++--- oa/magicOA.cpp | 38 ++++++++++++++++++++++++++++++++++---- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/oa/magicInit.cpp b/oa/magicInit.cpp index 06ab4472..60e8befb 100644 --- a/oa/magicInit.cpp +++ b/oa/magicInit.cpp @@ -301,10 +301,9 @@ int Magicoa_Init(Tcl_Interp *interp) { return TCL_ERROR; #endif try { - char argvbuf[32]; + char argvbuf[] = "tclsh"; /* mutable: oaDBInit takes char** */ int args=1; - snprintf(argvbuf, sizeof(argvbuf), "tclsh"); - char *argv[] = {&argvbuf[0]}; + char *argv[] = {argvbuf}; oaDBInit(&args, argv); } CATCH diff --git a/oa/magicOA.cpp b/oa/magicOA.cpp index e81b2aa2..a59b3252 100644 --- a/oa/magicOA.cpp +++ b/oa/magicOA.cpp @@ -13,7 +13,38 @@ #ifndef rsize_t #define rsize_t size_t #endif -EXTERN_C /*errno_t*/ int strcpy_s(char *__restrict dest, rsize_t destsz, const char *__restrict src); // FIXME glibc does not include +EXTERN_C /*errno_t*/ int strcpy_s(char *__restrict dest, rsize_t destsz, const char *__restrict src); // glibc does not provide C11 Annex K + +#ifndef __STDC_LIB_EXT1__ +/* + * Inline fallback for platforms whose C library does not implement the C11 + * Annex K bounds-checked interfaces (notably glibc, which never defines + * __STDC_LIB_EXT1__). Without this the declaration above would be an + * unresolved symbol at link time. Copies src into dest (capacity destsz, + * including the terminating NUL); on a bad argument or on truncation it empties + * dest and returns non-zero, matching strcpy_s's error contract closely enough + * for our use. + */ +EXTERN_C int strcpy_s(char *__restrict dest, rsize_t destsz, const char *__restrict src) { + rsize_t i; + if (dest == NULL || destsz == 0) { + return 22; /* ~EINVAL */ + } + if (src == NULL) { + dest[0] = '\0'; + return 22; /* ~EINVAL */ + } + for (i = 0; i + 1 < destsz && src[i] != '\0'; i++) { + dest[i] = src[i]; + } + if (src[i] != '\0') { /* src did not fit */ + dest[0] = '\0'; + return 34; /* ~ERANGE */ + } + dest[i] = '\0'; + return 0; +} +#endif /* __STDC_LIB_EXT1__ */ using namespace std; @@ -24,9 +55,8 @@ oaCellView *curCellView; int getTechInfo (const char *techName) { - char argvbuf[32]; - snprintf(argvbuf, sizeof(argvbuf), "tclsh"); - char *argArray[] = {&argvbuf[0]}; + char argvbuf[] = "tclsh"; /* mutable: oaDBInit takes char** */ + char *argArray[] = {argvbuf}; int argCount = 1; // initialize OA DB oaDBInit( &argCount, argArray );