001: /* Copyright 2002-2005 Elliotte Rusty Harold
002:
003: This library is free software; you can redistribute it and/or modify
004: it under the terms of version 2.1 of the GNU Lesser General Public
005: License as published by the Free Software Foundation.
006:
007: This library is distributed in the hope that it will be useful,
008: but WITHOUT ANY WARRANTY; without even the implied warranty of
009: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
010: GNU Lesser General Public License for more details.
011:
012: You should have received a copy of the GNU Lesser General Public
013: License along with this library; if not, write to the
014: Free Software Foundation, Inc., 59 Temple Place, Suite 330,
015: Boston, MA 02111-1307 USA
016:
017: You can contact Elliotte Rusty Harold by sending e-mail to
018: elharo@metalab.unc.edu. Please include the word "XOM" in the
019: subject line. The XOM home page is located at http://www.xom.nu/
020: */
021:
022: package nu.xom.tests;
023:
024: import nu.xom.Attribute;
025: import nu.xom.DocType;
026: import nu.xom.Element;
027: import nu.xom.IllegalDataException;
028: import nu.xom.IllegalNameException;
029: import nu.xom.MalformedURIException;
030: import nu.xom.Text;
031:
032: import org.apache.xerces.util.XMLChar;
033:
034: /**
035: * <p>
036: * Tests to make sure name and character rules are enforced.
037: * The rules are tested by comparison with the rules in
038: * the org.apache.xerces.util.XMLChar class.
039: * This is an undocumented class so this is potentially dangerous
040: * in the long run. it also means the tests depend on Xerces 2
041: * specifically. However, this dependence does not extend into the
042: * core API.
043: * </p>
044: *
045: * @author Elliotte Rusty Harold
046: * @version 1.1d7
047: *
048: */
049: public class VerifierTest extends XOMTestCase {
050:
051: private final static char[] subdelims = { '!', '$', '&', '\'', '(',
052: ')', '*', '+', ',', ';', '=' };
053: private final static char[] unreserved = { '-', '.', '_', '~' };
054: private final static char[] unwise = { '{', '}', '|', '\\', '^',
055: '[', ']', '`' };
056: private final static char[] delims = { '<', '>', '#', '%', '^', '"' };
057:
058: public VerifierTest(String name) {
059: super (name);
060: }
061:
062: public void testElementNames() {
063:
064: for (char c = 0; c < 65535; c++) {
065:
066: // XXX remove dependence on this class by providing
067: // your own table of name characters as a config file for
068: // the tests
069: if (XMLChar.isNCNameStart(c)) {
070: String name = String.valueOf(c);
071: Element e = new Element(name);
072: assertEquals(name, e.getLocalName());
073: } else {
074: try {
075: new Element(String.valueOf(c));
076: fail("Allowed illegal name start character "
077: + Integer.toHexString(c)
078: + " in element name");
079: } catch (IllegalNameException success) {
080: assertNotNull(success.getMessage());
081: }
082: }
083:
084: if (XMLChar.isNCName(c)) {
085: String name = "a" + c;
086: Element e = new Element(name);
087: assertEquals(name, e.getLocalName());
088: } else {
089: try {
090: new Element(String.valueOf(c));
091: fail("Allowed illegal character "
092: + Integer.toHexString(c)
093: + " in element name");
094: } catch (IllegalNameException success) {
095: assertNotNull(success.getMessage());
096: assertEquals(String.valueOf(c), success.getData());
097: }
098: }
099:
100: }
101:
102: }
103:
104: // From IRI draft:
105: /* ucschar = %xA0-D7FF / %xF900-FDCF / %xFDF0-FFEF /
106: / %x10000-1FFFD / %x20000-2FFFD / %x30000-3FFFD
107: / %x40000-4FFFD / %x50000-5FFFD / %x60000-6FFFD
108: / %x70000-7FFFD / %x80000-8FFFD / %x90000-9FFFD
109: / %xA0000-AFFFD / %xB0000-BFFFD / %xC0000-CFFFD
110: / %xD0000-DFFFD / %xE1000-EFFFD */
111:
112: // From RFC 2396 reallowed into IRIs
113: // "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
114: public void testLegalIRIs() {
115:
116: int[] legalChars = { '{', '}', '<', '>', '"', '|', '\\', '^',
117: '`', '\u007F', 0xA0, 0xD7FF, 0xF900, 0xFDCF, 0xFDF0,
118: 0xFFEF, 0x10000, 0x1FFFD, 0x20000, 0x2FFFD, 0x30000,
119: 0x3FFFD, 0x40000, 0x4FFFD, 0x50000, 0x5FFFD, 0x60000,
120: 0x6FFFD, 0x70000, 0x7FFFD, 0x80000, 0x8FFFD, 0x90000,
121: 0x9FFFD, 0xA0000, 0xAFFFD, 0xB0000, 0xBFFFD, 0xC0000,
122: 0xCFFFD, 0xD0000, 0xDFFFD, 0xE1000, 0xEFFFD, 0xCFFFD };
123:
124: Element element = new Element("test");
125: for (int i = 0; i < legalChars.length; i++) {
126: String utf16 = convertToUTF16(legalChars[i]);
127: String url = "http://www.example.com/" + utf16 + ".xml";
128: element.addAttribute(new Attribute("xml:base",
129: "http://www.w3.org/XML/1998/namespace", url));
130: assertEquals(url, element.getAttributeValue("base",
131: "http://www.w3.org/XML/1998/namespace"));
132: }
133:
134: }
135:
136: public void testAllASCIILettersAllowedToBeginSchemeNames() {
137:
138: Element e = new Element("e");
139:
140: for (char c = 'A'; c <= 'Z'; c++) {
141: String uri = c + "scheme:schemeSpecificData";
142: e.setNamespaceURI(uri);
143: assertEquals(uri, e.getNamespaceURI());
144: }
145:
146: for (char c = 'a'; c <= 'z'; c++) {
147: String uri = c + "scheme:schemeSpecificData";
148: e.setNamespaceURI(uri);
149: assertEquals(uri, e.getNamespaceURI());
150: }
151:
152: }
153:
154: public void testAllASCIILettersAllowedInSchemeNames() {
155:
156: Element e = new Element("e");
157:
158: for (char c = 'A'; c <= 'Z'; c++) {
159: String uri = "scheme" + c + ":schemeSpecificData";
160: e.setNamespaceURI(uri);
161: assertEquals(uri, e.getNamespaceURI());
162: }
163:
164: for (char c = 'a'; c <= 'z'; c++) {
165: String uri = "scheme" + c + ":schemeSpecificData";
166: e.setNamespaceURI(uri);
167: assertEquals(uri, e.getNamespaceURI());
168: }
169:
170: }
171:
172: public void testAllASCIILettersAllowedInQueryStrings() {
173:
174: Element e = new Element("e");
175:
176: for (char c = 'A'; c <= 'Z'; c++) {
177: String uri = "http://www.example.com/?name=" + c;
178: e.setNamespaceURI(uri);
179: assertEquals(uri, e.getNamespaceURI());
180: }
181:
182: for (char c = 'a'; c <= 'z'; c++) {
183: String uri = "http://www.example.com/?name=" + c;
184: e.setNamespaceURI(uri);
185: assertEquals(uri, e.getNamespaceURI());
186: }
187:
188: }
189:
190: public void testAllASCIIDigitsAllowedInQueryStrings() {
191:
192: Element e = new Element("e");
193:
194: for (char c = '0'; c <= '9'; c++) {
195: String uri = "http://www.example.com/?value=" + c;
196: e.setNamespaceURI(uri);
197: assertEquals(uri, e.getNamespaceURI());
198: }
199:
200: }
201:
202: public void testSlashAllowedInQueryString() {
203:
204: Element e = new Element("e");
205:
206: String uri = "http://www.example.com/?path=/home/elharo/docs/";
207: e.setNamespaceURI(uri);
208: assertEquals(uri, e.getNamespaceURI());
209:
210: }
211:
212: public void testQuestionMarkAllowedInQueryString() {
213:
214: Element e = new Element("e");
215:
216: String uri = "http://www.example.com/?path=?home?elharo?docs?";
217: e.setNamespaceURI(uri);
218: assertEquals(uri, e.getNamespaceURI());
219:
220: }
221:
222: public void testColonAllowedInQueryString() {
223:
224: Element e = new Element("e");
225:
226: String uri = "http://www.example.com/?path=:home:elharo:docs:";
227: e.setNamespaceURI(uri);
228: assertEquals(uri, e.getNamespaceURI());
229:
230: }
231:
232: public void testAtSignAllowedInQueryString() {
233:
234: Element e = new Element("e");
235:
236: String uri = "http://www.example.com/?path=@home@elharo@docs@";
237: e.setNamespaceURI(uri);
238: assertEquals(uri, e.getNamespaceURI());
239:
240: }
241:
242: public void testNonASCIICharactersNotAllowedInQueryStrings() {
243:
244: Element e = new Element("e");
245:
246: for (char c = 128; c <= 1024; c++) {
247: String uri = "http://www.example.com/?value=" + c;
248: try {
249: e.setNamespaceURI(uri);
250: fail("Allowed unescaped non-ASCII character " + c
251: + " in query string");
252: } catch (MalformedURIException success) {
253: assertEquals(uri, success.getData());
254: }
255: }
256:
257: }
258:
259: public void testDelimsNotAllowedInQueryStrings() {
260:
261: Element e = new Element("e");
262:
263: for (int i = 0; i < delims.length; i++) {
264: String uri = "http://www.example.com/?value=" + delims[i]
265: + "#Must_Use_Fragment_ID";
266: try {
267: e.setNamespaceURI(uri);
268: fail("Allowed delimiter character " + delims[i]
269: + " in query string");
270: } catch (MalformedURIException success) {
271: assertEquals(uri, success.getData());
272: }
273: }
274:
275: }
276:
277: public void testUnwiseCharactersNotAllowedInQueryStrings() {
278:
279: Element e = new Element("e");
280:
281: for (int i = 0; i < unwise.length; i++) {
282: String uri = "http://www.example.com/?value=" + unwise[i];
283: try {
284: e.setNamespaceURI(uri);
285: fail("Allowed unwise character " + unwise[i]
286: + " in query string");
287: } catch (MalformedURIException success) {
288: assertEquals(uri, success.getData());
289: }
290: }
291:
292: }
293:
294: public void testUnwiseCharactersNotAllowedInUserInfo() {
295:
296: Element e = new Element("e");
297:
298: for (int i = 0; i < unwise.length; i++) {
299: String uri = "http://user" + unwise[i]
300: + "name@www.example.com/?value=" + unwise[i];
301: try {
302: e.setNamespaceURI(uri);
303: fail("Allowed unwise character " + unwise[i]
304: + " in user info");
305: } catch (MalformedURIException success) {
306: assertEquals(uri, success.getData());
307: }
308: }
309:
310: }
311:
312: public void testUnwiseCharactersNotAllowedInHost() {
313:
314: Element e = new Element("e");
315:
316: for (int i = 0; i < unwise.length; i++) {
317: String uri = "http://u" + unwise[i] + "www.example.com/";
318: try {
319: e.setNamespaceURI(uri);
320: fail("Allowed unwise character " + unwise[i]
321: + " in host");
322: } catch (MalformedURIException success) {
323: assertEquals(uri, success.getData());
324: }
325: }
326:
327: }
328:
329: public void testDelimsNotAllowedInHost() {
330:
331: Element e = new Element("e");
332:
333: for (int i = 0; i < delims.length; i++) {
334: String uri = "http://u" + delims[i]
335: + "www.example.com/#value";
336: try {
337: e.setNamespaceURI(uri);
338: fail("Allowed unwise character " + delims[i]
339: + " in host");
340: } catch (MalformedURIException success) {
341: assertEquals(uri, success.getData());
342: }
343: }
344:
345: }
346:
347: public void testUnwiseCharactersNotAllowedInPath() {
348:
349: Element e = new Element("e");
350:
351: for (int i = 0; i < unwise.length; i++) {
352: String uri = "http://www.example.com/path" + unwise[i]
353: + "/path";
354: try {
355: e.setNamespaceURI(uri);
356: fail("Allowed unwise character " + unwise[i]
357: + " in path");
358: } catch (MalformedURIException success) {
359: assertEquals(uri, success.getData());
360: }
361: }
362:
363: }
364:
365: public void testAllASCIILettersAllowedInHostNames() {
366:
367: Element e = new Element("e");
368:
369: for (char c = 'A'; c <= 'Z'; c++) {
370: String uri = "http://" + c + ".com/";
371: e.setNamespaceURI(uri);
372: assertEquals(uri, e.getNamespaceURI());
373: }
374:
375: for (char c = 'a'; c <= 'z'; c++) {
376: String uri = "http://" + c + ".com/";
377: e.setNamespaceURI(uri);
378: assertEquals(uri, e.getNamespaceURI());
379: }
380:
381: }
382:
383: public void testAllASCIIDigitsAllowedInHostNames() {
384:
385: Element e = new Element("e");
386:
387: for (char c = '0'; c <= '9'; c++) {
388: String uri = "http://c" + c + ".com/";
389: e.setNamespaceURI(uri);
390: assertEquals(uri, e.getNamespaceURI());
391: }
392:
393: }
394:
395: public void testNonASCIICharactersNotAllowedInHostNames() {
396:
397: Element e = new Element("e");
398:
399: for (char c = 128; c <= 1024; c++) {
400: String uri = "http://c" + c + ".com/";
401: try {
402: e.setNamespaceURI(uri);
403: fail("Allowed unescaped non-ASCII character " + c
404: + " in host name");
405: } catch (MalformedURIException success) {
406: assertEquals(uri, success.getData());
407: }
408: }
409:
410: }
411:
412: public void testAllASCIILettersAllowedInUserInfo() {
413:
414: Element e = new Element("e");
415:
416: for (char c = 'A'; c <= 'Z'; c++) {
417: String uri = "http://" + c + "@c.com/";
418: e.setNamespaceURI(uri);
419: assertEquals(uri, e.getNamespaceURI());
420: }
421:
422: for (char c = 'a'; c <= 'z'; c++) {
423: String uri = "http://" + c + "@c.com/";
424: e.setNamespaceURI(uri);
425: assertEquals(uri, e.getNamespaceURI());
426: }
427:
428: }
429:
430: public void testAllSubDelimsAllowedInUserInfo() {
431:
432: Element e = new Element("e");
433:
434: for (int i = 0; i < subdelims.length; i++) {
435: String uri = "http://c" + subdelims[i] + "x@c.com/";
436: e.setNamespaceURI(uri);
437: assertEquals(uri, e.getNamespaceURI());
438: }
439:
440: }
441:
442: public void testAllSubDelimsAllowedInPath() {
443:
444: Element e = new Element("e");
445:
446: for (int i = 0; i < subdelims.length; i++) {
447: String uri = "http://cc.com/path" + subdelims[i] + ".html";
448: e.setNamespaceURI(uri);
449: assertEquals(uri, e.getNamespaceURI());
450: }
451:
452: }
453:
454: public void testAllUnreservedPunctuationMarksAllowedInUserInfo() {
455:
456: Element e = new Element("e");
457:
458: for (int i = 0; i < unreserved.length; i++) {
459: String uri = "http://c" + unreserved[i] + "x@c.com/";
460: e.setNamespaceURI(uri);
461: assertEquals(uri, e.getNamespaceURI());
462: }
463:
464: }
465:
466: public void testAllUnreservedPunctuationMarksAllowedInHost() {
467:
468: Element e = new Element("e");
469:
470: for (int i = 0; i < unreserved.length; i++) {
471: String uri = "http://c" + unreserved[i] + "xc.com/";
472: e.setNamespaceURI(uri);
473: assertEquals(uri, e.getNamespaceURI());
474: }
475:
476: }
477:
478: public void testAllSubDelimsAllowedInQueryString() {
479:
480: Element e = new Element("e");
481:
482: for (int i = 0; i < subdelims.length; i++) {
483: String uri = "http://cx@c.com/?name=" + subdelims[i];
484: e.setNamespaceURI(uri);
485: assertEquals(uri, e.getNamespaceURI());
486: }
487:
488: }
489:
490: public void testAllSubDelimsAllowedInHost() {
491:
492: Element e = new Element("e");
493:
494: for (int i = 0; i < subdelims.length; i++) {
495: String uri = "http://cx" + subdelims[i] + "c.com/";
496: e.setNamespaceURI(uri);
497: assertEquals(uri, e.getNamespaceURI());
498: }
499:
500: }
501:
502: public void testAllUnreservedPunctuationMarksAllowedInQueryString() {
503:
504: Element e = new Element("e");
505:
506: for (int i = 0; i < unreserved.length; i++) {
507: String uri = "http://cx@c.com/?name=" + unreserved[i];
508: e.setNamespaceURI(uri);
509: assertEquals(uri, e.getNamespaceURI());
510: }
511:
512: }
513:
514: public void testAllASCIIDigitsAllowedInUserInfo() {
515:
516: Element e = new Element("e");
517:
518: for (char c = '0'; c <= '9'; c++) {
519: String uri = "http://" + c + "@c.com/";
520: e.setNamespaceURI(uri);
521: assertEquals(uri, e.getNamespaceURI());
522: }
523:
524: }
525:
526: public void testNonASCIICharactersNotAllowedInUserInfo() {
527:
528: Element e = new Element("e");
529:
530: for (char c = 128; c <= 1024; c++) {
531: String uri = "http://" + c + "@c.com/";
532: try {
533: e.setNamespaceURI(uri);
534: fail("Allowed unescaped non-ASCII character " + c
535: + " in user info");
536: } catch (MalformedURIException success) {
537: assertEquals(uri, success.getData());
538: }
539: }
540:
541: }
542:
543: public void testDelimCharactersNotAllowedInUserInfo() {
544:
545: Element e = new Element("e");
546:
547: for (int i = 0; i < delims.length; i++) {
548: String uri = "http://c" + delims[i]
549: + "c@c.com/?name=value#fragID";
550: try {
551: e.setNamespaceURI(uri);
552: fail("Allowed delim character " + delims[i]
553: + " in user info");
554: } catch (MalformedURIException success) {
555: assertEquals(uri, success.getData());
556: }
557: }
558:
559: }
560:
561: public void testMalformedURI() {
562:
563: Element e = new Element("e");
564:
565: String uri = "http://c#c@c.com/?name=value#fragID";
566: try {
567: e.setNamespaceURI(uri);
568: fail("Allowed http://c#c@c.com/?name=value#fragID as URI");
569: } catch (MalformedURIException success) {
570: assertEquals(uri, success.getData());
571: }
572:
573: }
574:
575: public void testFragmentIDContainsQuestionMark() {
576:
577: Element e = new Element("e");
578:
579: String uri = "http://cc@c.com/?name=value#fragID?home/?elharo?";
580: e.setNamespaceURI(uri);
581: assertEquals(uri, e.getNamespaceURI());
582:
583: uri = "http://cc@c.com/#fragID?name=value";
584: e.setNamespaceURI(uri);
585: assertEquals(uri, e.getNamespaceURI());
586:
587: }
588:
589: public void testFragmentIDContainsFirstColon() {
590:
591: Element e = new Element("e");
592:
593: String uri = "http://c.com/#fragID:home";
594: e.setNamespaceURI(uri);
595: assertEquals(uri, e.getNamespaceURI());
596:
597: uri = "http://c.com/#fragID:home@eharo.com/somewhere";
598: e.setNamespaceURI(uri);
599: assertEquals(uri, e.getNamespaceURI());
600:
601: }
602:
603: public void testEmptyHostAllowed() {
604:
605: Element e = new Element("e");
606:
607: String uri = "scheme://elharo@:80/data";
608: e.setNamespaceURI(uri);
609: assertEquals(uri, e.getNamespaceURI());
610:
611: }
612:
613: public void testC0ControlsNotAllowedInUserInfo() {
614:
615: Element e = new Element("e");
616:
617: for (char c = 0; c <= ' '; c++) {
618: String uri = "http://" + c + "@c.com/";
619: try {
620: e.setNamespaceURI(uri);
621: fail("Allowed C0 control 0x" + Integer.toHexString(c)
622: + " in user info");
623: } catch (MalformedURIException success) {
624: assertEquals(uri, success.getData());
625: }
626: }
627:
628: }
629:
630: public void testC0ControlsNotAllowedInPath() {
631:
632: Element e = new Element("e");
633:
634: for (char c = 0; c <= ' '; c++) {
635: String uri = "http://www.example.com/test/" + c + "data/";
636: try {
637: e.setNamespaceURI(uri);
638: fail("Allowed C0 control 0x" + Integer.toHexString(c)
639: + " in path");
640: } catch (MalformedURIException success) {
641: assertEquals(uri, success.getData());
642: }
643: }
644:
645: }
646:
647: public void testC0ControlsNotAllowedInQueryString() {
648:
649: Element e = new Element("e");
650:
651: for (char c = 0; c <= ' '; c++) {
652: String uri = "http://www.c.com/?name=" + c + "&value=7";
653: try {
654: e.setNamespaceURI(uri);
655: fail("Allowed C0 control 0x" + Integer.toHexString(c)
656: + " in query string");
657: } catch (MalformedURIException success) {
658: assertEquals(uri, success.getData());
659: }
660: }
661:
662: }
663:
664: public void testHostNameTooLong() {
665:
666: StringBuffer uri = new StringBuffer("http://");
667: for (int i = 0; i < 255; i++)
668: uri.append('c');
669: uri.append(".com/");
670: Element e = new Element("e");
671: try {
672: e.setNamespaceURI(uri.toString());
673: fail("Allowed excessively long host name");
674: } catch (MalformedURIException success) {
675: assertNotNull(success.getMessage());
676: }
677:
678: }
679:
680: public void testSymbolsNotAllowedInSchemeNames() {
681:
682: Element e = new Element("e");
683:
684: char[] disallowed = { ';', '@', '&', '=', '$', ',', '"', '?',
685: '#', '/', '\\', '|', '_', '!', '~', '*', '\'', '(',
686: ')', '<', '>', '[', ']', '{', '}', '^', '`' };
687:
688: for (int i = 0; i < disallowed.length; i++) {
689: String uri = "scheme" + disallowed[i]
690: + ":schemeSpecificData";
691: try {
692: e.setNamespaceURI(uri);
693: fail("allowed " + uri + " as namespace URI");
694: } catch (MalformedURIException success) {
695: assertEquals(uri, success.getData());
696: }
697: }
698:
699: }
700:
701: public void testNonASCIILettersNotAllowedToBeginSchemeNames() {
702:
703: Element e = new Element("e");
704:
705: for (char c = 'Z' + 1; c < 'a'; c++) {
706: String uri = c + "scheme:schemeSpecificData";
707: try {
708: e.setNamespaceURI(uri);
709: fail("allowed " + uri + " as namespace URI");
710: } catch (MalformedURIException success) {
711: assertEquals(uri, success.getData());
712: }
713: }
714:
715: }
716:
717: public void testBadHexEscapeInQueryString() {
718:
719: Element e = new Element("e");
720:
721: String uri = "scheme:schemeSpecificData?test%5test";
722: try {
723: e.setNamespaceURI(uri);
724: fail("allowed " + uri + " as namespace URI");
725: } catch (MalformedURIException success) {
726: assertEquals(uri, success.getData());
727: }
728:
729: uri = "scheme:schemeSpecificData?test%5";
730: try {
731: e.setNamespaceURI(uri);
732: fail("allowed " + uri + " as namespace URI");
733: } catch (MalformedURIException success) {
734: assertEquals(uri, success.getData());
735: }
736:
737: }
738:
739: public void testHexEscapeInUserInfo() {
740:
741: Element e = new Element("e");
742:
743: String uri = "scheme://user%C3%80TED@www.example.com/";
744: e.setNamespaceURI(uri);
745: assertEquals(uri, e.getNamespaceURI());
746:
747: }
748:
749: public void testHexEscapeInHost() {
750:
751: Element e = new Element("e");
752:
753: String uri = "scheme://user%C3%80www.example.com/";
754: e.setNamespaceURI(uri);
755: assertEquals(uri, e.getNamespaceURI());
756:
757: }
758:
759: public void testBadHexEscapeInUserInfo() {
760:
761: Element e = new Element("e");
762:
763: String uri = "scheme://user%5TED@www.example.com/";
764: try {
765: e.setNamespaceURI(uri);
766: fail("allowed " + uri + " as namespace URI");
767: } catch (MalformedURIException success) {
768: assertEquals(uri, success.getData());
769: }
770:
771: uri = "scheme://user%5@www.example.com/";
772: try {
773: e.setNamespaceURI(uri);
774: fail("allowed " + uri + " as namespace URI");
775: } catch (MalformedURIException success) {
776: assertEquals(uri, success.getData());
777: }
778:
779: }
780:
781: public void testBadHexEscapeInHost() {
782:
783: Element e = new Element("e");
784:
785: String uri = "scheme://user%5TEDwww.example.com/";
786: try {
787: e.setNamespaceURI(uri);
788: fail("allowed " + uri + " as namespace URI");
789: } catch (MalformedURIException success) {
790: assertEquals(uri, success.getData());
791: }
792:
793: uri = "scheme://www.example.co%5/";
794: try {
795: e.setNamespaceURI(uri);
796: fail("allowed " + uri + " as namespace URI");
797: } catch (MalformedURIException success) {
798: assertEquals(uri, success.getData());
799: }
800:
801: }
802:
803: public void testQuestionmarkIsNotAHexDigit() {
804:
805: Element e = new Element("e");
806:
807: // Have to do this in a fragment ID to keep it from being
808: // interpreted as a query string separator
809: String uri = "scheme://user@www.example.com/#fragment%?Adata";
810: try {
811: e.setNamespaceURI(uri);
812: fail("allowed " + uri + " as namespace URI");
813: } catch (MalformedURIException success) {
814: assertEquals(uri, success.getData());
815: }
816:
817: }
818:
819: public void testIllegalIRIs() {
820:
821: int[] illegalChars = { 0x00, 0xDC00, 0xE7FF, 0xF899, 0xD800,
822: 0xFDE0, 0xFFFF, 0x1FFFE, 0x2FFFE, 0x3FFFF, 0x4FFFE,
823: 0x4FFFF, 0x5FFFE, 0x6FFFF, 0x7FFFE, 0x8FFFF, 0x9FFFE,
824: 0xAFFFE, 0xBFFFF, 0xCFFFE, 0xDFFFE, 0xEFFFF, 0xFDDF };
825:
826: for (int i = 0; i < illegalChars.length; i++) {
827: String utf16 = convertToUTF16(illegalChars[i]);
828: String url = "http://www.example.com/" + utf16 + ".xml";
829: try {
830: new DocType("root", url);
831: fail("Allowed URL containing 0x"
832: + Integer.toHexString(illegalChars[i])
833: .toUpperCase());
834: } catch (MalformedURIException success) {
835: assertNotNull(success.getMessage());
836: assertEquals(url, success.getData());
837: }
838: }
839:
840: }
841:
842: public void testLegalIP6Addresses() {
843:
844: String[] addresses = {
845: "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210",
846: "1080:0:0:0:8:800:200C:4171", "3ffe:2a00:100:7031::1",
847: "1080::8:800:200C:417A", "::192.9.5.5",
848: "::FFFF:129.144.52.38", "2010:836B:4179::836B:4179",
849: "1080:0:0:0:8:800:200C:417A", "FF01:0:0:0:0:0:0:101",
850: "0:0:0:0:0:0:0:1", "0:0:0:0:0:0:0:0",
851: "1080::8:800:200C:417A", "FF01::101", "::1", "::",
852: "0:0:0:0:0:0:13.1.68.3",
853: "0:0:0:0:0:FFFF:129.144.52.38", "::13.1.68.3",
854: "::FFFF:129.144.52.38" };
855:
856: Element element = new Element("test");
857: for (int i = 0; i < addresses.length; i++) {
858: String url = "http://[" + addresses[i] + "]/";
859: element.addAttribute(new Attribute("xml:base",
860: "http://www.w3.org/XML/1998/namespace", url));
861: assertEquals(url, element.getBaseURI());
862: }
863:
864: }
865:
866: public void testIllegalIP6Addresses() {
867:
868: String[] addresses = {
869: "FEDC:BA98:7654:3210:GEDC:BA98:7654:3 210",
870: "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210:4352",
871: "FEDC:BA98:7654:3210:GEDC:BA98:7654:3210",
872: "FEDC:BA98:7654:3210:GEDC:BA98:7654:G210",
873: "FEDC:BA98:7654:3210:GEDC:BA98:7654: 3210",
874: "FEDC:BA98:7654:3210:GEDC:BA98:7654:+3210",
875: "FEDC:BA98:7654:3210:GEDC:BA98:7654:3210 ",
876: "FEDC:BA98:7654:3210:GEDC:BA98:7654:32 10",
877: "1080:0:::8:800:200C:4171", "3ffe::100:7031::1",
878: "::192.9.5", "::FFFF:129.144.52.38.56",
879: "::FFFF:129.144.52.A3", "::FFFF:129.144.52.-22",
880: "::FFFF:129.144.52.+22", "::FFFF:256.144.52.+22",
881: "::FFFF:www.apple.com", "1080:0:0:0:8:800:-200C:417A",
882: "1080:0:0:0:-8:800:-200C:417A" };
883:
884: for (int i = 0; i < addresses.length; i++) {
885: String url = "http://[" + addresses[i] + "]/";
886: try {
887: new DocType("root", url);
888: fail("Allowed illegal IPv6 address: " + addresses[i]);
889: } catch (MalformedURIException success) {
890: assertNotNull(success.getMessage());
891: assertTrue(success.getData().indexOf(addresses[i]) >= 0);
892: }
893: }
894:
895: }
896:
897: // from Unicode FAQ
898: // http://www.unicode.org/faq/utf_bom.html#35
899: private static int LEAD_OFFSET = 0xD800 - (0x10000 >> 10);
900:
901: private static String convertToUTF16(int c) {
902:
903: if (c <= 0xFFFF)
904: return String.valueOf((char) c);
905: char high = (char) (LEAD_OFFSET + (c >> 10));
906: char low = (char) (0xDC00 + (c & 0x3FF));
907: StringBuffer sb = new StringBuffer(2);
908: sb.append(high);
909: sb.append(low);
910: return sb.toString().toLowerCase();
911:
912: }
913:
914: public void testC0Controls() {
915:
916: for (char c = 0; c < '\t'; c++) {
917: try {
918: new Text(String.valueOf(c));
919: } catch (IllegalDataException success) {
920: assertNotNull(success.getMessage());
921: }
922: }
923:
924: for (char c = '\r' + 1; c < ' '; c++) {
925: try {
926: new Text(String.valueOf(c));
927: } catch (IllegalDataException success) {
928: assertNotNull(success.getMessage());
929: assertEquals(String.valueOf(c), success.getData());
930: }
931: }
932:
933: }
934:
935: public void testAttributeNameThatEndsWithAColon() {
936:
937: try {
938: new Attribute("name:", "http://www.example.com", "value",
939: Attribute.Type.CDATA);
940: fail("Allowed attribute name that ends with a colon");
941: } catch (IllegalNameException success) {
942: assertNotNull(success.getMessage());
943: assertEquals("name:", success.getData());
944: }
945:
946: }
947:
948: public void testAttributeNameThatBeginsWithAColon() {
949:
950: try {
951: new Attribute(":name", "http://www.example.com", "value",
952: Attribute.Type.CDATA);
953: fail("Allowed attribute name that begins with a colon");
954: } catch (IllegalNameException success) {
955: assertNotNull(success.getMessage());
956: assertEquals(":name", success.getData());
957: }
958:
959: }
960:
961: public void testElementNameThatEndsWithAColon() {
962:
963: try {
964: new Element("name:", "http://www.example.com");
965: fail("Allowed element name that ends with a colon");
966: } catch (IllegalNameException success) {
967: assertNotNull(success.getMessage());
968: assertEquals("name:", success.getData());
969: }
970:
971: }
972:
973: public void testElementNameThatBeginsWithAColon() {
974:
975: try {
976: new Element(":name", "http://www.example.com");
977: fail("Allowed element name that begins with a colon");
978: } catch (IllegalNameException success) {
979: assertNotNull(success.getMessage());
980: assertEquals(":name", success.getData());
981: }
982:
983: }
984:
985: }
|