runtests.c 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514
  1. /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
  2. See the file COPYING for copying permission.
  3. runtest.c : run the Expat test suite
  4. */
  5. #ifdef HAVE_EXPAT_CONFIG_H
  6. #include <expat_config.h>
  7. #endif
  8. #include <assert.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include "expat.h"
  13. #include "chardata.h"
  14. #include "minicheck.h"
  15. #if defined(__amigaos__) && defined(__USE_INLINE__)
  16. #include <proto/expat.h>
  17. #endif
  18. #ifdef XML_LARGE_SIZE
  19. #define XML_FMT_INT_MOD "ll"
  20. #else
  21. #define XML_FMT_INT_MOD "l"
  22. #endif
  23. static XML_Parser parser;
  24. static void
  25. basic_setup(void)
  26. {
  27. parser = XML_ParserCreate(NULL);
  28. if (parser == NULL)
  29. fail("Parser not created.");
  30. }
  31. static void
  32. basic_teardown(void)
  33. {
  34. if (parser != NULL)
  35. XML_ParserFree(parser);
  36. }
  37. /* Generate a failure using the parser state to create an error message;
  38. this should be used when the parser reports an error we weren't
  39. expecting.
  40. */
  41. static void
  42. _xml_failure(XML_Parser parser, const char *file, int line)
  43. {
  44. char buffer[1024];
  45. enum XML_Error err = XML_GetErrorCode(parser);
  46. sprintf(buffer,
  47. " %d: %s (line %" XML_FMT_INT_MOD "u, offset %"\
  48. XML_FMT_INT_MOD "u)\n reported from %s, line %d\n",
  49. err,
  50. XML_ErrorString(err),
  51. XML_GetCurrentLineNumber(parser),
  52. XML_GetCurrentColumnNumber(parser),
  53. file, line);
  54. _fail_unless(0, file, line, buffer);
  55. }
  56. #define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__)
  57. static void
  58. _expect_failure(char *text, enum XML_Error errorCode, char *errorMessage,
  59. char *file, int lineno)
  60. {
  61. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK)
  62. /* Hackish use of _fail_unless() macro, but let's us report
  63. the right filename and line number. */
  64. _fail_unless(0, file, lineno, errorMessage);
  65. if (XML_GetErrorCode(parser) != errorCode)
  66. _xml_failure(parser, file, lineno);
  67. }
  68. #define expect_failure(text, errorCode, errorMessage) \
  69. _expect_failure((text), (errorCode), (errorMessage), \
  70. __FILE__, __LINE__)
  71. /* Dummy handlers for when we need to set a handler to tickle a bug,
  72. but it doesn't need to do anything.
  73. */
  74. static void XMLCALL
  75. dummy_start_doctype_handler(void *userData,
  76. const XML_Char *doctypeName,
  77. const XML_Char *sysid,
  78. const XML_Char *pubid,
  79. int has_internal_subset)
  80. {}
  81. static void XMLCALL
  82. dummy_end_doctype_handler(void *userData)
  83. {}
  84. static void XMLCALL
  85. dummy_entity_decl_handler(void *userData,
  86. const XML_Char *entityName,
  87. int is_parameter_entity,
  88. const XML_Char *value,
  89. int value_length,
  90. const XML_Char *base,
  91. const XML_Char *systemId,
  92. const XML_Char *publicId,
  93. const XML_Char *notationName)
  94. {}
  95. static void XMLCALL
  96. dummy_notation_decl_handler(void *userData,
  97. const XML_Char *notationName,
  98. const XML_Char *base,
  99. const XML_Char *systemId,
  100. const XML_Char *publicId)
  101. {}
  102. static void XMLCALL
  103. dummy_element_decl_handler(void *userData,
  104. const XML_Char *name,
  105. XML_Content *model)
  106. {}
  107. static void XMLCALL
  108. dummy_attlist_decl_handler(void *userData,
  109. const XML_Char *elname,
  110. const XML_Char *attname,
  111. const XML_Char *att_type,
  112. const XML_Char *dflt,
  113. int isrequired)
  114. {}
  115. static void XMLCALL
  116. dummy_comment_handler(void *userData, const XML_Char *data)
  117. {}
  118. static void XMLCALL
  119. dummy_pi_handler(void *userData, const XML_Char *target, const XML_Char *data)
  120. {}
  121. static void XMLCALL
  122. dummy_start_element(void *userData,
  123. const XML_Char *name, const XML_Char **atts)
  124. {}
  125. /*
  126. * Character & encoding tests.
  127. */
  128. START_TEST(test_nul_byte)
  129. {
  130. char text[] = "<doc>\0</doc>";
  131. /* test that a NUL byte (in US-ASCII data) is an error */
  132. if (XML_Parse(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_OK)
  133. fail("Parser did not report error on NUL-byte.");
  134. if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
  135. xml_failure(parser);
  136. }
  137. END_TEST
  138. START_TEST(test_u0000_char)
  139. {
  140. /* test that a NUL byte (in US-ASCII data) is an error */
  141. expect_failure("<doc>&#0;</doc>",
  142. XML_ERROR_BAD_CHAR_REF,
  143. "Parser did not report error on NUL-byte.");
  144. }
  145. END_TEST
  146. START_TEST(test_bom_utf8)
  147. {
  148. /* This test is really just making sure we don't core on a UTF-8 BOM. */
  149. char *text = "\357\273\277<e/>";
  150. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  151. xml_failure(parser);
  152. }
  153. END_TEST
  154. START_TEST(test_bom_utf16_be)
  155. {
  156. char text[] = "\376\377\0<\0e\0/\0>";
  157. if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
  158. xml_failure(parser);
  159. }
  160. END_TEST
  161. START_TEST(test_bom_utf16_le)
  162. {
  163. char text[] = "\377\376<\0e\0/\0>\0";
  164. if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
  165. xml_failure(parser);
  166. }
  167. END_TEST
  168. static void XMLCALL
  169. accumulate_characters(void *userData, const XML_Char *s, int len)
  170. {
  171. CharData_AppendXMLChars((CharData *)userData, s, len);
  172. }
  173. static void XMLCALL
  174. accumulate_attribute(void *userData, const XML_Char *name,
  175. const XML_Char **atts)
  176. {
  177. CharData *storage = (CharData *)userData;
  178. if (storage->count < 0 && atts != NULL && atts[0] != NULL) {
  179. /* "accumulate" the value of the first attribute we see */
  180. CharData_AppendXMLChars(storage, atts[1], -1);
  181. }
  182. }
  183. static void
  184. _run_character_check(XML_Char *text, XML_Char *expected,
  185. const char *file, int line)
  186. {
  187. CharData storage;
  188. CharData_Init(&storage);
  189. XML_SetUserData(parser, &storage);
  190. XML_SetCharacterDataHandler(parser, accumulate_characters);
  191. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  192. _xml_failure(parser, file, line);
  193. CharData_CheckXMLChars(&storage, expected);
  194. }
  195. #define run_character_check(text, expected) \
  196. _run_character_check(text, expected, __FILE__, __LINE__)
  197. static void
  198. _run_attribute_check(XML_Char *text, XML_Char *expected,
  199. const char *file, int line)
  200. {
  201. CharData storage;
  202. CharData_Init(&storage);
  203. XML_SetUserData(parser, &storage);
  204. XML_SetStartElementHandler(parser, accumulate_attribute);
  205. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  206. _xml_failure(parser, file, line);
  207. CharData_CheckXMLChars(&storage, expected);
  208. }
  209. #define run_attribute_check(text, expected) \
  210. _run_attribute_check(text, expected, __FILE__, __LINE__)
  211. /* Regression test for SF bug #491986. */
  212. START_TEST(test_danish_latin1)
  213. {
  214. char *text =
  215. "<?xml version='1.0' encoding='iso-8859-1'?>\n"
  216. "<e>J\xF8rgen \xE6\xF8\xE5\xC6\xD8\xC5</e>";
  217. run_character_check(text,
  218. "J\xC3\xB8rgen \xC3\xA6\xC3\xB8\xC3\xA5\xC3\x86\xC3\x98\xC3\x85");
  219. }
  220. END_TEST
  221. /* Regression test for SF bug #514281. */
  222. START_TEST(test_french_charref_hexidecimal)
  223. {
  224. char *text =
  225. "<?xml version='1.0' encoding='iso-8859-1'?>\n"
  226. "<doc>&#xE9;&#xE8;&#xE0;&#xE7;&#xEA;&#xC8;</doc>";
  227. run_character_check(text,
  228. "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
  229. }
  230. END_TEST
  231. START_TEST(test_french_charref_decimal)
  232. {
  233. char *text =
  234. "<?xml version='1.0' encoding='iso-8859-1'?>\n"
  235. "<doc>&#233;&#232;&#224;&#231;&#234;&#200;</doc>";
  236. run_character_check(text,
  237. "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
  238. }
  239. END_TEST
  240. START_TEST(test_french_latin1)
  241. {
  242. char *text =
  243. "<?xml version='1.0' encoding='iso-8859-1'?>\n"
  244. "<doc>\xE9\xE8\xE0\xE7\xEa\xC8</doc>";
  245. run_character_check(text,
  246. "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
  247. }
  248. END_TEST
  249. START_TEST(test_french_utf8)
  250. {
  251. char *text =
  252. "<?xml version='1.0' encoding='utf-8'?>\n"
  253. "<doc>\xC3\xA9</doc>";
  254. run_character_check(text, "\xC3\xA9");
  255. }
  256. END_TEST
  257. /* Regression test for SF bug #600479.
  258. XXX There should be a test that exercises all legal XML Unicode
  259. characters as PCDATA and attribute value content, and XML Name
  260. characters as part of element and attribute names.
  261. */
  262. START_TEST(test_utf8_false_rejection)
  263. {
  264. char *text = "<doc>\xEF\xBA\xBF</doc>";
  265. run_character_check(text, "\xEF\xBA\xBF");
  266. }
  267. END_TEST
  268. /* Regression test for SF bug #477667.
  269. This test assures that any 8-bit character followed by a 7-bit
  270. character will not be mistakenly interpreted as a valid UTF-8
  271. sequence.
  272. */
  273. START_TEST(test_illegal_utf8)
  274. {
  275. char text[100];
  276. int i;
  277. for (i = 128; i <= 255; ++i) {
  278. sprintf(text, "<e>%ccd</e>", i);
  279. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK) {
  280. sprintf(text,
  281. "expected token error for '%c' (ordinal %d) in UTF-8 text",
  282. i, i);
  283. fail(text);
  284. }
  285. else if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
  286. xml_failure(parser);
  287. /* Reset the parser since we use the same parser repeatedly. */
  288. XML_ParserReset(parser, NULL);
  289. }
  290. }
  291. END_TEST
  292. START_TEST(test_utf16)
  293. {
  294. /* <?xml version="1.0" encoding="UTF-16"?>
  295. <doc a='123'>some text</doc>
  296. */
  297. char text[] =
  298. "\000<\000?\000x\000m\000\154\000 \000v\000e\000r\000s\000i\000o"
  299. "\000n\000=\000'\0001\000.\000\060\000'\000 \000e\000n\000c\000o"
  300. "\000d\000i\000n\000g\000=\000'\000U\000T\000F\000-\0001\000\066"
  301. "\000'\000?\000>\000\n"
  302. "\000<\000d\000o\000c\000 \000a\000=\000'\0001\0002\0003\000'"
  303. "\000>\000s\000o\000m\000e\000 \000t\000e\000x\000t\000<\000/"
  304. "\000d\000o\000c\000>";
  305. if (XML_Parse(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
  306. xml_failure(parser);
  307. }
  308. END_TEST
  309. START_TEST(test_utf16_le_epilog_newline)
  310. {
  311. unsigned int first_chunk_bytes = 17;
  312. char text[] =
  313. "\xFF\xFE" /* BOM */
  314. "<\000e\000/\000>\000" /* document element */
  315. "\r\000\n\000\r\000\n\000"; /* epilog */
  316. if (first_chunk_bytes >= sizeof(text) - 1)
  317. fail("bad value of first_chunk_bytes");
  318. if ( XML_Parse(parser, text, first_chunk_bytes, XML_FALSE)
  319. == XML_STATUS_ERROR)
  320. xml_failure(parser);
  321. else {
  322. enum XML_Status rc;
  323. rc = XML_Parse(parser, text + first_chunk_bytes,
  324. sizeof(text) - first_chunk_bytes - 1, XML_TRUE);
  325. if (rc == XML_STATUS_ERROR)
  326. xml_failure(parser);
  327. }
  328. }
  329. END_TEST
  330. /* Regression test for SF bug #481609, #774028. */
  331. START_TEST(test_latin1_umlauts)
  332. {
  333. char *text =
  334. "<?xml version='1.0' encoding='iso-8859-1'?>\n"
  335. "<e a='\xE4 \xF6 \xFC &#228; &#246; &#252; &#x00E4; &#x0F6; &#xFC; >'\n"
  336. " >\xE4 \xF6 \xFC &#228; &#246; &#252; &#x00E4; &#x0F6; &#xFC; ></e>";
  337. char *utf8 =
  338. "\xC3\xA4 \xC3\xB6 \xC3\xBC "
  339. "\xC3\xA4 \xC3\xB6 \xC3\xBC "
  340. "\xC3\xA4 \xC3\xB6 \xC3\xBC >";
  341. run_character_check(text, utf8);
  342. XML_ParserReset(parser, NULL);
  343. run_attribute_check(text, utf8);
  344. }
  345. END_TEST
  346. /* Regression test #1 for SF bug #653180. */
  347. START_TEST(test_line_number_after_parse)
  348. {
  349. char *text =
  350. "<tag>\n"
  351. "\n"
  352. "\n</tag>";
  353. XML_Size lineno;
  354. if (XML_Parse(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
  355. xml_failure(parser);
  356. lineno = XML_GetCurrentLineNumber(parser);
  357. if (lineno != 4) {
  358. char buffer[100];
  359. sprintf(buffer,
  360. "expected 4 lines, saw %" XML_FMT_INT_MOD "u", lineno);
  361. fail(buffer);
  362. }
  363. }
  364. END_TEST
  365. /* Regression test #2 for SF bug #653180. */
  366. START_TEST(test_column_number_after_parse)
  367. {
  368. char *text = "<tag></tag>";
  369. XML_Size colno;
  370. if (XML_Parse(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
  371. xml_failure(parser);
  372. colno = XML_GetCurrentColumnNumber(parser);
  373. if (colno != 11) {
  374. char buffer[100];
  375. sprintf(buffer,
  376. "expected 11 columns, saw %" XML_FMT_INT_MOD "u", colno);
  377. fail(buffer);
  378. }
  379. }
  380. END_TEST
  381. static void XMLCALL
  382. start_element_event_handler2(void *userData, const XML_Char *name,
  383. const XML_Char **attr)
  384. {
  385. CharData *storage = (CharData *) userData;
  386. char buffer[100];
  387. sprintf(buffer,
  388. "<%s> at col:%" XML_FMT_INT_MOD "u line:%"\
  389. XML_FMT_INT_MOD "u\n", name,
  390. XML_GetCurrentColumnNumber(parser),
  391. XML_GetCurrentLineNumber(parser));
  392. CharData_AppendString(storage, buffer);
  393. }
  394. static void XMLCALL
  395. end_element_event_handler2(void *userData, const XML_Char *name)
  396. {
  397. CharData *storage = (CharData *) userData;
  398. char buffer[100];
  399. sprintf(buffer,
  400. "</%s> at col:%" XML_FMT_INT_MOD "u line:%"\
  401. XML_FMT_INT_MOD "u\n", name,
  402. XML_GetCurrentColumnNumber(parser),
  403. XML_GetCurrentLineNumber(parser));
  404. CharData_AppendString(storage, buffer);
  405. }
  406. /* Regression test #3 for SF bug #653180. */
  407. START_TEST(test_line_and_column_numbers_inside_handlers)
  408. {
  409. char *text =
  410. "<a>\n" /* Unix end-of-line */
  411. " <b>\r\n" /* Windows end-of-line */
  412. " <c/>\r" /* Mac OS end-of-line */
  413. " </b>\n"
  414. " <d>\n"
  415. " <f/>\n"
  416. " </d>\n"
  417. "</a>";
  418. char *expected =
  419. "<a> at col:0 line:1\n"
  420. "<b> at col:2 line:2\n"
  421. "<c> at col:4 line:3\n"
  422. "</c> at col:8 line:3\n"
  423. "</b> at col:2 line:4\n"
  424. "<d> at col:2 line:5\n"
  425. "<f> at col:4 line:6\n"
  426. "</f> at col:8 line:6\n"
  427. "</d> at col:2 line:7\n"
  428. "</a> at col:0 line:8\n";
  429. CharData storage;
  430. CharData_Init(&storage);
  431. XML_SetUserData(parser, &storage);
  432. XML_SetStartElementHandler(parser, start_element_event_handler2);
  433. XML_SetEndElementHandler(parser, end_element_event_handler2);
  434. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  435. xml_failure(parser);
  436. CharData_CheckString(&storage, expected);
  437. }
  438. END_TEST
  439. /* Regression test #4 for SF bug #653180. */
  440. START_TEST(test_line_number_after_error)
  441. {
  442. char *text =
  443. "<a>\n"
  444. " <b>\n"
  445. " </a>"; /* missing </b> */
  446. XML_Size lineno;
  447. if (XML_Parse(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
  448. fail("Expected a parse error");
  449. lineno = XML_GetCurrentLineNumber(parser);
  450. if (lineno != 3) {
  451. char buffer[100];
  452. sprintf(buffer, "expected 3 lines, saw %" XML_FMT_INT_MOD "u", lineno);
  453. fail(buffer);
  454. }
  455. }
  456. END_TEST
  457. /* Regression test #5 for SF bug #653180. */
  458. START_TEST(test_column_number_after_error)
  459. {
  460. char *text =
  461. "<a>\n"
  462. " <b>\n"
  463. " </a>"; /* missing </b> */
  464. XML_Size colno;
  465. if (XML_Parse(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
  466. fail("Expected a parse error");
  467. colno = XML_GetCurrentColumnNumber(parser);
  468. if (colno != 4) {
  469. char buffer[100];
  470. sprintf(buffer,
  471. "expected 4 columns, saw %" XML_FMT_INT_MOD "u", colno);
  472. fail(buffer);
  473. }
  474. }
  475. END_TEST
  476. /* Regression test for SF bug #478332. */
  477. START_TEST(test_really_long_lines)
  478. {
  479. /* This parses an input line longer than INIT_DATA_BUF_SIZE
  480. characters long (defined to be 1024 in xmlparse.c). We take a
  481. really cheesy approach to building the input buffer, because
  482. this avoids writing bugs in buffer-filling code.
  483. */
  484. char *text =
  485. "<e>"
  486. /* 64 chars */
  487. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  488. /* until we have at least 1024 characters on the line: */
  489. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  490. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  491. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  492. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  493. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  494. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  495. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  496. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  497. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  498. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  499. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  500. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  501. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  502. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  503. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  504. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  505. "</e>";
  506. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  507. xml_failure(parser);
  508. }
  509. END_TEST
  510. /*
  511. * Element event tests.
  512. */
  513. static void XMLCALL
  514. end_element_event_handler(void *userData, const XML_Char *name)
  515. {
  516. CharData *storage = (CharData *) userData;
  517. CharData_AppendString(storage, "/");
  518. CharData_AppendXMLChars(storage, name, -1);
  519. }
  520. START_TEST(test_end_element_events)
  521. {
  522. char *text = "<a><b><c/></b><d><f/></d></a>";
  523. char *expected = "/c/b/f/d/a";
  524. CharData storage;
  525. CharData_Init(&storage);
  526. XML_SetUserData(parser, &storage);
  527. XML_SetEndElementHandler(parser, end_element_event_handler);
  528. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  529. xml_failure(parser);
  530. CharData_CheckString(&storage, expected);
  531. }
  532. END_TEST
  533. /*
  534. * Attribute tests.
  535. */
  536. /* Helpers used by the following test; this checks any "attr" and "refs"
  537. attributes to make sure whitespace has been normalized.
  538. Return true if whitespace has been normalized in a string, using
  539. the rules for attribute value normalization. The 'is_cdata' flag
  540. is needed since CDATA attributes don't need to have multiple
  541. whitespace characters collapsed to a single space, while other
  542. attribute data types do. (Section 3.3.3 of the recommendation.)
  543. */
  544. static int
  545. is_whitespace_normalized(const XML_Char *s, int is_cdata)
  546. {
  547. int blanks = 0;
  548. int at_start = 1;
  549. while (*s) {
  550. if (*s == ' ')
  551. ++blanks;
  552. else if (*s == '\t' || *s == '\n' || *s == '\r')
  553. return 0;
  554. else {
  555. if (at_start) {
  556. at_start = 0;
  557. if (blanks && !is_cdata)
  558. /* illegal leading blanks */
  559. return 0;
  560. }
  561. else if (blanks > 1 && !is_cdata)
  562. return 0;
  563. blanks = 0;
  564. }
  565. ++s;
  566. }
  567. if (blanks && !is_cdata)
  568. return 0;
  569. return 1;
  570. }
  571. /* Check the attribute whitespace checker: */
  572. static void
  573. testhelper_is_whitespace_normalized(void)
  574. {
  575. assert(is_whitespace_normalized("abc", 0));
  576. assert(is_whitespace_normalized("abc", 1));
  577. assert(is_whitespace_normalized("abc def ghi", 0));
  578. assert(is_whitespace_normalized("abc def ghi", 1));
  579. assert(!is_whitespace_normalized(" abc def ghi", 0));
  580. assert(is_whitespace_normalized(" abc def ghi", 1));
  581. assert(!is_whitespace_normalized("abc def ghi", 0));
  582. assert(is_whitespace_normalized("abc def ghi", 1));
  583. assert(!is_whitespace_normalized("abc def ghi ", 0));
  584. assert(is_whitespace_normalized("abc def ghi ", 1));
  585. assert(!is_whitespace_normalized(" ", 0));
  586. assert(is_whitespace_normalized(" ", 1));
  587. assert(!is_whitespace_normalized("\t", 0));
  588. assert(!is_whitespace_normalized("\t", 1));
  589. assert(!is_whitespace_normalized("\n", 0));
  590. assert(!is_whitespace_normalized("\n", 1));
  591. assert(!is_whitespace_normalized("\r", 0));
  592. assert(!is_whitespace_normalized("\r", 1));
  593. assert(!is_whitespace_normalized("abc\t def", 1));
  594. }
  595. static void XMLCALL
  596. check_attr_contains_normalized_whitespace(void *userData,
  597. const XML_Char *name,
  598. const XML_Char **atts)
  599. {
  600. int i;
  601. for (i = 0; atts[i] != NULL; i += 2) {
  602. const XML_Char *attrname = atts[i];
  603. const XML_Char *value = atts[i + 1];
  604. if (strcmp("attr", attrname) == 0
  605. || strcmp("ents", attrname) == 0
  606. || strcmp("refs", attrname) == 0) {
  607. if (!is_whitespace_normalized(value, 0)) {
  608. char buffer[256];
  609. sprintf(buffer, "attribute value not normalized: %s='%s'",
  610. attrname, value);
  611. fail(buffer);
  612. }
  613. }
  614. }
  615. }
  616. START_TEST(test_attr_whitespace_normalization)
  617. {
  618. char *text =
  619. "<!DOCTYPE doc [\n"
  620. " <!ATTLIST doc\n"
  621. " attr NMTOKENS #REQUIRED\n"
  622. " ents ENTITIES #REQUIRED\n"
  623. " refs IDREFS #REQUIRED>\n"
  624. "]>\n"
  625. "<doc attr=' a b c\t\td\te\t' refs=' id-1 \t id-2\t\t' \n"
  626. " ents=' ent-1 \t\r\n"
  627. " ent-2 ' >\n"
  628. " <e id='id-1'/>\n"
  629. " <e id='id-2'/>\n"
  630. "</doc>";
  631. XML_SetStartElementHandler(parser,
  632. check_attr_contains_normalized_whitespace);
  633. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  634. xml_failure(parser);
  635. }
  636. END_TEST
  637. /*
  638. * XML declaration tests.
  639. */
  640. START_TEST(test_xmldecl_misplaced)
  641. {
  642. expect_failure("\n"
  643. "<?xml version='1.0'?>\n"
  644. "<a/>",
  645. XML_ERROR_MISPLACED_XML_PI,
  646. "failed to report misplaced XML declaration");
  647. }
  648. END_TEST
  649. /* Regression test for SF bug #584832. */
  650. static int XMLCALL
  651. UnknownEncodingHandler(void *data,const XML_Char *encoding,XML_Encoding *info)
  652. {
  653. if (strcmp(encoding,"unsupported-encoding") == 0) {
  654. int i;
  655. for (i = 0; i < 256; ++i)
  656. info->map[i] = i;
  657. info->data = NULL;
  658. info->convert = NULL;
  659. info->release = NULL;
  660. return XML_STATUS_OK;
  661. }
  662. return XML_STATUS_ERROR;
  663. }
  664. START_TEST(test_unknown_encoding_internal_entity)
  665. {
  666. char *text =
  667. "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
  668. "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
  669. "<test a='&foo;'/>";
  670. XML_SetUnknownEncodingHandler(parser, UnknownEncodingHandler, NULL);
  671. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  672. xml_failure(parser);
  673. }
  674. END_TEST
  675. /* Regression test for SF bug #620106. */
  676. static int XMLCALL
  677. external_entity_loader_set_encoding(XML_Parser parser,
  678. const XML_Char *context,
  679. const XML_Char *base,
  680. const XML_Char *systemId,
  681. const XML_Char *publicId)
  682. {
  683. /* This text says it's an unsupported encoding, but it's really
  684. UTF-8, which we tell Expat using XML_SetEncoding().
  685. */
  686. char *text =
  687. "<?xml encoding='iso-8859-3'?>"
  688. "\xC3\xA9";
  689. XML_Parser extparser;
  690. extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
  691. if (extparser == NULL)
  692. fail("Could not create external entity parser.");
  693. if (!XML_SetEncoding(extparser, "utf-8"))
  694. fail("XML_SetEncoding() ignored for external entity");
  695. if ( XML_Parse(extparser, text, strlen(text), XML_TRUE)
  696. == XML_STATUS_ERROR) {
  697. xml_failure(parser);
  698. return 0;
  699. }
  700. return 1;
  701. }
  702. START_TEST(test_ext_entity_set_encoding)
  703. {
  704. char *text =
  705. "<!DOCTYPE doc [\n"
  706. " <!ENTITY en SYSTEM 'http://xml.libexpat.org/dummy.ent'>\n"
  707. "]>\n"
  708. "<doc>&en;</doc>";
  709. XML_SetExternalEntityRefHandler(parser,
  710. external_entity_loader_set_encoding);
  711. run_character_check(text, "\xC3\xA9");
  712. }
  713. END_TEST
  714. /* Test that no error is reported for unknown entities if we don't
  715. read an external subset. This was fixed in Expat 1.95.5.
  716. */
  717. START_TEST(test_wfc_undeclared_entity_unread_external_subset) {
  718. char *text =
  719. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  720. "<doc>&entity;</doc>";
  721. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  722. xml_failure(parser);
  723. }
  724. END_TEST
  725. /* Test that an error is reported for unknown entities if we don't
  726. have an external subset.
  727. */
  728. START_TEST(test_wfc_undeclared_entity_no_external_subset) {
  729. expect_failure("<doc>&entity;</doc>",
  730. XML_ERROR_UNDEFINED_ENTITY,
  731. "Parser did not report undefined entity w/out a DTD.");
  732. }
  733. END_TEST
  734. /* Test that an error is reported for unknown entities if we don't
  735. read an external subset, but have been declared standalone.
  736. */
  737. START_TEST(test_wfc_undeclared_entity_standalone) {
  738. char *text =
  739. "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
  740. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  741. "<doc>&entity;</doc>";
  742. expect_failure(text,
  743. XML_ERROR_UNDEFINED_ENTITY,
  744. "Parser did not report undefined entity (standalone).");
  745. }
  746. END_TEST
  747. static int XMLCALL
  748. external_entity_loader(XML_Parser parser,
  749. const XML_Char *context,
  750. const XML_Char *base,
  751. const XML_Char *systemId,
  752. const XML_Char *publicId)
  753. {
  754. char *text = (char *)XML_GetUserData(parser);
  755. XML_Parser extparser;
  756. extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
  757. if (extparser == NULL)
  758. fail("Could not create external entity parser.");
  759. if ( XML_Parse(extparser, text, strlen(text), XML_TRUE)
  760. == XML_STATUS_ERROR) {
  761. xml_failure(parser);
  762. return XML_STATUS_ERROR;
  763. }
  764. return XML_STATUS_OK;
  765. }
  766. /* Test that an error is reported for unknown entities if we have read
  767. an external subset, and standalone is true.
  768. */
  769. START_TEST(test_wfc_undeclared_entity_with_external_subset_standalone) {
  770. char *text =
  771. "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
  772. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  773. "<doc>&entity;</doc>";
  774. char *foo_text =
  775. "<!ELEMENT doc (#PCDATA)*>";
  776. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  777. XML_SetUserData(parser, foo_text);
  778. XML_SetExternalEntityRefHandler(parser, external_entity_loader);
  779. expect_failure(text,
  780. XML_ERROR_UNDEFINED_ENTITY,
  781. "Parser did not report undefined entity (external DTD).");
  782. }
  783. END_TEST
  784. /* Test that no error is reported for unknown entities if we have read
  785. an external subset, and standalone is false.
  786. */
  787. START_TEST(test_wfc_undeclared_entity_with_external_subset) {
  788. char *text =
  789. "<?xml version='1.0' encoding='us-ascii'?>\n"
  790. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  791. "<doc>&entity;</doc>";
  792. char *foo_text =
  793. "<!ELEMENT doc (#PCDATA)*>";
  794. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  795. XML_SetUserData(parser, foo_text);
  796. XML_SetExternalEntityRefHandler(parser, external_entity_loader);
  797. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  798. xml_failure(parser);
  799. }
  800. END_TEST
  801. START_TEST(test_wfc_no_recursive_entity_refs)
  802. {
  803. char *text =
  804. "<!DOCTYPE doc [\n"
  805. " <!ENTITY entity '&#38;entity;'>\n"
  806. "]>\n"
  807. "<doc>&entity;</doc>";
  808. expect_failure(text,
  809. XML_ERROR_RECURSIVE_ENTITY_REF,
  810. "Parser did not report recursive entity reference.");
  811. }
  812. END_TEST
  813. /* Regression test for SF bug #483514. */
  814. START_TEST(test_dtd_default_handling)
  815. {
  816. char *text =
  817. "<!DOCTYPE doc [\n"
  818. "<!ENTITY e SYSTEM 'http://xml.libexpat.org/e'>\n"
  819. "<!NOTATION n SYSTEM 'http://xml.libexpat.org/n'>\n"
  820. "<!ELEMENT doc EMPTY>\n"
  821. "<!ATTLIST doc a CDATA #IMPLIED>\n"
  822. "<?pi in dtd?>\n"
  823. "<!--comment in dtd-->\n"
  824. "]><doc/>";
  825. XML_SetDefaultHandler(parser, accumulate_characters);
  826. XML_SetDoctypeDeclHandler(parser,
  827. dummy_start_doctype_handler,
  828. dummy_end_doctype_handler);
  829. XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
  830. XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
  831. XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
  832. XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
  833. XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
  834. XML_SetCommentHandler(parser, dummy_comment_handler);
  835. run_character_check(text, "\n\n\n\n\n\n\n<doc/>");
  836. }
  837. END_TEST
  838. /* See related SF bug #673791.
  839. When namespace processing is enabled, setting the namespace URI for
  840. a prefix is not allowed; this test ensures that it *is* allowed
  841. when namespace processing is not enabled.
  842. (See Namespaces in XML, section 2.)
  843. */
  844. START_TEST(test_empty_ns_without_namespaces)
  845. {
  846. char *text =
  847. "<doc xmlns:prefix='http://www.example.com/'>\n"
  848. " <e xmlns:prefix=''/>\n"
  849. "</doc>";
  850. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  851. xml_failure(parser);
  852. }
  853. END_TEST
  854. /* Regression test for SF bug #824420.
  855. Checks that an xmlns:prefix attribute set in an attribute's default
  856. value isn't misinterpreted.
  857. */
  858. START_TEST(test_ns_in_attribute_default_without_namespaces)
  859. {
  860. char *text =
  861. "<!DOCTYPE e:element [\n"
  862. " <!ATTLIST e:element\n"
  863. " xmlns:e CDATA 'http://example.com/'>\n"
  864. " ]>\n"
  865. "<e:element/>";
  866. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  867. xml_failure(parser);
  868. }
  869. END_TEST
  870. static char *long_character_data_text =
  871. "<?xml version='1.0' encoding='iso-8859-1'?><s>"
  872. "012345678901234567890123456789012345678901234567890123456789"
  873. "012345678901234567890123456789012345678901234567890123456789"
  874. "012345678901234567890123456789012345678901234567890123456789"
  875. "012345678901234567890123456789012345678901234567890123456789"
  876. "012345678901234567890123456789012345678901234567890123456789"
  877. "012345678901234567890123456789012345678901234567890123456789"
  878. "012345678901234567890123456789012345678901234567890123456789"
  879. "012345678901234567890123456789012345678901234567890123456789"
  880. "012345678901234567890123456789012345678901234567890123456789"
  881. "012345678901234567890123456789012345678901234567890123456789"
  882. "012345678901234567890123456789012345678901234567890123456789"
  883. "012345678901234567890123456789012345678901234567890123456789"
  884. "012345678901234567890123456789012345678901234567890123456789"
  885. "012345678901234567890123456789012345678901234567890123456789"
  886. "012345678901234567890123456789012345678901234567890123456789"
  887. "012345678901234567890123456789012345678901234567890123456789"
  888. "012345678901234567890123456789012345678901234567890123456789"
  889. "012345678901234567890123456789012345678901234567890123456789"
  890. "012345678901234567890123456789012345678901234567890123456789"
  891. "012345678901234567890123456789012345678901234567890123456789"
  892. "</s>";
  893. static XML_Bool resumable = XML_FALSE;
  894. static void
  895. clearing_aborting_character_handler(void *userData,
  896. const XML_Char *s, int len)
  897. {
  898. XML_StopParser(parser, resumable);
  899. XML_SetCharacterDataHandler(parser, NULL);
  900. }
  901. /* Regression test for SF bug #1515266: missing check of stopped
  902. parser in doContext() 'for' loop. */
  903. START_TEST(test_stop_parser_between_char_data_calls)
  904. {
  905. /* The sample data must be big enough that there are two calls to
  906. the character data handler from within the inner "for" loop of
  907. the XML_TOK_DATA_CHARS case in doContent(), and the character
  908. handler must stop the parser and clear the character data
  909. handler.
  910. */
  911. char *text = long_character_data_text;
  912. XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
  913. resumable = XML_FALSE;
  914. if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
  915. xml_failure(parser);
  916. if (XML_GetErrorCode(parser) != XML_ERROR_ABORTED)
  917. xml_failure(parser);
  918. }
  919. END_TEST
  920. /* Regression test for SF bug #1515266: missing check of stopped
  921. parser in doContext() 'for' loop. */
  922. START_TEST(test_suspend_parser_between_char_data_calls)
  923. {
  924. /* The sample data must be big enough that there are two calls to
  925. the character data handler from within the inner "for" loop of
  926. the XML_TOK_DATA_CHARS case in doContent(), and the character
  927. handler must stop the parser and clear the character data
  928. handler.
  929. */
  930. char *text = long_character_data_text;
  931. XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
  932. resumable = XML_TRUE;
  933. if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED)
  934. xml_failure(parser);
  935. if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
  936. xml_failure(parser);
  937. }
  938. END_TEST
  939. /*
  940. * Namespaces tests.
  941. */
  942. static void
  943. namespace_setup(void)
  944. {
  945. parser = XML_ParserCreateNS(NULL, ' ');
  946. if (parser == NULL)
  947. fail("Parser not created.");
  948. }
  949. static void
  950. namespace_teardown(void)
  951. {
  952. basic_teardown();
  953. }
  954. /* Check that an element name and attribute name match the expected values.
  955. The expected values are passed as an array reference of string pointers
  956. provided as the userData argument; the first is the expected
  957. element name, and the second is the expected attribute name.
  958. */
  959. static void XMLCALL
  960. triplet_start_checker(void *userData, const XML_Char *name,
  961. const XML_Char **atts)
  962. {
  963. char **elemstr = (char **)userData;
  964. char buffer[1024];
  965. if (strcmp(elemstr[0], name) != 0) {
  966. sprintf(buffer, "unexpected start string: '%s'", name);
  967. fail(buffer);
  968. }
  969. if (strcmp(elemstr[1], atts[0]) != 0) {
  970. sprintf(buffer, "unexpected attribute string: '%s'", atts[0]);
  971. fail(buffer);
  972. }
  973. }
  974. /* Check that the element name passed to the end-element handler matches
  975. the expected value. The expected value is passed as the first element
  976. in an array of strings passed as the userData argument.
  977. */
  978. static void XMLCALL
  979. triplet_end_checker(void *userData, const XML_Char *name)
  980. {
  981. char **elemstr = (char **)userData;
  982. if (strcmp(elemstr[0], name) != 0) {
  983. char buffer[1024];
  984. sprintf(buffer, "unexpected end string: '%s'", name);
  985. fail(buffer);
  986. }
  987. }
  988. START_TEST(test_return_ns_triplet)
  989. {
  990. char *text =
  991. "<foo:e xmlns:foo='http://expat.sf.net/' bar:a='12'\n"
  992. " xmlns:bar='http://expat.sf.net/'></foo:e>";
  993. char *elemstr[] = {
  994. "http://expat.sf.net/ e foo",
  995. "http://expat.sf.net/ a bar"
  996. };
  997. XML_SetReturnNSTriplet(parser, XML_TRUE);
  998. XML_SetUserData(parser, elemstr);
  999. XML_SetElementHandler(parser, triplet_start_checker, triplet_end_checker);
  1000. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  1001. xml_failure(parser);
  1002. }
  1003. END_TEST
  1004. static void XMLCALL
  1005. overwrite_start_checker(void *userData, const XML_Char *name,
  1006. const XML_Char **atts)
  1007. {
  1008. CharData *storage = (CharData *) userData;
  1009. CharData_AppendString(storage, "start ");
  1010. CharData_AppendXMLChars(storage, name, -1);
  1011. while (*atts != NULL) {
  1012. CharData_AppendString(storage, "\nattribute ");
  1013. CharData_AppendXMLChars(storage, *atts, -1);
  1014. atts += 2;
  1015. }
  1016. CharData_AppendString(storage, "\n");
  1017. }
  1018. static void XMLCALL
  1019. overwrite_end_checker(void *userData, const XML_Char *name)
  1020. {
  1021. CharData *storage = (CharData *) userData;
  1022. CharData_AppendString(storage, "end ");
  1023. CharData_AppendXMLChars(storage, name, -1);
  1024. CharData_AppendString(storage, "\n");
  1025. }
  1026. static void
  1027. run_ns_tagname_overwrite_test(char *text, char *result)
  1028. {
  1029. CharData storage;
  1030. CharData_Init(&storage);
  1031. XML_SetUserData(parser, &storage);
  1032. XML_SetElementHandler(parser,
  1033. overwrite_start_checker, overwrite_end_checker);
  1034. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  1035. xml_failure(parser);
  1036. CharData_CheckString(&storage, result);
  1037. }
  1038. /* Regression test for SF bug #566334. */
  1039. START_TEST(test_ns_tagname_overwrite)
  1040. {
  1041. char *text =
  1042. "<n:e xmlns:n='http://xml.libexpat.org/'>\n"
  1043. " <n:f n:attr='foo'/>\n"
  1044. " <n:g n:attr2='bar'/>\n"
  1045. "</n:e>";
  1046. char *result =
  1047. "start http://xml.libexpat.org/ e\n"
  1048. "start http://xml.libexpat.org/ f\n"
  1049. "attribute http://xml.libexpat.org/ attr\n"
  1050. "end http://xml.libexpat.org/ f\n"
  1051. "start http://xml.libexpat.org/ g\n"
  1052. "attribute http://xml.libexpat.org/ attr2\n"
  1053. "end http://xml.libexpat.org/ g\n"
  1054. "end http://xml.libexpat.org/ e\n";
  1055. run_ns_tagname_overwrite_test(text, result);
  1056. }
  1057. END_TEST
  1058. /* Regression test for SF bug #566334. */
  1059. START_TEST(test_ns_tagname_overwrite_triplet)
  1060. {
  1061. char *text =
  1062. "<n:e xmlns:n='http://xml.libexpat.org/'>\n"
  1063. " <n:f n:attr='foo'/>\n"
  1064. " <n:g n:attr2='bar'/>\n"
  1065. "</n:e>";
  1066. char *result =
  1067. "start http://xml.libexpat.org/ e n\n"
  1068. "start http://xml.libexpat.org/ f n\n"
  1069. "attribute http://xml.libexpat.org/ attr n\n"
  1070. "end http://xml.libexpat.org/ f n\n"
  1071. "start http://xml.libexpat.org/ g n\n"
  1072. "attribute http://xml.libexpat.org/ attr2 n\n"
  1073. "end http://xml.libexpat.org/ g n\n"
  1074. "end http://xml.libexpat.org/ e n\n";
  1075. XML_SetReturnNSTriplet(parser, XML_TRUE);
  1076. run_ns_tagname_overwrite_test(text, result);
  1077. }
  1078. END_TEST
  1079. /* Regression test for SF bug #620343. */
  1080. static void XMLCALL
  1081. start_element_fail(void *userData,
  1082. const XML_Char *name, const XML_Char **atts)
  1083. {
  1084. /* We should never get here. */
  1085. fail("should never reach start_element_fail()");
  1086. }
  1087. static void XMLCALL
  1088. start_ns_clearing_start_element(void *userData,
  1089. const XML_Char *prefix,
  1090. const XML_Char *uri)
  1091. {
  1092. XML_SetStartElementHandler((XML_Parser) userData, NULL);
  1093. }
  1094. START_TEST(test_start_ns_clears_start_element)
  1095. {
  1096. /* This needs to use separate start/end tags; using the empty tag
  1097. syntax doesn't cause the problematic path through Expat to be
  1098. taken.
  1099. */
  1100. char *text = "<e xmlns='http://xml.libexpat.org/'></e>";
  1101. XML_SetStartElementHandler(parser, start_element_fail);
  1102. XML_SetStartNamespaceDeclHandler(parser, start_ns_clearing_start_element);
  1103. XML_UseParserAsHandlerArg(parser);
  1104. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  1105. xml_failure(parser);
  1106. }
  1107. END_TEST
  1108. /* Regression test for SF bug #616863. */
  1109. static int XMLCALL
  1110. external_entity_handler(XML_Parser parser,
  1111. const XML_Char *context,
  1112. const XML_Char *base,
  1113. const XML_Char *systemId,
  1114. const XML_Char *publicId)
  1115. {
  1116. long callno = 1 + (long)XML_GetUserData(parser);
  1117. char *text;
  1118. XML_Parser p2;
  1119. if (callno == 1)
  1120. text = ("<!ELEMENT doc (e+)>\n"
  1121. "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
  1122. "<!ELEMENT e EMPTY>\n");
  1123. else
  1124. text = ("<?xml version='1.0' encoding='us-ascii'?>"
  1125. "<e/>");
  1126. XML_SetUserData(parser, (void *) callno);
  1127. p2 = XML_ExternalEntityParserCreate(parser, context, NULL);
  1128. if (XML_Parse(p2, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) {
  1129. xml_failure(p2);
  1130. return 0;
  1131. }
  1132. XML_ParserFree(p2);
  1133. return 1;
  1134. }
  1135. START_TEST(test_default_ns_from_ext_subset_and_ext_ge)
  1136. {
  1137. char *text =
  1138. "<?xml version='1.0'?>\n"
  1139. "<!DOCTYPE doc SYSTEM 'http://xml.libexpat.org/doc.dtd' [\n"
  1140. " <!ENTITY en SYSTEM 'http://xml.libexpat.org/entity.ent'>\n"
  1141. "]>\n"
  1142. "<doc xmlns='http://xml.libexpat.org/ns1'>\n"
  1143. "&en;\n"
  1144. "</doc>";
  1145. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1146. XML_SetExternalEntityRefHandler(parser, external_entity_handler);
  1147. /* We actually need to set this handler to tickle this bug. */
  1148. XML_SetStartElementHandler(parser, dummy_start_element);
  1149. XML_SetUserData(parser, NULL);
  1150. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  1151. xml_failure(parser);
  1152. }
  1153. END_TEST
  1154. /* Regression test #1 for SF bug #673791. */
  1155. START_TEST(test_ns_prefix_with_empty_uri_1)
  1156. {
  1157. char *text =
  1158. "<doc xmlns:prefix='http://xml.libexpat.org/'>\n"
  1159. " <e xmlns:prefix=''/>\n"
  1160. "</doc>";
  1161. expect_failure(text,
  1162. XML_ERROR_UNDECLARING_PREFIX,
  1163. "Did not report re-setting namespace"
  1164. " URI with prefix to ''.");
  1165. }
  1166. END_TEST
  1167. /* Regression test #2 for SF bug #673791. */
  1168. START_TEST(test_ns_prefix_with_empty_uri_2)
  1169. {
  1170. char *text =
  1171. "<?xml version='1.0'?>\n"
  1172. "<docelem xmlns:pre=''/>";
  1173. expect_failure(text,
  1174. XML_ERROR_UNDECLARING_PREFIX,
  1175. "Did not report setting namespace URI with prefix to ''.");
  1176. }
  1177. END_TEST
  1178. /* Regression test #3 for SF bug #673791. */
  1179. START_TEST(test_ns_prefix_with_empty_uri_3)
  1180. {
  1181. char *text =
  1182. "<!DOCTYPE doc [\n"
  1183. " <!ELEMENT doc EMPTY>\n"
  1184. " <!ATTLIST doc\n"
  1185. " xmlns:prefix CDATA ''>\n"
  1186. "]>\n"
  1187. "<doc/>";
  1188. expect_failure(text,
  1189. XML_ERROR_UNDECLARING_PREFIX,
  1190. "Didn't report attr default setting NS w/ prefix to ''.");
  1191. }
  1192. END_TEST
  1193. /* Regression test #4 for SF bug #673791. */
  1194. START_TEST(test_ns_prefix_with_empty_uri_4)
  1195. {
  1196. char *text =
  1197. "<!DOCTYPE doc [\n"
  1198. " <!ELEMENT prefix:doc EMPTY>\n"
  1199. " <!ATTLIST prefix:doc\n"
  1200. " xmlns:prefix CDATA 'http://xml.libexpat.org/'>\n"
  1201. "]>\n"
  1202. "<prefix:doc/>";
  1203. /* Packaged info expected by the end element handler;
  1204. the weird structuring lets us re-use the triplet_end_checker()
  1205. function also used for another test. */
  1206. char *elemstr[] = {
  1207. "http://xml.libexpat.org/ doc prefix"
  1208. };
  1209. XML_SetReturnNSTriplet(parser, XML_TRUE);
  1210. XML_SetUserData(parser, elemstr);
  1211. XML_SetEndElementHandler(parser, triplet_end_checker);
  1212. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  1213. xml_failure(parser);
  1214. }
  1215. END_TEST
  1216. START_TEST(test_ns_default_with_empty_uri)
  1217. {
  1218. char *text =
  1219. "<doc xmlns='http://xml.libexpat.org/'>\n"
  1220. " <e xmlns=''/>\n"
  1221. "</doc>";
  1222. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  1223. xml_failure(parser);
  1224. }
  1225. END_TEST
  1226. /* Regression test for SF bug #692964: two prefixes for one namespace. */
  1227. START_TEST(test_ns_duplicate_attrs_diff_prefixes)
  1228. {
  1229. char *text =
  1230. "<doc xmlns:a='http://xml.libexpat.org/a'\n"
  1231. " xmlns:b='http://xml.libexpat.org/a'\n"
  1232. " a:a='v' b:a='v' />";
  1233. expect_failure(text,
  1234. XML_ERROR_DUPLICATE_ATTRIBUTE,
  1235. "did not report multiple attributes with same URI+name");
  1236. }
  1237. END_TEST
  1238. /* Regression test for SF bug #695401: unbound prefix. */
  1239. START_TEST(test_ns_unbound_prefix_on_attribute)
  1240. {
  1241. char *text = "<doc a:attr=''/>";
  1242. expect_failure(text,
  1243. XML_ERROR_UNBOUND_PREFIX,
  1244. "did not report unbound prefix on attribute");
  1245. }
  1246. END_TEST
  1247. /* Regression test for SF bug #695401: unbound prefix. */
  1248. START_TEST(test_ns_unbound_prefix_on_element)
  1249. {
  1250. char *text = "<a:doc/>";
  1251. expect_failure(text,
  1252. XML_ERROR_UNBOUND_PREFIX,
  1253. "did not report unbound prefix on element");
  1254. }
  1255. END_TEST
  1256. static Suite *
  1257. make_suite(void)
  1258. {
  1259. Suite *s = suite_create("basic");
  1260. TCase *tc_basic = tcase_create("basic tests");
  1261. TCase *tc_namespace = tcase_create("XML namespaces");
  1262. suite_add_tcase(s, tc_basic);
  1263. tcase_add_checked_fixture(tc_basic, basic_setup, basic_teardown);
  1264. tcase_add_test(tc_basic, test_nul_byte);
  1265. tcase_add_test(tc_basic, test_u0000_char);
  1266. tcase_add_test(tc_basic, test_bom_utf8);
  1267. tcase_add_test(tc_basic, test_bom_utf16_be);
  1268. tcase_add_test(tc_basic, test_bom_utf16_le);
  1269. tcase_add_test(tc_basic, test_illegal_utf8);
  1270. tcase_add_test(tc_basic, test_utf16);
  1271. tcase_add_test(tc_basic, test_utf16_le_epilog_newline);
  1272. tcase_add_test(tc_basic, test_latin1_umlauts);
  1273. /* Regression test for SF bug #491986. */
  1274. tcase_add_test(tc_basic, test_danish_latin1);
  1275. /* Regression test for SF bug #514281. */
  1276. tcase_add_test(tc_basic, test_french_charref_hexidecimal);
  1277. tcase_add_test(tc_basic, test_french_charref_decimal);
  1278. tcase_add_test(tc_basic, test_french_latin1);
  1279. tcase_add_test(tc_basic, test_french_utf8);
  1280. tcase_add_test(tc_basic, test_utf8_false_rejection);
  1281. tcase_add_test(tc_basic, test_line_number_after_parse);
  1282. tcase_add_test(tc_basic, test_column_number_after_parse);
  1283. tcase_add_test(tc_basic, test_line_and_column_numbers_inside_handlers);
  1284. tcase_add_test(tc_basic, test_line_number_after_error);
  1285. tcase_add_test(tc_basic, test_column_number_after_error);
  1286. tcase_add_test(tc_basic, test_really_long_lines);
  1287. tcase_add_test(tc_basic, test_end_element_events);
  1288. tcase_add_test(tc_basic, test_attr_whitespace_normalization);
  1289. tcase_add_test(tc_basic, test_xmldecl_misplaced);
  1290. tcase_add_test(tc_basic, test_unknown_encoding_internal_entity);
  1291. tcase_add_test(tc_basic,
  1292. test_wfc_undeclared_entity_unread_external_subset);
  1293. tcase_add_test(tc_basic, test_wfc_undeclared_entity_no_external_subset);
  1294. tcase_add_test(tc_basic, test_wfc_undeclared_entity_standalone);
  1295. tcase_add_test(tc_basic, test_wfc_undeclared_entity_with_external_subset);
  1296. tcase_add_test(tc_basic,
  1297. test_wfc_undeclared_entity_with_external_subset_standalone);
  1298. tcase_add_test(tc_basic, test_wfc_no_recursive_entity_refs);
  1299. tcase_add_test(tc_basic, test_ext_entity_set_encoding);
  1300. tcase_add_test(tc_basic, test_dtd_default_handling);
  1301. tcase_add_test(tc_basic, test_empty_ns_without_namespaces);
  1302. tcase_add_test(tc_basic, test_ns_in_attribute_default_without_namespaces);
  1303. tcase_add_test(tc_basic, test_stop_parser_between_char_data_calls);
  1304. tcase_add_test(tc_basic, test_suspend_parser_between_char_data_calls);
  1305. suite_add_tcase(s, tc_namespace);
  1306. tcase_add_checked_fixture(tc_namespace,
  1307. namespace_setup, namespace_teardown);
  1308. tcase_add_test(tc_namespace, test_return_ns_triplet);
  1309. tcase_add_test(tc_namespace, test_ns_tagname_overwrite);
  1310. tcase_add_test(tc_namespace, test_ns_tagname_overwrite_triplet);
  1311. tcase_add_test(tc_namespace, test_start_ns_clears_start_element);
  1312. tcase_add_test(tc_namespace, test_default_ns_from_ext_subset_and_ext_ge);
  1313. tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_1);
  1314. tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_2);
  1315. tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_3);
  1316. tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_4);
  1317. tcase_add_test(tc_namespace, test_ns_default_with_empty_uri);
  1318. tcase_add_test(tc_namespace, test_ns_duplicate_attrs_diff_prefixes);
  1319. tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_attribute);
  1320. tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_element);
  1321. return s;
  1322. }
  1323. int
  1324. main(int argc, char *argv[])
  1325. {
  1326. int i, nf;
  1327. int verbosity = CK_NORMAL;
  1328. Suite *s = make_suite();
  1329. SRunner *sr = srunner_create(s);
  1330. /* run the tests for internal helper functions */
  1331. testhelper_is_whitespace_normalized();
  1332. for (i = 1; i < argc; ++i) {
  1333. char *opt = argv[i];
  1334. if (strcmp(opt, "-v") == 0 || strcmp(opt, "--verbose") == 0)
  1335. verbosity = CK_VERBOSE;
  1336. else if (strcmp(opt, "-q") == 0 || strcmp(opt, "--quiet") == 0)
  1337. verbosity = CK_SILENT;
  1338. else {
  1339. fprintf(stderr, "runtests: unknown option '%s'\n", opt);
  1340. return 2;
  1341. }
  1342. }
  1343. if (verbosity != CK_SILENT)
  1344. printf("Expat version: %s\n", XML_ExpatVersion());
  1345. srunner_run_all(sr, verbosity);
  1346. nf = srunner_ntests_failed(sr);
  1347. srunner_free(sr);
  1348. return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
  1349. }