[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] master b909718: * idna.el (idna-decode-string-internal): I
From: |
Lars Ingebrigtsen |
Subject: |
[Emacs-diffs] master b909718: * idna.el (idna-decode-string-internal): Implement decoding. |
Date: |
Mon, 28 Dec 2015 03:15:27 +0000 |
branch: master
commit b9097188f7a6dbfd408a1fe8c6df80526d3bd944
Author: Lars Ingebrigtsen <address@hidden>
Commit: Lars Ingebrigtsen <address@hidden>
* idna.el (idna-decode-string-internal): Implement decoding.
---
lisp/net/idna.el | 66 +++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 60 insertions(+), 6 deletions(-)
diff --git a/lisp/net/idna.el b/lisp/net/idna.el
index dfaf711..052a9f6 100644
--- a/lisp/net/idna.el
+++ b/lisp/net/idna.el
@@ -30,6 +30,9 @@
(require 'seq)
(defun idna-encode-string (string)
+ "Encode STRING according to the IDNA/punycode algorithm.
+This is used to encode non-ASCII domain names.
+For instance, \"bücher\" => \"xn--bcher-kva\"."
(let ((ascii (seq-filter (lambda (char)
(< char 128))
string)))
@@ -37,6 +40,13 @@
string
(concat "xn--" ascii "-" (idna-encode-complex (length ascii) string)))))
+(defun idna-decode-string (string)
+ "Decode an IDNA/punycode-encoded string.
+For instance \"xn--bcher-kva\" => \"bücher\"."
+ (if (string-match "\\`xn--.*-" string)
+ (idna-decode-string-internal (substring string 4))
+ string))
+
(defconst idna-initial-n 128)
(defconst idna-initial-bias 72)
(defconst idna-base 36)
@@ -47,12 +57,12 @@
(defun idna-decode-digit (cp)
(cond
- ((< (- cp 48) 10)
- (- cp 22))
- ((< (- cp 65) 26)
- (- cp 65))
- ((< (- cp 97) 26)
- (- cp 97))
+ ((<= cp ?9)
+ (- cp ?0))
+ ((<= cp ?Z)
+ (- cp ?A))
+ ((<= cp ?z)
+ (- cp ?a))
(t
idna-base)))
@@ -119,6 +129,50 @@
(cl-incf n))
(nreverse result)))
+(defun idna-decode-string-internal (string)
+ (with-temp-buffer
+ (insert string)
+ (goto-char (point-max))
+ (if (not (search-backward "-" nil t))
+ (error "Invalid IDNA string")
+ ;; The encoded chars are after the final dash.
+ (let ((encoded (buffer-substring (1+ (point)) (point-max)))
+ (ic 0)
+ (i 0)
+ (bias idna-initial-bias)
+ (n idna-initial-n)
+ out)
+ (delete-region (point) (point-max))
+ (while (< ic (length encoded))
+ (let ((old-i i)
+ (w 1)
+ (k idna-base)
+ digit t1)
+ (cl-loop do (progn
+ (setq digit (idna-decode-digit (aref encoded ic)))
+ (cl-incf ic)
+ (cl-incf i (* digit w))
+ (setq t1 (cond
+ ((<= k bias)
+ idna-tmin)
+ ((>= k (+ bias idna-tmax))
+ idna-tmax)
+ (t
+ (- k bias)))))
+ while (>= digit t1)
+ do (setq w (* w (- idna-base t1))
+ k (+ k idna-base)))
+ (setq out (1+ (buffer-size)))
+ (setq bias (idna-adapt (- i old-i) out (= old-i 0))))
+
+ (setq n (+ n (/ i out))
+ i (mod i out))
+ (goto-char (point-min))
+ (forward-char i)
+ (insert (format "%c" n))
+ (cl-incf i))))
+ (buffer-string)))
+
(provide 'idna)
;;; shr.el ends here
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] master b909718: * idna.el (idna-decode-string-internal): Implement decoding.,
Lars Ingebrigtsen <=