alloc_tests.c 97 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390
  1. /* Tests in the "allocation" test case for the Expat test suite
  2. __ __ _
  3. ___\ \/ /_ __ __ _| |_
  4. / _ \\ /| '_ \ / _` | __|
  5. | __// \| |_) | (_| | |_
  6. \___/_/\_\ .__/ \__,_|\__|
  7. |_| XML parser
  8. Copyright (c) 2001-2006 Fred L. Drake, Jr. <[email protected]>
  9. Copyright (c) 2003 Greg Stein <[email protected]>
  10. Copyright (c) 2005-2007 Steven Solie <[email protected]>
  11. Copyright (c) 2005-2012 Karl Waclawek <[email protected]>
  12. Copyright (c) 2016-2025 Sebastian Pipping <[email protected]>
  13. Copyright (c) 2017-2022 Rhodri James <[email protected]>
  14. Copyright (c) 2017 Joe Orton <[email protected]>
  15. Copyright (c) 2017 José Gutiérrez de la Concha <[email protected]>
  16. Copyright (c) 2018 Marco Maggi <[email protected]>
  17. Copyright (c) 2019 David Loffredo <[email protected]>
  18. Copyright (c) 2020 Tim Gates <[email protected]>
  19. Copyright (c) 2021 Donghee Na <[email protected]>
  20. Copyright (c) 2023 Sony Corporation / Snild Dolkow <[email protected]>
  21. Copyright (c) 2025 Berkay Eren Ürün <[email protected]>
  22. Licensed under the MIT license:
  23. Permission is hereby granted, free of charge, to any person obtaining
  24. a copy of this software and associated documentation files (the
  25. "Software"), to deal in the Software without restriction, including
  26. without limitation the rights to use, copy, modify, merge, publish,
  27. distribute, sublicense, and/or sell copies of the Software, and to permit
  28. persons to whom the Software is furnished to do so, subject to the
  29. following conditions:
  30. The above copyright notice and this permission notice shall be included
  31. in all copies or substantial portions of the Software.
  32. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  33. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  34. MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  35. NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  36. DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  37. OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  38. USE OR OTHER DEALINGS IN THE SOFTWARE.
  39. */
  40. #if defined(NDEBUG)
  41. # undef NDEBUG /* because test suite relies on assert(...) at the moment */
  42. #endif
  43. #include <math.h> /* NAN, INFINITY */
  44. #include <stdbool.h>
  45. #include <stdint.h> /* for SIZE_MAX */
  46. #include <string.h>
  47. #include <assert.h>
  48. #include "expat_config.h"
  49. #include "expat.h"
  50. #include "internal.h"
  51. #include "common.h"
  52. #include "minicheck.h"
  53. #include "dummy.h"
  54. #include "handlers.h"
  55. #include "alloc_tests.h"
  56. static void
  57. alloc_setup(void) {
  58. XML_Memory_Handling_Suite memsuite = {duff_allocator, duff_reallocator, free};
  59. /* Ensure the parser creation will go through */
  60. g_allocation_count = ALLOC_ALWAYS_SUCCEED;
  61. g_reallocation_count = REALLOC_ALWAYS_SUCCEED;
  62. g_parser = XML_ParserCreate_MM(NULL, &memsuite, NULL);
  63. if (g_parser == NULL)
  64. fail("Parser not created");
  65. }
  66. static void
  67. alloc_teardown(void) {
  68. basic_teardown();
  69. }
  70. /* Test the effects of allocation failures on xml declaration processing */
  71. START_TEST(test_alloc_parse_xdecl) {
  72. const char *text = "<?xml version='1.0' encoding='utf-8'?>\n"
  73. "<doc>Hello, world</doc>";
  74. int i;
  75. const int max_alloc_count = 15;
  76. for (i = 0; i < max_alloc_count; i++) {
  77. g_allocation_count = i;
  78. XML_SetXmlDeclHandler(g_parser, dummy_xdecl_handler);
  79. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  80. != XML_STATUS_ERROR)
  81. break;
  82. /* Resetting the parser is insufficient, because some memory
  83. * allocations are cached within the parser. Instead we use
  84. * the teardown and setup routines to ensure that we have the
  85. * right sort of parser back in our hands.
  86. */
  87. alloc_teardown();
  88. alloc_setup();
  89. }
  90. if (i == 0)
  91. fail("Parse succeeded despite failing allocator");
  92. if (i == max_alloc_count)
  93. fail("Parse failed with max allocations");
  94. }
  95. END_TEST
  96. /* As above, but with an encoding big enough to cause storing the
  97. * version information to expand the string pool being used.
  98. */
  99. START_TEST(test_alloc_parse_xdecl_2) {
  100. const char *text
  101. = "<?xml version='1.0' encoding='"
  102. /* Each line is 64 characters */
  103. "ThisIsAStupidlyLongEncodingNameIntendedToTriggerPoolGrowth123456"
  104. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  105. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  106. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  107. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  108. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  109. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  110. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  111. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  112. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  113. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  114. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  115. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  116. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  117. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  118. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMN"
  119. "'?>"
  120. "<doc>Hello, world</doc>";
  121. int i;
  122. const int max_alloc_count = 20;
  123. for (i = 0; i < max_alloc_count; i++) {
  124. g_allocation_count = i;
  125. XML_SetXmlDeclHandler(g_parser, dummy_xdecl_handler);
  126. XML_SetUnknownEncodingHandler(g_parser, long_encoding_handler, NULL);
  127. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  128. != XML_STATUS_ERROR)
  129. break;
  130. /* See comment in test_alloc_parse_xdecl() */
  131. alloc_teardown();
  132. alloc_setup();
  133. }
  134. if (i == 0)
  135. fail("Parse succeeded despite failing allocator");
  136. if (i == max_alloc_count)
  137. fail("Parse failed with max allocations");
  138. }
  139. END_TEST
  140. /* Test the effects of allocation failures on a straightforward parse */
  141. START_TEST(test_alloc_parse_pi) {
  142. const char *text = "<?xml version='1.0' encoding='utf-8'?>\n"
  143. "<?pi unknown?>\n"
  144. "<doc>"
  145. "Hello, world"
  146. "</doc>";
  147. int i;
  148. const int max_alloc_count = 15;
  149. for (i = 0; i < max_alloc_count; i++) {
  150. g_allocation_count = i;
  151. XML_SetProcessingInstructionHandler(g_parser, dummy_pi_handler);
  152. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  153. != XML_STATUS_ERROR)
  154. break;
  155. /* See comment in test_alloc_parse_xdecl() */
  156. alloc_teardown();
  157. alloc_setup();
  158. }
  159. if (i == 0)
  160. fail("Parse succeeded despite failing allocator");
  161. if (i == max_alloc_count)
  162. fail("Parse failed with max allocations");
  163. }
  164. END_TEST
  165. START_TEST(test_alloc_parse_pi_2) {
  166. const char *text = "<?xml version='1.0' encoding='utf-8'?>\n"
  167. "<doc>"
  168. "Hello, world"
  169. "<?pi unknown?>\n"
  170. "</doc>";
  171. int i;
  172. const int max_alloc_count = 15;
  173. for (i = 0; i < max_alloc_count; i++) {
  174. g_allocation_count = i;
  175. XML_SetProcessingInstructionHandler(g_parser, dummy_pi_handler);
  176. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  177. != XML_STATUS_ERROR)
  178. break;
  179. /* See comment in test_alloc_parse_xdecl() */
  180. alloc_teardown();
  181. alloc_setup();
  182. }
  183. if (i == 0)
  184. fail("Parse succeeded despite failing allocator");
  185. if (i == max_alloc_count)
  186. fail("Parse failed with max allocations");
  187. }
  188. END_TEST
  189. START_TEST(test_alloc_parse_pi_3) {
  190. const char *text
  191. = "<?"
  192. /* 64 characters per line */
  193. "This processing instruction should be long enough to ensure that"
  194. "it triggers the growth of an internal string pool when the "
  195. "allocator fails at a cruicial moment FGHIJKLMNOPABCDEFGHIJKLMNOP"
  196. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  197. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  198. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  199. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  200. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  201. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  202. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  203. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  204. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  205. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  206. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  207. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  208. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  209. "Q?><doc/>";
  210. int i;
  211. const int max_alloc_count = 20;
  212. for (i = 0; i < max_alloc_count; i++) {
  213. g_allocation_count = i;
  214. XML_SetProcessingInstructionHandler(g_parser, dummy_pi_handler);
  215. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  216. != XML_STATUS_ERROR)
  217. break;
  218. /* See comment in test_alloc_parse_xdecl() */
  219. alloc_teardown();
  220. alloc_setup();
  221. }
  222. if (i == 0)
  223. fail("Parse succeeded despite failing allocator");
  224. if (i == max_alloc_count)
  225. fail("Parse failed with max allocations");
  226. }
  227. END_TEST
  228. START_TEST(test_alloc_parse_comment) {
  229. const char *text = "<?xml version='1.0' encoding='utf-8'?>\n"
  230. "<!-- Test parsing this comment -->"
  231. "<doc>Hi</doc>";
  232. int i;
  233. const int max_alloc_count = 15;
  234. for (i = 0; i < max_alloc_count; i++) {
  235. g_allocation_count = i;
  236. XML_SetCommentHandler(g_parser, dummy_comment_handler);
  237. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  238. != XML_STATUS_ERROR)
  239. break;
  240. /* See comment in test_alloc_parse_xdecl() */
  241. alloc_teardown();
  242. alloc_setup();
  243. }
  244. if (i == 0)
  245. fail("Parse succeeded despite failing allocator");
  246. if (i == max_alloc_count)
  247. fail("Parse failed with max allocations");
  248. }
  249. END_TEST
  250. START_TEST(test_alloc_parse_comment_2) {
  251. const char *text = "<?xml version='1.0' encoding='utf-8'?>\n"
  252. "<doc>"
  253. "Hello, world"
  254. "<!-- Parse this comment too -->"
  255. "</doc>";
  256. int i;
  257. const int max_alloc_count = 15;
  258. for (i = 0; i < max_alloc_count; i++) {
  259. g_allocation_count = i;
  260. XML_SetCommentHandler(g_parser, dummy_comment_handler);
  261. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  262. != XML_STATUS_ERROR)
  263. break;
  264. /* See comment in test_alloc_parse_xdecl() */
  265. alloc_teardown();
  266. alloc_setup();
  267. }
  268. if (i == 0)
  269. fail("Parse succeeded despite failing allocator");
  270. if (i == max_alloc_count)
  271. fail("Parse failed with max allocations");
  272. }
  273. END_TEST
  274. /* Test that external parser creation running out of memory is
  275. * correctly reported. Based on the external entity test cases.
  276. */
  277. START_TEST(test_alloc_create_external_parser) {
  278. const char *text = "<?xml version='1.0' encoding='us-ascii'?>\n"
  279. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  280. "<doc>&entity;</doc>";
  281. char foo_text[] = "<!ELEMENT doc (#PCDATA)*>";
  282. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  283. XML_SetUserData(g_parser, foo_text);
  284. XML_SetExternalEntityRefHandler(g_parser, external_entity_duff_loader);
  285. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  286. != XML_STATUS_ERROR) {
  287. fail("External parser allocator returned success incorrectly");
  288. }
  289. }
  290. END_TEST
  291. /* More external parser memory allocation testing */
  292. START_TEST(test_alloc_run_external_parser) {
  293. const char *text = "<?xml version='1.0' encoding='us-ascii'?>\n"
  294. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  295. "<doc>&entity;</doc>";
  296. char foo_text[] = "<!ELEMENT doc (#PCDATA)*>";
  297. unsigned int i;
  298. const unsigned int max_alloc_count = 15;
  299. for (i = 0; i < max_alloc_count; i++) {
  300. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  301. XML_SetUserData(g_parser, foo_text);
  302. XML_SetExternalEntityRefHandler(g_parser, external_entity_null_loader);
  303. g_allocation_count = (int)i;
  304. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  305. != XML_STATUS_ERROR)
  306. break;
  307. /* See comment in test_alloc_parse_xdecl() */
  308. alloc_teardown();
  309. alloc_setup();
  310. }
  311. if (i == 0)
  312. fail("Parsing ignored failing allocator");
  313. else if (i == max_alloc_count)
  314. fail("Parsing failed with allocation count 10");
  315. }
  316. END_TEST
  317. /* Test that running out of memory in dtdCopy is correctly reported.
  318. * Based on test_default_ns_from_ext_subset_and_ext_ge()
  319. */
  320. START_TEST(test_alloc_dtd_copy_default_atts) {
  321. const char *text = "<?xml version='1.0'?>\n"
  322. "<!DOCTYPE doc SYSTEM 'http://example.org/doc.dtd' [\n"
  323. " <!ENTITY en SYSTEM 'http://example.org/entity.ent'>\n"
  324. "]>\n"
  325. "<doc xmlns='http://example.org/ns1'>\n"
  326. "&en;\n"
  327. "</doc>";
  328. int callno = 0;
  329. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  330. XML_SetExternalEntityRefHandler(g_parser, external_entity_dbl_handler);
  331. XML_SetUserData(g_parser, &callno);
  332. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  333. == XML_STATUS_ERROR)
  334. xml_failure(g_parser);
  335. }
  336. END_TEST
  337. /* Test more external entity allocation failure paths */
  338. START_TEST(test_alloc_external_entity) {
  339. const char *text = "<?xml version='1.0'?>\n"
  340. "<!DOCTYPE doc SYSTEM 'http://example.org/doc.dtd' [\n"
  341. " <!ENTITY en SYSTEM 'http://example.org/entity.ent'>\n"
  342. "]>\n"
  343. "<doc xmlns='http://example.org/ns1'>\n"
  344. "&en;\n"
  345. "</doc>";
  346. int i;
  347. const int alloc_test_max_repeats = 50;
  348. int callno = 0;
  349. for (i = 0; i < alloc_test_max_repeats; i++) {
  350. g_allocation_count = -1;
  351. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  352. XML_SetExternalEntityRefHandler(g_parser, external_entity_dbl_handler_2);
  353. callno = 0;
  354. XML_SetUserData(g_parser, &callno);
  355. g_allocation_count = i;
  356. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  357. == XML_STATUS_OK)
  358. break;
  359. /* See comment in test_alloc_parse_xdecl() */
  360. alloc_teardown();
  361. alloc_setup();
  362. }
  363. g_allocation_count = -1;
  364. if (i == 0)
  365. fail("External entity parsed despite duff allocator");
  366. if (i == alloc_test_max_repeats)
  367. fail("External entity not parsed at max allocation count");
  368. }
  369. END_TEST
  370. /* Test more allocation failure paths */
  371. START_TEST(test_alloc_ext_entity_set_encoding) {
  372. const char *text = "<!DOCTYPE doc [\n"
  373. " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
  374. "]>\n"
  375. "<doc>&en;</doc>";
  376. int i;
  377. const int max_allocation_count = 30;
  378. for (i = 0; i < max_allocation_count; i++) {
  379. XML_SetExternalEntityRefHandler(g_parser,
  380. external_entity_alloc_set_encoding);
  381. g_allocation_count = i;
  382. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  383. == XML_STATUS_OK)
  384. break;
  385. g_allocation_count = -1;
  386. /* See comment in test_alloc_parse_xdecl() */
  387. alloc_teardown();
  388. alloc_setup();
  389. }
  390. if (i == 0)
  391. fail("Encoding check succeeded despite failing allocator");
  392. if (i == max_allocation_count)
  393. fail("Encoding failed at max allocation count");
  394. }
  395. END_TEST
  396. /* Test the effects of allocation failure in internal entities.
  397. * Based on test_unknown_encoding_internal_entity
  398. */
  399. START_TEST(test_alloc_internal_entity) {
  400. const char *text = "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
  401. "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
  402. "<test a='&foo;'/>";
  403. unsigned int i;
  404. const unsigned int max_alloc_count = 20;
  405. for (i = 0; i < max_alloc_count; i++) {
  406. g_allocation_count = (int)i;
  407. XML_SetUnknownEncodingHandler(g_parser, unknown_released_encoding_handler,
  408. NULL);
  409. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  410. != XML_STATUS_ERROR)
  411. break;
  412. /* See comment in test_alloc_parse_xdecl() */
  413. alloc_teardown();
  414. alloc_setup();
  415. }
  416. if (i == 0)
  417. fail("Internal entity worked despite failing allocations");
  418. else if (i == max_alloc_count)
  419. fail("Internal entity failed at max allocation count");
  420. }
  421. END_TEST
  422. START_TEST(test_alloc_parameter_entity) {
  423. const char *text = "<!DOCTYPE foo ["
  424. "<!ENTITY % param1 \"<!ENTITY internal 'some_text'>\">"
  425. "%param1;"
  426. "]> <foo>&internal;content</foo>";
  427. int i;
  428. const int alloc_test_max_repeats = 30;
  429. for (i = 0; i < alloc_test_max_repeats; i++) {
  430. g_allocation_count = i;
  431. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  432. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  433. != XML_STATUS_ERROR)
  434. break;
  435. alloc_teardown();
  436. alloc_setup();
  437. }
  438. g_allocation_count = -1;
  439. if (i == 0)
  440. fail("Parameter entity processed despite duff allocator");
  441. if (i == alloc_test_max_repeats)
  442. fail("Parameter entity not processed at max allocation count");
  443. }
  444. END_TEST
  445. /* Test the robustness against allocation failure of element handling
  446. * Based on test_dtd_default_handling().
  447. */
  448. START_TEST(test_alloc_dtd_default_handling) {
  449. const char *text = "<!DOCTYPE doc [\n"
  450. "<!ENTITY e SYSTEM 'http://example.org/e'>\n"
  451. "<!NOTATION n SYSTEM 'http://example.org/n'>\n"
  452. "<!ENTITY e1 SYSTEM 'http://example.org/e' NDATA n>\n"
  453. "<!ELEMENT doc (#PCDATA)>\n"
  454. "<!ATTLIST doc a CDATA #IMPLIED>\n"
  455. "<?pi in dtd?>\n"
  456. "<!--comment in dtd-->\n"
  457. "]>\n"
  458. "<doc><![CDATA[text in doc]]></doc>";
  459. const XML_Char *expected = XCS("\n\n\n\n\n\n\n\n\n<doc>text in doc</doc>");
  460. CharData storage;
  461. int i;
  462. const int max_alloc_count = 25;
  463. for (i = 0; i < max_alloc_count; i++) {
  464. g_allocation_count = i;
  465. init_dummy_handlers();
  466. XML_SetDefaultHandler(g_parser, accumulate_characters);
  467. XML_SetDoctypeDeclHandler(g_parser, dummy_start_doctype_handler,
  468. dummy_end_doctype_handler);
  469. XML_SetEntityDeclHandler(g_parser, dummy_entity_decl_handler);
  470. XML_SetNotationDeclHandler(g_parser, dummy_notation_decl_handler);
  471. XML_SetElementDeclHandler(g_parser, dummy_element_decl_handler);
  472. XML_SetAttlistDeclHandler(g_parser, dummy_attlist_decl_handler);
  473. XML_SetProcessingInstructionHandler(g_parser, dummy_pi_handler);
  474. XML_SetCommentHandler(g_parser, dummy_comment_handler);
  475. XML_SetCdataSectionHandler(g_parser, dummy_start_cdata_handler,
  476. dummy_end_cdata_handler);
  477. XML_SetUnparsedEntityDeclHandler(g_parser,
  478. dummy_unparsed_entity_decl_handler);
  479. CharData_Init(&storage);
  480. XML_SetUserData(g_parser, &storage);
  481. XML_SetCharacterDataHandler(g_parser, accumulate_characters);
  482. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  483. != XML_STATUS_ERROR)
  484. break;
  485. /* See comment in test_alloc_parse_xdecl() */
  486. alloc_teardown();
  487. alloc_setup();
  488. }
  489. if (i == 0)
  490. fail("Default DTD parsed despite allocation failures");
  491. if (i == max_alloc_count)
  492. fail("Default DTD not parsed with maximum alloc count");
  493. CharData_CheckXMLChars(&storage, expected);
  494. if (get_dummy_handler_flags()
  495. != (DUMMY_START_DOCTYPE_HANDLER_FLAG | DUMMY_END_DOCTYPE_HANDLER_FLAG
  496. | DUMMY_ENTITY_DECL_HANDLER_FLAG | DUMMY_NOTATION_DECL_HANDLER_FLAG
  497. | DUMMY_ELEMENT_DECL_HANDLER_FLAG | DUMMY_ATTLIST_DECL_HANDLER_FLAG
  498. | DUMMY_COMMENT_HANDLER_FLAG | DUMMY_PI_HANDLER_FLAG
  499. | DUMMY_START_CDATA_HANDLER_FLAG | DUMMY_END_CDATA_HANDLER_FLAG
  500. | DUMMY_UNPARSED_ENTITY_DECL_HANDLER_FLAG))
  501. fail("Not all handlers were called");
  502. }
  503. END_TEST
  504. /* Test robustness of XML_SetEncoding() with a failing allocator */
  505. START_TEST(test_alloc_explicit_encoding) {
  506. int i;
  507. const int max_alloc_count = 5;
  508. for (i = 0; i < max_alloc_count; i++) {
  509. g_allocation_count = i;
  510. if (XML_SetEncoding(g_parser, XCS("us-ascii")) == XML_STATUS_OK)
  511. break;
  512. }
  513. if (i == 0)
  514. fail("Encoding set despite failing allocator");
  515. else if (i == max_alloc_count)
  516. fail("Encoding not set at max allocation count");
  517. }
  518. END_TEST
  519. /* Test robustness of XML_SetBase against a failing allocator */
  520. START_TEST(test_alloc_set_base) {
  521. const XML_Char *new_base = XCS("/local/file/name.xml");
  522. int i;
  523. const int max_alloc_count = 5;
  524. for (i = 0; i < max_alloc_count; i++) {
  525. g_allocation_count = i;
  526. if (XML_SetBase(g_parser, new_base) == XML_STATUS_OK)
  527. break;
  528. }
  529. if (i == 0)
  530. fail("Base set despite failing allocator");
  531. else if (i == max_alloc_count)
  532. fail("Base not set with max allocation count");
  533. }
  534. END_TEST
  535. /* Test buffer extension in the face of a duff reallocator */
  536. START_TEST(test_alloc_realloc_buffer) {
  537. const char *text = get_buffer_test_text;
  538. void *buffer;
  539. int i;
  540. const int max_realloc_count = 10;
  541. /* Get a smallish buffer */
  542. for (i = 0; i < max_realloc_count; i++) {
  543. g_reallocation_count = i;
  544. buffer = XML_GetBuffer(g_parser, 1536);
  545. if (buffer == NULL)
  546. fail("1.5K buffer reallocation failed");
  547. assert(buffer != NULL);
  548. memcpy(buffer, text, strlen(text));
  549. if (XML_ParseBuffer(g_parser, (int)strlen(text), XML_FALSE)
  550. == XML_STATUS_OK)
  551. break;
  552. /* See comment in test_alloc_parse_xdecl() */
  553. alloc_teardown();
  554. alloc_setup();
  555. }
  556. g_reallocation_count = -1;
  557. if (i == 0)
  558. fail("Parse succeeded with no reallocation");
  559. else if (i == max_realloc_count)
  560. fail("Parse failed with max reallocation count");
  561. }
  562. END_TEST
  563. /* Same test for external entity parsers */
  564. START_TEST(test_alloc_ext_entity_realloc_buffer) {
  565. const char *text = "<!DOCTYPE doc [\n"
  566. " <!ENTITY en SYSTEM 'http://example.org/dummy.ent'>\n"
  567. "]>\n"
  568. "<doc>&en;</doc>";
  569. int i;
  570. const int max_realloc_count = 10;
  571. for (i = 0; i < max_realloc_count; i++) {
  572. XML_SetExternalEntityRefHandler(g_parser, external_entity_reallocator);
  573. XML_SetUserData(g_parser, &i);
  574. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  575. == XML_STATUS_OK)
  576. break;
  577. /* See comment in test_alloc_parse_xdecl() */
  578. alloc_teardown();
  579. alloc_setup();
  580. }
  581. if (i == 0)
  582. fail("Succeeded with no reallocations");
  583. if (i == max_realloc_count)
  584. fail("Failed with max reallocations");
  585. }
  586. END_TEST
  587. /* Test elements with many attributes are handled correctly */
  588. START_TEST(test_alloc_realloc_many_attributes) {
  589. const char *text = "<!DOCTYPE doc [\n"
  590. "<!ATTLIST doc za CDATA 'default'>\n"
  591. "<!ATTLIST doc zb CDATA 'def2'>\n"
  592. "<!ATTLIST doc zc CDATA 'def3'>\n"
  593. "]>\n"
  594. "<doc a='1'"
  595. " b='2'"
  596. " c='3'"
  597. " d='4'"
  598. " e='5'"
  599. " f='6'"
  600. " g='7'"
  601. " h='8'"
  602. " i='9'"
  603. " j='10'"
  604. " k='11'"
  605. " l='12'"
  606. " m='13'"
  607. " n='14'"
  608. " p='15'"
  609. " q='16'"
  610. " r='17'"
  611. " s='18'>"
  612. "</doc>";
  613. int i;
  614. const int max_realloc_count = 10;
  615. for (i = 0; i < max_realloc_count; i++) {
  616. g_reallocation_count = i;
  617. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  618. != XML_STATUS_ERROR)
  619. break;
  620. /* See comment in test_alloc_parse_xdecl() */
  621. alloc_teardown();
  622. alloc_setup();
  623. }
  624. if (i == 0)
  625. fail("Parse succeeded despite no reallocations");
  626. if (i == max_realloc_count)
  627. fail("Parse failed at max reallocations");
  628. }
  629. END_TEST
  630. /* Test handling of a public entity with failing allocator */
  631. START_TEST(test_alloc_public_entity_value) {
  632. const char *text = "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
  633. "<doc></doc>\n";
  634. char dtd_text[]
  635. = "<!ELEMENT doc EMPTY>\n"
  636. "<!ENTITY % e1 PUBLIC 'foo' 'bar.ent'>\n"
  637. "<!ENTITY % "
  638. /* Each line is 64 characters */
  639. "ThisIsAStupidlyLongParameterNameIntendedToTriggerPoolGrowth12345"
  640. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  641. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  642. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  643. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  644. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  645. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  646. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  647. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  648. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  649. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  650. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  651. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  652. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  653. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  654. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  655. " '%e1;'>\n"
  656. "%e1;\n";
  657. int i;
  658. const int max_alloc_count = 50;
  659. for (i = 0; i < max_alloc_count; i++) {
  660. g_allocation_count = i;
  661. init_dummy_handlers();
  662. XML_SetUserData(g_parser, dtd_text);
  663. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  664. XML_SetExternalEntityRefHandler(g_parser, external_entity_public);
  665. /* Provoke a particular code path */
  666. XML_SetEntityDeclHandler(g_parser, dummy_entity_decl_handler);
  667. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  668. != XML_STATUS_ERROR)
  669. break;
  670. /* See comment in test_alloc_parse_xdecl() */
  671. alloc_teardown();
  672. alloc_setup();
  673. }
  674. if (i == 0)
  675. fail("Parsing worked despite failing allocation");
  676. if (i == max_alloc_count)
  677. fail("Parsing failed at max allocation count");
  678. if (get_dummy_handler_flags() != DUMMY_ENTITY_DECL_HANDLER_FLAG)
  679. fail("Entity declaration handler not called");
  680. }
  681. END_TEST
  682. START_TEST(test_alloc_realloc_subst_public_entity_value) {
  683. const char *text = "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
  684. "<doc></doc>\n";
  685. char dtd_text[]
  686. = "<!ELEMENT doc EMPTY>\n"
  687. "<!ENTITY % "
  688. /* Each line is 64 characters */
  689. "ThisIsAStupidlyLongParameterNameIntendedToTriggerPoolGrowth12345"
  690. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  691. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  692. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  693. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  694. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  695. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  696. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  697. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  698. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  699. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  700. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  701. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  702. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  703. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  704. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  705. " PUBLIC 'foo' 'bar.ent'>\n"
  706. "%ThisIsAStupidlyLongParameterNameIntendedToTriggerPoolGrowth12345"
  707. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  708. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  709. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  710. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  711. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  712. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  713. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  714. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  715. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  716. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  717. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  718. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  719. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  720. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  721. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP;";
  722. int i;
  723. const int max_realloc_count = 10;
  724. for (i = 0; i < max_realloc_count; i++) {
  725. g_reallocation_count = i;
  726. XML_SetUserData(g_parser, dtd_text);
  727. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  728. XML_SetExternalEntityRefHandler(g_parser, external_entity_public);
  729. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  730. != XML_STATUS_ERROR)
  731. break;
  732. /* See comment in test_alloc_parse_xdecl() */
  733. alloc_teardown();
  734. alloc_setup();
  735. }
  736. if (i == 0)
  737. fail("Parsing worked despite failing reallocation");
  738. if (i == max_realloc_count)
  739. fail("Parsing failed at max reallocation count");
  740. }
  741. END_TEST
  742. START_TEST(test_alloc_parse_public_doctype) {
  743. const char *text
  744. = "<?xml version='1.0' encoding='utf-8'?>\n"
  745. "<!DOCTYPE doc PUBLIC '"
  746. /* 64 characters per line */
  747. "http://example.com/a/long/enough/name/to/trigger/pool/growth/zz/"
  748. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  749. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  750. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  751. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  752. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  753. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  754. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  755. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  756. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  757. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  758. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  759. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  760. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  761. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  762. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  763. "' 'test'>\n"
  764. "<doc></doc>";
  765. int i;
  766. const int max_alloc_count = 25;
  767. for (i = 0; i < max_alloc_count; i++) {
  768. g_allocation_count = i;
  769. init_dummy_handlers();
  770. XML_SetDoctypeDeclHandler(g_parser, dummy_start_doctype_decl_handler,
  771. dummy_end_doctype_decl_handler);
  772. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  773. != XML_STATUS_ERROR)
  774. break;
  775. /* See comment in test_alloc_parse_xdecl() */
  776. alloc_teardown();
  777. alloc_setup();
  778. }
  779. if (i == 0)
  780. fail("Parse succeeded despite failing allocator");
  781. if (i == max_alloc_count)
  782. fail("Parse failed at maximum allocation count");
  783. if (get_dummy_handler_flags()
  784. != (DUMMY_START_DOCTYPE_DECL_HANDLER_FLAG
  785. | DUMMY_END_DOCTYPE_DECL_HANDLER_FLAG))
  786. fail("Doctype handler functions not called");
  787. }
  788. END_TEST
  789. START_TEST(test_alloc_parse_public_doctype_long_name) {
  790. const char *text
  791. = "<?xml version='1.0' encoding='utf-8'?>\n"
  792. "<!DOCTYPE doc PUBLIC 'http://example.com/foo' '"
  793. /* 64 characters per line */
  794. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  795. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  796. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  797. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  798. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  799. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  800. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  801. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  802. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  803. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  804. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  805. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  806. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  807. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  808. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  809. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNOP"
  810. "'>\n"
  811. "<doc></doc>";
  812. int i;
  813. const int max_alloc_count = 25;
  814. for (i = 0; i < max_alloc_count; i++) {
  815. g_allocation_count = i;
  816. XML_SetDoctypeDeclHandler(g_parser, dummy_start_doctype_decl_handler,
  817. dummy_end_doctype_decl_handler);
  818. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  819. != XML_STATUS_ERROR)
  820. break;
  821. /* See comment in test_alloc_parse_xdecl() */
  822. alloc_teardown();
  823. alloc_setup();
  824. }
  825. if (i == 0)
  826. fail("Parse succeeded despite failing allocator");
  827. if (i == max_alloc_count)
  828. fail("Parse failed at maximum allocation count");
  829. }
  830. END_TEST
  831. /* Test foreign DTD handling */
  832. START_TEST(test_alloc_set_foreign_dtd) {
  833. const char *text1 = "<?xml version='1.0' encoding='us-ascii'?>\n"
  834. "<doc>&entity;</doc>";
  835. char text2[] = "<!ELEMENT doc (#PCDATA)*>";
  836. int i;
  837. const int max_alloc_count = 25;
  838. for (i = 0; i < max_alloc_count; i++) {
  839. g_allocation_count = i;
  840. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  841. XML_SetUserData(g_parser, &text2);
  842. XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc);
  843. if (XML_UseForeignDTD(g_parser, XML_TRUE) != XML_ERROR_NONE)
  844. fail("Could not set foreign DTD");
  845. if (_XML_Parse_SINGLE_BYTES(g_parser, text1, (int)strlen(text1), XML_TRUE)
  846. != XML_STATUS_ERROR)
  847. break;
  848. /* See comment in test_alloc_parse_xdecl() */
  849. alloc_teardown();
  850. alloc_setup();
  851. }
  852. if (i == 0)
  853. fail("Parse succeeded despite failing allocator");
  854. if (i == max_alloc_count)
  855. fail("Parse failed at maximum allocation count");
  856. }
  857. END_TEST
  858. /* Test based on ibm/valid/P32/ibm32v04.xml */
  859. START_TEST(test_alloc_attribute_enum_value) {
  860. const char *text = "<?xml version='1.0' standalone='no'?>\n"
  861. "<!DOCTYPE animal SYSTEM 'test.dtd'>\n"
  862. "<animal>This is a \n <a/> \n\nyellow tiger</animal>";
  863. char dtd_text[] = "<!ELEMENT animal (#PCDATA|a)*>\n"
  864. "<!ELEMENT a EMPTY>\n"
  865. "<!ATTLIST animal xml:space (default|preserve) 'preserve'>";
  866. int i;
  867. const int max_alloc_count = 30;
  868. for (i = 0; i < max_alloc_count; i++) {
  869. g_allocation_count = i;
  870. XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc);
  871. XML_SetUserData(g_parser, dtd_text);
  872. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  873. /* An attribute list handler provokes a different code path */
  874. XML_SetAttlistDeclHandler(g_parser, dummy_attlist_decl_handler);
  875. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  876. != XML_STATUS_ERROR)
  877. break;
  878. /* See comment in test_alloc_parse_xdecl() */
  879. alloc_teardown();
  880. alloc_setup();
  881. }
  882. if (i == 0)
  883. fail("Parse succeeded despite failing allocator");
  884. if (i == max_alloc_count)
  885. fail("Parse failed at maximum allocation count");
  886. }
  887. END_TEST
  888. /* Test attribute enums sufficient to overflow the string pool */
  889. START_TEST(test_alloc_realloc_attribute_enum_value) {
  890. const char *text = "<?xml version='1.0' standalone='no'?>\n"
  891. "<!DOCTYPE animal SYSTEM 'test.dtd'>\n"
  892. "<animal>This is a yellow tiger</animal>";
  893. /* We wish to define a collection of attribute enums that will
  894. * cause the string pool storing them to have to expand. This
  895. * means more than 1024 bytes, including the parentheses and
  896. * separator bars.
  897. */
  898. char dtd_text[]
  899. = "<!ELEMENT animal (#PCDATA)*>\n"
  900. "<!ATTLIST animal thing "
  901. "(default"
  902. /* Each line is 64 characters */
  903. "|ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  904. "|BBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  905. "|CBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  906. "|DBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  907. "|EBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  908. "|FBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  909. "|GBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  910. "|HBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  911. "|IBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  912. "|JBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  913. "|KBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  914. "|LBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  915. "|MBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  916. "|NBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  917. "|OBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  918. "|PBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO)"
  919. " 'default'>";
  920. int i;
  921. const int max_realloc_count = 10;
  922. for (i = 0; i < max_realloc_count; i++) {
  923. g_reallocation_count = i;
  924. XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc);
  925. XML_SetUserData(g_parser, dtd_text);
  926. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  927. /* An attribute list handler provokes a different code path */
  928. XML_SetAttlistDeclHandler(g_parser, dummy_attlist_decl_handler);
  929. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  930. != XML_STATUS_ERROR)
  931. break;
  932. /* See comment in test_alloc_parse_xdecl() */
  933. alloc_teardown();
  934. alloc_setup();
  935. }
  936. if (i == 0)
  937. fail("Parse succeeded despite failing reallocator");
  938. if (i == max_realloc_count)
  939. fail("Parse failed at maximum reallocation count");
  940. }
  941. END_TEST
  942. /* Test attribute enums in a #IMPLIED attribute forcing pool growth */
  943. START_TEST(test_alloc_realloc_implied_attribute) {
  944. /* Forcing this particular code path is a balancing act. The
  945. * addition of the closing parenthesis and terminal NUL must be
  946. * what pushes the string of enums over the 1024-byte limit,
  947. * otherwise a different code path will pick up the realloc.
  948. */
  949. const char *text
  950. = "<!DOCTYPE doc [\n"
  951. "<!ELEMENT doc EMPTY>\n"
  952. "<!ATTLIST doc a "
  953. /* Each line is 64 characters */
  954. "(ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  955. "|BBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  956. "|CBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  957. "|DBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  958. "|EBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  959. "|FBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  960. "|GBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  961. "|HBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  962. "|IBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  963. "|JBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  964. "|KBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  965. "|LBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  966. "|MBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  967. "|NBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  968. "|OBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  969. "|PBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMN)"
  970. " #IMPLIED>\n"
  971. "]><doc/>";
  972. int i;
  973. const int max_realloc_count = 10;
  974. for (i = 0; i < max_realloc_count; i++) {
  975. g_reallocation_count = i;
  976. XML_SetAttlistDeclHandler(g_parser, dummy_attlist_decl_handler);
  977. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  978. != XML_STATUS_ERROR)
  979. break;
  980. /* See comment in test_alloc_parse_xdecl() */
  981. alloc_teardown();
  982. alloc_setup();
  983. }
  984. if (i == 0)
  985. fail("Parse succeeded despite failing reallocator");
  986. if (i == max_realloc_count)
  987. fail("Parse failed at maximum reallocation count");
  988. }
  989. END_TEST
  990. /* Test attribute enums in a defaulted attribute forcing pool growth */
  991. START_TEST(test_alloc_realloc_default_attribute) {
  992. /* Forcing this particular code path is a balancing act. The
  993. * addition of the closing parenthesis and terminal NUL must be
  994. * what pushes the string of enums over the 1024-byte limit,
  995. * otherwise a different code path will pick up the realloc.
  996. */
  997. const char *text
  998. = "<!DOCTYPE doc [\n"
  999. "<!ELEMENT doc EMPTY>\n"
  1000. "<!ATTLIST doc a "
  1001. /* Each line is 64 characters */
  1002. "(ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  1003. "|BBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  1004. "|CBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  1005. "|DBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  1006. "|EBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  1007. "|FBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  1008. "|GBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  1009. "|HBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  1010. "|IBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  1011. "|JBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  1012. "|KBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  1013. "|LBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  1014. "|MBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  1015. "|NBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  1016. "|OBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO"
  1017. "|PBCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMN)"
  1018. " 'ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNO'"
  1019. ">\n]><doc/>";
  1020. int i;
  1021. const int max_realloc_count = 10;
  1022. for (i = 0; i < max_realloc_count; i++) {
  1023. g_reallocation_count = i;
  1024. XML_SetAttlistDeclHandler(g_parser, dummy_attlist_decl_handler);
  1025. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1026. != XML_STATUS_ERROR)
  1027. break;
  1028. /* See comment in test_alloc_parse_xdecl() */
  1029. alloc_teardown();
  1030. alloc_setup();
  1031. }
  1032. if (i == 0)
  1033. fail("Parse succeeded despite failing reallocator");
  1034. if (i == max_realloc_count)
  1035. fail("Parse failed at maximum reallocation count");
  1036. }
  1037. END_TEST
  1038. /* Test long notation name with dodgy allocator */
  1039. START_TEST(test_alloc_notation) {
  1040. const char *text
  1041. = "<!DOCTYPE doc [\n"
  1042. "<!NOTATION "
  1043. /* Each line is 64 characters */
  1044. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1045. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1046. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1047. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1048. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1049. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1050. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1051. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1052. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1053. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1054. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1055. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1056. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1057. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1058. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1059. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1060. " SYSTEM 'http://example.org/n'>\n"
  1061. "<!ENTITY e SYSTEM 'http://example.org/e' NDATA "
  1062. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1063. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1064. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1065. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1066. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1067. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1068. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1069. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1070. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1071. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1072. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1073. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1074. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1075. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1076. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1077. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1078. ">\n"
  1079. "<!ELEMENT doc EMPTY>\n"
  1080. "]>\n<doc/>";
  1081. int i;
  1082. const int max_alloc_count = 20;
  1083. for (i = 0; i < max_alloc_count; i++) {
  1084. g_allocation_count = i;
  1085. init_dummy_handlers();
  1086. XML_SetNotationDeclHandler(g_parser, dummy_notation_decl_handler);
  1087. XML_SetEntityDeclHandler(g_parser, dummy_entity_decl_handler);
  1088. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1089. != XML_STATUS_ERROR)
  1090. break;
  1091. /* See comment in test_alloc_parse_xdecl() */
  1092. alloc_teardown();
  1093. alloc_setup();
  1094. }
  1095. if (i == 0)
  1096. fail("Parse succeeded despite allocation failures");
  1097. if (i == max_alloc_count)
  1098. fail("Parse failed at maximum allocation count");
  1099. if (get_dummy_handler_flags()
  1100. != (DUMMY_ENTITY_DECL_HANDLER_FLAG | DUMMY_NOTATION_DECL_HANDLER_FLAG))
  1101. fail("Entity declaration handler not called");
  1102. }
  1103. END_TEST
  1104. /* Test public notation with dodgy allocator */
  1105. START_TEST(test_alloc_public_notation) {
  1106. const char *text
  1107. = "<!DOCTYPE doc [\n"
  1108. "<!NOTATION note PUBLIC '"
  1109. /* 64 characters per line */
  1110. "http://example.com/a/long/enough/name/to/trigger/pool/growth/zz/"
  1111. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1112. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1113. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1114. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1115. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1116. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1117. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1118. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1119. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1120. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1121. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1122. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1123. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1124. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1125. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1126. "' 'foo'>\n"
  1127. "<!ENTITY e SYSTEM 'http://example.com/e' NDATA note>\n"
  1128. "<!ELEMENT doc EMPTY>\n"
  1129. "]>\n<doc/>";
  1130. int i;
  1131. const int max_alloc_count = 20;
  1132. for (i = 0; i < max_alloc_count; i++) {
  1133. g_allocation_count = i;
  1134. init_dummy_handlers();
  1135. XML_SetNotationDeclHandler(g_parser, dummy_notation_decl_handler);
  1136. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1137. != XML_STATUS_ERROR)
  1138. break;
  1139. /* See comment in test_alloc_parse_xdecl() */
  1140. alloc_teardown();
  1141. alloc_setup();
  1142. }
  1143. if (i == 0)
  1144. fail("Parse succeeded despite allocation failures");
  1145. if (i == max_alloc_count)
  1146. fail("Parse failed at maximum allocation count");
  1147. if (get_dummy_handler_flags() != DUMMY_NOTATION_DECL_HANDLER_FLAG)
  1148. fail("Notation handler not called");
  1149. }
  1150. END_TEST
  1151. /* Test public notation with dodgy allocator */
  1152. START_TEST(test_alloc_system_notation) {
  1153. const char *text
  1154. = "<!DOCTYPE doc [\n"
  1155. "<!NOTATION note SYSTEM '"
  1156. /* 64 characters per line */
  1157. "http://example.com/a/long/enough/name/to/trigger/pool/growth/zz/"
  1158. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1159. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1160. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1161. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1162. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1163. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1164. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1165. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1166. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1167. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1168. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1169. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1170. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1171. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1172. "ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/ABCDEFGHIJKLMNO/"
  1173. "'>\n"
  1174. "<!ENTITY e SYSTEM 'http://example.com/e' NDATA note>\n"
  1175. "<!ELEMENT doc EMPTY>\n"
  1176. "]>\n<doc/>";
  1177. int i;
  1178. const int max_alloc_count = 20;
  1179. for (i = 0; i < max_alloc_count; i++) {
  1180. g_allocation_count = i;
  1181. init_dummy_handlers();
  1182. XML_SetNotationDeclHandler(g_parser, dummy_notation_decl_handler);
  1183. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1184. != XML_STATUS_ERROR)
  1185. break;
  1186. /* See comment in test_alloc_parse_xdecl() */
  1187. alloc_teardown();
  1188. alloc_setup();
  1189. }
  1190. if (i == 0)
  1191. fail("Parse succeeded despite allocation failures");
  1192. if (i == max_alloc_count)
  1193. fail("Parse failed at maximum allocation count");
  1194. if (get_dummy_handler_flags() != DUMMY_NOTATION_DECL_HANDLER_FLAG)
  1195. fail("Notation handler not called");
  1196. }
  1197. END_TEST
  1198. START_TEST(test_alloc_nested_groups) {
  1199. const char *text
  1200. = "<!DOCTYPE doc [\n"
  1201. "<!ELEMENT doc "
  1202. /* Sixteen elements per line */
  1203. "(e,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,"
  1204. "(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?"
  1205. "))))))))))))))))))))))))))))))))>\n"
  1206. "<!ELEMENT e EMPTY>"
  1207. "]>\n"
  1208. "<doc><e/></doc>";
  1209. CharData storage;
  1210. int i;
  1211. const int max_alloc_count = 20;
  1212. for (i = 0; i < max_alloc_count; i++) {
  1213. g_allocation_count = i;
  1214. CharData_Init(&storage);
  1215. XML_SetElementDeclHandler(g_parser, dummy_element_decl_handler);
  1216. XML_SetStartElementHandler(g_parser, record_element_start_handler);
  1217. XML_SetUserData(g_parser, &storage);
  1218. init_dummy_handlers();
  1219. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1220. != XML_STATUS_ERROR)
  1221. break;
  1222. /* See comment in test_alloc_parse_xdecl() */
  1223. alloc_teardown();
  1224. alloc_setup();
  1225. }
  1226. if (i == 0)
  1227. fail("Parse succeeded despite failing reallocator");
  1228. if (i == max_alloc_count)
  1229. fail("Parse failed at maximum reallocation count");
  1230. CharData_CheckXMLChars(&storage, XCS("doce"));
  1231. if (get_dummy_handler_flags() != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
  1232. fail("Element handler not fired");
  1233. }
  1234. END_TEST
  1235. START_TEST(test_alloc_realloc_nested_groups) {
  1236. const char *text
  1237. = "<!DOCTYPE doc [\n"
  1238. "<!ELEMENT doc "
  1239. /* Sixteen elements per line */
  1240. "(e,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,"
  1241. "(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?,(e?"
  1242. "))))))))))))))))))))))))))))))))>\n"
  1243. "<!ELEMENT e EMPTY>"
  1244. "]>\n"
  1245. "<doc><e/></doc>";
  1246. CharData storage;
  1247. int i;
  1248. const int max_realloc_count = 10;
  1249. for (i = 0; i < max_realloc_count; i++) {
  1250. g_reallocation_count = i;
  1251. CharData_Init(&storage);
  1252. XML_SetElementDeclHandler(g_parser, dummy_element_decl_handler);
  1253. XML_SetStartElementHandler(g_parser, record_element_start_handler);
  1254. XML_SetUserData(g_parser, &storage);
  1255. init_dummy_handlers();
  1256. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1257. != XML_STATUS_ERROR)
  1258. break;
  1259. /* See comment in test_alloc_parse_xdecl() */
  1260. alloc_teardown();
  1261. alloc_setup();
  1262. }
  1263. if (i == 0)
  1264. fail("Parse succeeded despite failing reallocator");
  1265. if (i == max_realloc_count)
  1266. fail("Parse failed at maximum reallocation count");
  1267. CharData_CheckXMLChars(&storage, XCS("doce"));
  1268. if (get_dummy_handler_flags() != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
  1269. fail("Element handler not fired");
  1270. }
  1271. END_TEST
  1272. START_TEST(test_alloc_large_group) {
  1273. const char *text = "<!DOCTYPE doc [\n"
  1274. "<!ELEMENT doc ("
  1275. "a1|a2|a3|a4|a5|a6|a7|a8|"
  1276. "b1|b2|b3|b4|b5|b6|b7|b8|"
  1277. "c1|c2|c3|c4|c5|c6|c7|c8|"
  1278. "d1|d2|d3|d4|d5|d6|d7|d8|"
  1279. "e1"
  1280. ")+>\n"
  1281. "]>\n"
  1282. "<doc>\n"
  1283. "<a1/>\n"
  1284. "</doc>\n";
  1285. int i;
  1286. const int max_alloc_count = 50;
  1287. for (i = 0; i < max_alloc_count; i++) {
  1288. g_allocation_count = i;
  1289. XML_SetElementDeclHandler(g_parser, dummy_element_decl_handler);
  1290. init_dummy_handlers();
  1291. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1292. != XML_STATUS_ERROR)
  1293. break;
  1294. /* See comment in test_alloc_parse_xdecl() */
  1295. alloc_teardown();
  1296. alloc_setup();
  1297. }
  1298. if (i == 0)
  1299. fail("Parse succeeded despite failing allocator");
  1300. if (i == max_alloc_count)
  1301. fail("Parse failed at maximum allocation count");
  1302. if (get_dummy_handler_flags() != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
  1303. fail("Element handler flag not raised");
  1304. }
  1305. END_TEST
  1306. START_TEST(test_alloc_realloc_group_choice) {
  1307. const char *text = "<!DOCTYPE doc [\n"
  1308. "<!ELEMENT doc ("
  1309. "a1|a2|a3|a4|a5|a6|a7|a8|"
  1310. "b1|b2|b3|b4|b5|b6|b7|b8|"
  1311. "c1|c2|c3|c4|c5|c6|c7|c8|"
  1312. "d1|d2|d3|d4|d5|d6|d7|d8|"
  1313. "e1"
  1314. ")+>\n"
  1315. "]>\n"
  1316. "<doc>\n"
  1317. "<a1/>\n"
  1318. "<b2 attr='foo'>This is a foo</b2>\n"
  1319. "<c3></c3>\n"
  1320. "</doc>\n";
  1321. int i;
  1322. const int max_realloc_count = 10;
  1323. for (i = 0; i < max_realloc_count; i++) {
  1324. g_reallocation_count = i;
  1325. XML_SetElementDeclHandler(g_parser, dummy_element_decl_handler);
  1326. init_dummy_handlers();
  1327. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1328. != XML_STATUS_ERROR)
  1329. break;
  1330. /* See comment in test_alloc_parse_xdecl() */
  1331. alloc_teardown();
  1332. alloc_setup();
  1333. }
  1334. if (i == 0)
  1335. fail("Parse succeeded despite failing reallocator");
  1336. if (i == max_realloc_count)
  1337. fail("Parse failed at maximum reallocation count");
  1338. if (get_dummy_handler_flags() != DUMMY_ELEMENT_DECL_HANDLER_FLAG)
  1339. fail("Element handler flag not raised");
  1340. }
  1341. END_TEST
  1342. START_TEST(test_alloc_pi_in_epilog) {
  1343. const char *text = "<doc></doc>\n"
  1344. "<?pi in epilog?>";
  1345. int i;
  1346. const int max_alloc_count = 15;
  1347. for (i = 0; i < max_alloc_count; i++) {
  1348. g_allocation_count = i;
  1349. XML_SetProcessingInstructionHandler(g_parser, dummy_pi_handler);
  1350. init_dummy_handlers();
  1351. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1352. != XML_STATUS_ERROR)
  1353. break;
  1354. /* See comment in test_alloc_parse_xdecl() */
  1355. alloc_teardown();
  1356. alloc_setup();
  1357. }
  1358. if (i == 0)
  1359. fail("Parse completed despite failing allocator");
  1360. if (i == max_alloc_count)
  1361. fail("Parse failed at maximum allocation count");
  1362. if (get_dummy_handler_flags() != DUMMY_PI_HANDLER_FLAG)
  1363. fail("Processing instruction handler not invoked");
  1364. }
  1365. END_TEST
  1366. START_TEST(test_alloc_comment_in_epilog) {
  1367. const char *text = "<doc></doc>\n"
  1368. "<!-- comment in epilog -->";
  1369. int i;
  1370. const int max_alloc_count = 15;
  1371. for (i = 0; i < max_alloc_count; i++) {
  1372. g_allocation_count = i;
  1373. XML_SetCommentHandler(g_parser, dummy_comment_handler);
  1374. init_dummy_handlers();
  1375. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1376. != XML_STATUS_ERROR)
  1377. break;
  1378. /* See comment in test_alloc_parse_xdecl() */
  1379. alloc_teardown();
  1380. alloc_setup();
  1381. }
  1382. if (i == 0)
  1383. fail("Parse completed despite failing allocator");
  1384. if (i == max_alloc_count)
  1385. fail("Parse failed at maximum allocation count");
  1386. if (get_dummy_handler_flags() != DUMMY_COMMENT_HANDLER_FLAG)
  1387. fail("Processing instruction handler not invoked");
  1388. }
  1389. END_TEST
  1390. START_TEST(test_alloc_realloc_long_attribute_value) {
  1391. const char *text
  1392. = "<!DOCTYPE doc [<!ENTITY foo '"
  1393. /* Each line is 64 characters */
  1394. "This entity will be substituted as an attribute value, and is "
  1395. "calculated to be exactly long enough that the terminating NUL "
  1396. "that the library adds internally will trigger the string pool to"
  1397. "grow. GHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1398. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1399. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1400. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1401. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1402. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1403. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1404. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1405. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1406. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1407. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1408. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1409. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1410. "'>]>\n"
  1411. "<doc a='&foo;'></doc>";
  1412. int i;
  1413. const int max_realloc_count = 10;
  1414. for (i = 0; i < max_realloc_count; i++) {
  1415. g_reallocation_count = i;
  1416. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1417. != XML_STATUS_ERROR)
  1418. break;
  1419. /* See comment in test_alloc_parse_xdecl() */
  1420. alloc_teardown();
  1421. alloc_setup();
  1422. }
  1423. if (i == 0)
  1424. fail("Parse succeeded despite failing reallocator");
  1425. if (i == max_realloc_count)
  1426. fail("Parse failed at maximum reallocation count");
  1427. }
  1428. END_TEST
  1429. START_TEST(test_alloc_attribute_whitespace) {
  1430. const char *text = "<doc a=' '></doc>";
  1431. int i;
  1432. const int max_alloc_count = 15;
  1433. for (i = 0; i < max_alloc_count; i++) {
  1434. g_allocation_count = i;
  1435. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1436. != XML_STATUS_ERROR)
  1437. break;
  1438. /* See comment in test_alloc_parse_xdecl() */
  1439. alloc_teardown();
  1440. alloc_setup();
  1441. }
  1442. if (i == 0)
  1443. fail("Parse succeeded despite failing allocator");
  1444. if (i == max_alloc_count)
  1445. fail("Parse failed at maximum allocation count");
  1446. }
  1447. END_TEST
  1448. START_TEST(test_alloc_attribute_predefined_entity) {
  1449. const char *text = "<doc a='&amp;'></doc>";
  1450. int i;
  1451. const int max_alloc_count = 15;
  1452. for (i = 0; i < max_alloc_count; i++) {
  1453. g_allocation_count = i;
  1454. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1455. != XML_STATUS_ERROR)
  1456. break;
  1457. /* See comment in test_alloc_parse_xdecl() */
  1458. alloc_teardown();
  1459. alloc_setup();
  1460. }
  1461. if (i == 0)
  1462. fail("Parse succeeded despite failing allocator");
  1463. if (i == max_alloc_count)
  1464. fail("Parse failed at maximum allocation count");
  1465. }
  1466. END_TEST
  1467. /* Test that a character reference at the end of a suitably long
  1468. * default value for an attribute can trigger pool growth, and recovers
  1469. * if the allocator fails on it.
  1470. */
  1471. START_TEST(test_alloc_long_attr_default_with_char_ref) {
  1472. const char *text
  1473. = "<!DOCTYPE doc [<!ATTLIST doc a CDATA '"
  1474. /* 64 characters per line */
  1475. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1476. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1477. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1478. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1479. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1480. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1481. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1482. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1483. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1484. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1485. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1486. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1487. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1488. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1489. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1490. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHI"
  1491. "&#x31;'>]>\n"
  1492. "<doc/>";
  1493. int i;
  1494. const int max_alloc_count = 20;
  1495. for (i = 0; i < max_alloc_count; i++) {
  1496. g_allocation_count = i;
  1497. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1498. != XML_STATUS_ERROR)
  1499. break;
  1500. /* See comment in test_alloc_parse_xdecl() */
  1501. alloc_teardown();
  1502. alloc_setup();
  1503. }
  1504. if (i == 0)
  1505. fail("Parse succeeded despite failing allocator");
  1506. if (i == max_alloc_count)
  1507. fail("Parse failed at maximum allocation count");
  1508. }
  1509. END_TEST
  1510. /* Test that a long character reference substitution triggers a pool
  1511. * expansion correctly for an attribute value.
  1512. */
  1513. START_TEST(test_alloc_long_attr_value) {
  1514. const char *text
  1515. = "<!DOCTYPE test [<!ENTITY foo '\n"
  1516. /* 64 characters per line */
  1517. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1518. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1519. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1520. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1521. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1522. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1523. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1524. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1525. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1526. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1527. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1528. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1529. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1530. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1531. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1532. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1533. "'>]>\n"
  1534. "<test a='&foo;'/>";
  1535. int i;
  1536. const int max_alloc_count = 25;
  1537. for (i = 0; i < max_alloc_count; i++) {
  1538. g_allocation_count = i;
  1539. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1540. != XML_STATUS_ERROR)
  1541. break;
  1542. /* See comment in test_alloc_parse_xdecl() */
  1543. alloc_teardown();
  1544. alloc_setup();
  1545. }
  1546. if (i == 0)
  1547. fail("Parse succeeded despite failing allocator");
  1548. if (i == max_alloc_count)
  1549. fail("Parse failed at maximum allocation count");
  1550. }
  1551. END_TEST
  1552. /* Test that an error in a nested parameter entity substitution is
  1553. * handled correctly. It seems unlikely that the code path being
  1554. * exercised can be reached purely by carefully crafted XML, but an
  1555. * allocation error in the right place will definitely do it.
  1556. */
  1557. START_TEST(test_alloc_nested_entities) {
  1558. const char *text = "<!DOCTYPE doc SYSTEM 'http://example.org/one.ent'>\n"
  1559. "<doc />";
  1560. ExtFaults test_data
  1561. = {"<!ENTITY % pe1 '"
  1562. /* 64 characters per line */
  1563. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1564. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1565. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1566. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1567. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1568. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1569. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1570. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1571. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1572. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1573. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1574. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1575. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1576. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1577. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1578. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1579. "'>\n"
  1580. "<!ENTITY % pe2 '%pe1;'>\n"
  1581. "<!ENTITY % pe3 '%pe2;'>",
  1582. "Memory Fail not faulted", NULL, XML_ERROR_NO_MEMORY};
  1583. /* Causes an allocation error in a nested storeEntityValue() */
  1584. g_allocation_count = 12;
  1585. XML_SetUserData(g_parser, &test_data);
  1586. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1587. XML_SetExternalEntityRefHandler(g_parser, external_entity_faulter);
  1588. expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
  1589. "Entity allocation failure not noted");
  1590. }
  1591. END_TEST
  1592. START_TEST(test_alloc_realloc_param_entity_newline) {
  1593. const char *text = "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
  1594. "<doc/>";
  1595. char dtd_text[]
  1596. = "<!ENTITY % pe '<!ATTLIST doc att CDATA \""
  1597. /* 64 characters per line */
  1598. "This default value is carefully crafted so that the carriage "
  1599. "return right at the end of the entity string causes an internal "
  1600. "string pool to have to grow. This allows us to test the alloc "
  1601. "failure path from that point. OPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1602. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1603. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1604. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1605. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1606. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1607. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1608. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1609. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1610. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1611. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1612. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1613. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDE"
  1614. "\">\n'>"
  1615. "%pe;\n";
  1616. int i;
  1617. const int max_realloc_count = 5;
  1618. for (i = 0; i < max_realloc_count; i++) {
  1619. g_reallocation_count = i;
  1620. XML_SetUserData(g_parser, dtd_text);
  1621. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1622. XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc);
  1623. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1624. != XML_STATUS_ERROR)
  1625. break;
  1626. /* See comment in test_alloc_parse_xdecl() */
  1627. alloc_teardown();
  1628. alloc_setup();
  1629. }
  1630. if (i == 0)
  1631. fail("Parse succeeded despite failing reallocator");
  1632. if (i == max_realloc_count)
  1633. fail("Parse failed at maximum reallocation count");
  1634. }
  1635. END_TEST
  1636. START_TEST(test_alloc_realloc_ce_extends_pe) {
  1637. const char *text = "<!DOCTYPE doc SYSTEM 'http://example.org/'>\n"
  1638. "<doc/>";
  1639. char dtd_text[]
  1640. = "<!ENTITY % pe '<!ATTLIST doc att CDATA \""
  1641. /* 64 characters per line */
  1642. "This default value is carefully crafted so that the character "
  1643. "entity at the end causes an internal string pool to have to "
  1644. "grow. This allows us to test the allocation failure path from "
  1645. "that point onwards. EFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1646. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1647. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1648. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1649. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1650. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1651. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1652. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1653. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1654. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1655. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1656. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP"
  1657. "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOPABCDEFG&#x51;"
  1658. "\">\n'>"
  1659. "%pe;\n";
  1660. int i;
  1661. const int max_realloc_count = 5;
  1662. for (i = 0; i < max_realloc_count; i++) {
  1663. g_reallocation_count = i;
  1664. XML_SetUserData(g_parser, dtd_text);
  1665. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1666. XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc);
  1667. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1668. != XML_STATUS_ERROR)
  1669. break;
  1670. /* See comment in test_alloc_parse_xdecl() */
  1671. alloc_teardown();
  1672. alloc_setup();
  1673. }
  1674. if (i == 0)
  1675. fail("Parse succeeded despite failing reallocator");
  1676. if (i == max_realloc_count)
  1677. fail("Parse failed at maximum reallocation count");
  1678. }
  1679. END_TEST
  1680. START_TEST(test_alloc_realloc_attributes) {
  1681. const char *text = "<!DOCTYPE doc [\n"
  1682. " <!ATTLIST doc\n"
  1683. " a1 (a|b|c) 'a'\n"
  1684. " a2 (foo|bar) #IMPLIED\n"
  1685. " a3 NMTOKEN #IMPLIED\n"
  1686. " a4 NMTOKENS #IMPLIED\n"
  1687. " a5 ID #IMPLIED\n"
  1688. " a6 IDREF #IMPLIED\n"
  1689. " a7 IDREFS #IMPLIED\n"
  1690. " a8 ENTITY #IMPLIED\n"
  1691. " a9 ENTITIES #IMPLIED\n"
  1692. " a10 CDATA #IMPLIED\n"
  1693. " >]>\n"
  1694. "<doc>wombat</doc>\n";
  1695. int i;
  1696. const int max_realloc_count = 5;
  1697. for (i = 0; i < max_realloc_count; i++) {
  1698. g_reallocation_count = i;
  1699. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1700. != XML_STATUS_ERROR)
  1701. break;
  1702. /* See comment in test_alloc_parse_xdecl() */
  1703. alloc_teardown();
  1704. alloc_setup();
  1705. }
  1706. if (i == 0)
  1707. fail("Parse succeeded despite failing reallocator");
  1708. if (i == max_realloc_count)
  1709. fail("Parse failed at maximum reallocation count");
  1710. }
  1711. END_TEST
  1712. START_TEST(test_alloc_long_doc_name) {
  1713. const char *text =
  1714. /* 64 characters per line */
  1715. "<LongRootElementNameThatWillCauseTheNextAllocationToExpandTheStr"
  1716. "ingPoolForTheDTDQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
  1717. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
  1718. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
  1719. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
  1720. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
  1721. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
  1722. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
  1723. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
  1724. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
  1725. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
  1726. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
  1727. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
  1728. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
  1729. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
  1730. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AZ"
  1731. " a='1'/>";
  1732. int i;
  1733. const int max_alloc_count = 20;
  1734. for (i = 0; i < max_alloc_count; i++) {
  1735. g_allocation_count = i;
  1736. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1737. != XML_STATUS_ERROR)
  1738. break;
  1739. /* See comment in test_alloc_parse_xdecl() */
  1740. alloc_teardown();
  1741. alloc_setup();
  1742. }
  1743. if (i == 0)
  1744. fail("Parsing worked despite failing reallocations");
  1745. else if (i == max_alloc_count)
  1746. fail("Parsing failed even at max reallocation count");
  1747. }
  1748. END_TEST
  1749. START_TEST(test_alloc_long_base) {
  1750. const char *text = "<!DOCTYPE doc [\n"
  1751. " <!ENTITY e SYSTEM 'foo'>\n"
  1752. "]>\n"
  1753. "<doc>&e;</doc>";
  1754. char entity_text[] = "Hello world";
  1755. const XML_Char *base =
  1756. /* 64 characters per line */
  1757. /* clang-format off */
  1758. XCS("LongBaseURI/that/will/overflow/an/internal/buffer/and/cause/it/t")
  1759. XCS("o/have/to/grow/PQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
  1760. XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
  1761. XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
  1762. XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
  1763. XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
  1764. XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
  1765. XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
  1766. XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
  1767. XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
  1768. XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
  1769. XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
  1770. XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
  1771. XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
  1772. XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/")
  1773. XCS("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789A/");
  1774. /* clang-format on */
  1775. int i;
  1776. const int max_alloc_count = 25;
  1777. for (i = 0; i < max_alloc_count; i++) {
  1778. g_allocation_count = i;
  1779. XML_SetUserData(g_parser, entity_text);
  1780. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1781. XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc);
  1782. if (XML_SetBase(g_parser, base) == XML_STATUS_ERROR) {
  1783. XML_ParserReset(g_parser, NULL);
  1784. continue;
  1785. }
  1786. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1787. != XML_STATUS_ERROR)
  1788. break;
  1789. /* See comment in test_alloc_parse_xdecl() */
  1790. alloc_teardown();
  1791. alloc_setup();
  1792. }
  1793. if (i == 0)
  1794. fail("Parsing worked despite failing allocations");
  1795. else if (i == max_alloc_count)
  1796. fail("Parsing failed even at max allocation count");
  1797. }
  1798. END_TEST
  1799. START_TEST(test_alloc_long_public_id) {
  1800. const char *text
  1801. = "<!DOCTYPE doc [\n"
  1802. " <!ENTITY e PUBLIC '"
  1803. /* 64 characters per line */
  1804. "LongPublicIDThatShouldResultInAnInternalStringPoolGrowingAtASpec"
  1805. "ificMomentKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1806. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1807. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1808. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1809. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1810. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1811. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1812. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1813. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1814. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1815. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1816. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1817. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1818. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1819. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1820. "' 'bar'>\n"
  1821. "]>\n"
  1822. "<doc>&e;</doc>";
  1823. char entity_text[] = "Hello world";
  1824. int i;
  1825. const int max_alloc_count = 40;
  1826. for (i = 0; i < max_alloc_count; i++) {
  1827. g_allocation_count = i;
  1828. XML_SetUserData(g_parser, entity_text);
  1829. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1830. XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc);
  1831. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1832. != XML_STATUS_ERROR)
  1833. break;
  1834. /* See comment in test_alloc_parse_xdecl() */
  1835. alloc_teardown();
  1836. alloc_setup();
  1837. }
  1838. if (i == 0)
  1839. fail("Parsing worked despite failing allocations");
  1840. else if (i == max_alloc_count)
  1841. fail("Parsing failed even at max allocation count");
  1842. }
  1843. END_TEST
  1844. START_TEST(test_alloc_long_entity_value) {
  1845. const char *text
  1846. = "<!DOCTYPE doc [\n"
  1847. " <!ENTITY e1 '"
  1848. /* 64 characters per line */
  1849. "Long entity value that should provoke a string pool to grow whil"
  1850. "e setting up to parse the external entity below. xyz0123456789AB"
  1851. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1852. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1853. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1854. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1855. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1856. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1857. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1858. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1859. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1860. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1861. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1862. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1863. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1864. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1865. "'>\n"
  1866. " <!ENTITY e2 SYSTEM 'bar'>\n"
  1867. "]>\n"
  1868. "<doc>&e2;</doc>";
  1869. char entity_text[] = "Hello world";
  1870. int i;
  1871. const int max_alloc_count = 40;
  1872. for (i = 0; i < max_alloc_count; i++) {
  1873. g_allocation_count = i;
  1874. XML_SetUserData(g_parser, entity_text);
  1875. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1876. XML_SetExternalEntityRefHandler(g_parser, external_entity_alloc);
  1877. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1878. != XML_STATUS_ERROR)
  1879. break;
  1880. /* See comment in test_alloc_parse_xdecl() */
  1881. alloc_teardown();
  1882. alloc_setup();
  1883. }
  1884. if (i == 0)
  1885. fail("Parsing worked despite failing allocations");
  1886. else if (i == max_alloc_count)
  1887. fail("Parsing failed even at max allocation count");
  1888. }
  1889. END_TEST
  1890. START_TEST(test_alloc_long_notation) {
  1891. const char *text
  1892. = "<!DOCTYPE doc [\n"
  1893. " <!NOTATION note SYSTEM '"
  1894. /* 64 characters per line */
  1895. "ALongNotationNameThatShouldProvokeStringPoolGrowthWhileCallingAn"
  1896. "ExternalEntityParserUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1897. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1898. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1899. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1900. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1901. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1902. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1903. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1904. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1905. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1906. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1907. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1908. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1909. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1910. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1911. "'>\n"
  1912. " <!ENTITY e1 SYSTEM 'foo' NDATA "
  1913. /* 64 characters per line */
  1914. "ALongNotationNameThatShouldProvokeStringPoolGrowthWhileCallingAn"
  1915. "ExternalEntityParserUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1916. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1917. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1918. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1919. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1920. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1921. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1922. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1923. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1924. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1925. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1926. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1927. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1928. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1929. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB"
  1930. ">\n"
  1931. " <!ENTITY e2 SYSTEM 'bar'>\n"
  1932. "]>\n"
  1933. "<doc>&e2;</doc>";
  1934. ExtOption options[]
  1935. = {{XCS("foo"), "Entity Foo"}, {XCS("bar"), "Entity Bar"}, {NULL, NULL}};
  1936. int i;
  1937. const int max_alloc_count = 40;
  1938. for (i = 0; i < max_alloc_count; i++) {
  1939. g_allocation_count = i;
  1940. XML_SetUserData(g_parser, options);
  1941. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1942. XML_SetExternalEntityRefHandler(g_parser, external_entity_optioner);
  1943. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1944. != XML_STATUS_ERROR)
  1945. break;
  1946. /* See comment in test_alloc_parse_xdecl() */
  1947. alloc_teardown();
  1948. alloc_setup();
  1949. }
  1950. if (i == 0)
  1951. fail("Parsing worked despite failing allocations");
  1952. else if (i == max_alloc_count)
  1953. fail("Parsing failed even at max allocation count");
  1954. }
  1955. END_TEST
  1956. START_TEST(test_alloc_reset_after_external_entity_parser_create_fail) {
  1957. const char *const text = "<!DOCTYPE doc SYSTEM 'foo'><doc/>";
  1958. XML_SetExternalEntityRefHandler(
  1959. g_parser, external_entity_parser_create_alloc_fail_handler);
  1960. XML_SetParamEntityParsing(g_parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1961. if (_XML_Parse_SINGLE_BYTES(g_parser, text, (int)strlen(text), XML_TRUE)
  1962. != XML_STATUS_ERROR)
  1963. fail("Call to parse was expected to fail");
  1964. if (XML_GetErrorCode(g_parser) != XML_ERROR_EXTERNAL_ENTITY_HANDLING)
  1965. fail("Call to parse was expected to fail from the external entity handler");
  1966. XML_ParserReset(g_parser, NULL);
  1967. }
  1968. END_TEST
  1969. #if XML_GE == 1
  1970. static size_t
  1971. sizeRecordedFor(void *ptr) {
  1972. return *(size_t *)((char *)ptr - EXPAT_MALLOC_PADDING - sizeof(size_t));
  1973. }
  1974. #endif // XML_GE == 1
  1975. START_TEST(test_alloc_tracker_size_recorded) {
  1976. XML_Memory_Handling_Suite memsuite = {malloc, realloc, free};
  1977. bool values[] = {true, false};
  1978. for (size_t i = 0; i < sizeof(values) / sizeof(values[0]); i++) {
  1979. const bool useMemSuite = values[i];
  1980. set_subtest("useMemSuite=%d", (int)useMemSuite);
  1981. XML_Parser parser = useMemSuite
  1982. ? XML_ParserCreate_MM(NULL, &memsuite, XCS("|"))
  1983. : XML_ParserCreate(NULL);
  1984. #if XML_GE == 1
  1985. void *ptr = expat_malloc(parser, 10, -1);
  1986. assert_true(ptr != NULL);
  1987. assert_true(sizeRecordedFor(ptr) == 10);
  1988. assert_true(expat_realloc(parser, ptr, SIZE_MAX / 2, -1) == NULL);
  1989. assert_true(sizeRecordedFor(ptr) == 10); // i.e. unchanged
  1990. ptr = expat_realloc(parser, ptr, 20, -1);
  1991. assert_true(ptr != NULL);
  1992. assert_true(sizeRecordedFor(ptr) == 20);
  1993. expat_free(parser, ptr, -1);
  1994. #endif
  1995. XML_ParserFree(parser);
  1996. }
  1997. }
  1998. END_TEST
  1999. START_TEST(test_alloc_tracker_pointer_alignment) {
  2000. XML_Parser parser = XML_ParserCreate(NULL);
  2001. #if XML_GE == 1
  2002. assert_true(sizeof(long long) >= sizeof(size_t)); // self-test
  2003. long long *const ptr
  2004. = (long long *)expat_malloc(parser, 4 * sizeof(long long), -1);
  2005. ptr[0] = 0LL;
  2006. ptr[1] = 1LL;
  2007. ptr[2] = 2LL;
  2008. ptr[3] = 3LL;
  2009. expat_free(parser, ptr, -1);
  2010. #endif
  2011. XML_ParserFree(parser);
  2012. }
  2013. END_TEST
  2014. START_TEST(test_alloc_tracker_maximum_amplification) {
  2015. if (g_reparseDeferralEnabledDefault == XML_TRUE) {
  2016. return;
  2017. }
  2018. XML_Parser parser = XML_ParserCreate(NULL);
  2019. // Get .m_accounting.countBytesDirect from 0 to 3
  2020. const char *const chunk = "<e>";
  2021. assert_true(_XML_Parse_SINGLE_BYTES(parser, chunk, (int)strlen(chunk),
  2022. /*isFinal=*/XML_FALSE)
  2023. == XML_STATUS_OK);
  2024. #if XML_GE == 1
  2025. // Stop activation threshold from interfering
  2026. assert_true(XML_SetAllocTrackerActivationThreshold(parser, 0) == XML_TRUE);
  2027. // Exceed maximum amplification: should be rejected.
  2028. assert_true(expat_malloc(parser, 1000, -1) == NULL);
  2029. // Increase maximum amplification, and try the same amount once more: should
  2030. // work.
  2031. assert_true(XML_SetAllocTrackerMaximumAmplification(parser, 3000.0f)
  2032. == XML_TRUE);
  2033. void *const ptr = expat_malloc(parser, 1000, -1);
  2034. assert_true(ptr != NULL);
  2035. expat_free(parser, ptr, -1);
  2036. #endif
  2037. XML_ParserFree(parser);
  2038. }
  2039. END_TEST
  2040. START_TEST(test_alloc_tracker_threshold) {
  2041. XML_Parser parser = XML_ParserCreate(NULL);
  2042. #if XML_GE == 1
  2043. // Exceed maximum amplification *before* (default) threshold: should work.
  2044. void *const ptr = expat_malloc(parser, 1000, -1);
  2045. assert_true(ptr != NULL);
  2046. expat_free(parser, ptr, -1);
  2047. // Exceed maximum amplification *after* threshold: should be rejected.
  2048. assert_true(XML_SetAllocTrackerActivationThreshold(parser, 999) == XML_TRUE);
  2049. assert_true(expat_malloc(parser, 1000, -1) == NULL);
  2050. #endif
  2051. XML_ParserFree(parser);
  2052. }
  2053. END_TEST
  2054. START_TEST(test_alloc_tracker_getbuffer_unlimited) {
  2055. XML_Parser parser = XML_ParserCreate(NULL);
  2056. #if XML_GE == 1
  2057. // Artificially lower threshold
  2058. assert_true(XML_SetAllocTrackerActivationThreshold(parser, 0) == XML_TRUE);
  2059. // Self-test: Prove that threshold is as rejecting as expected
  2060. assert_true(expat_malloc(parser, 1000, -1) == NULL);
  2061. #endif
  2062. // XML_GetBuffer should be allowed to pass, though
  2063. assert_true(XML_GetBuffer(parser, 1000) != NULL);
  2064. XML_ParserFree(parser);
  2065. }
  2066. END_TEST
  2067. START_TEST(test_alloc_tracker_api) {
  2068. XML_Parser parserWithoutParent = XML_ParserCreate(NULL);
  2069. XML_Parser parserWithParent = XML_ExternalEntityParserCreate(
  2070. parserWithoutParent, XCS("entity123"), NULL);
  2071. if (parserWithoutParent == NULL)
  2072. fail("parserWithoutParent is NULL");
  2073. if (parserWithParent == NULL)
  2074. fail("parserWithParent is NULL");
  2075. #if XML_GE == 1
  2076. // XML_SetAllocTrackerMaximumAmplification, error cases
  2077. if (XML_SetAllocTrackerMaximumAmplification(NULL, 123.0f) == XML_TRUE)
  2078. fail("Call with NULL parser is NOT supposed to succeed");
  2079. if (XML_SetAllocTrackerMaximumAmplification(parserWithParent, 123.0f)
  2080. == XML_TRUE)
  2081. fail("Call with non-root parser is NOT supposed to succeed");
  2082. if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, NAN)
  2083. == XML_TRUE)
  2084. fail("Call with NaN limit is NOT supposed to succeed");
  2085. if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, -1.0f)
  2086. == XML_TRUE)
  2087. fail("Call with negative limit is NOT supposed to succeed");
  2088. if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, 0.9f)
  2089. == XML_TRUE)
  2090. fail("Call with positive limit <1.0 is NOT supposed to succeed");
  2091. // XML_SetAllocTrackerMaximumAmplification, success cases
  2092. if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, 1.0f)
  2093. == XML_FALSE)
  2094. fail("Call with positive limit >=1.0 is supposed to succeed");
  2095. if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, 123456.789f)
  2096. == XML_FALSE)
  2097. fail("Call with positive limit >=1.0 is supposed to succeed");
  2098. if (XML_SetAllocTrackerMaximumAmplification(parserWithoutParent, INFINITY)
  2099. == XML_FALSE)
  2100. fail("Call with positive limit >=1.0 is supposed to succeed");
  2101. // XML_SetAllocTrackerActivationThreshold, error cases
  2102. if (XML_SetAllocTrackerActivationThreshold(NULL, 123) == XML_TRUE)
  2103. fail("Call with NULL parser is NOT supposed to succeed");
  2104. if (XML_SetAllocTrackerActivationThreshold(parserWithParent, 123) == XML_TRUE)
  2105. fail("Call with non-root parser is NOT supposed to succeed");
  2106. // XML_SetAllocTrackerActivationThreshold, success cases
  2107. if (XML_SetAllocTrackerActivationThreshold(parserWithoutParent, 123)
  2108. == XML_FALSE)
  2109. fail("Call with non-NULL parentless parser is supposed to succeed");
  2110. #endif // XML_GE == 1
  2111. XML_ParserFree(parserWithParent);
  2112. XML_ParserFree(parserWithoutParent);
  2113. }
  2114. END_TEST
  2115. START_TEST(test_mem_api_cycle) {
  2116. XML_Parser parser = XML_ParserCreate(NULL);
  2117. void *ptr = XML_MemMalloc(parser, 10);
  2118. assert_true(ptr != NULL);
  2119. memset(ptr, 'x', 10); // assert writability, with ASan in mind
  2120. ptr = XML_MemRealloc(parser, ptr, 20);
  2121. assert_true(ptr != NULL);
  2122. memset(ptr, 'y', 20); // assert writability, with ASan in mind
  2123. XML_MemFree(parser, ptr);
  2124. XML_ParserFree(parser);
  2125. }
  2126. END_TEST
  2127. START_TEST(test_mem_api_unlimited) {
  2128. XML_Parser parser = XML_ParserCreate(NULL);
  2129. #if XML_GE == 1
  2130. assert_true(XML_SetAllocTrackerActivationThreshold(parser, 0) == XML_TRUE);
  2131. #endif
  2132. void *ptr = XML_MemMalloc(parser, 1000);
  2133. assert_true(ptr != NULL);
  2134. ptr = XML_MemRealloc(parser, ptr, 2000);
  2135. assert_true(ptr != NULL);
  2136. XML_MemFree(parser, ptr);
  2137. XML_ParserFree(parser);
  2138. }
  2139. END_TEST
  2140. void
  2141. make_alloc_test_case(Suite *s) {
  2142. TCase *tc_alloc = tcase_create("allocation tests");
  2143. suite_add_tcase(s, tc_alloc);
  2144. tcase_add_checked_fixture(tc_alloc, alloc_setup, alloc_teardown);
  2145. tcase_add_test(tc_alloc, test_alloc_parse_xdecl);
  2146. tcase_add_test(tc_alloc, test_alloc_parse_xdecl_2);
  2147. tcase_add_test(tc_alloc, test_alloc_parse_pi);
  2148. tcase_add_test(tc_alloc, test_alloc_parse_pi_2);
  2149. tcase_add_test(tc_alloc, test_alloc_parse_pi_3);
  2150. tcase_add_test(tc_alloc, test_alloc_parse_comment);
  2151. tcase_add_test(tc_alloc, test_alloc_parse_comment_2);
  2152. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_create_external_parser);
  2153. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_run_external_parser);
  2154. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_dtd_copy_default_atts);
  2155. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_external_entity);
  2156. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_ext_entity_set_encoding);
  2157. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_internal_entity);
  2158. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_parameter_entity);
  2159. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_dtd_default_handling);
  2160. tcase_add_test(tc_alloc, test_alloc_explicit_encoding);
  2161. tcase_add_test(tc_alloc, test_alloc_set_base);
  2162. tcase_add_test(tc_alloc, test_alloc_realloc_buffer);
  2163. tcase_add_test__if_xml_ge(tc_alloc, test_alloc_ext_entity_realloc_buffer);
  2164. tcase_add_test(tc_alloc, test_alloc_realloc_many_attributes);
  2165. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_public_entity_value);
  2166. tcase_add_test__ifdef_xml_dtd(tc_alloc,
  2167. test_alloc_realloc_subst_public_entity_value);
  2168. tcase_add_test(tc_alloc, test_alloc_parse_public_doctype);
  2169. tcase_add_test(tc_alloc, test_alloc_parse_public_doctype_long_name);
  2170. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_set_foreign_dtd);
  2171. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_attribute_enum_value);
  2172. tcase_add_test__ifdef_xml_dtd(tc_alloc,
  2173. test_alloc_realloc_attribute_enum_value);
  2174. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_realloc_implied_attribute);
  2175. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_realloc_default_attribute);
  2176. tcase_add_test__if_xml_ge(tc_alloc, test_alloc_notation);
  2177. tcase_add_test(tc_alloc, test_alloc_public_notation);
  2178. tcase_add_test(tc_alloc, test_alloc_system_notation);
  2179. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_nested_groups);
  2180. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_realloc_nested_groups);
  2181. tcase_add_test(tc_alloc, test_alloc_large_group);
  2182. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_realloc_group_choice);
  2183. tcase_add_test(tc_alloc, test_alloc_pi_in_epilog);
  2184. tcase_add_test(tc_alloc, test_alloc_comment_in_epilog);
  2185. tcase_add_test__ifdef_xml_dtd(tc_alloc,
  2186. test_alloc_realloc_long_attribute_value);
  2187. tcase_add_test(tc_alloc, test_alloc_attribute_whitespace);
  2188. tcase_add_test(tc_alloc, test_alloc_attribute_predefined_entity);
  2189. tcase_add_test(tc_alloc, test_alloc_long_attr_default_with_char_ref);
  2190. tcase_add_test__if_xml_ge(tc_alloc, test_alloc_long_attr_value);
  2191. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_nested_entities);
  2192. tcase_add_test__ifdef_xml_dtd(tc_alloc,
  2193. test_alloc_realloc_param_entity_newline);
  2194. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_realloc_ce_extends_pe);
  2195. tcase_add_test__ifdef_xml_dtd(tc_alloc, test_alloc_realloc_attributes);
  2196. tcase_add_test(tc_alloc, test_alloc_long_doc_name);
  2197. tcase_add_test__if_xml_ge(tc_alloc, test_alloc_long_base);
  2198. tcase_add_test__if_xml_ge(tc_alloc, test_alloc_long_public_id);
  2199. tcase_add_test__if_xml_ge(tc_alloc, test_alloc_long_entity_value);
  2200. tcase_add_test__if_xml_ge(tc_alloc, test_alloc_long_notation);
  2201. tcase_add_test__ifdef_xml_dtd(
  2202. tc_alloc, test_alloc_reset_after_external_entity_parser_create_fail);
  2203. tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_size_recorded);
  2204. tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_pointer_alignment);
  2205. tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_maximum_amplification);
  2206. tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_threshold);
  2207. tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_getbuffer_unlimited);
  2208. tcase_add_test__if_xml_ge(tc_alloc, test_alloc_tracker_api);
  2209. tcase_add_test(tc_alloc, test_mem_api_cycle);
  2210. tcase_add_test__if_xml_ge(tc_alloc, test_mem_api_unlimited);
  2211. }