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

w3m-decode-buffer and handling URIs containing non-ASCII characters



>> On Tue, 20 Feb 2007 18:36:32 +0900
>> yamaoka@xxxxxxx (Katsumi Yamaoka) said as follows:

>そうですね。結局 w3m-decode-buffer で、コンテンツを取得して全体をデコー
>ドした直後の html ソースの段階で、その手の非-ASCII文字を含む url をエン
>コードしてしまうことにしました。これなら shimbun でも有効なはずです。

これも,ちょっと問題が多い変更ではないかと思います.

もともとの設計では,

    w3m-decode-buffer() は文字コードの解釈のみ.
    URI の対処は,w3m-fontify-anchors() で行う.
    
と切り分けてありました.具体的には,w3m-url-transfer-encode-string() を呼
び出している個所を grep してみて下さい.現状では,w3m-decode-buffer() で
encode し,さらに,w3m-fontify-anchors() でも encode するという二度手間を
やっていませんか?

そもそも,w3m-url-transfer-encode-string() は,非常に危険で暫定的な関数な
ので,安易に使うべきではないと思います.と言うのは,

    http://example.net/サンプル.html

のような URI について,

    http://example.net/%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB.html (utf-8でエンコード)
    http://example.net/%A5%B5%A5%F3%A5%D7%A5%EB.html (euc-jpでエンコード)
    http://example.net/%83%54%83%93%83%76%83%8B.html (sjisでエンコード)

のどれを送信するべきかということについて,広く普及した規約(および,その実
装)というものがまだ存在しない状態なので,w3m-url-transfer-encode-string()
の正しい動作が決められないからです.

;; チェックしていませんが,最近の RFC は utf-8 だと言ってましたっけ?
;; でも現実としては,Windows で動いているサーバは sjis でうまくいくことが
;; 多いですし,ja_JP.eucJP なロケールで動いている apache なんかは euc-jp
;; でうまくいくことが多いでしょう.

w3m-url-transfer-encode-string() は,とりあえずの代替案として,「現在表示
中のページで使われている文字コードでエンコードする」という実装になってい
ますが,これは暫定案に過ぎません.

shimbun ライブラリの場合は,アクセスするサーバ毎(つまりモジュール毎)に適
切な文字コードが分かるのですから,このような暫定案よりも,shimbun モジュー
ル側でエンコードする方が確実だと思います.



-- 
土屋 雅稔 ( TSUCHIYA Masatoshi )
--- shimbun.el	27 Sep 2007 03:06:23 -0000	1.179
+++ shimbun.el	27 Sep 2007 11:04:20 -0000
@@ -94,7 +94,10 @@
 			  text-content-start text-content-end
 			  ;; Say whether to convert Japanese zenkaku
 			  ;; ASCII chars into hankaku.
