Commit | Line | Data |
---|---|---|
fbf2e7ad CY |
1 | ;;; xml-parse-tests.el --- Test suite for XML parsing. |
2 | ||
ba318903 | 3 | ;; Copyright (C) 2012-2014 Free Software Foundation, Inc. |
fbf2e7ad CY |
4 | |
5 | ;; Author: Chong Yidong <cyd@stupidchicken.com> | |
6 | ;; Keywords: internal | |
7 | ;; Human-Keywords: internal | |
8 | ||
9 | ;; This file is part of GNU Emacs. | |
10 | ||
11 | ;; GNU Emacs is free software: you can redistribute it and/or modify | |
12 | ;; it under the terms of the GNU General Public License as published by | |
13 | ;; the Free Software Foundation, either version 3 of the License, or | |
14 | ;; (at your option) any later version. | |
15 | ||
16 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
17 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
18 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
19 | ;; GNU General Public License for more details. | |
20 | ||
21 | ;; You should have received a copy of the GNU General Public License | |
22 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. | |
23 | ||
24 | ;;; Commentary: | |
25 | ||
26 | ;; Type M-x test-xml-parse RET to generate the test buffer. | |
27 | ||
28 | ;;; Code: | |
29 | ||
771b2fc3 | 30 | (require 'ert) |
fbf2e7ad CY |
31 | (require 'xml) |
32 | ||
33 | (defvar xml-parse-tests--data | |
566df3fc | 34 | `(;; General entity substitution |
fbf2e7ad CY |
35 | ("<?xml version=\"1.0\"?><!DOCTYPE foo SYSTEM \"bar.dtd\" [<!ENTITY ent \"AbC\">]><foo a=\"b\"><bar>&ent;;</bar></foo>" . |
36 | ((foo ((a . "b")) (bar nil "AbC;")))) | |
566df3fc | 37 | ("<?xml version=\"1.0\"?><foo>&amp;&apos;'<>"</foo>" . |
a7aef6f5 | 38 | ((foo () "&''<>\""))) |
fbf2e7ad CY |
39 | ;; Parameter entity substitution |
40 | ("<?xml version=\"1.0\"?><!DOCTYPE foo SYSTEM \"bar.dtd\" [<!ENTITY % pent \"AbC\"><!ENTITY ent \"%pent;\">]><foo a=\"b\"><bar>&ent;;</bar></foo>" . | |
41 | ((foo ((a . "b")) (bar nil "AbC;")))) | |
42 | ;; Tricky parameter entity substitution (like XML spec Appendix D) | |
43 | ("<?xml version='1.0'?><!DOCTYPE foo [ <!ENTITY % xx '%zz;'><!ENTITY % zz '<!ENTITY ent \"b\" >' > %xx; ]><foo>A&ent;C</foo>" . | |
a7aef6f5 | 44 | ((foo () "AbC"))) |
6fe566a7 CY |
45 | ;; Bug#7172 |
46 | ("<?xml version=\"1.0\"?><!DOCTYPE foo [ <!ELEMENT EXAM_PLE EMPTY> ]><foo></foo>" . | |
a7aef6f5 CY |
47 | ((foo ()))) |
48 | ;; Entities referencing entities, in character data | |
49 | ("<!DOCTYPE foo [ <!ENTITY b \"B\"><!ENTITY abc \"a&b;c\">]><foo>&abc;</foo>" . | |
50 | ((foo () "aBc"))) | |
51 | ;; Entities referencing entities, in attribute values | |
52 | ("<!DOCTYPE foo [ <!ENTITY b \"B\"><!ENTITY abc \"a&b;c\">]><foo a=\"-&abc;-\">1</foo>" . | |
53 | ((foo ((a . "-aBc-")) "1"))) | |
54 | ;; Character references must be treated as character data | |
55 | ("<foo>AT&T;</foo>" . ((foo () "AT&T;"))) | |
566df3fc CY |
56 | ("<foo>&amp;</foo>" . ((foo () "&"))) |
57 | ("<foo>&amp;</foo>" . ((foo () "&"))) | |
58 | ;; Unusual but valid XML names [5] | |
59 | ("<ÀÖØö.3·-‿⁀>abc</ÀÖØö.3·-‿⁀>" . ((,(intern "ÀÖØö.3·-‿⁀") () "abc"))) | |
60 | ("<:>abc</:>" . ((,(intern ":") () "abc")))) | |
fbf2e7ad CY |
61 | "Alist of XML strings and their expected parse trees.") |
62 | ||
a76e6535 CY |
63 | (defvar xml-parse-tests--bad-data |
64 | '(;; XML bomb in content | |
65 | "<!DOCTYPE foo [<!ENTITY lol \"lol\"><!ENTITY lol1 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\"><!ENTITY lol2 \"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;\">]><foo>&lol2;</foo>" | |
66 | ;; XML bomb in attribute value | |
67 | "<!DOCTYPE foo [<!ENTITY lol \"lol\"><!ENTITY lol1 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\"><!ENTITY lol2 \"&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;\">]><foo a=\"&lol2;\">!</foo>" | |
68 | ;; Non-terminating DTD | |
69 | "<!DOCTYPE foo [ <!ENTITY b \"B\"><!ENTITY abc \"a&b;c\">" | |
70 | "<!DOCTYPE foo [ <!ENTITY b \"B\"><!ENTITY abc \"a&b;c\">asdf" | |
566df3fc CY |
71 | "<!DOCTYPE foo [ <!ENTITY b \"B\"><!ENTITY abc \"a&b;c\">asdf&abc;" |
72 | ;; Invalid XML names | |
73 | "<0foo>abc</0foo>" | |
74 | "<‿foo>abc</‿foo>" | |
75 | "<f¿>abc</f¿>") | |
a76e6535 CY |
76 | "List of XML strings that should signal an error in the parser") |
77 | ||
c91562a6 DE |
78 | (defvar xml-parse-tests--qnames |
79 | '( ;; Test data for name expansion | |
80 | ("<?xml version=\"1.0\" encoding=\"UTF-8\"?><D:multistatus xmlns:D=\"DAV:\"><D:response><D:href>/calendar/events/</D:href><D:propstat><D:status>HTTP/1.1 200 OK</D:status></D:propstat></D:response></D:multistatus>" | |
81 | ;; Result with qnames as cons | |
82 | ((("DAV:" . "multistatus") | |
83 | ((("http://www.w3.org/2000/xmlns/" . "D") . "DAV:")) | |
84 | (("DAV:" . "response") nil (("DAV:" . "href") nil "/calendar/events/") | |
85 | (("DAV:" . "propstat") nil (("DAV:" . "status") nil "HTTP/1.1 200 OK"))))) | |
86 | ;; Result with qnames as symbols | |
87 | ((DAV:multistatus | |
88 | ((("http://www.w3.org/2000/xmlns/" . "D") . "DAV:")) | |
89 | (DAV:response nil (DAV:href nil "/calendar/events/") | |
90 | (DAV:propstat nil (DAV:status nil "HTTP/1.1 200 OK")))))) | |
91 | ("<?xml version=\"1.0\" encoding=\"UTF-8\"?><F:something>hi there</F:something>" | |
92 | ((("FOOBAR:" . "something") nil "hi there")) | |
93 | ((FOOBAR:something nil "hi there")))) | |
94 | "List of strings which are parsed using namespace expansion. | |
95 | Parser is called with and without 'symbol-qnames argument.") | |
96 | ||
fbf2e7ad CY |
97 | (ert-deftest xml-parse-tests () |
98 | "Test XML parsing." | |
99 | (with-temp-buffer | |
100 | (dolist (test xml-parse-tests--data) | |
101 | (erase-buffer) | |
102 | (insert (car test)) | |
a76e6535 CY |
103 | (should (equal (cdr test) (xml-parse-region)))) |
104 | (let ((xml-entity-expansion-limit 50)) | |
105 | (dolist (test xml-parse-tests--bad-data) | |
106 | (erase-buffer) | |
107 | (insert test) | |
c91562a6 DE |
108 | (should-error (xml-parse-region)))) |
109 | (let ((testdata (car xml-parse-tests--qnames))) | |
110 | (erase-buffer) | |
111 | (insert (car testdata)) | |
112 | (should (equal (nth 1 testdata) | |
113 | (xml-parse-region nil nil nil nil t))) | |
114 | (should (equal (nth 2 testdata) | |
115 | (xml-parse-region nil nil nil nil 'symbol-qnames)))) | |
116 | (let ((testdata (nth 1 xml-parse-tests--qnames))) | |
117 | (erase-buffer) | |
118 | (insert (car testdata)) | |
119 | ;; Provide additional namespace-URI mapping | |
120 | (should (equal (nth 1 testdata) | |
121 | (xml-parse-region | |
122 | nil nil nil nil | |
123 | (append xml-default-ns | |
124 | '(("F" . "FOOBAR:")))))) | |
125 | (should (equal (nth 2 testdata) | |
126 | (xml-parse-region | |
127 | nil nil nil nil | |
128 | (cons 'symbol-qnames | |
129 | (append xml-default-ns | |
130 | '(("F" . "FOOBAR:")))))))))) | |
fbf2e7ad CY |
131 | |
132 | ;; Local Variables: | |
133 | ;; no-byte-compile: t | |
134 | ;; End: | |
135 | ||
136 | ;;; xml-parse-tests.el ends here. |