Austin Group Defect Tracker

Aardvark Mark IV

Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0001047 [1003.1(2013)/Issue7+TC1] Shell and Utilities Objection Error 2016-04-25 11:34 2024-06-11 08:56
Reporter geoffclare View Status public  
Assigned To
Priority normal Resolution Accepted As Marked  
Status Closed  
Name Geoff Clare
Organization The Open Group
User Reference
Section cd
Page Number 2530
Line Number 81651
Interp Status ---
Final Accepted Text See Note: 0003751.
Summary 0001047: Unspecified behaviour for cd "" causes a safety issue
Description The description of the directory operand for cd says "If directory is an
empty string, the results are unspecified."

This is bad because many scripts do:

cd "$dir" || exit 1

for safety, and if $dir is empty this will not give the expected protection.

It is unspecified because existing practice varies:

* ksh93 always treats cd "" as an error

* bash and dash do a CDPATH search as per step 5 in the cd description;
when CDPATH is empty or not set (or begins with a colon), this results in cd
checking whether "./" exists (which it does) and changing directory to it.
Thus the end result is exit status 0 without any change of current directory.

* ksh88 treats cd "" as cd "$HOME"

However, the ksh93 behaviour is the right thing to do to ensure that:

cd "$dir" || exit 1

is safe, and this behaviour should be required in the next revision of the
Desired Action Change:

If directory is an empty string, the results are unspecified.


If directory is an empty string, cd shall write a
diagnostic message to standard error and exit with non-zero status.
Tags issue8
Attached Files

- Relationships
related to 0001045Closed 1003.1(2013)/Issue7+TC1 Issues with "cd -" 
related to 0001013Closedajosey 1003.1(2008)/Issue 7 cd and pwd should not default to -L 

-  Notes
joerg (reporter)
2016-04-25 11:43
edited on: 2016-04-25 11:44

The behavior of ksh you describe applies only to recent versions of ksh93. Older versions of ksh93 behave like ksh88.

But I am happy to see this as the Bourne Shell did at least since 1989 (for SVr4) make cd "" illegal.

BTW: maybe it makes sense to add a relation to Bug 0001013

stephane (reporter)
2016-04-25 13:44
edited on: 2016-04-25 19:06

Good point Geoff. However note that

    cd "$dir" || exit 1

is also unreliable for values of "$dir" like "-L", "-P" or "-". Not to mention $CDPATH and that in scripts, one should use "cd -P".
CDPATH= cd -P -- "$dir"
addresses most of the problems but not "-" (see Bug 0001045) nor "" (this Bug 0001049).

shell   CDPATH="/usr" cd ""   CDPATH="/usr" cd -P ""
bash    chdir("/usr")         chdir("/usr/")
dash    chdir("/usr")         chdir("/usr/.")
ksh93u  "bad directory" error "bad directory" error
mkshR52 chdir("/usr")         chdir("/usr/")
zsh     chdir("/usr")         chdir("/usr/")
yash    chdir("$curdir")      chdir("") -> ENOENT error or Linux

shware_systems (reporter)
2016-04-28 18:04

For the case where only options are provided or "" is lexically stripped as a non-argument during quote removal, that is covered by Step 1 & 2 of cd as implementation-defined or equivalent to 'cd $HOME' as an exec()able 'cd ~' workalike, that I see. Running out of argv[] pointers when checking for options is different from a zero length argument being encountered, however. The ambiguity is 'empty string' can be taken to mean either, it looks, and most shells treat no argument as a zero length argument and process Steps 3 to 10 accordingly, skipping the $HOME-being-set check in the process. ksh93 appears to skip the check also, defeating the tilde expansion work-alike, and just reports it as a syntax error as its implementation-defined looking response. This is mostly a bug imo, because:

What the
cd "$dir" || exit 1
tests is that a different process or a called utility hasn't deleted $dir asynchronously or changed permissions in applications that don't go out of their way to guard against it. For that purpose 0 is a valid exit code, even for the current directory, when Steps 3 to 10 are applied, erroneously or because $HOME is unset. It is a kludgy "things still ok, proceed" IPC semaphore if cd succeeds, or "don't start, files for dir not ready yet" one on fail. I can see kludges of this nature as frequently necessary when utilities that presume they will be executed synchronously are used in parallel make job script sections. A script may be relying on $dir being zero length as a synonym for "use current directory if alternate not provided explicitly or on CDPATH" to support out of tree builds. Treating no argument as a syntax error defeats this usage also.

In note 3177 the yash output is consistent with the others, besides ksh, if it requires superuser privileges to access /usr as the current directory, to avoid malicious changes there of the rm -rf * variety. A Usage note to the effect such limitations may be imposed administratively as an extension seems to me desirable, but is an out of scope matter.

Given the existing behaviors, I believe to have all behavior specified with minimal breakage, Step 1 & 2 should be changed from:
1. If no directory operand is given and the HOME environment variable is empty or undefined, the default behavior is implementation-defined and no further steps shall be taken.
2. If no directory operand is given...

