Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ksh93: read -r doesn't work if -d is also specified #37

Closed
zakukai opened this issue May 22, 2017 · 1 comment
Closed

ksh93: read -r doesn't work if -d is also specified #37

zakukai opened this issue May 22, 2017 · 1 comment

Comments

@zakukai
Copy link

zakukai commented May 22, 2017

(This is using ksh 93u+ 2012-08-01 on RHEL7)

Hi, I'm really hoping Korn Shell development will continue. Right now it kind of looks like a dead project - which is a shame because it's probably still the best of the Unix shells.

Anyway, I'm writing this shell library called "shell-pepper" and in the course of thinking about how to write a version of "read" that would read a single JSON value from the input (and stop at the end - and without writing it as a loadable "built-in") it led to this line of experimentation with the built-in "read":

$ a='foo\ bar }'
$ echo "'$a'"      # sanity check that $a contains what I expect
'foo\ bar }'
$ IFS='' read -r -d '}' x <<<"$a"     # Read to the next '}' or EOF.  $? tells us whether it was a delimiter or EOF.
$ echo "'$x'"                       # Thanks to IFS the space at the end is preserved, but we lose the backslash.
'foo bar '
$ IFS='' read -r y <<<"$a"    # If I remove -d, then the backslash is retained, but I lose the ability to stop the read at the next curly brace
$ echo "'$y'"
'foo\ bar }'

Basically the idea here is that if I've started reading a JSON object, reading to the next '}' may not get me to the end of the object, but it certainly won't take me past the end of the object. But I need backslashes intact (hence the -r), but when I use "-d" as well, backslashes in the input are lost (as if -r weren't specified)

BASH gets this one right:

a='foo\ bar }'
$ echo "'$a'"
'foo\ bar }'
$ IFS='' read -r -d '}' x <<<"$a"
$ echo "'$x'"
'foo\ bar '

As a side note - I had heard that JSON read and write were to be added to Korn Shell in upcoming versions. I am mostly using 93u but with a couple 93v builds kicking around. At the time I wrote this I was unaware that the JSON functionality is already present in 93v. Nice!

@zakukai zakukai changed the title read -r doesn't work if -d is also specified ksh93: read -r doesn't work if -d is also specified May 22, 2017
@zakukai
Copy link
Author

zakukai commented May 23, 2017

...Actually, it appears this bug is already fixed in 93v (Version ABIJM 93v- 2014-12-24), and there's a test covering the issue... So I guess this one should be closed.

@zakukai zakukai closed this as completed May 23, 2017
JohnoKing added a commit to JohnoKing/ksh that referenced this issue Jun 16, 2020
This bug was previously reported in att#37.
Ksh ignores `-r` when `read -r -d` is run because when
the bit for `D_FLAG` is set, the bit for `R_FLAG` is unset
as a side effect of setting `D_FLAG`. The following set
of commands fails to print a backslash:

$ printf '\\\000' | read -r -d ''
$ echo $REPLY

The fix for this bug is to set `D_FLAG` with `D_FLAG + 1`,
which prevents `R_FLAG` from being unset. This bugfix
has been backported from ksh93v- 2013-10-10-alpha.

src/cmd/ksh93/bltins/read.c:
 - Set `D_FLAG` with `D_FLAG + 1` to prevent the bit for
   `R_FLAG` from being unset.

src/cmd/ksh93/tests/builtins.sh:
 - Add the regression test for `read -r -d` from ksh93v-.
JohnoKing added a commit to JohnoKing/ksh that referenced this issue Jun 16, 2020
This bug was previously reported in att#37.
Ksh ignores `-r` when `read -r -d` is run because when
the bit for `D_FLAG` is set, the bit for `R_FLAG` is unset
as a side effect of setting `D_FLAG`. The following set
of commands fails to print a backslash:

$ printf '\\\000' | read -r -d ''
$ echo $REPLY

The fix for this bug is to set `D_FLAG` with `D_FLAG + 1`,
which prevents `R_FLAG` from being unset. This bugfix
has been backported from ksh93v- 2013-10-10-alpha.

src/cmd/ksh93/bltins/read.c:
 - Set `D_FLAG` with `D_FLAG + 1` to prevent the bit for
   `R_FLAG` from being unset.

src/cmd/ksh93/tests/builtins.sh:
 - Add the regression test for `read -r -d` from ksh93v-.
McDutchie pushed a commit to ksh93/ksh that referenced this issue Jun 16, 2020
This bug was previously reported in att#37.
Ksh ignores `-r` when `read -r -d` is run because when
the bit for `D_FLAG` is set, the bit for `R_FLAG` is unset
as a side effect of setting `D_FLAG`. The following set
of commands fails to print a backslash:

$ printf '\\\000' | read -r -d ''
$ echo $REPLY

The fix for this bug is to set `D_FLAG` with `D_FLAG + 1`,
which prevents `R_FLAG` from being unset. This bugfix
has been backported from ksh93v- 2013-10-10-alpha.

src/cmd/ksh93/bltins/read.c:
 - Set `D_FLAG` with `D_FLAG + 1` to prevent the bit for
   `R_FLAG` from being unset.

src/cmd/ksh93/tests/builtins.sh:
 - Add the regression test for `read -r -d` from ksh93v-.
citrus-it pushed a commit to citrus-it/ast that referenced this issue Apr 15, 2021
This commit fixes the bug described in att#32. The fix and
following explanation is from att#467:

While copying variables from function's local scope to a new scope,
variable attributes were not copied. Such variables were not marked
to be exported in the new function. For e.g.

function f2 { env | grep -i "^foo"; }
function f1 { env | grep -i "^foo"; f2; }
foo=bar f1

prints 'foo=bar' only once, but it should print be twice.

src/cmd/ksh93/sh/xec.c:
 - When variables from the local scope of a function are copied into
   the scope of a nested function, the attributes of the variables
   need to be copied as well.

src/cmd/ksh93/tests/functions.sh:
 - Add regression tests from ksh2020 to check environment variables
   passed to functions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant