web-dev-qa-db-ja.com

variables / printfのnullバイトに対するPOSIX awkのスタンスは何ですか?

POSIXに従ってawkのprintf関数を使用してnullバイトを出力することは合法ですか? POSIX標準のawk では、どちらの方法でも明示的に言及されていないようです。実際の実装では、動作が異なります。

_+$ gawk 'BEGIN { x = sprintf("\000"); print(length(x)); }'
1
+$ busybox awk 'BEGIN { x = sprintf("\000"); print(length(x)); }'
0
+$
_

そして

_+$ gawk 'BEGIN { printf("\000"); }' | xxd
00000000: 00                                       .
+$ busybox awk 'BEGIN { printf("\000"); }' | xxd
+$
_

これは規格のどこかに指定されていますか?はいの場合、変数(x = sprintf("\000"))とprintf(printf("\000"))に必要な動作は同じですか?

12
graywolf

POSIX.2018仕様のawk には、少なくとも4つの関連するテキストがあります。

強調(太字)は、以下のすべての引用テキストで私のものです。

以下のソースのいずれかからawkプログラムへの入力ファイルは、textファイルである必要があります

つまり、入力にNUL文字(テキストのPOSIX定義に従って非テキストになる)が含まれている場合、動作は規定されていません。

\ ddd:<バックスラッシュ>文字の後に、1桁、2桁、または3桁の8進数の文字(01234567)の最も長いシーケンスが続きます。 すべての桁が0(つまり、NUL文字の表現)である場合、動作は未定義です

そう \000は未定義の動作になります。

正規表現一致について:

ただし、すべてのawk ERE一致では、パターン、入力レコード、またはテキスト文字列で1つ以上のNUL文字を使用すると、未定義の結果が生成されます

printf/sprintfについて:

7. c変換指定子文字の場合:引数に数値がある場合、その値がエンコードである文字が出力されます。 値がゼロであるか、文字セット内のどの文字のエンコーディングでもない場合、動作は未定義です

したがって、これは未定義の動作につながるNUL文字を取得する別の方法です。

したがって、要約すると、awkのPOSIXは、入力、出力、変数への格納のいずれであっても、NUL文字を移植して使用できないことを示しています。

gawk(1989年に少なくとも2.10であり、これは最も古いバージョンです NULサポートが文書化されています )および @ ThomasDickey's mawk (それ以降 バージョン20140914 )は、NULを処理できる2つの実装です。

17