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

[debian-devel:16151] Re: xdvik-ja: Cannot open gziped DVI files



At Mon, 20 Sep 2004 13:41:52 +0900,
Kenshi Muto wrote:

> At Mon, 20 Sep 2004 10:47:49 +0900,
> TSUCHIYA Masatoshi wrote:
> > xdvik-ja パッケージをインストールしている状態で,圧縮された dvi ファイ
> > ルが閲覧できません.
> > 
> >     % LANG=C xdvi /usr/share/doc/texmf/latex/supertab/supertabular.dvi.gz
> >     xdvi.bin: Fatal error: Could not open `/dev/fd/3': Bad address.
> > 
> > xdvi.bin の alternatives を xdvi.real に戻すと,無事に閲覧できますので 
> > xdvi-ja.real の問題だろうと思います.
> > 
> > で,このバグの修正方法をご存じの方は,情報提供をお願いします.
> > 
> > なお,xdvi コマンドの代わりに xdvi-ja コマンドを利用すれば,この問題を
> > 回避することができます.
> 
> xdvi-jaの場合にはテンポラリファイルという実体があるけど、xdviの場合に
> は/dev/fd/*のファイルデスクリプタを直接使っているのですね。
> 
> Code Readingをしてみましたが、とっかかりだけで続きは偉い人に期待…。
> 
> 1. xdvi.cのmainでfile_name2 = is_good_dvi_file(file_name, False)) を呼
>    び出し。これが成功したときのみ、run_dvi_file(file_name2, &info);に
>    よって表示が行われる。
> 2. xdvi.cのis_good_dvi_file(const char *filename, Boolean
>    from_history)。
>    real_filename = find_dvi_file(filename, &tried_dvi_extension,
>    from_history)の時点ではreal_filenameの/dev/fd/*は保持されている。
> 3. この中のret = REALPATH(real_filename, canonical_path); で検査してい
>    る。REALPATHはrealpathとdefineされているのでこれが使われる(非推奨の
>    関数のはずだけど…。my_realpathというのもあるけどやっぱりうまく動かな
>    いですね)。

非推奨なのは resolved_path側のバッファー長を指定できないので潜在的に
バッファーオーバーフローする可能性があるからですね。
(いちおうPATH_MAX用意しておけば大丈夫のはずですが)

> 4. しかし、/dev/fd/*をrealpathに通すと、realpathはENOENTを返し、
>     retは(null)、canonical_pathは/tmp/gxLyQcgfEZ (deleted)のような一時
>    ファイルとなる(すぐに存在しなくなっちゃうけど)。

File::Tempのtempfileでつくっているのですでにディレクトリエントリーからは
消されているので (deleted)がついています。そのファイルディスクリプタを
closeするまでは(にぎっているプロセスが終了するまでは)ファイルの実体は
残っています。

まぁここでREALPATHをするのが間違い(/dev/fd/*のように symlinkを
たどってみつからなくてもファイルは存在しないわけではない)のような
気がするので

1) REALPATHが NULLをかえしてきたら(&& errno == ENOENTなら) 
   real_filename のほうを使う。
2) REALPATHのかわりに canonicalize_path()を使う? 
   (他の個所ではそうしているように見える)

のどちらかじゃないでしょうか。
canonicalize_path()ではsymlinkをたどって同じかどうかという判断が
できなくなるので 1)のほうがよいかも。

-- 
鵜飼文敏