-			  japanese-hankaku))
+			  japanese-hankaku
+			  ;; Coding system for encoding URIs when
+			  ;; accessing the server.
+			  url-coding-system))
   (luna-define-internal-accessors 'shimbun))
 
 (defgroup shimbun nil
@@ -220,8 +223,13 @@
 (defun shimbun-fetch-url (shimbun url &optional no-cache no-decode referer)
   "Retrieve contents specified by URL for SHIMBUN.
 This function is exacly similar to `shimbun-retrieve-url', but
-considers the `coding-system' slot of SHIMBUN when estimating a coding
-system of retrieved contents."
+considers the `coding-system' slot of SHIMBUN when estimating a
+coding system of retrieved contents and the `url-coding-system'
+slot of SHIMBUN to encode URL."
+  (setq url (w3m-url-transfer-encode-string
+	     url
+	     (or (shimbun-url-coding-system-internal shimbun)
+		 'utf-8)))
   (if (shimbun-coding-system-internal shimbun)
       (let ((w3m-coding-system-priority-list
 	     (cons (shimbun-coding-system-internal shimbun)
@@ -558,7 +566,8 @@
   (luna-call-next-method)
   (insert (base64-encode-string (shimbun-entity-data-internal entity))))
 
-(defun shimbun-mime-replace-image-tags (base-cid &optional base-url images)
+(defun shimbun-mime-replace-image-tags (shimbun base-cid
+						&optional base-url images)
   "Replace all IMG tags with references to inlined image parts.
 This function takes a BASE-CID as a base string for CIDs of inlined
 image parts, and returns an alist of URLs and image entities."
@@ -600,7 +609,7 @@
       (unless (setq img (assoc url images))
 	(with-temp-buffer
 	  (set-buffer-multibyte nil)
-	  (setq type (shimbun-retrieve-url url nil t base-url))
+	  (setq type (shimbun-fetch-url shimbun url nil t base-url))
 	  (when (or (and type (string-match "\\`image/" type))
 		    ;; headlines.yahoo.co.jp often specifies it mistakenly.
 		    (and (string-match "\\.\\(gif\\|jpe?g\\|png\\)\\'" url)
@@ -633,7 +642,8 @@
       (setq base-cid (match-string 1 base-cid)))
     (when shimbun-encapsulate-images
       (setq images
-	    (shimbun-mime-replace-image-tags base-cid
+	    (shimbun-mime-replace-image-tags shimbun
+					     base-cid
 					     (or base-url
 						 (shimbun-article-url
 						  shimbun header)))))
@@ -767,7 +777,7 @@
   '(url groups coding-system server-name from-address
 	content-start content-end x-face-alist expiration-days
 	prefer-text-plain text-content-start text-content-end
-	japanese-hankaku))
+	japanese-hankaku url-coding-system))
 
 (defun shimbun-open (server &optional mua)
   "Open a shimbun for SERVER.
--- sb-multi.el	12 Jul 2006 09:14:52 -0000	1.1
+++ sb-multi.el	27 Sep 2007 11:05:02 -0000
@@ -64,7 +64,10 @@
 	  (insert "\n</body>\n</html>\n")
 	(shimbun-insert-footer shimbun header t "</body>\n</html>\n")))
     (when shimbun-encapsulate-images
-      (setq images (shimbun-mime-replace-image-tags base-cid base-url images)))
+      (setq images (shimbun-mime-replace-image-tags shimbun
+						    base-cid
+						    base-url
+						    images)))
     (let ((body (shimbun-make-text-entity "text/html" (buffer-string)))
 	  (result
 	   (when next-url
--- w3m.el	27 Sep 2007 10:51:14 -0000	1.1313
+++ w3m.el	27 Sep 2007 11:07:27 -0000
@@ -4355,49 +4355,7 @@
        (prog1
 	   (decode-coding-string (buffer-string) w3m-current-coding-system)
 	 (erase-buffer)
-	 (set-buffer-multibyte t)))
-
-      ;; Encode urls containing non-ASCII characters.
-      (when (and (<= level 0)
-		 (or (featurep 'xemacs)
-		     ;; For the unknown reason Emacs 21.* causes
-		     ;; segfault by this.
-		     (>= emacs-major-version 22)))
-	(goto-char (point-min))
-	(let ((case-fold-search t))
-	  (while (re-search-forward "\
-<[\t\n\r ]*\\(?:\\(a\\)\\|\\(img\\)\\)[\t\n\r ]+\
-\\(?:[\000-\075\077-\177]*[^\000-\177]+\\)+[\000-\075\077-\177]*>"
-				    nil t)
-	    (save-match-data
-	      (save-excursion
-		(when (if (match-end 1)
-			  (re-search-backward "\
-\[\t\n\r ]href[\t\n\r ]*=[\t\n\r ]*\
-\"\\(\\(?:[\000-\041\043-\177]*[^\000-\177]+\\)+[\000-\041\043-\177]*\\)"
-					      (match-end 1) t)
-			(re-search-backward "[\t\n\r ]src[\t\n\r ]*=[\t\n\r ]*\
-\"\\(\\(?:[\000-\041\043-\177]*[^\000-\177]+\\)+[\000-\041\043-\177]*\\)"
-					    (match-end 2) t))
-		  (insert (w3m-url-transfer-encode-string
-			   (prog1
-			       (match-string 1)
-			     (delete-region (goto-char (match-beginning 1))
-					    (match-end 1)))
-			   w3m-current-coding-system)))))
-	    (when (if (match-end 1)
-		      (re-search-backward "[\t\n\r ]href[\t\n\r ]*=[\t\n\r ]*\
-'\\(\\(?:[\000-\046\048-\177]*[^\000-\177]+\\)+[\000-\046\048-\177]*\\)"
-					  (match-end 1) t)
-		    (re-search-backward "[\t\n\r ]src[\t\n\r ]*=[\t\n\r ]*\
-'\\(\\(?:[\000-\046\048-\177]*[^\000-\177]+\\)+[\000-\046\048-\177]*\\)"
-					(match-end 2) t))
-	      (insert (w3m-url-transfer-encode-string
-		       (prog1
-			   (match-string 1)
-			 (delete-region (goto-char (match-beginning 1))
-					(match-end 1)))
-		       w3m-current-coding-system)))))))))
+	 (set-buffer-multibyte t))))))
 
 (defun w3m-x-moe-decode-buffer ()
   (let ((args '("-i" "-cs" "x-moe-internal"))