Skip to content

Reject making LINENO, OLDPWD, OPTARG, OPTIND, and PWD readonly #170

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

Merged
merged 1 commit into from
May 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
depending on the cause of the error.
- The `read` built-in now supports the `-d` option, which can be
used to specify a delimiter character.
- The `readonly` built-in now refuses to make the `$LINENO`,
`$OLDPWD`, `$OPTARG`, `$OPTIND`, and `$PWD` variables read-only in
the POSIXly-correct mode.
- The `test` (`[`) built-in no longer accepts binary operators `-a`
and `-o` and parentheses `(` and `)` in the POSIXly-correct mode.
- The `trap` built-in now supports the `-p` option in the POSIXly-
Expand Down
3 changes: 3 additions & 0 deletions NEWS.ja
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
- `read` 組込みは結果に応じてより細分化された終了ステータスを返す
ようになった
- `read` 組込みに行区切り文字を指定する `-d` オプションを追加
- POSIX 準拠モードでは `readonly` 組込みは `$LINENO`, `$OLDPWD`,
`$OPTARG`, `$OPTIND`, `$PWD` 変数を読み取り専用にできないように
なった
- POSIX 準拠モードでは `test` (`[`) 組込みで二項演算子 `-a` および
`-o` ならびに括弧 `(`, `)` を使用できなくなった
- POSIX 準拠モードで `trap` 組込みに `-p` オプションを使えるように
Expand Down
9 changes: 9 additions & 0 deletions doc/_readonly.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,13 @@ The POSIX standard defines the +-p+ option only;
other options cannot be used in the link:posix.html[POSIXly-correct mode].
The POSIX does not allow using the option together with operands.

In the link:posix.html[POSIXly-correct mode], the following variables cannot
be made readonly:

- link:params.html#sv-lineno[+LINENO+]
- link:params.html#sv-oldpwd[+OLDPWD+]
- link:params.html#sv-optarg[+OPTARG+]
- link:params.html#sv-optind[+OPTIND+]
- link:params.html#sv-pwd[+PWD+]

// vim: set filetype=asciidoc textwidth=78 expandtab:
8 changes: 8 additions & 0 deletions doc/ja/_readonly.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,12 @@ readonly コマンドは{zwsp}link:builtin.html#types[特殊組込みコマン

POSIX には readonly コマンドに関する規定はありますが、オプションは +-p+ しか規定がありません。その他のオプションは link:posix.html[POSIX 準拠モード]では使えません。また POSIX は +-p+ オプションをオペランドとともに使うことを認めていません。

link:posix.html[POSIX 準拠モード]では以下の変数は読み取り専用にできません:

- link:params.html#sv-lineno[+LINENO+]
- link:params.html#sv-oldpwd[+OLDPWD+]
- link:params.html#sv-optarg[+OPTARG+]
- link:params.html#sv-optind[+OPTIND+]
- link:params.html#sv-pwd[+PWD+]

// vim: set filetype=asciidoc expandtab:
1 change: 1 addition & 0 deletions doc/ja/posix.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ POSIX 準拠モードを有効にすると、yash は POSIX の規定にでき
- link:syntax.html#simple[単純コマンド]での{zwsp}link:params.html#arrays[配列]の代入はできません。
- シェル実行中に link:params.html#sv-lc_ctype[+LC_CTYPE+ 変数]の値が変わっても、それをシェルのロケール情報に反映しません。
- link:params.html#sv-random[+RANDOM+ 変数]は使えません。
- link:params.html#sv-lineno[+LINENO+], link:params.html#sv-oldpwd[+OLDPWD+], link:params.html#sv-optarg[+OPTARG+], link:params.html#sv-optind[+OPTIND+], link:params.html#sv-pwd[+PWD+] の各変数は{zwsp}link:_readonly.html[読み取り専用]にできません。
- link:expand.html#tilde[チルダ展開]で +~+ と +~{{ユーザ名}}+ 以外の形式の展開が使えません。
- link:expand.html#params[パラメータ展開]の{zwsp}link:expand.html#param-name[入れ子]はできません。また{zwsp}link:expand.html#param-index[インデックス]および{{単語2}}のある{zwsp}link:expand.html#param-mod[加工指定]は使用できません。
- +$(+ と +)+ で囲んだ{zwsp}link:expand.html#cmdsub[コマンド置換]に含まれるコマンドは、コマンド置換が実行される時に毎回解析されます。
Expand Down
4 changes: 4 additions & 0 deletions doc/posix.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ When the POSIXly-correct mode is enabled:
after the shell has been initialized does not affect the shell's locale.
- The link:params.html#sv-random[+RANDOM+ variable] cannot be used to generate
random numbers.
- The link:params.html#sv-lineno[+LINENO+],
link:params.html#sv-oldpwd[+OLDPWD+], link:params.html#sv-optarg[+OPTARG+],
link:params.html#sv-optind[+OPTIND+], and link:params.html#sv-pwd[+PWD+]
variables cannot be made link:_readonly.html[readonly].
- link:expand.html#tilde[Tilde expansion] only expands +~+ and
+~{{username}}+.
- link:expand.html#params[Parameter expansion] cannot be nested.
Expand Down
30 changes: 30 additions & 0 deletions tests/readonly-y.tst
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,36 @@ __ERR__
#'
#`

