[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[FDclone-users:01058] Re: FDclone 3.01h has been released



 しらいです。

In Message-Id <20180810172202.58F76200CE0A0@mx1.unixusers.net>
        Takashi SHIRAI <shirai@unixusers.net>writes:
>  しらいです。

>  本日、下記 URL にて FDclone 3.01h を公開しましたのでご案内
> 申上げます。

 今回の変更点は主にバグ修正になりますが、多分セキュリティ的
な面では特に問題ないものだけだと思います。


>  以下は HISTORY より今回の変更点の抜粋です。

 では詳細を解説します。


> 	ファイル名コード変換時に UTF-8 テーブルが一対一を保つよう修正。

 これは従来より懸念事項となっていた、内部コードとして UTF-8
を使っていないことに起因する問題の一つを解決したという話にな
ります。
 内部コードを UTF-8 にしないと本質的な解決には至らないのは
判っているんですが、目に見えて実害が出ているところを少しでも
無くせればと考えています。

 ご存知の通り、EUC-JP 等の JIS 系コードと UTF-8 との間には
一対多の対応関係があり、その「多」の部分を解消すべく、これま
で UTF8-mac や UTF8-iconv という枠組を用意して来ました。
 これにより、UTF-8 への変換に於いては一対一の関係を構築出来
たのですが、UTF-8 からの変換に於いては依然多対一の関係になっ
ていました。
 例えば UTF8-mac では「が」は合字の「か゛」というコードを用
いますが、UTF8-mac からの変換に於いては「か゛」と「が」の両
方を JIS 系コードの「が」に変換していました。
 これをしないと、「か゛」の方は表示出来るのに「が」の方は表
示出来なくなるため、見えないよりはましだろうという配慮から選
んだ実装でした。

 しかし、一旦内部コードで「が」に変換されてしまうと元が「が」
なのか「か゛」なのかを判別することが出来ません。
 UTF8-mac の設定では「か゛」が正しいコード体系なので、元の
UTF-8 に戻す際には「が」→「が」→「か゛」という不可逆な変換
が生じてしまいます。
 表示する時は戻す必要が無いので特に問題無いのですが、ファイ
ル名に使用された UTF-8 を扱う場合は、この不可逆性が期待外れ
の挙動を生んでしまいます。
 ファイルを編集したり属性を取得したりしようとすると、「が」
も「か゛」も「か゛」を参照しに行くので、別のファイルや存在し
ないファイルにアクセスしてしまいます。

 ということで、ファイル名に関するコード変換に於いては、この
ような一対多の関係にある UTF-8 文字は、正規のコードのみ変換
してそれ以外のコード体系は敢えて失敗させることにしました。
 なので UTF8-mac の場合、「か゛」は正しく表示される一方で、
「が」は「\343\201\214」のように UTF-8 コードの八進表記にな
り、一見文字化けしているように処理されてしまいます。
 その代わり、これはファイルアクセスの際に本来のファイルを参
照するので、操作上の問題だけは無くなることになります。

 多分この問題が一番多く表面化するのは、Linux 環境に Windows
端末でアクセスしているケースだと思います。
 Linux の採用している UTF-8 は iconv の変換テーブルに則って
いるという主張があって、Linux の標準コードを「UTF8」ではなく
「UTF8-iconv」にしたという経緯がありました。
 その一方、例えば TeraTerm では「UTF-8m」というコード体系は
用意されていても iconv 相当のコード体系は用意されていないた
め、「〜」や「¬」は Windows のコード体系で吐かれます。
 ここに齟齬が生じた結果、Linux 側の一部ファイルが期待したも
のとは異なる実体をアクセスしてしまうという問題が発生していた
と思います。

 今回の対処法がベストだとは思いませんが、次善策としては容認
可能な範囲なのではないかと思っています。


> 	一つ前のジョブがカレントジョブになれない点を修正。

 これは内蔵シェルの挙動に関する話です。原語で「current job」
「previous job」と呼ばれるジョブの挙動が期待通りではありませ
んでした。
 current job が追加される際に従来の current job を previous
job とする部分は実装されていたので、次々とジョブ生成している
分には期待通りの挙動でした。
 その一方で、current job が失われた際に従来の previous job
を current job とする部分が実装されていなかったので、この時
には current job がどこにも存在しない状態になっていました。
 処理中の全ジョブに優先順位を設け、current job の次の候補や
次の次の候補を用意する実装に改めたので、バックグラウンドジョ
ブが残っている限りは current job が存在するようになりました。

 因みに、FDclone のジョブは Bourne shell に準拠した実装にし
てあるので、bash や POSIX シェルとは一部異なる挙動になってい
ます。
 例えば %1, %3 があるところにジョブ生成した場合、bash は %4
を割当てますが、Bourne shell や FDclone は %2 を再利用して割
当てます。
 また POSIX には current job や previous job として stopped
job から優先的に採用するという規則がありますが、Bourne shell
や FDclone では全てのジョブは平等になっています。
 その辺りを変更したい場合もあるかと思ったので、BASHSTYLE や
STRICTPOSIX といった識別子を有効にしてコンパイルすることで、
それぞれの挙動が実装されるようにしました。


> 	外部コマンドの終了や停止時に出力を失うことがある点を修正。

 一般に、子プロセスが終了したり停止したりした場合には、親プ
ロセスに SIGCHLD シグナルが飛んで、その時に実行中だったシス
テムコールが EINTR で失敗するというのが UNIX の仕様です。
 このたまたまのタイミングで親プロセス側が stdout や stderr
に出力していた場合、EINTR で失敗するので ferror() が真となっ
てしまいます。
 従来の実装では、一旦 ferror() が真となった以降の入出力は全
て失敗にしていたため、プロンプトが表示出来なくなったり echo
の結果が表示されなかったりという症状になっていました。
 これを回避する為、まめに clearerr() を行なってエラーリセッ
トすると共に、EINTR 時に再試行させて失敗しないような実装に改
めました。

 タイミングの問題なので再現性が小さいのですが、コマンドライ
ンから「cat &」と打つと割と簡単に再現させられると思います。
 cat コマンドは background で実行させられると SIGTTOU で即
座に停止するので、丁度同じタイミングでジョブ情報を表示しよう
とした親プロセス側を EINTR で止めてしまいます。
 3.01g では結構頻繁に再現しましたが、3.01h では今のところ一
回も再現していないので、修正は有効だと思います。

                                               しらい たかし