summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--generic/tclPathObj.c32
-rw-r--r--tests/fileName.test15
3 files changed, 50 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 8085ef8..0b02323 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-03-27 Don Porter <dgp@users.sourceforge.net>
+
+ * generic/tclPathObj.c (TclPathPart): TclPathPart() was computing
+ * tests/fileName.test: the wrong results for both [file dirname] and
+ [file tail] on "path" arguments with the PATHFLAGS != 0 intrep and
+ with an empty string for the "joined-on" part. [Bug 2710920]
+
2009-03-20 Don Porter <dgp@users.sourceforge.net>
* generic/tclStringObj.c: Test stringObj-6.9 checks that
diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c
index 28345da..bb7b0f4 100644
--- a/generic/tclPathObj.c
+++ b/generic/tclPathObj.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclPathObj.c,v 1.66.2.6 2009/02/20 18:19:32 dgp Exp $
+ * RCS: @(#) $Id: tclPathObj.c,v 1.66.2.7 2009/03/27 19:16:49 dgp Exp $
*/
#include "tclInt.h"
@@ -577,11 +577,24 @@ TclPathPart(
* the standardPath code.
*/
- const char *rest = TclGetString(fsPathPtr->normPathPtr);
+ int numBytes;
+ const char *rest =
+ Tcl_GetStringFromObj(fsPathPtr->normPathPtr, &numBytes);
if (strchr(rest, '/') != NULL) {
goto standardPath;
}
+ /*
+ * If the joined-on bit is empty, then [file dirname] is
+ * documented to return all but the last non-empty element
+ * of the path, so we need to split apart the main part to
+ * get the right answer. We could do that here, but it's
+ * simpler to fall back to the standardPath code.
+ * [Bug 2710920]
+ */
+ if (numBytes == 0) {
+ goto standardPath;
+ }
if (tclPlatform == TCL_PLATFORM_WINDOWS
&& strchr(rest, '\\') != NULL) {
goto standardPath;
@@ -602,11 +615,24 @@ TclPathPart(
* we don't, and instead just use the standardPath code.
*/
- const char *rest = TclGetString(fsPathPtr->normPathPtr);
+ int numBytes;
+ const char *rest =
+ Tcl_GetStringFromObj(fsPathPtr->normPathPtr, &numBytes);
if (strchr(rest, '/') != NULL) {
goto standardPath;
}
+ /*
+ * If the joined-on bit is empty, then [file tail] is
+ * documented to return the last non-empty element
+ * of the path, so we need to split off the last element
+ * of the main part to get the right answer. We could do
+ * that here, but it's simpler to fall back to the
+ * standardPath code. [Bug 2710920]
+ */
+ if (numBytes == 0) {
+ goto standardPath;
+ }
if (tclPlatform == TCL_PLATFORM_WINDOWS
&& strchr(rest, '\\') != NULL) {
goto standardPath;
diff --git a/tests/fileName.test b/tests/fileName.test
index 2cd68c6..97bbc31 100644
--- a/tests/fileName.test
+++ b/tests/fileName.test
@@ -10,7 +10,7 @@
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
-# RCS: @(#) $Id: fileName.test,v 1.51.8.3 2009/02/20 18:19:32 dgp Exp $
+# RCS: @(#) $Id: fileName.test,v 1.51.8.4 2009/03/27 19:16:49 dgp Exp $
if {[lsearch [namespace children] ::tcltest] == -1} {
package require tcltest
@@ -1335,6 +1335,19 @@ test filename-14.25.1 {type specific globbing} {win} {
test filename-14.26 {type specific globbing} {
list [catch {glob -nocomplain -dir globTest -types {readonly} *} msg] $msg
} [list 0 {}]
+test filename-14.27 {Bug 2710920} {unixOrPc} {
+ file tail [lindex [lsort [glob globTest/*/]] 0]
+} a1
+test filename-14.28 {Bug 2710920} {unixOrPc} {
+ file dirname [lindex [lsort [glob globTest/*/]] 0]
+} globTest
+test filename-14.29 {Bug 2710920} {unixOrPc} {
+ file extension [lindex [lsort [glob globTest/*/]] 0]
+} {}
+test filename-14.30 {Bug 2710920} {unixOrPc} {
+ file rootname [lindex [lsort [glob globTest/*/]] 0]
+} globTest/a1/
+
unset globname