summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapnadkarni <apnmbx-wits@yahoo.com>2025-10-02 10:41:30 (GMT)
committerapnadkarni <apnmbx-wits@yahoo.com>2025-10-02 10:41:30 (GMT)
commita5ab7bd4eecd67bb9b3466cd9dcf8432886dd464 (patch)
tree0b89bb3e6fee95b18ef01108b1ca831a3e822b1f
parentcec352053fea1c817b5435ab7b79abe4f2bcc5fe (diff)
downloadtcl-core-bug-6fbabfe166.zip
tcl-core-bug-6fbabfe166.tar.gz
tcl-core-bug-6fbabfe166.tar.bz2
Duh. Need to mount archives before searchingcore-bug-6fbabfe166
-rw-r--r--generic/tclListObj.c44
-rw-r--r--generic/tclUtil.c2
-rw-r--r--generic/tclZipfs.c23
3 files changed, 50 insertions, 19 deletions
diff --git a/generic/tclListObj.c b/generic/tclListObj.c
index e3d9bbc..486537a 100644
--- a/generic/tclListObj.c
+++ b/generic/tclListObj.c
@@ -1939,19 +1939,26 @@ Tcl_ListObjAppendElement(
*
* TclListObjAppendIfAbsent --
*
- * Appends an element to a Tcl_Obj list object if the string value is
- * not present. If the passed Tcl_Obj is not a list object, it will be
- * converted and an error raised if the conversion fails.
- *
- * The Tcl_Obj must not be shared though the internal representation
- * may be.
+ * Appends an element elemObj to list toObj if no element with the same
+ * string representation is not already present. If toObj is not a list
+ * object, it will be converted and an error raised if the conversion
+ * fails.
+ *
+ * Reference counting:
+ * - toObj must not be shared else the function will panic.
+ * - if elemObj is not added to the list, either because it already
+ * exists or because of an error, it will be freed if there are no
+ * references to it. Caller can therefore pass in a 0-ref elemObj and
+ * not have to worry about decrementing it on return. Conversely,
+ * this means if caller passes in a 0-ref elemObj it should NOT
+ * decrement the reference count on return irrespective of return
+ * code.
*
* CAUTION: Linear search (of course)
*
* Results:
- * On success, TCL_OK is returned with the specified element appended.
- * On failure, TCL_ERROR is returned with an error message in the
- * interpreter if not NULL.
+ * Standard Tcl result code. Note element being already present is not
+ * an error.
*
* Side effects:
* None.
@@ -1966,13 +1973,17 @@ TclListObjAppendIfAbsent(
{
Tcl_Obj **elemObjs;
Tcl_Size numElems;
- if (Tcl_ListObjGetElements(interp, toObj, &numElems, &elemObjs) != TCL_OK) {
- return TCL_ERROR;
+ int result;
+
+ result = Tcl_ListObjGetElements(interp, toObj, &numElems, &elemObjs);
+ if (result != TCL_OK) {
+ goto vamoose;
}
/* Assume it is worth doing a pointer compare over the whole list first */
for (Tcl_Size i = 0; i < numElems; ++i) {
if (elemObjs[i] == elemObj) {
- return TCL_OK;
+ result = TCL_OK;
+ goto vamoose;
}
}
Tcl_Size elemLen;
@@ -1982,10 +1993,15 @@ TclListObjAppendIfAbsent(
Tcl_Size toLen;
const char *toStr = Tcl_GetStringFromObj(elemObjs[i], &toLen);
if (toLen == elemLen && !strncmp(elemStr, toStr, elemLen)) {
- return TCL_OK;
+ result = TCL_OK;
+ goto vamoose;
}
}
- return TclListObjAppendElements(interp, toObj, 1, &elemObj);
+ result = TclListObjAppendElements(interp, toObj, 1, &elemObj);
+
+vamoose: /* Return result after freeing elemObj if unreferenced */
+ Tcl_BounceRefCount(elemObj);
+ return result;
}
/*
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
index 7e321f6..57c3865 100644
--- a/generic/tclUtil.c
+++ b/generic/tclUtil.c
@@ -4415,7 +4415,7 @@ TclSetObjNameOfShlib(
*
* Results:
* A pointer to an "fsPath" Tcl_Obj, or to an empty Tcl_Obj if the
- * pathname of the application is unknown.
+ * pathname of the shared library is unknown.
*
* Side effects:
* None.
diff --git a/generic/tclZipfs.c b/generic/tclZipfs.c
index 2d84b68..3fcd811 100644
--- a/generic/tclZipfs.c
+++ b/generic/tclZipfs.c
@@ -4411,8 +4411,21 @@ TclZipfs_TclLibrary(void)
* applications (e.g. tkinter - Bug [6fbabfe166]) may not do so.
* So if not already set, try to find it.
*/
- if (zipfs_literal_tcl_library == NULL) {
- TclZipfsLocateTclLibrary(1, 1);
+ if (!zipfs_tcl_library_init) {
+ const char *archive = Tcl_GetNameOfExecutable();
+ int appZipfsPresent =
+ (TclZipfs_Mount(NULL, archive, ZIPFS_APP_MOUNT, NULL) == TCL_OK);
+#if !defined(STATIC_BUILD)
+ int shlibZipfsPresent = 0;
+ Tcl_Obj *shlibPathObj = TclGetObjNameOfShlib();
+ if (shlibPathObj && TclZipfs_Mount(NULL,
+ Tcl_GetString(shlibPathObj),
+ ZIPFS_ZIP_MOUNT,
+ NULL) == TCL_OK) {
+ shlibZipfsPresent = 1;
+ }
+#endif
+ TclZipfsLocateTclLibrary(appZipfsPresent, shlibZipfsPresent);
}
if (zipfs_literal_tcl_library) {
@@ -6468,9 +6481,11 @@ TclZipfsInitEncodingDirs(void)
else {
searchPathObj = Tcl_DuplicateObj(searchPathObj);
}
- Tcl_ListObjAppendElement(NULL, searchPathObj,
- Tcl_FSJoinToPath(libDirObj, 1, &subDirObj));
+ Tcl_Obj *fullPathObj = Tcl_FSJoinToPath(libDirObj, 1, &subDirObj);
+ Tcl_IncrRefCount(fullPathObj);
+ TclListObjAppendIfAbsent(NULL, searchPathObj, fullPathObj);
Tcl_IncrRefCount(searchPathObj);
+ Tcl_DecrRefCount(fullPathObj);
Tcl_DecrRefCount(subDirObj);
Tcl_DecrRefCount(libDirObj);
Tcl_SetEncodingSearchPath(searchPathObj);