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

"%" を含むファイル名を Drag & Dropできない



藤井と申します。

mule-ja の皆様はじめまして。宜しくお願いします。

meadow-users-jp ML に投稿された不具合ですが、Emacs の不具合だと思います
し、文字列エンコーディングにも絡む(かもしれない)ことなので、こちらに投
稿させていただきます。

[現象]

URI のパーセントエンコーディングを含む文字列をファイル名に含むファイル
ど Drag & Drop すると、正しく開けません。
Meadow3.00-dev と NTEmacs CVS のそれぞれの HEAD で再現します。

Message-ID: <20060503.092343.132849383.zxcv3794@xxxxxxxxxxxxxxx>
> 『%30.txt』という名前のファイルを開こうとすると、*Messages* バッファに
> 「dnd-open-local-file: Can not read file:C:\var\mina\test\0.txt」が記録
> されエラーになります

[考えられる原因]

w32-drag-n-drop() ではファイル名に file: を追加しただけのパーセントエン
コーディングが施されていない文字列を、dnd-handle-one-url() に渡していま
す。そのため、dnd-handle-one-url() においてファイル名の「%30.txt」がデ
コードされて、「0.txt」 となり、これを開こうとするために正しく開けませ
ん。

また、x-dnd-handle-file-name() でも同様にファイル名の先頭に file: を付
けるだけの作業て URI を生成しているように見えます。UNIX 系 OS でも再現
するかもしれません。

# UNIX 系 OS のファイルシステムでファイル名に % が許されているのかどう
# か知りませんが。

[対策]

w32-drag-n-drop でファイル名をちゃんと URI エンコーディングする。

末尾にパッチを添付しています。

上記不具合を解決するだけならば '%' を '%25' にするだけで良いのですが、
パッチではちゃんと URI エンコードするようにしたつもりです。

[質問]

パッチを作成した時に分からなかった点があります。

マルチバイト文字を含むファイル名を URI エンコードする時に、マルチバイト
文字の文字コードをどうするべきでしょうか?

ファイル名なので file-name-coding-system でエンコードしたあと URI エン
コードすべきかとも思ったのですが、URL だとファイル名とは限らないかもし
れないので、とりあえず emacs-mule でエンコードしたあと URI エンコードし
ています。

以下、パッチです。(Meadow のパッチですが、NTEmacs にも適用できます)

# X-Window 関係も修正しないといけないとのですが、確認できる環境がないの
# でWindows 向けのみの修正になっています。

Index: lisp/term/w32-win.el
===================================================================
--- lisp/term/w32-win.el	(revision 4067)
+++ lisp/term/w32-win.el	(working copy)
@@ -112,6 +112,19 @@
       (if (and (> x 0) (> y 0))
 	  (set-frame-selected-window nil window))
       (mapcar (lambda (file-name)
+		(setq file-name
+		      (mapconcat (lambda (c)
+				   (cond
+				    ((string-match "[].[_~a-zA-Z0-9!$&'()*+,;=:/?#@-]"
+						   (char-to-string c))
+				     (char-to-string c))
+				    ((char-equal c ?\x20)
+				     "+")
+				    (t
+				     (format "%%%02x" c))))
+				 (encode-coding-string file-name
+						       'emacs-mule)
+				 ""))
 		(dnd-handle-one-url window 'private
 				    (concat "file:" file-name)))
 		(car (cdr (cdr event)))))
Index: lisp/dnd.el
===================================================================
--- lisp/dnd.el	(revision 4067)
+++ lisp/dnd.el	(working copy)
@@ -79,11 +79,15 @@
 ARG is the URL that has been dropped.
 Returns ACTION."
   (require 'browse-url)
-  (let* ((uri (replace-regexp-in-string
-	       "%[A-Z0-9][A-Z0-9]"
-	       (lambda (arg)
-		 (format "%c" (string-to-number (substring arg 1) 16)))
-	       arg))
+  (let* ((uri (decode-coding-string
+	       (replace-regexp-in-string
+		"+\\|%[A-Z0-9][A-Z0-9]"
+		(lambda (arg)
+		  (if (string-equal arg "+")
+		      " "
+		    (format "%c" (string-to-number (substring arg 1) 16))))
+		arg nil t)
+	       'emacs-mule))
 	 ret)
     (or
      (catch 'done

--
藤井 正行 / Masayuki FUJII ( boochang@xxxxxxxxxxxx )