test_Oe -e 1 'LINENO cannot be read-only (POSIX)'
readonly LINENO
__IN__
readonly: $LINENO cannot be made read-only in the POSIXly-correct mode
__ERR__

test_Oe -e 1 'OPTARG cannot be read-only (POSIX)'
readonly OPTARG
__IN__
readonly: $OPTARG cannot be made read-only in the POSIXly-correct mode
__ERR__

test_Oe -e 1 'OPTIND cannot be read-only (POSIX)'
readonly OPTIND
__IN__
readonly: $OPTIND cannot be made read-only in the POSIXly-correct mode
__ERR__

test_Oe -e 1 'PWD cannot be read-only (POSIX)'
readonly PWD
__IN__
readonly: $PWD cannot be made read-only in the POSIXly-correct mode
__ERR__

test_Oe -e 1 'OLDPWD cannot be read-only (POSIX)'
readonly OLDPWD
__IN__
readonly: $OLDPWD cannot be made read-only in the POSIXly-correct mode
__ERR__

)

test_Oe -e 2 'invalid option -z'
Expand Down
24 changes: 22 additions & 2 deletions variable.c
Original file line number Diff line number Diff line change
Expand Up @@ -1578,6 +1578,8 @@ static void print_function(
__attribute__((nonnull));
static char *vartype_option_string(vartype_T type)
__attribute__((malloc,warn_unused_result));
static bool can_make_readonly(const wchar_t *name)
__attribute__((nonnull,pure));
#if YASH_ENABLE_ARRAY
static int array_dump_all(const wchar_t *argv0);
static void array_remove_elements(
Expand Down Expand Up @@ -1751,8 +1753,13 @@ int typeset_builtin(int argc, void **argv)
var->v_getter = NULL;
}
}
if (readonly)
var->v_type |= VF_READONLY | VF_NODELETE;
if (readonly) {
if (can_make_readonly(arg))
var->v_type |= VF_READONLY | VF_NODELETE;
else
xerror(0, Ngt("$%ls cannot be made read-only "
"in the POSIXly-correct mode"), arg);
}
if (export)
var->v_type |= VF_EXPORT;
else if (unexport)
Expand Down Expand Up @@ -1979,6 +1986,19 @@ char *vartype_option_string(vartype_T type)
return sb_tostr(&opts);
}

/* Determines whether the specified variable can be made read-only.
* Returns true if it can be made read-only. */
bool can_make_readonly(const wchar_t *name)
{
if (!posixly_correct)
return true;
return wcscmp(name, L VAR_LINENO) != 0 &&
wcscmp(name, L VAR_OPTARG) != 0 &&
wcscmp(name, L VAR_OPTIND) != 0 &&
wcscmp(name, L VAR_PWD) != 0 &&
wcscmp(name, L VAR_OLDPWD) != 0;
}

#if YASH_ENABLE_HELP
const char typeset_help[] = Ngt(
"set or print variables"
Expand Down
Loading