1. If no directory operand is given, or is specified as a zero length string as a shell parameter, and the HOME environment variable is of zero length or undefined, the default behavior is processing shall continue with Step 5 and a zero length string shall be provided as the directory operand. If a directory operand is given, but is of zero length, also proceed to Step 5.
2. If no directory operand is given, or is specified as a zero length string as a shell parameter,... The effect shall be the same as:
cd ~<newline>
entered interactively at a command prompt.

To Step 5, insert before:
If CDPATH is unset in the environment, or is set but its value has zero length proceed to Step 6.

Delete unspecified sentence from directory operand clause.

Add wording to Rationale that ksh93 treating "" or no operand always as a syntax error is a non-conforming extension, as the operand is specified as optional in the syntax.

Explicitly allow full tilde expansion of CDPATH values as an extension that may become a future requirement. A conforming script would be expected to use the ./~ form to indicate expansion shouldn't occur and can be incorporated into existing scripts already.

stephane (reporter)
2016-04-29 05:02

Re; 0003181

You lost me there.

"cd" without arguments takes you to your home directory in all shells. Technically, that should be "cd -P" but if you have a home directory that contains "..", you're looking for trouble in the first place. I can see some variation in that bash for instance doesn't honour $CDPATH there (but again a $HOME as a relative directory is not normal, though you could expect HOME being set but empty following some configuration error).

I'm not sure why you would want the empty string to mean the current directory. chdir("") fails, ls -ld "" fails. It sounds reasonable to me for cd "" to fail.

$CDPATH handling and "-L" being the default are features for interactive use. It's a shame that it affects scripts where you'd expect cd something to do the same thing as chdir("something") in other languages. You've got to go through hoops to make it work that way like:

  case $1 in
    (/*) cd -P "$1";;
    ("") echo >&2 bad directory; return 1;;
    (*) CDPATH= cd -P "./$1";;

I don't see the point of having CDPATH treat ~ specially. ~ is a shell *expansion*. And it's been designed so that it expands in assignments after ":", so it is expanded in CDPATH=~:~/dir. Have a dynamic CDPATH is asking for yet more trouble.
Don Cragun (manager)
2017-06-01 15:44

Make the change in the desired action and also the following changes (after applying 0001045):

On page 2564 line 83048 section cd, change:
applications should use the following:
        case $dir in
        (/*) CDPATH= cd -P "$dir";;
        ("") CDPATH= cd -P "";;
        (*) CDPATH= cd -P "./$dir";;

    (The special treatment of "" is to avoid prefixing it with "./"; an alternative would be to report empty "$dir" as an error to avoid unspecified behavior.)

applications should use the following:
        case $dir in
        (/*) cd -P "$dir";;
        ("") echo >&2 directory is an empty string; exit 1;;
        (*) CDPATH= cd -P "./$dir";;

On page 2565 line 83080 section cd, change FUTURE DIRECTIONS from:
A future version of this standard may require cd to treat an empty directory operand as an error.


- Issue History
Date Modified Username Field Change
2016-04-25 11:34 geoffclare New Issue
2016-04-25 11:34 geoffclare Name => Geoff Clare
2016-04-25 11:34 geoffclare Organization => The Open Group
2016-04-25 11:34 geoffclare Section => cd
2016-04-25 11:34 geoffclare Page Number => 2530
2016-04-25 11:34 geoffclare Line Number => 81651
2016-04-25 11:34 geoffclare Interp Status => ---
2016-04-25 11:34 geoffclare Relationship added related to 0001045
2016-04-25 11:43 joerg Note Added: 0003176
2016-04-25 11:44 joerg Note Edited: 0003176
2016-04-25 11:44 joerg Note Edited: 0003176
2016-04-25 11:44 joerg Note Edited: 0003176
2016-04-25 13:44 stephane Note Added: 0003177
2016-04-25 13:47 stephane Note Edited: 0003177
2016-04-25 13:48 stephane Note Edited: 0003177
2016-04-25 13:55 stephane Note Edited: 0003177
2016-04-25 13:55 stephane Note Edited: 0003177
2016-04-25 19:06 stephane Note Edited: 0003177
2016-04-25 19:06 stephane Note Edited: 0003177
2016-04-28 18:04 shware_systems Note Added: 0003181
2016-04-29 05:02 stephane Note Added: 0003183
2017-06-01 15:20 eblake Relationship added related to 0001013
2017-06-01 15:44 Don Cragun Note Added: 0003751
2017-06-01 15:46 Don Cragun Final Accepted Text => See Note: 0003751.
2017-06-01 15:46 Don Cragun Status New => Resolved
2017-06-01 15:46 Don Cragun Resolution Open => Accepted As Marked
2017-06-01 15:47 Don Cragun Tag Attached: issue8
2020-04-16 08:55 geoffclare Status Resolved => Applied
2024-06-11 08:56 agadmin Status Applied => Closed

Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker