runtests.c 122 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631
  1. /* Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
  2. See the file COPYING for copying permission.
  3. runtest.c : run the Expat test suite
  4. */
  5. #ifdef HAVE_EXPAT_CONFIG_H
  6. #include <expat_config.h>
  7. #endif
  8. #include <assert.h>
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <stdint.h>
  13. #include <stddef.h> /* ptrdiff_t */
  14. #include <ctype.h>
  15. #ifndef __cplusplus
  16. # include <stdbool.h>
  17. #endif
  18. #include <limits.h>
  19. #include "expat.h"
  20. #include "chardata.h"
  21. #include "internal.h" /* for UNUSED_P only */
  22. #include "minicheck.h"
  23. #include "memcheck.h"
  24. #include "siphash.h"
  25. #ifdef XML_LARGE_SIZE
  26. #define XML_FMT_INT_MOD "ll"
  27. #else
  28. #define XML_FMT_INT_MOD "l"
  29. #endif
  30. #if defined(NDEBUG)
  31. # error \
  32. The test suite relies on assert(...) at the moment. \
  33. You have NDEBUG defined which removes that code so that failures in the \
  34. test suite can go unnoticed. \
  35. \
  36. While we rely on assert(...), compiling the test suite with NDEBUG \
  37. defined is not supported.
  38. #endif
  39. static XML_Parser parser = NULL;
  40. static void
  41. basic_setup(void)
  42. {
  43. parser = XML_ParserCreate(NULL);
  44. if (parser == NULL)
  45. fail("Parser not created.");
  46. }
  47. static void
  48. basic_teardown(void)
  49. {
  50. if (parser != NULL) {
  51. XML_ParserFree(parser);
  52. parser = NULL;
  53. }
  54. }
  55. /* Generate a failure using the parser state to create an error message;
  56. this should be used when the parser reports an error we weren't
  57. expecting.
  58. */
  59. static void
  60. _xml_failure(XML_Parser parser, const char *file, int line)
  61. {
  62. char buffer[1024];
  63. enum XML_Error err = XML_GetErrorCode(parser);
  64. sprintf(buffer,
  65. " %d: %s (line %" XML_FMT_INT_MOD "u, offset %"\
  66. XML_FMT_INT_MOD "u)\n reported from %s, line %d\n",
  67. err,
  68. XML_ErrorString(err),
  69. XML_GetCurrentLineNumber(parser),
  70. XML_GetCurrentColumnNumber(parser),
  71. file, line);
  72. _fail_unless(0, file, line, buffer);
  73. }
  74. static enum XML_Status
  75. _XML_Parse_SINGLE_BYTES(XML_Parser parser, const char *s, int len, int isFinal)
  76. {
  77. enum XML_Status res = XML_STATUS_ERROR;
  78. int offset = 0;
  79. if (len == 0) {
  80. return XML_Parse(parser, s, len, isFinal);
  81. }
  82. for (; offset < len; offset++) {
  83. const int innerIsFinal = (offset == len - 1) && isFinal;
  84. const char c = s[offset]; /* to help out-of-bounds detection */
  85. res = XML_Parse(parser, &c, sizeof(char), innerIsFinal);
  86. if (res != XML_STATUS_OK) {
  87. return res;
  88. }
  89. }
  90. return res;
  91. }
  92. #define xml_failure(parser) _xml_failure((parser), __FILE__, __LINE__)
  93. static void
  94. _expect_failure(const char *text, enum XML_Error errorCode, const char *errorMessage,
  95. const char *file, int lineno)
  96. {
  97. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK)
  98. /* Hackish use of _fail_unless() macro, but let's us report
  99. the right filename and line number. */
  100. _fail_unless(0, file, lineno, errorMessage);
  101. if (XML_GetErrorCode(parser) != errorCode)
  102. _xml_failure(parser, file, lineno);
  103. }
  104. #define expect_failure(text, errorCode, errorMessage) \
  105. _expect_failure((text), (errorCode), (errorMessage), \
  106. __FILE__, __LINE__)
  107. /* Dummy handlers for when we need to set a handler to tickle a bug,
  108. but it doesn't need to do anything.
  109. */
  110. static void XMLCALL
  111. dummy_start_doctype_handler(void *UNUSED_P(userData),
  112. const XML_Char *UNUSED_P(doctypeName),
  113. const XML_Char *UNUSED_P(sysid),
  114. const XML_Char *UNUSED_P(pubid),
  115. int UNUSED_P(has_internal_subset))
  116. {}
  117. static void XMLCALL
  118. dummy_end_doctype_handler(void *UNUSED_P(userData))
  119. {}
  120. static void XMLCALL
  121. dummy_entity_decl_handler(void *UNUSED_P(userData),
  122. const XML_Char *UNUSED_P(entityName),
  123. int UNUSED_P(is_parameter_entity),
  124. const XML_Char *UNUSED_P(value),
  125. int UNUSED_P(value_length),
  126. const XML_Char *UNUSED_P(base),
  127. const XML_Char *UNUSED_P(systemId),
  128. const XML_Char *UNUSED_P(publicId),
  129. const XML_Char *UNUSED_P(notationName))
  130. {}
  131. static void XMLCALL
  132. dummy_notation_decl_handler(void *UNUSED_P(userData),
  133. const XML_Char *UNUSED_P(notationName),
  134. const XML_Char *UNUSED_P(base),
  135. const XML_Char *UNUSED_P(systemId),
  136. const XML_Char *UNUSED_P(publicId))
  137. {}
  138. static void XMLCALL
  139. dummy_element_decl_handler(void *UNUSED_P(userData),
  140. const XML_Char *UNUSED_P(name),
  141. XML_Content *UNUSED_P(model))
  142. {}
  143. static void XMLCALL
  144. dummy_attlist_decl_handler(void *UNUSED_P(userData),
  145. const XML_Char *UNUSED_P(elname),
  146. const XML_Char *UNUSED_P(attname),
  147. const XML_Char *UNUSED_P(att_type),
  148. const XML_Char *UNUSED_P(dflt),
  149. int UNUSED_P(isrequired))
  150. {}
  151. static void XMLCALL
  152. dummy_comment_handler(void *UNUSED_P(userData), const XML_Char *UNUSED_P(data))
  153. {}
  154. static void XMLCALL
  155. dummy_pi_handler(void *UNUSED_P(userData), const XML_Char *UNUSED_P(target), const XML_Char *UNUSED_P(data))
  156. {}
  157. static void XMLCALL
  158. dummy_start_element(void *UNUSED_P(userData),
  159. const XML_Char *UNUSED_P(name), const XML_Char **UNUSED_P(atts))
  160. {}
  161. static void XMLCALL
  162. dummy_start_cdata_handler(void *UNUSED_P(userData))
  163. {}
  164. static void XMLCALL
  165. dummy_end_cdata_handler(void *UNUSED_P(userData))
  166. {}
  167. static void XMLCALL
  168. dummy_start_namespace_decl_handler(void *UNUSED_P(userData),
  169. const XML_Char *UNUSED_P(prefix),
  170. const XML_Char *UNUSED_P(uri))
  171. {}
  172. static void XMLCALL
  173. dummy_end_namespace_decl_handler(void *UNUSED_P(userData),
  174. const XML_Char *UNUSED_P(prefix))
  175. {}
  176. /* This handler is obsolete, but while the code exists we should
  177. * ensure that dealing with the handler is covered by tests.
  178. */
  179. static void XMLCALL
  180. dummy_unparsed_entity_decl_handler(void *UNUSED_P(userData),
  181. const XML_Char *UNUSED_P(entityName),
  182. const XML_Char *UNUSED_P(base),
  183. const XML_Char *UNUSED_P(systemId),
  184. const XML_Char *UNUSED_P(publicId),
  185. const XML_Char *UNUSED_P(notationName))
  186. {}
  187. /*
  188. * Character & encoding tests.
  189. */
  190. START_TEST(test_nul_byte)
  191. {
  192. char text[] = "<doc>\0</doc>";
  193. /* test that a NUL byte (in US-ASCII data) is an error */
  194. if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_OK)
  195. fail("Parser did not report error on NUL-byte.");
  196. if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
  197. xml_failure(parser);
  198. }
  199. END_TEST
  200. START_TEST(test_u0000_char)
  201. {
  202. /* test that a NUL byte (in US-ASCII data) is an error */
  203. expect_failure("<doc>&#0;</doc>",
  204. XML_ERROR_BAD_CHAR_REF,
  205. "Parser did not report error on NUL-byte.");
  206. }
  207. END_TEST
  208. START_TEST(test_siphash_self)
  209. {
  210. if (! sip24_valid())
  211. fail("SipHash self-test failed");
  212. }
  213. END_TEST
  214. START_TEST(test_siphash_spec)
  215. {
  216. /* https://131002.net/siphash/siphash.pdf (page 19, "Test values") */
  217. const char message[] = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09"
  218. "\x0a\x0b\x0c\x0d\x0e";
  219. const size_t len = sizeof(message) - 1;
  220. const uint64_t expected = _SIP_ULL(0xa129ca61U, 0x49be45e5U);
  221. struct siphash state;
  222. struct sipkey key;
  223. (void)sip_tobin;
  224. sip_tokey(&key,
  225. "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09"
  226. "\x0a\x0b\x0c\x0d\x0e\x0f");
  227. sip24_init(&state, &key);
  228. /* Cover spread across calls */
  229. sip24_update(&state, message, 4);
  230. sip24_update(&state, message + 4, len - 4);
  231. /* Cover null length */
  232. sip24_update(&state, message, 0);
  233. if (sip24_final(&state) != expected)
  234. fail("sip24_final failed spec test\n");
  235. /* Cover wrapper */
  236. if (siphash24(message, len, &key) != expected)
  237. fail("siphash24 failed spec test\n");
  238. }
  239. END_TEST
  240. START_TEST(test_bom_utf8)
  241. {
  242. /* This test is really just making sure we don't core on a UTF-8 BOM. */
  243. const char *text = "\357\273\277<e/>";
  244. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  245. xml_failure(parser);
  246. }
  247. END_TEST
  248. START_TEST(test_bom_utf16_be)
  249. {
  250. char text[] = "\376\377\0<\0e\0/\0>";
  251. if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
  252. xml_failure(parser);
  253. }
  254. END_TEST
  255. START_TEST(test_bom_utf16_le)
  256. {
  257. char text[] = "\377\376<\0e\0/\0>\0";
  258. if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
  259. xml_failure(parser);
  260. }
  261. END_TEST
  262. static void XMLCALL
  263. accumulate_characters(void *userData, const XML_Char *s, int len)
  264. {
  265. CharData_AppendXMLChars((CharData *)userData, s, len);
  266. }
  267. static void XMLCALL
  268. accumulate_attribute(void *userData, const XML_Char *UNUSED_P(name),
  269. const XML_Char **atts)
  270. {
  271. CharData *storage = (CharData *)userData;
  272. if (storage->count < 0 && atts != NULL && atts[0] != NULL) {
  273. /* "accumulate" the value of the first attribute we see */
  274. CharData_AppendXMLChars(storage, atts[1], -1);
  275. }
  276. }
  277. static void
  278. _run_character_check(const XML_Char *text, const XML_Char *expected,
  279. const char *file, int line)
  280. {
  281. CharData storage;
  282. CharData_Init(&storage);
  283. XML_SetUserData(parser, &storage);
  284. XML_SetCharacterDataHandler(parser, accumulate_characters);
  285. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  286. _xml_failure(parser, file, line);
  287. CharData_CheckXMLChars(&storage, expected);
  288. }
  289. #define run_character_check(text, expected) \
  290. _run_character_check(text, expected, __FILE__, __LINE__)
  291. static void
  292. _run_attribute_check(const XML_Char *text, const XML_Char *expected,
  293. const char *file, int line)
  294. {
  295. CharData storage;
  296. CharData_Init(&storage);
  297. XML_SetUserData(parser, &storage);
  298. XML_SetStartElementHandler(parser, accumulate_attribute);
  299. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  300. _xml_failure(parser, file, line);
  301. CharData_CheckXMLChars(&storage, expected);
  302. }
  303. #define run_attribute_check(text, expected) \
  304. _run_attribute_check(text, expected, __FILE__, __LINE__)
  305. /* Regression test for SF bug #491986. */
  306. START_TEST(test_danish_latin1)
  307. {
  308. const char *text =
  309. "<?xml version='1.0' encoding='iso-8859-1'?>\n"
  310. "<e>J\xF8rgen \xE6\xF8\xE5\xC6\xD8\xC5</e>";
  311. run_character_check(text,
  312. "J\xC3\xB8rgen \xC3\xA6\xC3\xB8\xC3\xA5\xC3\x86\xC3\x98\xC3\x85");
  313. }
  314. END_TEST
  315. /* Regression test for SF bug #514281. */
  316. START_TEST(test_french_charref_hexidecimal)
  317. {
  318. const char *text =
  319. "<?xml version='1.0' encoding='iso-8859-1'?>\n"
  320. "<doc>&#xE9;&#xE8;&#xE0;&#xE7;&#xEA;&#xC8;</doc>";
  321. run_character_check(text,
  322. "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
  323. }
  324. END_TEST
  325. START_TEST(test_french_charref_decimal)
  326. {
  327. const char *text =
  328. "<?xml version='1.0' encoding='iso-8859-1'?>\n"
  329. "<doc>&#233;&#232;&#224;&#231;&#234;&#200;</doc>";
  330. run_character_check(text,
  331. "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
  332. }
  333. END_TEST
  334. START_TEST(test_french_latin1)
  335. {
  336. const char *text =
  337. "<?xml version='1.0' encoding='iso-8859-1'?>\n"
  338. "<doc>\xE9\xE8\xE0\xE7\xEa\xC8</doc>";
  339. run_character_check(text,
  340. "\xC3\xA9\xC3\xA8\xC3\xA0\xC3\xA7\xC3\xAA\xC3\x88");
  341. }
  342. END_TEST
  343. START_TEST(test_french_utf8)
  344. {
  345. const char *text =
  346. "<?xml version='1.0' encoding='utf-8'?>\n"
  347. "<doc>\xC3\xA9</doc>";
  348. run_character_check(text, "\xC3\xA9");
  349. }
  350. END_TEST
  351. /* Regression test for SF bug #600479.
  352. XXX There should be a test that exercises all legal XML Unicode
  353. characters as PCDATA and attribute value content, and XML Name
  354. characters as part of element and attribute names.
  355. */
  356. START_TEST(test_utf8_false_rejection)
  357. {
  358. const char *text = "<doc>\xEF\xBA\xBF</doc>";
  359. run_character_check(text, "\xEF\xBA\xBF");
  360. }
  361. END_TEST
  362. /* Regression test for SF bug #477667.
  363. This test assures that any 8-bit character followed by a 7-bit
  364. character will not be mistakenly interpreted as a valid UTF-8
  365. sequence.
  366. */
  367. START_TEST(test_illegal_utf8)
  368. {
  369. char text[100];
  370. int i;
  371. for (i = 128; i <= 255; ++i) {
  372. sprintf(text, "<e>%ccd</e>", i);
  373. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_OK) {
  374. sprintf(text,
  375. "expected token error for '%c' (ordinal %d) in UTF-8 text",
  376. i, i);
  377. fail(text);
  378. }
  379. else if (XML_GetErrorCode(parser) != XML_ERROR_INVALID_TOKEN)
  380. xml_failure(parser);
  381. /* Reset the parser since we use the same parser repeatedly. */
  382. XML_ParserReset(parser, NULL);
  383. }
  384. }
  385. END_TEST
  386. /* Examples, not masks: */
  387. #define UTF8_LEAD_1 "\x7f" /* 0b01111111 */
  388. #define UTF8_LEAD_2 "\xdf" /* 0b11011111 */
  389. #define UTF8_LEAD_3 "\xef" /* 0b11101111 */
  390. #define UTF8_LEAD_4 "\xf7" /* 0b11110111 */
  391. #define UTF8_FOLLOW "\xbf" /* 0b10111111 */
  392. START_TEST(test_utf8_auto_align)
  393. {
  394. struct TestCase {
  395. ptrdiff_t expectedMovementInChars;
  396. const char * input;
  397. };
  398. struct TestCase cases[] = {
  399. {00, ""},
  400. {00, UTF8_LEAD_1},
  401. {-1, UTF8_LEAD_2},
  402. {00, UTF8_LEAD_2 UTF8_FOLLOW},
  403. {-1, UTF8_LEAD_3},
  404. {-2, UTF8_LEAD_3 UTF8_FOLLOW},
  405. {00, UTF8_LEAD_3 UTF8_FOLLOW UTF8_FOLLOW},
  406. {-1, UTF8_LEAD_4},
  407. {-2, UTF8_LEAD_4 UTF8_FOLLOW},
  408. {-3, UTF8_LEAD_4 UTF8_FOLLOW UTF8_FOLLOW},
  409. {00, UTF8_LEAD_4 UTF8_FOLLOW UTF8_FOLLOW UTF8_FOLLOW},
  410. };
  411. size_t i = 0;
  412. bool success = true;
  413. for (; i < sizeof(cases) / sizeof(*cases); i++) {
  414. const char * fromLim = cases[i].input + strlen(cases[i].input);
  415. const char * const fromLimInitially = fromLim;
  416. ptrdiff_t actualMovementInChars;
  417. align_limit_to_full_utf8_characters(cases[i].input, &fromLim);
  418. actualMovementInChars = (fromLim - fromLimInitially);
  419. if (actualMovementInChars != cases[i].expectedMovementInChars) {
  420. size_t j = 0;
  421. success = false;
  422. printf("[-] UTF-8 case %2u: Expected movement by %2d chars"
  423. ", actually moved by %2d chars: \"",
  424. (unsigned)(i + 1),
  425. (int)cases[i].expectedMovementInChars,
  426. (int)actualMovementInChars);
  427. for (; j < strlen(cases[i].input); j++) {
  428. printf("\\x%02x", (unsigned char)cases[i].input[j]);
  429. }
  430. printf("\"\n");
  431. }
  432. }
  433. if (! success) {
  434. fail("UTF-8 auto-alignment is not bullet-proof\n");
  435. }
  436. }
  437. END_TEST
  438. START_TEST(test_utf16)
  439. {
  440. /* <?xml version="1.0" encoding="UTF-16"?>
  441. <doc a='123'>some text</doc>
  442. */
  443. char text[] =
  444. "\000<\000?\000x\000m\000\154\000 \000v\000e\000r\000s\000i\000o"
  445. "\000n\000=\000'\0001\000.\000\060\000'\000 \000e\000n\000c\000o"
  446. "\000d\000i\000n\000g\000=\000'\000U\000T\000F\000-\0001\000\066"
  447. "\000'\000?\000>\000\n"
  448. "\000<\000d\000o\000c\000 \000a\000=\000'\0001\0002\0003\000'"
  449. "\000>\000s\000o\000m\000e\000 \000t\000e\000x\000t\000<\000/"
  450. "\000d\000o\000c\000>";
  451. if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text)-1, XML_TRUE) == XML_STATUS_ERROR)
  452. xml_failure(parser);
  453. }
  454. END_TEST
  455. START_TEST(test_utf16_le_epilog_newline)
  456. {
  457. unsigned int first_chunk_bytes = 17;
  458. char text[] =
  459. "\xFF\xFE" /* BOM */
  460. "<\000e\000/\000>\000" /* document element */
  461. "\r\000\n\000\r\000\n\000"; /* epilog */
  462. if (first_chunk_bytes >= sizeof(text) - 1)
  463. fail("bad value of first_chunk_bytes");
  464. if ( _XML_Parse_SINGLE_BYTES(parser, text, first_chunk_bytes, XML_FALSE)
  465. == XML_STATUS_ERROR)
  466. xml_failure(parser);
  467. else {
  468. enum XML_Status rc;
  469. rc = _XML_Parse_SINGLE_BYTES(parser, text + first_chunk_bytes,
  470. sizeof(text) - first_chunk_bytes - 1, XML_TRUE);
  471. if (rc == XML_STATUS_ERROR)
  472. xml_failure(parser);
  473. }
  474. }
  475. END_TEST
  476. /* Regression test for SF bug #481609, #774028. */
  477. START_TEST(test_latin1_umlauts)
  478. {
  479. const char *text =
  480. "<?xml version='1.0' encoding='iso-8859-1'?>\n"
  481. "<e a='\xE4 \xF6 \xFC &#228; &#246; &#252; &#x00E4; &#x0F6; &#xFC; >'\n"
  482. " >\xE4 \xF6 \xFC &#228; &#246; &#252; &#x00E4; &#x0F6; &#xFC; ></e>";
  483. const char *utf8 =
  484. "\xC3\xA4 \xC3\xB6 \xC3\xBC "
  485. "\xC3\xA4 \xC3\xB6 \xC3\xBC "
  486. "\xC3\xA4 \xC3\xB6 \xC3\xBC >";
  487. run_character_check(text, utf8);
  488. XML_ParserReset(parser, NULL);
  489. run_attribute_check(text, utf8);
  490. }
  491. END_TEST
  492. /* Regression test #1 for SF bug #653180. */
  493. START_TEST(test_line_number_after_parse)
  494. {
  495. const char *text =
  496. "<tag>\n"
  497. "\n"
  498. "\n</tag>";
  499. XML_Size lineno;
  500. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
  501. xml_failure(parser);
  502. lineno = XML_GetCurrentLineNumber(parser);
  503. if (lineno != 4) {
  504. char buffer[100];
  505. sprintf(buffer,
  506. "expected 4 lines, saw %" XML_FMT_INT_MOD "u", lineno);
  507. fail(buffer);
  508. }
  509. }
  510. END_TEST
  511. /* Regression test #2 for SF bug #653180. */
  512. START_TEST(test_column_number_after_parse)
  513. {
  514. const char *text = "<tag></tag>";
  515. XML_Size colno;
  516. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
  517. xml_failure(parser);
  518. colno = XML_GetCurrentColumnNumber(parser);
  519. if (colno != 11) {
  520. char buffer[100];
  521. sprintf(buffer,
  522. "expected 11 columns, saw %" XML_FMT_INT_MOD "u", colno);
  523. fail(buffer);
  524. }
  525. }
  526. END_TEST
  527. static void XMLCALL
  528. start_element_event_handler2(void *userData, const XML_Char *name,
  529. const XML_Char **UNUSED_P(attr))
  530. {
  531. CharData *storage = (CharData *) userData;
  532. char buffer[100];
  533. sprintf(buffer,
  534. "<%s> at col:%" XML_FMT_INT_MOD "u line:%"\
  535. XML_FMT_INT_MOD "u\n", name,
  536. XML_GetCurrentColumnNumber(parser),
  537. XML_GetCurrentLineNumber(parser));
  538. CharData_AppendString(storage, buffer);
  539. }
  540. static void XMLCALL
  541. end_element_event_handler2(void *userData, const XML_Char *name)
  542. {
  543. CharData *storage = (CharData *) userData;
  544. char buffer[100];
  545. sprintf(buffer,
  546. "</%s> at col:%" XML_FMT_INT_MOD "u line:%"\
  547. XML_FMT_INT_MOD "u\n", name,
  548. XML_GetCurrentColumnNumber(parser),
  549. XML_GetCurrentLineNumber(parser));
  550. CharData_AppendString(storage, buffer);
  551. }
  552. /* Regression test #3 for SF bug #653180. */
  553. START_TEST(test_line_and_column_numbers_inside_handlers)
  554. {
  555. const char *text =
  556. "<a>\n" /* Unix end-of-line */
  557. " <b>\r\n" /* Windows end-of-line */
  558. " <c/>\r" /* Mac OS end-of-line */
  559. " </b>\n"
  560. " <d>\n"
  561. " <f/>\n"
  562. " </d>\n"
  563. "</a>";
  564. const char *expected =
  565. "<a> at col:0 line:1\n"
  566. "<b> at col:2 line:2\n"
  567. "<c> at col:4 line:3\n"
  568. "</c> at col:8 line:3\n"
  569. "</b> at col:2 line:4\n"
  570. "<d> at col:2 line:5\n"
  571. "<f> at col:4 line:6\n"
  572. "</f> at col:8 line:6\n"
  573. "</d> at col:2 line:7\n"
  574. "</a> at col:0 line:8\n";
  575. CharData storage;
  576. CharData_Init(&storage);
  577. XML_SetUserData(parser, &storage);
  578. XML_SetStartElementHandler(parser, start_element_event_handler2);
  579. XML_SetEndElementHandler(parser, end_element_event_handler2);
  580. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  581. xml_failure(parser);
  582. CharData_CheckString(&storage, expected);
  583. }
  584. END_TEST
  585. /* Regression test #4 for SF bug #653180. */
  586. START_TEST(test_line_number_after_error)
  587. {
  588. const char *text =
  589. "<a>\n"
  590. " <b>\n"
  591. " </a>"; /* missing </b> */
  592. XML_Size lineno;
  593. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
  594. fail("Expected a parse error");
  595. lineno = XML_GetCurrentLineNumber(parser);
  596. if (lineno != 3) {
  597. char buffer[100];
  598. sprintf(buffer, "expected 3 lines, saw %" XML_FMT_INT_MOD "u", lineno);
  599. fail(buffer);
  600. }
  601. }
  602. END_TEST
  603. /* Regression test #5 for SF bug #653180. */
  604. START_TEST(test_column_number_after_error)
  605. {
  606. const char *text =
  607. "<a>\n"
  608. " <b>\n"
  609. " </a>"; /* missing </b> */
  610. XML_Size colno;
  611. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) != XML_STATUS_ERROR)
  612. fail("Expected a parse error");
  613. colno = XML_GetCurrentColumnNumber(parser);
  614. if (colno != 4) {
  615. char buffer[100];
  616. sprintf(buffer,
  617. "expected 4 columns, saw %" XML_FMT_INT_MOD "u", colno);
  618. fail(buffer);
  619. }
  620. }
  621. END_TEST
  622. /* Regression test for SF bug #478332. */
  623. START_TEST(test_really_long_lines)
  624. {
  625. /* This parses an input line longer than INIT_DATA_BUF_SIZE
  626. characters long (defined to be 1024 in xmlparse.c). We take a
  627. really cheesy approach to building the input buffer, because
  628. this avoids writing bugs in buffer-filling code.
  629. */
  630. const char *text =
  631. "<e>"
  632. /* 64 chars */
  633. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  634. /* until we have at least 1024 characters on the line: */
  635. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  636. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  637. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  638. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  639. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  640. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  641. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  642. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  643. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  644. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  645. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  646. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  647. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  648. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  649. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  650. "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-+"
  651. "</e>";
  652. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  653. xml_failure(parser);
  654. }
  655. END_TEST
  656. /*
  657. * Element event tests.
  658. */
  659. static void XMLCALL
  660. end_element_event_handler(void *userData, const XML_Char *name)
  661. {
  662. CharData *storage = (CharData *) userData;
  663. CharData_AppendString(storage, "/");
  664. CharData_AppendXMLChars(storage, name, -1);
  665. }
  666. START_TEST(test_end_element_events)
  667. {
  668. const char *text = "<a><b><c/></b><d><f/></d></a>";
  669. const char *expected = "/c/b/f/d/a";
  670. CharData storage;
  671. CharData_Init(&storage);
  672. XML_SetUserData(parser, &storage);
  673. XML_SetEndElementHandler(parser, end_element_event_handler);
  674. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  675. xml_failure(parser);
  676. CharData_CheckString(&storage, expected);
  677. }
  678. END_TEST
  679. /*
  680. * Attribute tests.
  681. */
  682. /* Helpers used by the following test; this checks any "attr" and "refs"
  683. attributes to make sure whitespace has been normalized.
  684. Return true if whitespace has been normalized in a string, using
  685. the rules for attribute value normalization. The 'is_cdata' flag
  686. is needed since CDATA attributes don't need to have multiple
  687. whitespace characters collapsed to a single space, while other
  688. attribute data types do. (Section 3.3.3 of the recommendation.)
  689. */
  690. static int
  691. is_whitespace_normalized(const XML_Char *s, int is_cdata)
  692. {
  693. int blanks = 0;
  694. int at_start = 1;
  695. while (*s) {
  696. if (*s == ' ')
  697. ++blanks;
  698. else if (*s == '\t' || *s == '\n' || *s == '\r')
  699. return 0;
  700. else {
  701. if (at_start) {
  702. at_start = 0;
  703. if (blanks && !is_cdata)
  704. /* illegal leading blanks */
  705. return 0;
  706. }
  707. else if (blanks > 1 && !is_cdata)
  708. return 0;
  709. blanks = 0;
  710. }
  711. ++s;
  712. }
  713. if (blanks && !is_cdata)
  714. return 0;
  715. return 1;
  716. }
  717. /* Check the attribute whitespace checker: */
  718. static void
  719. testhelper_is_whitespace_normalized(void)
  720. {
  721. assert(is_whitespace_normalized("abc", 0));
  722. assert(is_whitespace_normalized("abc", 1));
  723. assert(is_whitespace_normalized("abc def ghi", 0));
  724. assert(is_whitespace_normalized("abc def ghi", 1));
  725. assert(!is_whitespace_normalized(" abc def ghi", 0));
  726. assert(is_whitespace_normalized(" abc def ghi", 1));
  727. assert(!is_whitespace_normalized("abc def ghi", 0));
  728. assert(is_whitespace_normalized("abc def ghi", 1));
  729. assert(!is_whitespace_normalized("abc def ghi ", 0));
  730. assert(is_whitespace_normalized("abc def ghi ", 1));
  731. assert(!is_whitespace_normalized(" ", 0));
  732. assert(is_whitespace_normalized(" ", 1));
  733. assert(!is_whitespace_normalized("\t", 0));
  734. assert(!is_whitespace_normalized("\t", 1));
  735. assert(!is_whitespace_normalized("\n", 0));
  736. assert(!is_whitespace_normalized("\n", 1));
  737. assert(!is_whitespace_normalized("\r", 0));
  738. assert(!is_whitespace_normalized("\r", 1));
  739. assert(!is_whitespace_normalized("abc\t def", 1));
  740. }
  741. static void XMLCALL
  742. check_attr_contains_normalized_whitespace(void *UNUSED_P(userData),
  743. const XML_Char *UNUSED_P(name),
  744. const XML_Char **atts)
  745. {
  746. int i;
  747. for (i = 0; atts[i] != NULL; i += 2) {
  748. const XML_Char *attrname = atts[i];
  749. const XML_Char *value = atts[i + 1];
  750. if (strcmp("attr", attrname) == 0
  751. || strcmp("ents", attrname) == 0
  752. || strcmp("refs", attrname) == 0) {
  753. if (!is_whitespace_normalized(value, 0)) {
  754. char buffer[256];
  755. sprintf(buffer, "attribute value not normalized: %s='%s'",
  756. attrname, value);
  757. fail(buffer);
  758. }
  759. }
  760. }
  761. }
  762. START_TEST(test_attr_whitespace_normalization)
  763. {
  764. const char *text =
  765. "<!DOCTYPE doc [\n"
  766. " <!ATTLIST doc\n"
  767. " attr NMTOKENS #REQUIRED\n"
  768. " ents ENTITIES #REQUIRED\n"
  769. " refs IDREFS #REQUIRED>\n"
  770. "]>\n"
  771. "<doc attr=' a b c\t\td\te\t' refs=' id-1 \t id-2\t\t' \n"
  772. " ents=' ent-1 \t\r\n"
  773. " ent-2 ' >\n"
  774. " <e id='id-1'/>\n"
  775. " <e id='id-2'/>\n"
  776. "</doc>";
  777. XML_SetStartElementHandler(parser,
  778. check_attr_contains_normalized_whitespace);
  779. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  780. xml_failure(parser);
  781. }
  782. END_TEST
  783. /*
  784. * XML declaration tests.
  785. */
  786. START_TEST(test_xmldecl_misplaced)
  787. {
  788. expect_failure("\n"
  789. "<?xml version='1.0'?>\n"
  790. "<a/>",
  791. XML_ERROR_MISPLACED_XML_PI,
  792. "failed to report misplaced XML declaration");
  793. }
  794. END_TEST
  795. /* Regression test for SF bug #584832. */
  796. static int XMLCALL
  797. UnknownEncodingHandler(void *UNUSED_P(data),const XML_Char *encoding,XML_Encoding *info)
  798. {
  799. if (strcmp(encoding,"unsupported-encoding") == 0) {
  800. int i;
  801. for (i = 0; i < 256; ++i)
  802. info->map[i] = i;
  803. info->data = NULL;
  804. info->convert = NULL;
  805. info->release = NULL;
  806. return XML_STATUS_OK;
  807. }
  808. return XML_STATUS_ERROR;
  809. }
  810. START_TEST(test_unknown_encoding_internal_entity)
  811. {
  812. const char *text =
  813. "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
  814. "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
  815. "<test a='&foo;'/>";
  816. XML_SetUnknownEncodingHandler(parser, UnknownEncodingHandler, NULL);
  817. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  818. xml_failure(parser);
  819. }
  820. END_TEST
  821. /* Test unrecognised encoding handler */
  822. static void dummy_release(void *UNUSED_P(data))
  823. {
  824. }
  825. static int XMLCALL
  826. UnrecognisedEncodingHandler(void *UNUSED_P(data),
  827. const XML_Char *UNUSED_P(encoding),
  828. XML_Encoding *info)
  829. {
  830. info->data = NULL;
  831. info->convert = NULL;
  832. info->release = dummy_release;
  833. return XML_STATUS_ERROR;
  834. }
  835. START_TEST(test_unrecognised_encoding_internal_entity)
  836. {
  837. const char *text =
  838. "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
  839. "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
  840. "<test a='&foo;'/>";
  841. XML_SetUnknownEncodingHandler(parser,
  842. UnrecognisedEncodingHandler,
  843. NULL);
  844. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
  845. fail("Unrecognised encoding not rejected");
  846. }
  847. END_TEST
  848. /* Regression test for SF bug #620106. */
  849. static int XMLCALL
  850. external_entity_loader_set_encoding(XML_Parser parser,
  851. const XML_Char *context,
  852. const XML_Char *UNUSED_P(base),
  853. const XML_Char *UNUSED_P(systemId),
  854. const XML_Char *UNUSED_P(publicId))
  855. {
  856. /* This text says it's an unsupported encoding, but it's really
  857. UTF-8, which we tell Expat using XML_SetEncoding().
  858. */
  859. const char *text =
  860. "<?xml encoding='iso-8859-3'?>"
  861. "\xC3\xA9";
  862. XML_Parser extparser;
  863. extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
  864. if (extparser == NULL)
  865. fail("Could not create external entity parser.");
  866. if (!XML_SetEncoding(extparser, "utf-8"))
  867. fail("XML_SetEncoding() ignored for external entity");
  868. if ( _XML_Parse_SINGLE_BYTES(extparser, text, strlen(text), XML_TRUE)
  869. == XML_STATUS_ERROR) {
  870. xml_failure(parser);
  871. return 0;
  872. }
  873. return 1;
  874. }
  875. START_TEST(test_ext_entity_set_encoding)
  876. {
  877. const char *text =
  878. "<!DOCTYPE doc [\n"
  879. " <!ENTITY en SYSTEM 'http://xml.libexpat.org/dummy.ent'>\n"
  880. "]>\n"
  881. "<doc>&en;</doc>";
  882. XML_SetExternalEntityRefHandler(parser,
  883. external_entity_loader_set_encoding);
  884. run_character_check(text, "\xC3\xA9");
  885. }
  886. END_TEST
  887. /* Test that no error is reported for unknown entities if we don't
  888. read an external subset. This was fixed in Expat 1.95.5.
  889. */
  890. START_TEST(test_wfc_undeclared_entity_unread_external_subset) {
  891. const char *text =
  892. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  893. "<doc>&entity;</doc>";
  894. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  895. xml_failure(parser);
  896. }
  897. END_TEST
  898. /* Test that an error is reported for unknown entities if we don't
  899. have an external subset.
  900. */
  901. START_TEST(test_wfc_undeclared_entity_no_external_subset) {
  902. expect_failure("<doc>&entity;</doc>",
  903. XML_ERROR_UNDEFINED_ENTITY,
  904. "Parser did not report undefined entity w/out a DTD.");
  905. }
  906. END_TEST
  907. /* Test that an error is reported for unknown entities if we don't
  908. read an external subset, but have been declared standalone.
  909. */
  910. START_TEST(test_wfc_undeclared_entity_standalone) {
  911. const char *text =
  912. "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
  913. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  914. "<doc>&entity;</doc>";
  915. expect_failure(text,
  916. XML_ERROR_UNDEFINED_ENTITY,
  917. "Parser did not report undefined entity (standalone).");
  918. }
  919. END_TEST
  920. static int XMLCALL
  921. external_entity_loader(XML_Parser parser,
  922. const XML_Char *context,
  923. const XML_Char *UNUSED_P(base),
  924. const XML_Char *UNUSED_P(systemId),
  925. const XML_Char *UNUSED_P(publicId))
  926. {
  927. char *text = (char *)XML_GetUserData(parser);
  928. XML_Parser extparser;
  929. extparser = XML_ExternalEntityParserCreate(parser, context, NULL);
  930. if (extparser == NULL)
  931. fail("Could not create external entity parser.");
  932. if ( _XML_Parse_SINGLE_BYTES(extparser, text, strlen(text), XML_TRUE)
  933. == XML_STATUS_ERROR) {
  934. xml_failure(parser);
  935. return XML_STATUS_ERROR;
  936. }
  937. return XML_STATUS_OK;
  938. }
  939. /* Test that an error is reported for unknown entities if we have read
  940. an external subset, and standalone is true.
  941. */
  942. START_TEST(test_wfc_undeclared_entity_with_external_subset_standalone) {
  943. const char *text =
  944. "<?xml version='1.0' encoding='us-ascii' standalone='yes'?>\n"
  945. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  946. "<doc>&entity;</doc>";
  947. char foo_text[] =
  948. "<!ELEMENT doc (#PCDATA)*>";
  949. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  950. XML_SetUserData(parser, foo_text);
  951. XML_SetExternalEntityRefHandler(parser, external_entity_loader);
  952. expect_failure(text,
  953. XML_ERROR_UNDEFINED_ENTITY,
  954. "Parser did not report undefined entity (external DTD).");
  955. }
  956. END_TEST
  957. /* Test that no error is reported for unknown entities if we have read
  958. an external subset, and standalone is false.
  959. */
  960. START_TEST(test_wfc_undeclared_entity_with_external_subset) {
  961. const char *text =
  962. "<?xml version='1.0' encoding='us-ascii'?>\n"
  963. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  964. "<doc>&entity;</doc>";
  965. char foo_text[] =
  966. "<!ELEMENT doc (#PCDATA)*>";
  967. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  968. XML_SetUserData(parser, foo_text);
  969. XML_SetExternalEntityRefHandler(parser, external_entity_loader);
  970. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  971. xml_failure(parser);
  972. }
  973. END_TEST
  974. /* Test that an error is reported if our NotStandalone handler fails */
  975. static int XMLCALL
  976. reject_not_standalone_handler(void *UNUSED_P(userData))
  977. {
  978. return XML_STATUS_ERROR;
  979. }
  980. START_TEST(test_not_standalone_handler_reject)
  981. {
  982. const char *text =
  983. "<?xml version='1.0' encoding='us-ascii'?>\n"
  984. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  985. "<doc>&entity;</doc>";
  986. char foo_text[] =
  987. "<!ELEMENT doc (#PCDATA)*>";
  988. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  989. XML_SetUserData(parser, foo_text);
  990. XML_SetExternalEntityRefHandler(parser, external_entity_loader);
  991. XML_SetNotStandaloneHandler(parser, reject_not_standalone_handler);
  992. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
  993. fail("NotStandalone handler failed to reject");
  994. }
  995. END_TEST
  996. /* Test that no error is reported if our NotStandalone handler succeeds */
  997. static int XMLCALL
  998. accept_not_standalone_handler(void *UNUSED_P(userData))
  999. {
  1000. return XML_STATUS_OK;
  1001. }
  1002. START_TEST(test_not_standalone_handler_accept)
  1003. {
  1004. const char *text =
  1005. "<?xml version='1.0' encoding='us-ascii'?>\n"
  1006. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  1007. "<doc>&entity;</doc>";
  1008. char foo_text[] =
  1009. "<!ELEMENT doc (#PCDATA)*>";
  1010. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1011. XML_SetUserData(parser, foo_text);
  1012. XML_SetExternalEntityRefHandler(parser, external_entity_loader);
  1013. XML_SetNotStandaloneHandler(parser, accept_not_standalone_handler);
  1014. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  1015. xml_failure(parser);
  1016. }
  1017. END_TEST
  1018. START_TEST(test_wfc_no_recursive_entity_refs)
  1019. {
  1020. const char *text =
  1021. "<!DOCTYPE doc [\n"
  1022. " <!ENTITY entity '&#38;entity;'>\n"
  1023. "]>\n"
  1024. "<doc>&entity;</doc>";
  1025. expect_failure(text,
  1026. XML_ERROR_RECURSIVE_ENTITY_REF,
  1027. "Parser did not report recursive entity reference.");
  1028. }
  1029. END_TEST
  1030. /* Regression test for SF bug #483514. */
  1031. START_TEST(test_dtd_default_handling)
  1032. {
  1033. const char *text =
  1034. "<!DOCTYPE doc [\n"
  1035. "<!ENTITY e SYSTEM 'http://xml.libexpat.org/e'>\n"
  1036. "<!NOTATION n SYSTEM 'http://xml.libexpat.org/n'>\n"
  1037. "<!ELEMENT doc EMPTY>\n"
  1038. "<!ATTLIST doc a CDATA #IMPLIED>\n"
  1039. "<?pi in dtd?>\n"
  1040. "<!--comment in dtd-->\n"
  1041. "]><doc/>";
  1042. XML_SetDefaultHandler(parser, accumulate_characters);
  1043. XML_SetStartDoctypeDeclHandler(parser, dummy_start_doctype_handler);
  1044. XML_SetEndDoctypeDeclHandler(parser, dummy_end_doctype_handler);
  1045. XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
  1046. XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
  1047. XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
  1048. XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
  1049. XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
  1050. XML_SetCommentHandler(parser, dummy_comment_handler);
  1051. XML_SetStartCdataSectionHandler(parser, dummy_start_cdata_handler);
  1052. XML_SetEndCdataSectionHandler(parser, dummy_end_cdata_handler);
  1053. run_character_check(text, "\n\n\n\n\n\n\n<doc/>");
  1054. }
  1055. END_TEST
  1056. /* See related SF bug #673791.
  1057. When namespace processing is enabled, setting the namespace URI for
  1058. a prefix is not allowed; this test ensures that it *is* allowed
  1059. when namespace processing is not enabled.
  1060. (See Namespaces in XML, section 2.)
  1061. */
  1062. START_TEST(test_empty_ns_without_namespaces)
  1063. {
  1064. const char *text =
  1065. "<doc xmlns:prefix='http://www.example.com/'>\n"
  1066. " <e xmlns:prefix=''/>\n"
  1067. "</doc>";
  1068. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  1069. xml_failure(parser);
  1070. }
  1071. END_TEST
  1072. /* Regression test for SF bug #824420.
  1073. Checks that an xmlns:prefix attribute set in an attribute's default
  1074. value isn't misinterpreted.
  1075. */
  1076. START_TEST(test_ns_in_attribute_default_without_namespaces)
  1077. {
  1078. const char *text =
  1079. "<!DOCTYPE e:element [\n"
  1080. " <!ATTLIST e:element\n"
  1081. " xmlns:e CDATA 'http://example.com/'>\n"
  1082. " ]>\n"
  1083. "<e:element/>";
  1084. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  1085. xml_failure(parser);
  1086. }
  1087. END_TEST
  1088. static const char *long_character_data_text =
  1089. "<?xml version='1.0' encoding='iso-8859-1'?><s>"
  1090. "012345678901234567890123456789012345678901234567890123456789"
  1091. "012345678901234567890123456789012345678901234567890123456789"
  1092. "012345678901234567890123456789012345678901234567890123456789"
  1093. "012345678901234567890123456789012345678901234567890123456789"
  1094. "012345678901234567890123456789012345678901234567890123456789"
  1095. "012345678901234567890123456789012345678901234567890123456789"
  1096. "012345678901234567890123456789012345678901234567890123456789"
  1097. "012345678901234567890123456789012345678901234567890123456789"
  1098. "012345678901234567890123456789012345678901234567890123456789"
  1099. "012345678901234567890123456789012345678901234567890123456789"
  1100. "012345678901234567890123456789012345678901234567890123456789"
  1101. "012345678901234567890123456789012345678901234567890123456789"
  1102. "012345678901234567890123456789012345678901234567890123456789"
  1103. "012345678901234567890123456789012345678901234567890123456789"
  1104. "012345678901234567890123456789012345678901234567890123456789"
  1105. "012345678901234567890123456789012345678901234567890123456789"
  1106. "012345678901234567890123456789012345678901234567890123456789"
  1107. "012345678901234567890123456789012345678901234567890123456789"
  1108. "012345678901234567890123456789012345678901234567890123456789"
  1109. "012345678901234567890123456789012345678901234567890123456789"
  1110. "</s>";
  1111. static XML_Bool resumable = XML_FALSE;
  1112. static void
  1113. clearing_aborting_character_handler(void *UNUSED_P(userData),
  1114. const XML_Char *UNUSED_P(s), int UNUSED_P(len))
  1115. {
  1116. XML_StopParser(parser, resumable);
  1117. XML_SetCharacterDataHandler(parser, NULL);
  1118. }
  1119. /* Regression test for SF bug #1515266: missing check of stopped
  1120. parser in doContext() 'for' loop. */
  1121. START_TEST(test_stop_parser_between_char_data_calls)
  1122. {
  1123. /* The sample data must be big enough that there are two calls to
  1124. the character data handler from within the inner "for" loop of
  1125. the XML_TOK_DATA_CHARS case in doContent(), and the character
  1126. handler must stop the parser and clear the character data
  1127. handler.
  1128. */
  1129. const char *text = long_character_data_text;
  1130. XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
  1131. resumable = XML_FALSE;
  1132. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
  1133. xml_failure(parser);
  1134. if (XML_GetErrorCode(parser) != XML_ERROR_ABORTED)
  1135. xml_failure(parser);
  1136. }
  1137. END_TEST
  1138. /* Regression test for SF bug #1515266: missing check of stopped
  1139. parser in doContext() 'for' loop. */
  1140. START_TEST(test_suspend_parser_between_char_data_calls)
  1141. {
  1142. /* The sample data must be big enough that there are two calls to
  1143. the character data handler from within the inner "for" loop of
  1144. the XML_TOK_DATA_CHARS case in doContent(), and the character
  1145. handler must stop the parser and clear the character data
  1146. handler.
  1147. */
  1148. const char *text = long_character_data_text;
  1149. XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
  1150. resumable = XML_TRUE;
  1151. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_SUSPENDED)
  1152. xml_failure(parser);
  1153. if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
  1154. xml_failure(parser);
  1155. /* Try parsing directly */
  1156. if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
  1157. fail("Attempt to continue parse while suspended not faulted");
  1158. if (XML_GetErrorCode(parser) != XML_ERROR_SUSPENDED)
  1159. fail("Suspended parse not faulted with correct error");
  1160. }
  1161. END_TEST
  1162. static XML_Bool abortable = XML_FALSE;
  1163. static void
  1164. parser_stop_character_handler(void *UNUSED_P(userData),
  1165. const XML_Char *UNUSED_P(s),
  1166. int UNUSED_P(len))
  1167. {
  1168. XML_StopParser(parser, resumable);
  1169. XML_SetCharacterDataHandler(parser, NULL);
  1170. if (!resumable) {
  1171. /* Check that aborting an aborted parser is faulted */
  1172. if (XML_StopParser(parser, XML_FALSE) != XML_STATUS_ERROR)
  1173. fail("Aborting aborted parser not faulted");
  1174. if (XML_GetErrorCode(parser) != XML_ERROR_FINISHED)
  1175. xml_failure(parser);
  1176. } else if (abortable) {
  1177. /* Check that aborting a suspended parser works */
  1178. if (XML_StopParser(parser, XML_FALSE) == XML_STATUS_ERROR)
  1179. xml_failure(parser);
  1180. } else {
  1181. /* Check that suspending a suspended parser works */
  1182. if (XML_StopParser(parser, XML_TRUE) != XML_STATUS_ERROR)
  1183. fail("Suspending suspended parser not faulted");
  1184. if (XML_GetErrorCode(parser) != XML_ERROR_SUSPENDED)
  1185. xml_failure(parser);
  1186. }
  1187. }
  1188. /* Test repeated calls to XML_StopParser are handled correctly */
  1189. START_TEST(test_repeated_stop_parser_between_char_data_calls)
  1190. {
  1191. const char *text = long_character_data_text;
  1192. XML_SetCharacterDataHandler(parser, parser_stop_character_handler);
  1193. resumable = XML_FALSE;
  1194. abortable = XML_FALSE;
  1195. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
  1196. XML_TRUE) != XML_STATUS_ERROR)
  1197. fail("Failed to double-stop parser");
  1198. XML_ParserReset(parser, NULL);
  1199. XML_SetCharacterDataHandler(parser, parser_stop_character_handler);
  1200. resumable = XML_TRUE;
  1201. abortable = XML_FALSE;
  1202. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
  1203. XML_TRUE) != XML_STATUS_SUSPENDED)
  1204. fail("Failed to double-suspend parser");
  1205. XML_ParserReset(parser, NULL);
  1206. XML_SetCharacterDataHandler(parser, parser_stop_character_handler);
  1207. resumable = XML_TRUE;
  1208. abortable = XML_TRUE;
  1209. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
  1210. XML_TRUE) != XML_STATUS_ERROR)
  1211. fail("Failed to suspend-abort parser");
  1212. }
  1213. END_TEST
  1214. START_TEST(test_good_cdata_ascii)
  1215. {
  1216. const char *text = "<a><![CDATA[<greeting>Hello, world!</greeting>]]></a>";
  1217. const char *expected = "<greeting>Hello, world!</greeting>";
  1218. CharData storage;
  1219. CharData_Init(&storage);
  1220. XML_SetUserData(parser, &storage);
  1221. XML_SetCharacterDataHandler(parser, accumulate_characters);
  1222. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  1223. xml_failure(parser);
  1224. CharData_CheckXMLChars(&storage, expected);
  1225. }
  1226. END_TEST
  1227. START_TEST(test_good_cdata_utf16)
  1228. {
  1229. /* Test data is:
  1230. * <?xml version='1.0' encoding='utf-16'?>
  1231. * <a><![CDATA[hello]]></a>
  1232. */
  1233. const char text[] =
  1234. "\0<\0?\0x\0m\0l\0"
  1235. " \0v\0e\0r\0s\0i\0o\0n\0=\0'\0\x31\0.\0\x30\0'\0"
  1236. " \0e\0n\0c\0o\0d\0i\0n\0g\0=\0'\0u\0t\0f\0-\0""1\0""6\0'"
  1237. "\0?\0>\0\n"
  1238. "\0<\0a\0>\0<\0!\0[\0C\0D\0A\0T\0A\0[\0h\0e\0l\0l\0o\0]\0]\0>\0<\0/\0a\0>";
  1239. const char *expected = "hello";
  1240. CharData storage;
  1241. CharData_Init(&storage);
  1242. XML_SetUserData(parser, &storage);
  1243. XML_SetCharacterDataHandler(parser, accumulate_characters);
  1244. if (_XML_Parse_SINGLE_BYTES(parser, text, sizeof(text) - 1, XML_TRUE) == XML_STATUS_ERROR)
  1245. xml_failure(parser);
  1246. CharData_CheckXMLChars(&storage, expected);
  1247. }
  1248. END_TEST
  1249. START_TEST(test_bad_cdata)
  1250. {
  1251. struct CaseData {
  1252. const char *text;
  1253. enum XML_Error expectedError;
  1254. };
  1255. struct CaseData cases[] = {
  1256. {"<a><", XML_ERROR_UNCLOSED_TOKEN},
  1257. {"<a><!", XML_ERROR_UNCLOSED_TOKEN},
  1258. {"<a><![", XML_ERROR_UNCLOSED_TOKEN},
  1259. {"<a><![C", XML_ERROR_UNCLOSED_TOKEN},
  1260. {"<a><![CD", XML_ERROR_UNCLOSED_TOKEN},
  1261. {"<a><![CDA", XML_ERROR_UNCLOSED_TOKEN},
  1262. {"<a><![CDAT", XML_ERROR_UNCLOSED_TOKEN},
  1263. {"<a><![CDATA", XML_ERROR_UNCLOSED_TOKEN},
  1264. {"<a><![CDATA[", XML_ERROR_UNCLOSED_CDATA_SECTION},
  1265. {"<a><![CDATA[]", XML_ERROR_UNCLOSED_CDATA_SECTION},
  1266. {"<a><![CDATA[]]", XML_ERROR_UNCLOSED_CDATA_SECTION},
  1267. {"<a><!<a/>", XML_ERROR_INVALID_TOKEN},
  1268. {"<a><![<a/>", XML_ERROR_UNCLOSED_TOKEN}, /* ?! */
  1269. {"<a><![C<a/>", XML_ERROR_UNCLOSED_TOKEN}, /* ?! */
  1270. {"<a><![CD<a/>", XML_ERROR_INVALID_TOKEN},
  1271. {"<a><![CDA<a/>", XML_ERROR_INVALID_TOKEN},
  1272. {"<a><![CDAT<a/>", XML_ERROR_INVALID_TOKEN},
  1273. {"<a><![CDATA<a/>", XML_ERROR_INVALID_TOKEN},
  1274. {"<a><![CDATA[<a/>", XML_ERROR_UNCLOSED_CDATA_SECTION},
  1275. {"<a><![CDATA[]<a/>", XML_ERROR_UNCLOSED_CDATA_SECTION},
  1276. {"<a><![CDATA[]]<a/>", XML_ERROR_UNCLOSED_CDATA_SECTION}
  1277. };
  1278. size_t i = 0;
  1279. for (; i < sizeof(cases) / sizeof(struct CaseData); i++) {
  1280. const enum XML_Status actualStatus = _XML_Parse_SINGLE_BYTES(
  1281. parser, cases[i].text, strlen(cases[i].text), XML_TRUE);
  1282. const enum XML_Error actualError = XML_GetErrorCode(parser);
  1283. assert(actualStatus == XML_STATUS_ERROR);
  1284. if (actualError != cases[i].expectedError) {
  1285. char message[100];
  1286. sprintf(message, "Expected error %d but got error %d for case %u: \"%s\"\n",
  1287. cases[i].expectedError, actualError, (unsigned int)i + 1, cases[i].text);
  1288. fail(message);
  1289. }
  1290. XML_ParserReset(parser, NULL);
  1291. }
  1292. }
  1293. END_TEST
  1294. /* Test memory allocation functions */
  1295. START_TEST(test_memory_allocation)
  1296. {
  1297. char *buffer = (char *)XML_MemMalloc(parser, 256);
  1298. char *p;
  1299. if (buffer == NULL) {
  1300. fail("Allocation failed");
  1301. } else {
  1302. /* Try writing to memory; some OSes try to cheat! */
  1303. buffer[0] = 'T';
  1304. buffer[1] = 'E';
  1305. buffer[2] = 'S';
  1306. buffer[3] = 'T';
  1307. buffer[4] = '\0';
  1308. if (strcmp(buffer, "TEST") != 0) {
  1309. fail("Memory not writable");
  1310. } else {
  1311. p = (char *)XML_MemRealloc(parser, buffer, 512);
  1312. if (p == NULL) {
  1313. fail("Reallocation failed");
  1314. } else {
  1315. /* Write again, just to be sure */
  1316. buffer = p;
  1317. buffer[0] = 'V';
  1318. if (strcmp(buffer, "VEST") != 0) {
  1319. fail("Reallocated memory not writable");
  1320. }
  1321. }
  1322. }
  1323. XML_MemFree(parser, buffer);
  1324. }
  1325. }
  1326. END_TEST
  1327. static void XMLCALL
  1328. record_default_handler(void *userData,
  1329. const XML_Char *UNUSED_P(s),
  1330. int UNUSED_P(len))
  1331. {
  1332. CharData_AppendString((CharData *)userData, "D");
  1333. }
  1334. static void XMLCALL
  1335. record_cdata_handler(void *userData,
  1336. const XML_Char *UNUSED_P(s),
  1337. int UNUSED_P(len))
  1338. {
  1339. CharData_AppendString((CharData *)userData, "C");
  1340. XML_DefaultCurrent(parser);
  1341. }
  1342. static void XMLCALL
  1343. record_cdata_nodefault_handler(void *userData,
  1344. const XML_Char *UNUSED_P(s),
  1345. int UNUSED_P(len))
  1346. {
  1347. CharData_AppendString((CharData *)userData, "c");
  1348. }
  1349. /* Test XML_DefaultCurrent() passes handling on correctly */
  1350. START_TEST(test_default_current)
  1351. {
  1352. const char *text = "<doc>hello</doc>";
  1353. const char *entity_text =
  1354. "<!DOCTYPE doc [\n"
  1355. "<!ENTITY entity '&#37;'>\n"
  1356. "]>\n"
  1357. "<doc>&entity;</doc>";
  1358. CharData storage;
  1359. XML_SetDefaultHandler(parser, record_default_handler);
  1360. XML_SetCharacterDataHandler(parser, record_cdata_handler);
  1361. CharData_Init(&storage);
  1362. XML_SetUserData(parser, &storage);
  1363. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
  1364. XML_TRUE) == XML_STATUS_ERROR)
  1365. xml_failure(parser);
  1366. CharData_CheckString(&storage, "DCDCDCDCDCDD");
  1367. /* Again, without the defaulting */
  1368. XML_ParserReset(parser, NULL);
  1369. XML_SetDefaultHandler(parser, record_default_handler);
  1370. XML_SetCharacterDataHandler(parser, record_cdata_nodefault_handler);
  1371. CharData_Init(&storage);
  1372. XML_SetUserData(parser, &storage);
  1373. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
  1374. XML_TRUE) == XML_STATUS_ERROR)
  1375. xml_failure(parser);
  1376. CharData_CheckString(&storage, "DcccccD");
  1377. /* Now with an internal entity to complicate matters */
  1378. XML_ParserReset(parser, NULL);
  1379. XML_SetDefaultHandler(parser, record_default_handler);
  1380. XML_SetCharacterDataHandler(parser, record_cdata_handler);
  1381. CharData_Init(&storage);
  1382. XML_SetUserData(parser, &storage);
  1383. if (_XML_Parse_SINGLE_BYTES(parser, entity_text, strlen(entity_text),
  1384. XML_TRUE) == XML_STATUS_ERROR)
  1385. xml_failure(parser);
  1386. /* The default handler suppresses the entity */
  1387. CharData_CheckString(&storage, "DDDDDDDDDDDDDDDDDDD");
  1388. /* This time, allow the entity through */
  1389. XML_ParserReset(parser, NULL);
  1390. XML_SetDefaultHandlerExpand(parser, record_default_handler);
  1391. XML_SetCharacterDataHandler(parser, record_cdata_handler);
  1392. CharData_Init(&storage);
  1393. XML_SetUserData(parser, &storage);
  1394. if (_XML_Parse_SINGLE_BYTES(parser, entity_text, strlen(entity_text),
  1395. XML_TRUE) == XML_STATUS_ERROR)
  1396. xml_failure(parser);
  1397. CharData_CheckString(&storage, "DDDDDDDDDDDDDDDDDCDD");
  1398. /* Finally, without passing the cdata to the default handler */
  1399. XML_ParserReset(parser, NULL);
  1400. XML_SetDefaultHandlerExpand(parser, record_default_handler);
  1401. XML_SetCharacterDataHandler(parser, record_cdata_nodefault_handler);
  1402. CharData_Init(&storage);
  1403. XML_SetUserData(parser, &storage);
  1404. if (_XML_Parse_SINGLE_BYTES(parser, entity_text, strlen(entity_text),
  1405. XML_TRUE) == XML_STATUS_ERROR)
  1406. xml_failure(parser);
  1407. CharData_CheckString(&storage, "DDDDDDDDDDDDDDDDDcD");
  1408. }
  1409. END_TEST
  1410. /* Test DTD element parsing code paths */
  1411. START_TEST(test_dtd_elements)
  1412. {
  1413. const char *text =
  1414. "<!DOCTYPE doc [\n"
  1415. "<!ELEMENT doc (chapter)>\n"
  1416. "<!ELEMENT chapter (#PCDATA)>\n"
  1417. "]>\n"
  1418. "<doc><chapter>Wombats are go</chapter></doc>";
  1419. XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
  1420. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
  1421. XML_TRUE) == XML_STATUS_ERROR)
  1422. xml_failure(parser);
  1423. }
  1424. END_TEST
  1425. /* Test foreign DTD handling */
  1426. START_TEST(test_set_foreign_dtd)
  1427. {
  1428. const char *text1 =
  1429. "<?xml version='1.0' encoding='us-ascii'?>\n";
  1430. const char *text2 =
  1431. "<doc>&entity;</doc>";
  1432. char dtd_text[] = "<!ELEMENT doc (#PCDATA)*>";
  1433. /* Check hash salt is passed through too */
  1434. XML_SetHashSalt(parser, 0x12345678);
  1435. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1436. XML_SetUserData(parser, dtd_text);
  1437. XML_SetExternalEntityRefHandler(parser, external_entity_loader);
  1438. if (XML_UseForeignDTD(parser, XML_TRUE) != XML_ERROR_NONE)
  1439. fail("Could not set foreign DTD");
  1440. if (_XML_Parse_SINGLE_BYTES(parser, text1, strlen(text1),
  1441. XML_FALSE) == XML_STATUS_ERROR)
  1442. xml_failure(parser);
  1443. /* Ensure that trying to set the DTD after parsing has started
  1444. * is faulted, even if it's the same setting.
  1445. */
  1446. if (XML_UseForeignDTD(parser, XML_TRUE) == XML_ERROR_NONE)
  1447. fail("Failed to reject late foreign DTD setting");
  1448. /* Ditto for the hash salt */
  1449. if (XML_SetHashSalt(parser, 0x23456789))
  1450. fail("Failed to reject late hash salt change");
  1451. /* Now finish the parse */
  1452. if (_XML_Parse_SINGLE_BYTES(parser, text2, strlen(text2),
  1453. XML_TRUE) == XML_STATUS_ERROR)
  1454. xml_failure(parser);
  1455. }
  1456. END_TEST
  1457. /* Test XML Base is set and unset appropriately */
  1458. START_TEST(test_set_base)
  1459. {
  1460. const XML_Char *old_base;
  1461. const XML_Char *new_base = "/local/file/name.xml";
  1462. old_base = XML_GetBase(parser);
  1463. if (XML_SetBase(parser, new_base) != XML_STATUS_OK)
  1464. fail("Unable to set base");
  1465. if (strcmp(XML_GetBase(parser), new_base) != 0)
  1466. fail("Base setting not correct");
  1467. if (XML_SetBase(parser, NULL) != XML_STATUS_OK)
  1468. fail("Unable to NULL base");
  1469. if (XML_GetBase(parser) != NULL)
  1470. fail("Base setting not nulled");
  1471. XML_SetBase(parser, old_base);
  1472. }
  1473. END_TEST
  1474. /* Test attribute counts, indexing, etc */
  1475. typedef struct attrInfo {
  1476. const char *name;
  1477. const char *value;
  1478. } AttrInfo;
  1479. typedef struct elementInfo {
  1480. const char *name;
  1481. int attr_count;
  1482. const char *id_name;
  1483. AttrInfo *attributes;
  1484. } ElementInfo;
  1485. static void XMLCALL
  1486. counting_start_element_handler(void *userData,
  1487. const XML_Char *name,
  1488. const XML_Char **atts)
  1489. {
  1490. ElementInfo *info = (ElementInfo *)userData;
  1491. AttrInfo *attr;
  1492. int count, id, i;
  1493. while (info->name != NULL) {
  1494. if (!strcmp(name, info->name))
  1495. break;
  1496. info++;
  1497. }
  1498. if (info->name == NULL)
  1499. fail("Element not recognised");
  1500. /* Note attribute count is doubled */
  1501. count = XML_GetSpecifiedAttributeCount(parser);
  1502. if (info->attr_count * 2 != count) {
  1503. fail("Not got expected attribute count");
  1504. return;
  1505. }
  1506. id = XML_GetIdAttributeIndex(parser);
  1507. if (id == -1 && info->id_name != NULL) {
  1508. fail("ID not present");
  1509. return;
  1510. }
  1511. if (id != -1 && strcmp(atts[id], info->id_name)) {
  1512. fail("ID does not have the correct name");
  1513. return;
  1514. }
  1515. for (i = 0; i < info->attr_count; i++) {
  1516. attr = info->attributes;
  1517. while (attr->name != NULL) {
  1518. if (!strcmp(atts[0], attr->name))
  1519. break;
  1520. attr++;
  1521. }
  1522. if (attr->name == NULL) {
  1523. fail("Attribute not recognised");
  1524. return;
  1525. }
  1526. if (strcmp(atts[1], attr->value)) {
  1527. fail("Attribute has wrong value");
  1528. return;
  1529. }
  1530. atts += 2;
  1531. }
  1532. }
  1533. START_TEST(test_attributes)
  1534. {
  1535. const char *text =
  1536. "<!DOCTYPE doc [\n"
  1537. "<!ELEMENT doc (tag)>\n"
  1538. "<!ATTLIST doc id ID #REQUIRED>\n"
  1539. "]>"
  1540. "<doc a='1' id='one' b='2'>"
  1541. "<tag c='3'/>"
  1542. "</doc>";
  1543. AttrInfo doc_info[] = {
  1544. { "a", "1" },
  1545. { "b", "2" },
  1546. { "id", "one" },
  1547. { NULL, NULL }
  1548. };
  1549. AttrInfo tag_info[] = {
  1550. { "c", "3" },
  1551. { NULL, NULL }
  1552. };
  1553. ElementInfo info[] = {
  1554. { "doc", 3, "id", NULL },
  1555. { "tag", 1, NULL, NULL },
  1556. { NULL, 0, NULL, NULL }
  1557. };
  1558. info[0].attributes = doc_info;
  1559. info[1].attributes = tag_info;
  1560. XML_SetStartElementHandler(parser, counting_start_element_handler);
  1561. XML_SetUserData(parser, info);
  1562. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  1563. xml_failure(parser);
  1564. }
  1565. END_TEST
  1566. /* Test reset works correctly in the middle of processing an internal
  1567. * entity. Exercises some obscure code in XML_ParserReset().
  1568. */
  1569. START_TEST(test_reset_in_entity)
  1570. {
  1571. const char *text =
  1572. "<!DOCTYPE doc [\n"
  1573. "<!ENTITY wombat 'wom'>\n"
  1574. "<!ENTITY entity 'hi &wom; there'>\n"
  1575. "]>\n"
  1576. "<doc>&entity;</doc>";
  1577. XML_ParsingStatus status;
  1578. resumable = XML_TRUE;
  1579. XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
  1580. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
  1581. xml_failure(parser);
  1582. XML_GetParsingStatus(parser, &status);
  1583. if (status.parsing != XML_SUSPENDED)
  1584. fail("Parsing status not SUSPENDED");
  1585. XML_ParserReset(parser, NULL);
  1586. XML_GetParsingStatus(parser, &status);
  1587. if (status.parsing != XML_INITIALIZED)
  1588. fail("Parsing status doesn't reset to INITIALIZED");
  1589. }
  1590. END_TEST
  1591. /* Test that resume correctly passes through parse errors */
  1592. START_TEST(test_resume_invalid_parse)
  1593. {
  1594. const char *text = "<doc>Hello</doc"; /* Missing closing wedge */
  1595. resumable = XML_TRUE;
  1596. XML_SetCharacterDataHandler(parser,
  1597. clearing_aborting_character_handler);
  1598. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  1599. xml_failure(parser);
  1600. if (XML_ResumeParser(parser) == XML_STATUS_OK)
  1601. fail("Resumed invalid parse not faulted");
  1602. if (XML_GetErrorCode(parser) != XML_ERROR_UNCLOSED_TOKEN)
  1603. fail("Invalid parse not correctly faulted");
  1604. }
  1605. END_TEST
  1606. /* Test that re-suspended parses are correctly passed through */
  1607. START_TEST(test_resume_resuspended)
  1608. {
  1609. const char *text = "<doc>Hello<meep/>world</doc>";
  1610. resumable = XML_TRUE;
  1611. XML_SetCharacterDataHandler(parser,
  1612. clearing_aborting_character_handler);
  1613. if (XML_Parse(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  1614. xml_failure(parser);
  1615. resumable = XML_TRUE;
  1616. XML_SetCharacterDataHandler(parser,
  1617. clearing_aborting_character_handler);
  1618. if (XML_ResumeParser(parser) != XML_STATUS_SUSPENDED)
  1619. fail("Resumption not suspended");
  1620. /* This one should succeed and finish up */
  1621. if (XML_ResumeParser(parser) != XML_STATUS_OK)
  1622. xml_failure(parser);
  1623. }
  1624. END_TEST
  1625. /* Test resetting a subordinate parser does exactly nothing */
  1626. static int XMLCALL
  1627. external_entity_resetter(XML_Parser parser,
  1628. const XML_Char *context,
  1629. const XML_Char *UNUSED_P(base),
  1630. const XML_Char *UNUSED_P(systemId),
  1631. const XML_Char *UNUSED_P(publicId))
  1632. {
  1633. const char *text = "<!ELEMENT doc (#PCDATA)*>";
  1634. XML_Parser ext_parser;
  1635. XML_ParsingStatus status;
  1636. ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
  1637. if (ext_parser == NULL)
  1638. fail("Could not create external entity parser");
  1639. XML_GetParsingStatus(ext_parser, &status);
  1640. if (status.parsing != XML_INITIALIZED) {
  1641. fail("Parsing status is not INITIALIZED");
  1642. return XML_STATUS_ERROR;
  1643. }
  1644. if (_XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
  1645. XML_TRUE) == XML_STATUS_ERROR) {
  1646. xml_failure(parser);
  1647. return XML_STATUS_ERROR;
  1648. }
  1649. XML_GetParsingStatus(ext_parser, &status);
  1650. if (status.parsing != XML_FINISHED) {
  1651. fail("Parsing status is not FINISHED");
  1652. return XML_STATUS_ERROR;
  1653. }
  1654. /* Check we can't parse here */
  1655. if (XML_Parse(ext_parser, text, strlen(text),
  1656. XML_TRUE) != XML_STATUS_ERROR)
  1657. fail("Parsing when finished not faulted");
  1658. if (XML_GetErrorCode(ext_parser) != XML_ERROR_FINISHED)
  1659. fail("Parsing when finished faulted with wrong code");
  1660. XML_ParserReset(ext_parser, NULL);
  1661. XML_GetParsingStatus(ext_parser, &status);
  1662. if (status.parsing != XML_FINISHED) {
  1663. fail("Parsing status not still FINISHED");
  1664. return XML_STATUS_ERROR;
  1665. }
  1666. return XML_STATUS_OK;
  1667. }
  1668. START_TEST(test_subordinate_reset)
  1669. {
  1670. const char *text =
  1671. "<?xml version='1.0' encoding='us-ascii'?>\n"
  1672. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  1673. "<doc>&entity;</doc>";
  1674. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1675. XML_SetExternalEntityRefHandler(parser, external_entity_resetter);
  1676. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  1677. xml_failure(parser);
  1678. }
  1679. END_TEST
  1680. /* Test suspending a subordinate parser */
  1681. static void XMLCALL
  1682. entity_suspending_decl_handler(void *userData,
  1683. const XML_Char *UNUSED_P(name),
  1684. XML_Content *model)
  1685. {
  1686. XML_Parser ext_parser = (XML_Parser)userData;
  1687. if (XML_StopParser(ext_parser, XML_TRUE) != XML_STATUS_ERROR)
  1688. fail("Attempting to suspend a subordinate parser not faulted");
  1689. if (XML_GetErrorCode(ext_parser) != XML_ERROR_SUSPEND_PE)
  1690. fail("Suspending subordinate parser get wrong code");
  1691. XML_SetElementDeclHandler(ext_parser, NULL);
  1692. XML_FreeContentModel(parser, model);
  1693. }
  1694. static int XMLCALL
  1695. external_entity_suspender(XML_Parser parser,
  1696. const XML_Char *context,
  1697. const XML_Char *UNUSED_P(base),
  1698. const XML_Char *UNUSED_P(systemId),
  1699. const XML_Char *UNUSED_P(publicId))
  1700. {
  1701. const char *text = "<!ELEMENT doc (#PCDATA)*>";
  1702. XML_Parser ext_parser;
  1703. ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
  1704. if (ext_parser == NULL)
  1705. fail("Could not create external entity parser");
  1706. XML_SetElementDeclHandler(ext_parser, entity_suspending_decl_handler);
  1707. XML_SetUserData(ext_parser, ext_parser);
  1708. if (_XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
  1709. XML_TRUE) == XML_STATUS_ERROR) {
  1710. xml_failure(ext_parser);
  1711. return XML_STATUS_ERROR;
  1712. }
  1713. return XML_STATUS_OK;
  1714. }
  1715. START_TEST(test_subordinate_suspend)
  1716. {
  1717. const char *text =
  1718. "<?xml version='1.0' encoding='us-ascii'?>\n"
  1719. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  1720. "<doc>&entity;</doc>";
  1721. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1722. XML_SetExternalEntityRefHandler(parser, external_entity_suspender);
  1723. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  1724. xml_failure(parser);
  1725. }
  1726. END_TEST
  1727. /* Test setting an explicit encoding */
  1728. START_TEST(test_explicit_encoding)
  1729. {
  1730. const char *text1 = "<doc>Hello ";
  1731. const char *text2 = " World</doc>";
  1732. /* First say we are UTF-8 */
  1733. if (XML_SetEncoding(parser, "utf-8") != XML_STATUS_OK)
  1734. fail("Failed to set explicit encoding");
  1735. if (_XML_Parse_SINGLE_BYTES(parser, text1, strlen(text1),
  1736. XML_FALSE) == XML_STATUS_ERROR)
  1737. xml_failure(parser);
  1738. /* Try to switch encodings mid-parse */
  1739. if (XML_SetEncoding(parser, "us-ascii") != XML_STATUS_ERROR)
  1740. fail("Allowed encoding change");
  1741. if (_XML_Parse_SINGLE_BYTES(parser, text2, strlen(text2),
  1742. XML_TRUE) == XML_STATUS_ERROR)
  1743. xml_failure(parser);
  1744. /* Try now the parse is over */
  1745. if (XML_SetEncoding(parser, NULL) != XML_STATUS_OK)
  1746. fail("Failed to unset encoding");
  1747. }
  1748. END_TEST
  1749. /* Test user parameter settings */
  1750. /* Variable holding the expected handler userData */
  1751. static void *handler_data = NULL;
  1752. /* Count of the number of times the comment handler has been invoked */
  1753. static int comment_count = 0;
  1754. /* Count of the number of skipped entities */
  1755. static int skip_count = 0;
  1756. /* Count of the number of times the XML declaration handler is invoked */
  1757. static int xdecl_count = 0;
  1758. static void XMLCALL
  1759. xml_decl_handler(void *userData,
  1760. const XML_Char *UNUSED_P(version),
  1761. const XML_Char *UNUSED_P(encoding),
  1762. int standalone)
  1763. {
  1764. if (userData != handler_data)
  1765. fail("User data (xml decl) not correctly set");
  1766. if (standalone != -1)
  1767. fail("Standalone not show as not present");
  1768. xdecl_count++;
  1769. }
  1770. static void XMLCALL
  1771. param_check_skip_handler(void *userData,
  1772. const XML_Char *UNUSED_P(entityName),
  1773. int UNUSED_P(is_parameter_entity))
  1774. {
  1775. if (userData != handler_data)
  1776. fail("User data (skip) not correctly set");
  1777. skip_count++;
  1778. }
  1779. static void XMLCALL
  1780. data_check_comment_handler(void *userData, const XML_Char *UNUSED_P(data))
  1781. {
  1782. /* Check that the userData passed through is what we expect */
  1783. if (userData != handler_data)
  1784. fail("User data (parser) not correctly set");
  1785. /* Check that the user data in the parser is appropriate */
  1786. if (XML_GetUserData(userData) != (void *)1)
  1787. fail("User data in parser not correctly set");
  1788. comment_count++;
  1789. }
  1790. static int XMLCALL
  1791. external_entity_param_checker(XML_Parser parser,
  1792. const XML_Char *context,
  1793. const XML_Char *UNUSED_P(base),
  1794. const XML_Char *UNUSED_P(systemId),
  1795. const XML_Char *UNUSED_P(publicId))
  1796. {
  1797. const char *text =
  1798. "<!-- Subordinate parser -->\n"
  1799. "<!ELEMENT doc (#PCDATA)*>";
  1800. XML_Parser ext_parser;
  1801. ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
  1802. if (ext_parser == NULL)
  1803. fail("Could not create external entity parser");
  1804. handler_data = ext_parser;
  1805. if (_XML_Parse_SINGLE_BYTES(ext_parser, text, strlen(text),
  1806. XML_TRUE) == XML_STATUS_ERROR) {
  1807. xml_failure(parser);
  1808. return XML_STATUS_ERROR;
  1809. }
  1810. handler_data = parser;
  1811. return XML_STATUS_OK;
  1812. }
  1813. START_TEST(test_user_parameters)
  1814. {
  1815. const char *text =
  1816. "<?xml version='1.0' encoding='us-ascii'?>\n"
  1817. "<!-- Primary parse -->\n"
  1818. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  1819. "<doc>&entity;";
  1820. const char *epilog =
  1821. "<!-- Back to primary parser -->\n"
  1822. "</doc>";
  1823. comment_count = 0;
  1824. skip_count = 0;
  1825. xdecl_count = 0;
  1826. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1827. XML_SetXmlDeclHandler(parser, xml_decl_handler);
  1828. XML_SetExternalEntityRefHandler(parser, external_entity_param_checker);
  1829. XML_SetCommentHandler(parser, data_check_comment_handler);
  1830. XML_SetSkippedEntityHandler(parser, param_check_skip_handler);
  1831. XML_UseParserAsHandlerArg(parser);
  1832. XML_SetUserData(parser, (void *)1);
  1833. handler_data = parser;
  1834. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
  1835. XML_FALSE) == XML_STATUS_ERROR)
  1836. xml_failure(parser);
  1837. if (comment_count != 2)
  1838. fail("Comment handler not invoked enough times");
  1839. /* Ensure we can't change policy mid-parse */
  1840. if (XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_NEVER))
  1841. fail("Changed param entity parsing policy while parsing");
  1842. if (_XML_Parse_SINGLE_BYTES(parser, epilog, strlen(epilog),
  1843. XML_TRUE) == XML_STATUS_ERROR)
  1844. xml_failure(parser);
  1845. if (comment_count != 3)
  1846. fail("Comment handler not invoked enough times");
  1847. if (skip_count != 1)
  1848. fail("Skip handler not invoked enough times");
  1849. if (xdecl_count != 1)
  1850. fail("XML declaration handler not invoked");
  1851. }
  1852. END_TEST
  1853. /* Test that an explicit external entity handler argument replaces
  1854. * the parser as the first argument.
  1855. */
  1856. static int XMLCALL
  1857. external_entity_ref_param_checker(XML_Parser parser,
  1858. const XML_Char *UNUSED_P(context),
  1859. const XML_Char *UNUSED_P(base),
  1860. const XML_Char *UNUSED_P(systemId),
  1861. const XML_Char *UNUSED_P(publicId))
  1862. {
  1863. if ((void *)parser != handler_data)
  1864. fail("External entity ref handler parameter not correct");
  1865. return XML_STATUS_OK;
  1866. }
  1867. START_TEST(test_ext_entity_ref_parameter)
  1868. {
  1869. const char *text =
  1870. "<?xml version='1.0' encoding='us-ascii'?>\n"
  1871. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  1872. "<doc>&entity;</doc>";
  1873. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1874. XML_SetExternalEntityRefHandler(parser,
  1875. external_entity_ref_param_checker);
  1876. /* Set a handler arg that is not NULL and not parser (which is
  1877. * what NULL would cause to be passed.
  1878. */
  1879. XML_SetExternalEntityRefHandlerArg(parser, (void *)text);
  1880. handler_data = (void *)text;
  1881. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
  1882. XML_TRUE) == XML_STATUS_ERROR)
  1883. xml_failure(parser);
  1884. /* Now try again with unset args */
  1885. XML_ParserReset(parser, NULL);
  1886. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  1887. XML_SetExternalEntityRefHandler(parser,
  1888. external_entity_ref_param_checker);
  1889. XML_SetExternalEntityRefHandlerArg(parser, NULL);
  1890. handler_data = (void *)parser;
  1891. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
  1892. XML_TRUE) == XML_STATUS_ERROR)
  1893. xml_failure(parser);
  1894. }
  1895. END_TEST
  1896. /* Test the parsing of an empty string */
  1897. START_TEST(test_empty_parse)
  1898. {
  1899. const char *text = "<doc></doc>";
  1900. const char *partial = "<doc>";
  1901. if (XML_Parse(parser, NULL, 0, XML_FALSE) == XML_STATUS_ERROR)
  1902. fail("Parsing empty string faulted");
  1903. if (XML_Parse(parser, NULL, 0, XML_TRUE) != XML_STATUS_ERROR)
  1904. fail("Parsing final empty string not faulted");
  1905. if (XML_GetErrorCode(parser) != XML_ERROR_NO_ELEMENTS)
  1906. fail("Parsing final empty string faulted for wrong reason");
  1907. /* Now try with valid text before the empty end */
  1908. XML_ParserReset(parser, NULL);
  1909. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
  1910. XML_FALSE) == XML_STATUS_ERROR)
  1911. xml_failure(parser);
  1912. if (XML_Parse(parser, NULL, 0, XML_TRUE) == XML_STATUS_ERROR)
  1913. fail("Parsing final empty string faulted");
  1914. /* Now try with invalid text before the empty end */
  1915. XML_ParserReset(parser, NULL);
  1916. if (_XML_Parse_SINGLE_BYTES(parser, partial, strlen(partial),
  1917. XML_FALSE) == XML_STATUS_ERROR)
  1918. xml_failure(parser);
  1919. if (XML_Parse(parser, NULL, 0, XML_TRUE) != XML_STATUS_ERROR)
  1920. fail("Parsing final incomplete empty string not faulted");
  1921. }
  1922. END_TEST
  1923. /* Test odd corners of the XML_GetBuffer interface */
  1924. START_TEST(test_get_buffer_1)
  1925. {
  1926. const char *text =
  1927. "<documentwitharidiculouslylongelementnametotease" /* 0x030 */
  1928. "aparticularcorneroftheallocationinXML_GetBuffers" /* 0x060 */
  1929. "othatwecanimprovethecoverageyetagain012345678901" /* 0x090 */
  1930. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x0c0 */
  1931. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x0f0 */
  1932. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x120 */
  1933. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x150 */
  1934. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x180 */
  1935. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x1b0 */
  1936. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x1e0 */
  1937. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x210 */
  1938. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x240 */
  1939. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x270 */
  1940. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x2a0 */
  1941. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x2d0 */
  1942. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x300 */
  1943. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x330 */
  1944. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x360 */
  1945. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x390 */
  1946. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x3c0 */
  1947. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x3f0 */
  1948. "123456789abcdef0123456789abcdef0123456789>\n<ef0"; /* 0x420 */
  1949. void *buffer;
  1950. /* Attempt to allocate a negative length buffer */
  1951. if (XML_GetBuffer(parser, -12) != NULL)
  1952. fail("Negative length buffer not failed");
  1953. /* Now get a small buffer and extend it past valid length */
  1954. buffer = XML_GetBuffer(parser, 1536);
  1955. if (buffer == NULL)
  1956. fail("1.5K buffer failed");
  1957. memcpy(buffer, text, strlen(text));
  1958. if (XML_ParseBuffer(parser, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
  1959. xml_failure(parser);
  1960. if (XML_GetBuffer(parser, INT_MAX) != NULL)
  1961. fail("INT_MAX buffer not failed");
  1962. /* Now try extending it a more reasonable but still too large amount */
  1963. if (XML_GetBuffer(parser, INT_MAX - 2049) != NULL)
  1964. fail("INT_MAX- buffer not failed");
  1965. /* Now try extending it a carefully crafted amount */
  1966. if (XML_GetBuffer(parser, 1000) == NULL)
  1967. fail("1000 buffer failed");
  1968. }
  1969. END_TEST
  1970. /* Test more corners of the XML_GetBuffer interface */
  1971. START_TEST(test_get_buffer_2)
  1972. {
  1973. const char *text =
  1974. "<documentwitharidiculouslylongelementnametotease" /* 0x030 */
  1975. "aparticularcorneroftheallocationinXML_GetBuffers" /* 0x060 */
  1976. "othatwecanimprovethecoverageyetagain012345678901" /* 0x090 */
  1977. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x0c0 */
  1978. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x0f0 */
  1979. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x120 */
  1980. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x150 */
  1981. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x180 */
  1982. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x1b0 */
  1983. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x1e0 */
  1984. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x210 */
  1985. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x240 */
  1986. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x270 */
  1987. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x2a0 */
  1988. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x2d0 */
  1989. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x300 */
  1990. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x330 */
  1991. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x360 */
  1992. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x390 */
  1993. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x3c0 */
  1994. "123456789abcdef0123456789abcdef0123456789abcdef0" /* 0x3f0 */
  1995. "123456789abcdef0123456789abcdef0123456789>\n<ef0"; /* 0x420 */
  1996. void *buffer;
  1997. /* Now get a decent buffer */
  1998. buffer = XML_GetBuffer(parser, 1536);
  1999. if (buffer == NULL)
  2000. fail("1.5K buffer failed");
  2001. memcpy(buffer, text, strlen(text));
  2002. if (XML_ParseBuffer(parser, strlen(text), XML_FALSE) == XML_STATUS_ERROR)
  2003. xml_failure(parser);
  2004. /* Extend it, to catch a different code path */
  2005. if (XML_GetBuffer(parser, 1024) == NULL)
  2006. fail("1024 buffer failed");
  2007. }
  2008. END_TEST
  2009. /* Test position information macros */
  2010. START_TEST(test_byte_info_at_end)
  2011. {
  2012. const char *text = "<doc></doc>";
  2013. if (XML_GetCurrentByteIndex(parser) != -1 ||
  2014. XML_GetCurrentByteCount(parser) != 0)
  2015. fail("Byte index/count incorrect at start of parse");
  2016. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
  2017. XML_TRUE) == XML_STATUS_ERROR)
  2018. xml_failure(parser);
  2019. /* At end, the count will be zero and the index the end of string */
  2020. if (XML_GetCurrentByteCount(parser) != 0)
  2021. fail("Terminal byte count incorrect");
  2022. if (XML_GetCurrentByteIndex(parser) != (XML_Index)strlen(text))
  2023. fail("Terminal byte index incorrect");
  2024. }
  2025. END_TEST
  2026. /* Test position information from errors */
  2027. START_TEST(test_byte_info_at_error)
  2028. {
  2029. const char *text = "<doc></wombat></doc>";
  2030. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
  2031. XML_TRUE) == XML_STATUS_OK)
  2032. fail("Syntax error not faulted");
  2033. if (XML_GetCurrentByteCount(parser) != 0)
  2034. fail("Error byte count incorrect");
  2035. if (XML_GetCurrentByteIndex(parser) != 7)
  2036. fail("Error byte index incorrect");
  2037. }
  2038. END_TEST
  2039. /* Test position information in handler */
  2040. static void
  2041. byte_character_handler(void *userData,
  2042. const XML_Char *s,
  2043. int len)
  2044. {
  2045. #ifdef XML_CONTEXT_BYTES
  2046. int offset, size;
  2047. const char *buffer;
  2048. intptr_t buflen = (intptr_t)userData;
  2049. buffer = XML_GetInputContext(parser, &offset, &size);
  2050. if (buffer == NULL)
  2051. fail("Failed to get context buffer");
  2052. if (XML_GetCurrentByteIndex(parser) != offset)
  2053. fail("Character byte index incorrect");
  2054. if (XML_GetCurrentByteCount(parser) != len)
  2055. fail("Character byte count incorrect");
  2056. if (buflen != size)
  2057. fail("Buffer length incorrect");
  2058. if (s != buffer + offset)
  2059. fail("Buffer position incorrect");
  2060. #else
  2061. (void)userData;
  2062. (void)s;
  2063. (void)len;
  2064. #endif
  2065. }
  2066. START_TEST(test_byte_info_at_cdata)
  2067. {
  2068. const char *text = "<doc>Hello</doc>";
  2069. int offset, size;
  2070. /* Check initial context is empty */
  2071. if (XML_GetInputContext(parser, &offset, &size) != NULL)
  2072. fail("Unexpected context at start of parse");
  2073. XML_SetCharacterDataHandler(parser, byte_character_handler);
  2074. XML_SetUserData(parser, (void *)strlen(text));
  2075. if (XML_Parse(parser, text, strlen(text), XML_TRUE) != XML_STATUS_OK)
  2076. xml_failure(parser);
  2077. }
  2078. END_TEST
  2079. /* Regression test that an invalid tag in an external parameter
  2080. * reference in an external DTD is correctly faulted.
  2081. *
  2082. * Only a few specific tags are legal in DTDs ignoring comments and
  2083. * processing instructions, all of which begin with an exclamation
  2084. * mark. "<el/>" is not one of them, so the parser should raise an
  2085. * error on encountering it.
  2086. */
  2087. static int XMLCALL
  2088. external_entity_param(XML_Parser parser,
  2089. const XML_Char *context,
  2090. const XML_Char *UNUSED_P(base),
  2091. const XML_Char *systemId,
  2092. const XML_Char *UNUSED_P(publicId))
  2093. {
  2094. const char *text1 =
  2095. "<!ELEMENT doc EMPTY>\n"
  2096. "<!ENTITY % e1 SYSTEM '004-2.ent'>\n"
  2097. "<!ENTITY % e2 '%e1;'>\n"
  2098. "%e1;\n";
  2099. const char *text2 =
  2100. "<!ELEMENT el EMPTY>\n"
  2101. "<el/>\n";
  2102. XML_Parser ext_parser;
  2103. if (systemId == NULL)
  2104. return XML_STATUS_OK;
  2105. ext_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
  2106. if (ext_parser == NULL)
  2107. fail("Could not create external entity parser");
  2108. if (!strcmp(systemId, "004-1.ent")) {
  2109. if (_XML_Parse_SINGLE_BYTES(ext_parser, text1, strlen(text1),
  2110. XML_TRUE) != XML_STATUS_ERROR)
  2111. fail("Inner DTD with invalid tag not rejected");
  2112. if (XML_GetErrorCode(ext_parser) != XML_ERROR_EXTERNAL_ENTITY_HANDLING)
  2113. xml_failure(ext_parser);
  2114. }
  2115. else if (!strcmp(systemId, "004-2.ent")) {
  2116. if (_XML_Parse_SINGLE_BYTES(ext_parser, text2, strlen(text2),
  2117. XML_TRUE) != XML_STATUS_ERROR)
  2118. fail("Invalid tag in external param not rejected");
  2119. if (XML_GetErrorCode(ext_parser) != XML_ERROR_SYNTAX)
  2120. xml_failure(ext_parser);
  2121. } else {
  2122. fail("Unknown system ID");
  2123. }
  2124. return XML_STATUS_ERROR;
  2125. }
  2126. START_TEST(test_invalid_tag_in_dtd)
  2127. {
  2128. const char *text =
  2129. "<!DOCTYPE doc SYSTEM '004-1.ent'>\n"
  2130. "<doc></doc>\n";
  2131. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  2132. XML_SetExternalEntityRefHandler(parser, external_entity_param);
  2133. expect_failure(text, XML_ERROR_EXTERNAL_ENTITY_HANDLING,
  2134. "Invalid tag IN DTD external param not rejected");
  2135. }
  2136. END_TEST
  2137. /*
  2138. * Namespaces tests.
  2139. */
  2140. static void
  2141. namespace_setup(void)
  2142. {
  2143. parser = XML_ParserCreateNS(NULL, ' ');
  2144. if (parser == NULL)
  2145. fail("Parser not created.");
  2146. }
  2147. static void
  2148. namespace_teardown(void)
  2149. {
  2150. basic_teardown();
  2151. }
  2152. /* Check that an element name and attribute name match the expected values.
  2153. The expected values are passed as an array reference of string pointers
  2154. provided as the userData argument; the first is the expected
  2155. element name, and the second is the expected attribute name.
  2156. */
  2157. static int triplet_count = 0;
  2158. static void XMLCALL
  2159. triplet_start_checker(void *userData, const XML_Char *name,
  2160. const XML_Char **atts)
  2161. {
  2162. char **elemstr = (char **)userData;
  2163. char buffer[1024];
  2164. if (strcmp(elemstr[0], name) != 0) {
  2165. sprintf(buffer, "unexpected start string: '%s'", name);
  2166. fail(buffer);
  2167. }
  2168. if (strcmp(elemstr[1], atts[0]) != 0) {
  2169. sprintf(buffer, "unexpected attribute string: '%s'", atts[0]);
  2170. fail(buffer);
  2171. }
  2172. triplet_count++;
  2173. }
  2174. /* Check that the element name passed to the end-element handler matches
  2175. the expected value. The expected value is passed as the first element
  2176. in an array of strings passed as the userData argument.
  2177. */
  2178. static void XMLCALL
  2179. triplet_end_checker(void *userData, const XML_Char *name)
  2180. {
  2181. char **elemstr = (char **)userData;
  2182. if (strcmp(elemstr[0], name) != 0) {
  2183. char buffer[1024];
  2184. sprintf(buffer, "unexpected end string: '%s'", name);
  2185. fail(buffer);
  2186. }
  2187. triplet_count++;
  2188. }
  2189. START_TEST(test_return_ns_triplet)
  2190. {
  2191. const char *text =
  2192. "<foo:e xmlns:foo='http://expat.sf.net/' bar:a='12'\n"
  2193. " xmlns:bar='http://expat.sf.net/'>";
  2194. const char *epilog = "</foo:e>";
  2195. const char *elemstr[] = {
  2196. "http://expat.sf.net/ e foo",
  2197. "http://expat.sf.net/ a bar"
  2198. };
  2199. XML_SetReturnNSTriplet(parser, XML_TRUE);
  2200. XML_SetUserData(parser, elemstr);
  2201. XML_SetElementHandler(parser, triplet_start_checker,
  2202. triplet_end_checker);
  2203. XML_SetNamespaceDeclHandler(parser,
  2204. dummy_start_namespace_decl_handler,
  2205. dummy_end_namespace_decl_handler);
  2206. triplet_count = 0;
  2207. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
  2208. XML_FALSE) == XML_STATUS_ERROR)
  2209. xml_failure(parser);
  2210. if (triplet_count != 1)
  2211. fail("triplet_start_checker not invoked");
  2212. /* Check that unsetting "return triplets" fails while still parsing */
  2213. XML_SetReturnNSTriplet(parser, XML_FALSE);
  2214. if (_XML_Parse_SINGLE_BYTES(parser, epilog, strlen(epilog),
  2215. XML_TRUE) == XML_STATUS_ERROR)
  2216. xml_failure(parser);
  2217. if (triplet_count != 2)
  2218. fail("triplet_end_checker not invoked");
  2219. }
  2220. END_TEST
  2221. static void XMLCALL
  2222. overwrite_start_checker(void *userData, const XML_Char *name,
  2223. const XML_Char **atts)
  2224. {
  2225. CharData *storage = (CharData *) userData;
  2226. CharData_AppendString(storage, "start ");
  2227. CharData_AppendXMLChars(storage, name, -1);
  2228. while (*atts != NULL) {
  2229. CharData_AppendString(storage, "\nattribute ");
  2230. CharData_AppendXMLChars(storage, *atts, -1);
  2231. atts += 2;
  2232. }
  2233. CharData_AppendString(storage, "\n");
  2234. }
  2235. static void XMLCALL
  2236. overwrite_end_checker(void *userData, const XML_Char *name)
  2237. {
  2238. CharData *storage = (CharData *) userData;
  2239. CharData_AppendString(storage, "end ");
  2240. CharData_AppendXMLChars(storage, name, -1);
  2241. CharData_AppendString(storage, "\n");
  2242. }
  2243. static void
  2244. run_ns_tagname_overwrite_test(const char *text, const char *result)
  2245. {
  2246. CharData storage;
  2247. CharData_Init(&storage);
  2248. XML_SetUserData(parser, &storage);
  2249. XML_SetElementHandler(parser,
  2250. overwrite_start_checker, overwrite_end_checker);
  2251. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  2252. xml_failure(parser);
  2253. CharData_CheckString(&storage, result);
  2254. }
  2255. /* Regression test for SF bug #566334. */
  2256. START_TEST(test_ns_tagname_overwrite)
  2257. {
  2258. const char *text =
  2259. "<n:e xmlns:n='http://xml.libexpat.org/'>\n"
  2260. " <n:f n:attr='foo'/>\n"
  2261. " <n:g n:attr2='bar'/>\n"
  2262. "</n:e>";
  2263. const char *result =
  2264. "start http://xml.libexpat.org/ e\n"
  2265. "start http://xml.libexpat.org/ f\n"
  2266. "attribute http://xml.libexpat.org/ attr\n"
  2267. "end http://xml.libexpat.org/ f\n"
  2268. "start http://xml.libexpat.org/ g\n"
  2269. "attribute http://xml.libexpat.org/ attr2\n"
  2270. "end http://xml.libexpat.org/ g\n"
  2271. "end http://xml.libexpat.org/ e\n";
  2272. run_ns_tagname_overwrite_test(text, result);
  2273. }
  2274. END_TEST
  2275. /* Regression test for SF bug #566334. */
  2276. START_TEST(test_ns_tagname_overwrite_triplet)
  2277. {
  2278. const char *text =
  2279. "<n:e xmlns:n='http://xml.libexpat.org/'>\n"
  2280. " <n:f n:attr='foo'/>\n"
  2281. " <n:g n:attr2='bar'/>\n"
  2282. "</n:e>";
  2283. const char *result =
  2284. "start http://xml.libexpat.org/ e n\n"
  2285. "start http://xml.libexpat.org/ f n\n"
  2286. "attribute http://xml.libexpat.org/ attr n\n"
  2287. "end http://xml.libexpat.org/ f n\n"
  2288. "start http://xml.libexpat.org/ g n\n"
  2289. "attribute http://xml.libexpat.org/ attr2 n\n"
  2290. "end http://xml.libexpat.org/ g n\n"
  2291. "end http://xml.libexpat.org/ e n\n";
  2292. XML_SetReturnNSTriplet(parser, XML_TRUE);
  2293. run_ns_tagname_overwrite_test(text, result);
  2294. }
  2295. END_TEST
  2296. /* Regression test for SF bug #620343. */
  2297. static void XMLCALL
  2298. start_element_fail(void *UNUSED_P(userData),
  2299. const XML_Char *UNUSED_P(name), const XML_Char **UNUSED_P(atts))
  2300. {
  2301. /* We should never get here. */
  2302. fail("should never reach start_element_fail()");
  2303. }
  2304. static void XMLCALL
  2305. start_ns_clearing_start_element(void *userData,
  2306. const XML_Char *UNUSED_P(prefix),
  2307. const XML_Char *UNUSED_P(uri))
  2308. {
  2309. XML_SetStartElementHandler((XML_Parser) userData, NULL);
  2310. }
  2311. START_TEST(test_start_ns_clears_start_element)
  2312. {
  2313. /* This needs to use separate start/end tags; using the empty tag
  2314. syntax doesn't cause the problematic path through Expat to be
  2315. taken.
  2316. */
  2317. const char *text = "<e xmlns='http://xml.libexpat.org/'></e>";
  2318. XML_SetStartElementHandler(parser, start_element_fail);
  2319. XML_SetStartNamespaceDeclHandler(parser, start_ns_clearing_start_element);
  2320. XML_SetEndNamespaceDeclHandler(parser, dummy_end_namespace_decl_handler);
  2321. XML_UseParserAsHandlerArg(parser);
  2322. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  2323. xml_failure(parser);
  2324. }
  2325. END_TEST
  2326. /* Regression test for SF bug #616863. */
  2327. static int XMLCALL
  2328. external_entity_handler(XML_Parser parser,
  2329. const XML_Char *context,
  2330. const XML_Char *UNUSED_P(base),
  2331. const XML_Char *UNUSED_P(systemId),
  2332. const XML_Char *UNUSED_P(publicId))
  2333. {
  2334. intptr_t callno = 1 + (intptr_t)XML_GetUserData(parser);
  2335. const char *text;
  2336. XML_Parser p2;
  2337. if (callno == 1)
  2338. text = ("<!ELEMENT doc (e+)>\n"
  2339. "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
  2340. "<!ELEMENT e EMPTY>\n");
  2341. else
  2342. text = ("<?xml version='1.0' encoding='us-ascii'?>"
  2343. "<e/>");
  2344. XML_SetUserData(parser, (void *) callno);
  2345. p2 = XML_ExternalEntityParserCreate(parser, context, NULL);
  2346. if (_XML_Parse_SINGLE_BYTES(p2, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) {
  2347. xml_failure(p2);
  2348. return 0;
  2349. }
  2350. XML_ParserFree(p2);
  2351. return 1;
  2352. }
  2353. START_TEST(test_default_ns_from_ext_subset_and_ext_ge)
  2354. {
  2355. const char *text =
  2356. "<?xml version='1.0'?>\n"
  2357. "<!DOCTYPE doc SYSTEM 'http://xml.libexpat.org/doc.dtd' [\n"
  2358. " <!ENTITY en SYSTEM 'http://xml.libexpat.org/entity.ent'>\n"
  2359. "]>\n"
  2360. "<doc xmlns='http://xml.libexpat.org/ns1'>\n"
  2361. "&en;\n"
  2362. "</doc>";
  2363. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  2364. XML_SetExternalEntityRefHandler(parser, external_entity_handler);
  2365. /* We actually need to set this handler to tickle this bug. */
  2366. XML_SetStartElementHandler(parser, dummy_start_element);
  2367. XML_SetUserData(parser, NULL);
  2368. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  2369. xml_failure(parser);
  2370. }
  2371. END_TEST
  2372. /* Regression test #1 for SF bug #673791. */
  2373. START_TEST(test_ns_prefix_with_empty_uri_1)
  2374. {
  2375. const char *text =
  2376. "<doc xmlns:prefix='http://xml.libexpat.org/'>\n"
  2377. " <e xmlns:prefix=''/>\n"
  2378. "</doc>";
  2379. expect_failure(text,
  2380. XML_ERROR_UNDECLARING_PREFIX,
  2381. "Did not report re-setting namespace"
  2382. " URI with prefix to ''.");
  2383. }
  2384. END_TEST
  2385. /* Regression test #2 for SF bug #673791. */
  2386. START_TEST(test_ns_prefix_with_empty_uri_2)
  2387. {
  2388. const char *text =
  2389. "<?xml version='1.0'?>\n"
  2390. "<docelem xmlns:pre=''/>";
  2391. expect_failure(text,
  2392. XML_ERROR_UNDECLARING_PREFIX,
  2393. "Did not report setting namespace URI with prefix to ''.");
  2394. }
  2395. END_TEST
  2396. /* Regression test #3 for SF bug #673791. */
  2397. START_TEST(test_ns_prefix_with_empty_uri_3)
  2398. {
  2399. const char *text =
  2400. "<!DOCTYPE doc [\n"
  2401. " <!ELEMENT doc EMPTY>\n"
  2402. " <!ATTLIST doc\n"
  2403. " xmlns:prefix CDATA ''>\n"
  2404. "]>\n"
  2405. "<doc/>";
  2406. expect_failure(text,
  2407. XML_ERROR_UNDECLARING_PREFIX,
  2408. "Didn't report attr default setting NS w/ prefix to ''.");
  2409. }
  2410. END_TEST
  2411. /* Regression test #4 for SF bug #673791. */
  2412. START_TEST(test_ns_prefix_with_empty_uri_4)
  2413. {
  2414. const char *text =
  2415. "<!DOCTYPE doc [\n"
  2416. " <!ELEMENT prefix:doc EMPTY>\n"
  2417. " <!ATTLIST prefix:doc\n"
  2418. " xmlns:prefix CDATA 'http://xml.libexpat.org/'>\n"
  2419. "]>\n"
  2420. "<prefix:doc/>";
  2421. /* Packaged info expected by the end element handler;
  2422. the weird structuring lets us re-use the triplet_end_checker()
  2423. function also used for another test. */
  2424. const char *elemstr[] = {
  2425. "http://xml.libexpat.org/ doc prefix"
  2426. };
  2427. XML_SetReturnNSTriplet(parser, XML_TRUE);
  2428. XML_SetUserData(parser, elemstr);
  2429. XML_SetEndElementHandler(parser, triplet_end_checker);
  2430. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  2431. xml_failure(parser);
  2432. }
  2433. END_TEST
  2434. START_TEST(test_ns_default_with_empty_uri)
  2435. {
  2436. const char *text =
  2437. "<doc xmlns='http://xml.libexpat.org/'>\n"
  2438. " <e xmlns=''/>\n"
  2439. "</doc>";
  2440. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  2441. xml_failure(parser);
  2442. }
  2443. END_TEST
  2444. /* Regression test for SF bug #692964: two prefixes for one namespace. */
  2445. START_TEST(test_ns_duplicate_attrs_diff_prefixes)
  2446. {
  2447. const char *text =
  2448. "<doc xmlns:a='http://xml.libexpat.org/a'\n"
  2449. " xmlns:b='http://xml.libexpat.org/a'\n"
  2450. " a:a='v' b:a='v' />";
  2451. expect_failure(text,
  2452. XML_ERROR_DUPLICATE_ATTRIBUTE,
  2453. "did not report multiple attributes with same URI+name");
  2454. }
  2455. END_TEST
  2456. /* Regression test for SF bug #695401: unbound prefix. */
  2457. START_TEST(test_ns_unbound_prefix_on_attribute)
  2458. {
  2459. const char *text = "<doc a:attr=''/>";
  2460. expect_failure(text,
  2461. XML_ERROR_UNBOUND_PREFIX,
  2462. "did not report unbound prefix on attribute");
  2463. }
  2464. END_TEST
  2465. /* Regression test for SF bug #695401: unbound prefix. */
  2466. START_TEST(test_ns_unbound_prefix_on_element)
  2467. {
  2468. const char *text = "<a:doc/>";
  2469. expect_failure(text,
  2470. XML_ERROR_UNBOUND_PREFIX,
  2471. "did not report unbound prefix on element");
  2472. }
  2473. END_TEST
  2474. /* Test that the parsing status is correctly reset by XML_ParserReset().
  2475. * We usE test_return_ns_triplet() for our example parse to improve
  2476. * coverage of tidying up code executed.
  2477. */
  2478. START_TEST(test_ns_parser_reset)
  2479. {
  2480. XML_ParsingStatus status;
  2481. XML_GetParsingStatus(parser, &status);
  2482. if (status.parsing != XML_INITIALIZED)
  2483. fail("parsing status doesn't start INITIALIZED");
  2484. test_return_ns_triplet();
  2485. XML_GetParsingStatus(parser, &status);
  2486. if (status.parsing != XML_FINISHED)
  2487. fail("parsing status doesn't end FINISHED");
  2488. XML_ParserReset(parser, NULL);
  2489. XML_GetParsingStatus(parser, &status);
  2490. if (status.parsing != XML_INITIALIZED)
  2491. fail("parsing status doesn't reset to INITIALIZED");
  2492. }
  2493. END_TEST
  2494. /* Control variable; the number of times duff_allocator() will successfully allocate */
  2495. static unsigned int allocation_count = 0;
  2496. /* Crocked allocator for allocation failure tests */
  2497. static void *duff_allocator(size_t size)
  2498. {
  2499. if (allocation_count == 0)
  2500. return NULL;
  2501. allocation_count--;
  2502. return malloc(size);
  2503. }
  2504. /* Test that a failure to allocate the parser structure fails gracefully */
  2505. START_TEST(test_misc_alloc_create_parser)
  2506. {
  2507. XML_Memory_Handling_Suite memsuite = { duff_allocator, realloc, free };
  2508. unsigned int i;
  2509. /* Something this simple shouldn't need more than 10 allocations */
  2510. for (i = 0; i < 10; i++)
  2511. {
  2512. allocation_count = i;
  2513. parser = XML_ParserCreate_MM(NULL, &memsuite, NULL);
  2514. if (parser != NULL)
  2515. break;
  2516. }
  2517. if (i == 0)
  2518. fail("Parser unexpectedly ignored failing allocator");
  2519. else if (i == 10)
  2520. fail("Parser not created with allocation count 10");
  2521. }
  2522. END_TEST
  2523. /* Test memory allocation failures for a parser with an encoding */
  2524. START_TEST(test_misc_alloc_create_parser_with_encoding)
  2525. {
  2526. XML_Memory_Handling_Suite memsuite = { duff_allocator, realloc, free };
  2527. unsigned int i;
  2528. /* Try several levels of allocation */
  2529. for (i = 0; i < 10; i++) {
  2530. allocation_count = i;
  2531. parser = XML_ParserCreate_MM("us-ascii", &memsuite, NULL);
  2532. if (parser != NULL)
  2533. break;
  2534. }
  2535. if (i == 0)
  2536. fail("Parser ignored failing allocator");
  2537. else if (i == 10)
  2538. fail("Parser not created with allocation count 10");
  2539. }
  2540. END_TEST
  2541. /* Test the effects of allocation failure in simple namespace parsing.
  2542. * Based on test_ns_default_with_empty_uri()
  2543. */
  2544. START_TEST(test_misc_alloc_ns)
  2545. {
  2546. XML_Memory_Handling_Suite memsuite = { duff_allocator, realloc, free };
  2547. const char *text =
  2548. "<doc xmlns='http://xml.libexpat.org/'>\n"
  2549. " <e xmlns=''/>\n"
  2550. "</doc>";
  2551. unsigned int i;
  2552. int repeated = 0;
  2553. XML_Char ns_sep[2] = { ' ', '\0' };
  2554. allocation_count = 10000;
  2555. parser = XML_ParserCreate_MM(NULL, &memsuite, ns_sep);
  2556. if (parser == NULL) {
  2557. fail("Parser not created");
  2558. } else {
  2559. for (i = 0; i < 10; i++) {
  2560. /* Repeat some tests with the same allocation count to
  2561. * catch cached allocations not freed by XML_ParserReset()
  2562. */
  2563. if (repeated < 2 && i == 3) {
  2564. i--;
  2565. repeated++;
  2566. }
  2567. if (repeated == 2 && i == 5) {
  2568. i = 3;
  2569. repeated++;
  2570. }
  2571. allocation_count = i;
  2572. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
  2573. break;
  2574. XML_ParserReset(parser, NULL);
  2575. }
  2576. if (i == 0)
  2577. fail("Parsing worked despite failing allocations");
  2578. else if (i == 10)
  2579. fail("Parsing failed even at allocation count 10");
  2580. }
  2581. }
  2582. END_TEST
  2583. /* Test XML_ParseBuffer interface with namespace and a dicky allocator */
  2584. START_TEST(test_misc_alloc_ns_parse_buffer)
  2585. {
  2586. XML_Memory_Handling_Suite memsuite = { duff_allocator, realloc, free };
  2587. XML_Char ns_sep[2] = { ' ', '\0' };
  2588. const char *text = "<doc>Hello</doc>";
  2589. void *buffer;
  2590. /* Make sure the basic parser is allocated */
  2591. allocation_count = 10000;
  2592. parser = XML_ParserCreate_MM(NULL, &memsuite, ns_sep);
  2593. if (parser == NULL)
  2594. fail("Parser not created");
  2595. /* Try a parse before the start of the world */
  2596. /* (Exercises new code path) */
  2597. allocation_count = 0;
  2598. if (XML_ParseBuffer(parser, 0, XML_FALSE) != XML_STATUS_ERROR)
  2599. fail("Pre-init XML_ParseBuffer not faulted");
  2600. if (XML_GetErrorCode(parser) != XML_ERROR_NO_MEMORY)
  2601. fail("Pre-init XML_ParseBuffer faulted for wrong reason");
  2602. /* Now with actual memory allocation */
  2603. allocation_count = 10000;
  2604. if (XML_ParseBuffer(parser, 0, XML_FALSE) != XML_STATUS_OK)
  2605. xml_failure(parser);
  2606. /* Check that resuming an unsuspended parser is faulted */
  2607. if (XML_ResumeParser(parser) != XML_STATUS_ERROR)
  2608. fail("Resuming unsuspended parser not faulted");
  2609. if (XML_GetErrorCode(parser) != XML_ERROR_NOT_SUSPENDED)
  2610. xml_failure(parser);
  2611. /* Get the parser into suspended state */
  2612. XML_SetCharacterDataHandler(parser, clearing_aborting_character_handler);
  2613. resumable = XML_TRUE;
  2614. buffer = XML_GetBuffer(parser, strlen(text));
  2615. if (buffer == NULL)
  2616. fail("Could not acquire parse buffer");
  2617. memcpy(buffer, text, strlen(text));
  2618. if (XML_ParseBuffer(parser, strlen(text),
  2619. XML_TRUE) != XML_STATUS_SUSPENDED)
  2620. xml_failure(parser);
  2621. if (XML_GetErrorCode(parser) != XML_ERROR_NONE)
  2622. xml_failure(parser);
  2623. if (XML_ParseBuffer(parser, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
  2624. fail("Suspended XML_ParseBuffer not faulted");
  2625. if (XML_GetErrorCode(parser) != XML_ERROR_SUSPENDED)
  2626. xml_failure(parser);
  2627. if (XML_GetBuffer(parser, strlen(text)) != NULL)
  2628. fail("Suspended XML_GetBuffer not faulted");
  2629. /* Get it going again and complete the world */
  2630. XML_SetCharacterDataHandler(parser, NULL);
  2631. if (XML_ResumeParser(parser) != XML_STATUS_OK)
  2632. xml_failure(parser);
  2633. if (XML_ParseBuffer(parser, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
  2634. fail("Post-finishing XML_ParseBuffer not faulted");
  2635. if (XML_GetErrorCode(parser) != XML_ERROR_FINISHED)
  2636. xml_failure(parser);
  2637. if (XML_GetBuffer(parser, strlen(text)) != NULL)
  2638. fail("Post-finishing XML_GetBuffer not faulted");
  2639. }
  2640. END_TEST
  2641. /* Test that freeing a NULL parser doesn't cause an explosion.
  2642. * (Not actually tested anywhere else)
  2643. */
  2644. START_TEST(test_misc_null_parser)
  2645. {
  2646. XML_ParserFree(NULL);
  2647. }
  2648. END_TEST
  2649. /* Test that XML_ErrorString rejects out-of-range codes */
  2650. START_TEST(test_misc_error_string)
  2651. {
  2652. if (XML_ErrorString((enum XML_Error)-1) != NULL)
  2653. fail("Negative error code not rejected");
  2654. if (XML_ErrorString((enum XML_Error)100) != NULL)
  2655. fail("Large error code not rejected");
  2656. }
  2657. END_TEST
  2658. /* Test the version information is consistent */
  2659. START_TEST(test_misc_version)
  2660. {
  2661. XML_Expat_Version version_struct = XML_ExpatVersionInfo();
  2662. const XML_LChar *version_text = XML_ExpatVersion();
  2663. long value;
  2664. const char *p;
  2665. char *endp;
  2666. if (version_text == NULL)
  2667. fail("Could not obtain version text");
  2668. for (p = version_text; *p != '\0'; p++)
  2669. if (isdigit(*p))
  2670. break;
  2671. if (*p == '\0')
  2672. fail("No numbers in version text");
  2673. value = strtoul(p, &endp, 10);
  2674. if (*endp != '.')
  2675. fail("Major version conversion from text failed");
  2676. if (value != version_struct.major)
  2677. fail("Major version mismatch");
  2678. p = endp + 1;
  2679. value = strtoul(p, &endp, 10);
  2680. if (*endp != '.')
  2681. fail("Minor version conversion from text failed");
  2682. if (value != version_struct.minor)
  2683. fail("Minor version mismatch");
  2684. p = endp + 1;
  2685. value = strtoul(p, &endp, 10);
  2686. if (*endp != '\0')
  2687. fail("Micro version conversion from text failed");
  2688. if (value != version_struct.micro)
  2689. fail("Micro version mismatch");
  2690. }
  2691. END_TEST
  2692. /* Regression test for GitHub Issue #17: memory leak parsing attribute
  2693. * values with mixed bound and unbound namespaces.
  2694. */
  2695. START_TEST(test_misc_attribute_leak)
  2696. {
  2697. const char *text = "<D xmlns:L=\"D\" l:a='' L:a=''/>";
  2698. XML_Memory_Handling_Suite memsuite = {
  2699. tracking_malloc,
  2700. tracking_realloc,
  2701. tracking_free
  2702. };
  2703. parser = XML_ParserCreate_MM("UTF-8", &memsuite, "\n");
  2704. expect_failure(text, XML_ERROR_UNBOUND_PREFIX,
  2705. "Unbound prefixes not found");
  2706. XML_ParserFree(parser);
  2707. /* Prevent the teardown trying to double free */
  2708. parser = NULL;
  2709. if (!tracking_report())
  2710. fail("Memory leak found");
  2711. }
  2712. END_TEST
  2713. static void
  2714. alloc_setup(void)
  2715. {
  2716. XML_Memory_Handling_Suite memsuite = { duff_allocator, realloc, free };
  2717. /* Ensure the parser creation will go through */
  2718. allocation_count = 10000;
  2719. parser = XML_ParserCreate_MM(NULL, &memsuite, NULL);
  2720. if (parser == NULL)
  2721. fail("Parser not created");
  2722. }
  2723. static void
  2724. alloc_teardown(void)
  2725. {
  2726. basic_teardown();
  2727. }
  2728. static int XMLCALL
  2729. external_entity_duff_loader(XML_Parser parser,
  2730. const XML_Char *context,
  2731. const XML_Char *UNUSED_P(base),
  2732. const XML_Char *UNUSED_P(systemId),
  2733. const XML_Char *UNUSED_P(publicId))
  2734. {
  2735. XML_Parser new_parser;
  2736. unsigned int i;
  2737. /* Try a few different allocation levels */
  2738. for (i = 0; i < 10; i++)
  2739. {
  2740. allocation_count = i;
  2741. new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
  2742. if (new_parser != NULL)
  2743. {
  2744. XML_ParserFree(new_parser);
  2745. break;
  2746. }
  2747. }
  2748. if (i == 0)
  2749. fail("External parser creation ignored failing allocator");
  2750. else if (i == 10)
  2751. fail("Extern parser not created with allocation count 10");
  2752. /* Make sure other random allocation doesn't now fail */
  2753. allocation_count = 10000;
  2754. /* Make sure the failure code path is executed too */
  2755. return XML_STATUS_ERROR;
  2756. }
  2757. /* Test that external parser creation running out of memory is
  2758. * correctly reported. Based on the external entity test cases.
  2759. */
  2760. START_TEST(test_alloc_create_external_parser)
  2761. {
  2762. const char *text =
  2763. "<?xml version='1.0' encoding='us-ascii'?>\n"
  2764. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  2765. "<doc>&entity;</doc>";
  2766. char foo_text[] =
  2767. "<!ELEMENT doc (#PCDATA)*>";
  2768. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  2769. XML_SetUserData(parser, foo_text);
  2770. XML_SetExternalEntityRefHandler(parser,
  2771. external_entity_duff_loader);
  2772. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR) {
  2773. fail("External parser allocator returned success incorrectly");
  2774. }
  2775. }
  2776. END_TEST
  2777. static int XMLCALL
  2778. external_entity_null_loader(XML_Parser UNUSED_P(parser),
  2779. const XML_Char *UNUSED_P(context),
  2780. const XML_Char *UNUSED_P(base),
  2781. const XML_Char *UNUSED_P(systemId),
  2782. const XML_Char *UNUSED_P(publicId))
  2783. {
  2784. return XML_STATUS_OK;
  2785. }
  2786. /* More external parser memory allocation testing */
  2787. START_TEST(test_alloc_run_external_parser)
  2788. {
  2789. const char *text =
  2790. "<?xml version='1.0' encoding='us-ascii'?>\n"
  2791. "<!DOCTYPE doc SYSTEM 'foo'>\n"
  2792. "<doc>&entity;</doc>";
  2793. char foo_text[] =
  2794. "<!ELEMENT doc (#PCDATA)*>";
  2795. unsigned int i;
  2796. for (i = 0; i < 10; i++) {
  2797. XML_SetParamEntityParsing(parser,
  2798. XML_PARAM_ENTITY_PARSING_ALWAYS);
  2799. XML_SetUserData(parser, foo_text);
  2800. XML_SetExternalEntityRefHandler(parser,
  2801. external_entity_null_loader);
  2802. allocation_count = i;
  2803. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
  2804. break;
  2805. /* Re-use the parser */
  2806. XML_ParserReset(parser, NULL);
  2807. }
  2808. if (i == 0)
  2809. fail("Parsing ignored failing allocator");
  2810. else if (i == 10)
  2811. fail("Parsing failed with allocation count 10");
  2812. }
  2813. END_TEST
  2814. static int XMLCALL
  2815. external_entity_dbl_handler(XML_Parser parser,
  2816. const XML_Char *context,
  2817. const XML_Char *UNUSED_P(base),
  2818. const XML_Char *UNUSED_P(systemId),
  2819. const XML_Char *UNUSED_P(publicId))
  2820. {
  2821. intptr_t callno = (intptr_t)XML_GetUserData(parser);
  2822. const char *text;
  2823. XML_Parser new_parser;
  2824. int i;
  2825. if (callno == 0) {
  2826. /* First time through, check how many calls to malloc occur */
  2827. text = ("<!ELEMENT doc (e+)>\n"
  2828. "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
  2829. "<!ELEMENT e EMPTY>\n");
  2830. allocation_count = 10000;
  2831. new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
  2832. if (new_parser == NULL) {
  2833. fail("Unable to allocate first external parser");
  2834. return 0;
  2835. }
  2836. /* Stash the number of calls in the user data */
  2837. XML_SetUserData(parser, (void *)(intptr_t)(10000 - allocation_count));
  2838. } else {
  2839. text = ("<?xml version='1.0' encoding='us-ascii'?>"
  2840. "<e/>");
  2841. /* Try at varying levels to exercise more code paths */
  2842. for (i = 0; i < 20; i++) {
  2843. allocation_count = callno + i;
  2844. new_parser = XML_ExternalEntityParserCreate(parser,
  2845. context,
  2846. NULL);
  2847. if (new_parser != NULL)
  2848. break;
  2849. }
  2850. if (i == 0) {
  2851. fail("Second external parser unexpectedly created");
  2852. XML_ParserFree(new_parser);
  2853. return 0;
  2854. }
  2855. else if (i == 20) {
  2856. fail("Second external parser not created");
  2857. return 0;
  2858. }
  2859. }
  2860. allocation_count = 10000;
  2861. if (_XML_Parse_SINGLE_BYTES(new_parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR) {
  2862. xml_failure(new_parser);
  2863. return 0;
  2864. }
  2865. XML_ParserFree(new_parser);
  2866. return 1;
  2867. }
  2868. /* Test that running out of memory in dtdCopy is correctly reported.
  2869. * Based on test_default_ns_from_ext_subset_and_ext_ge()
  2870. */
  2871. START_TEST(test_alloc_dtd_copy_default_atts)
  2872. {
  2873. const char *text =
  2874. "<?xml version='1.0'?>\n"
  2875. "<!DOCTYPE doc SYSTEM 'http://xml.libexpat.org/doc.dtd' [\n"
  2876. " <!ENTITY en SYSTEM 'http://xml.libexpat.org/entity.ent'>\n"
  2877. "]>\n"
  2878. "<doc xmlns='http://xml.libexpat.org/ns1'>\n"
  2879. "&en;\n"
  2880. "</doc>";
  2881. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  2882. XML_SetExternalEntityRefHandler(parser,
  2883. external_entity_dbl_handler);
  2884. XML_SetUserData(parser, NULL);
  2885. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) == XML_STATUS_ERROR)
  2886. xml_failure(parser);
  2887. }
  2888. END_TEST
  2889. static int XMLCALL
  2890. external_entity_dbl_handler_2(XML_Parser parser,
  2891. const XML_Char *context,
  2892. const XML_Char *UNUSED_P(base),
  2893. const XML_Char *UNUSED_P(systemId),
  2894. const XML_Char *UNUSED_P(publicId))
  2895. {
  2896. intptr_t callno = (intptr_t)XML_GetUserData(parser);
  2897. const char *text;
  2898. XML_Parser new_parser;
  2899. int i;
  2900. if (callno == 0) {
  2901. /* Try different allocation levels for whole exercise */
  2902. text = ("<!ELEMENT doc (e+)>\n"
  2903. "<!ATTLIST doc xmlns CDATA #IMPLIED>\n"
  2904. "<!ELEMENT e EMPTY>\n");
  2905. XML_SetUserData(parser, (void *)(intptr_t)1);
  2906. for (i = 0; i < 20; i++) {
  2907. allocation_count = i;
  2908. new_parser = XML_ExternalEntityParserCreate(parser,
  2909. context,
  2910. NULL);
  2911. if (new_parser == NULL)
  2912. continue;
  2913. if (_XML_Parse_SINGLE_BYTES(new_parser, text, strlen(text),
  2914. XML_TRUE) != XML_STATUS_ERROR)
  2915. break;
  2916. XML_ParserFree(new_parser);
  2917. }
  2918. /* Ensure future allocations will be well */
  2919. allocation_count = 10000;
  2920. if (i == 0) {
  2921. fail("first external parser unexpectedly created");
  2922. XML_ParserFree(new_parser);
  2923. return 0;
  2924. }
  2925. else if (i == 20) {
  2926. fail("first external parser not allocated with count 20");
  2927. return 0;
  2928. }
  2929. } else {
  2930. /* Just run through once */
  2931. text = ("<?xml version='1.0' encoding='us-ascii'?>"
  2932. "<e/>");
  2933. allocation_count = 10000;
  2934. new_parser = XML_ExternalEntityParserCreate(parser, context, NULL);
  2935. if (new_parser == NULL) {
  2936. fail("Unable to create second external parser");
  2937. return 0;
  2938. }
  2939. if (_XML_Parse_SINGLE_BYTES(new_parser, text, strlen(text),
  2940. XML_TRUE) == XML_STATUS_ERROR) {
  2941. xml_failure(new_parser);
  2942. XML_ParserFree(new_parser);
  2943. return 0;
  2944. }
  2945. }
  2946. XML_ParserFree(new_parser);
  2947. return 1;
  2948. }
  2949. /* Test more external entity allocation failure paths */
  2950. START_TEST(test_alloc_external_entity)
  2951. {
  2952. const char *text =
  2953. "<?xml version='1.0'?>\n"
  2954. "<!DOCTYPE doc SYSTEM 'http://xml.libexpat.org/doc.dtd' [\n"
  2955. " <!ENTITY en SYSTEM 'http://xml.libexpat.org/entity.ent'>\n"
  2956. "]>\n"
  2957. "<doc xmlns='http://xml.libexpat.org/ns1'>\n"
  2958. "&en;\n"
  2959. "</doc>";
  2960. XML_SetParamEntityParsing(parser, XML_PARAM_ENTITY_PARSING_ALWAYS);
  2961. XML_SetExternalEntityRefHandler(parser,
  2962. external_entity_dbl_handler_2);
  2963. XML_SetUserData(parser, NULL);
  2964. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
  2965. XML_TRUE) == XML_STATUS_ERROR)
  2966. xml_failure(parser);
  2967. }
  2968. END_TEST
  2969. static int XMLCALL
  2970. unknown_released_encoding_handler(void *UNUSED_P(data),
  2971. const XML_Char *encoding,
  2972. XML_Encoding *info)
  2973. {
  2974. if (!strcmp(encoding, "unsupported-encoding")) {
  2975. int i;
  2976. for (i = 0; i < 256; i++)
  2977. info->map[i] = i;
  2978. info->data = NULL;
  2979. info->convert = NULL;
  2980. info->release = dummy_release;
  2981. return XML_STATUS_OK;
  2982. }
  2983. return XML_STATUS_ERROR;
  2984. }
  2985. /* Test the effects of allocation failure in internal entities.
  2986. * Based on test_unknown_encoding_internal_entity
  2987. */
  2988. START_TEST(test_alloc_internal_entity)
  2989. {
  2990. const char *text =
  2991. "<?xml version='1.0' encoding='unsupported-encoding'?>\n"
  2992. "<!DOCTYPE test [<!ENTITY foo 'bar'>]>\n"
  2993. "<test a='&foo;'/>";
  2994. unsigned int i;
  2995. int repeated = 0;
  2996. for (i = 0; i < 10; i++) {
  2997. /* Again, repeat some counts to account for caching */
  2998. if (repeated < 2 && i == 2) {
  2999. i--;
  3000. repeated++;
  3001. }
  3002. XML_SetUnknownEncodingHandler(parser,
  3003. unknown_released_encoding_handler,
  3004. NULL);
  3005. allocation_count = i;
  3006. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text), XML_TRUE) != XML_STATUS_ERROR)
  3007. break;
  3008. XML_ParserReset(parser, NULL);
  3009. }
  3010. if (i == 0)
  3011. fail("Internal entity worked despite failing allocations");
  3012. else if (i == 10)
  3013. fail("Internal entity failed at allocation count 10");
  3014. }
  3015. END_TEST
  3016. /* Test the robustness against allocation failure of element handling
  3017. * Based on test_dtd_default_handling().
  3018. */
  3019. START_TEST(test_alloc_dtd_default_handling)
  3020. {
  3021. const char *text =
  3022. "<!DOCTYPE doc [\n"
  3023. "<!ENTITY e SYSTEM 'http://xml.libexpat.org/e'>\n"
  3024. "<!NOTATION n SYSTEM 'http://xml.libexpat.org/n'>\n"
  3025. "<!ELEMENT doc EMPTY>\n"
  3026. "<!ATTLIST doc a CDATA #IMPLIED>\n"
  3027. "<?pi in dtd?>\n"
  3028. "<!--comment in dtd-->\n"
  3029. "]><doc/>";
  3030. const char *expected = "\n\n\n\n\n\n\n<doc/>";
  3031. CharData storage;
  3032. int i;
  3033. int repeat = 0;
  3034. for (i = 0; i < 10; i++) {
  3035. /* Repeat some counts to catch cached allocations */
  3036. if ((repeat < 4 && i == 2) ||
  3037. (repeat == 4 && i == 3)) {
  3038. i--;
  3039. repeat++;
  3040. }
  3041. allocation_count = i;
  3042. XML_SetDefaultHandler(parser, accumulate_characters);
  3043. XML_SetDoctypeDeclHandler(parser,
  3044. dummy_start_doctype_handler,
  3045. dummy_end_doctype_handler);
  3046. XML_SetEntityDeclHandler(parser, dummy_entity_decl_handler);
  3047. XML_SetNotationDeclHandler(parser, dummy_notation_decl_handler);
  3048. XML_SetElementDeclHandler(parser, dummy_element_decl_handler);
  3049. XML_SetAttlistDeclHandler(parser, dummy_attlist_decl_handler);
  3050. XML_SetProcessingInstructionHandler(parser, dummy_pi_handler);
  3051. XML_SetCommentHandler(parser, dummy_comment_handler);
  3052. XML_SetCdataSectionHandler(parser,
  3053. dummy_start_cdata_handler,
  3054. dummy_end_cdata_handler);
  3055. XML_SetUnparsedEntityDeclHandler(
  3056. parser,
  3057. dummy_unparsed_entity_decl_handler);
  3058. CharData_Init(&storage);
  3059. XML_SetUserData(parser, &storage);
  3060. XML_SetCharacterDataHandler(parser, accumulate_characters);
  3061. if (_XML_Parse_SINGLE_BYTES(parser, text, strlen(text),
  3062. XML_TRUE) != XML_STATUS_ERROR)
  3063. break;
  3064. XML_ParserReset(parser, NULL);
  3065. }
  3066. if (i == 0) {
  3067. fail("Default DTD parsed despite allocation failures");
  3068. } else if (i == 10) {
  3069. fail("Default DTD not parsed with alloc count 10");
  3070. } else {
  3071. CharData_CheckXMLChars(&storage, expected);
  3072. }
  3073. }
  3074. END_TEST
  3075. /* Test robustness of XML_SetEncoding() with a failing allocator */
  3076. START_TEST(test_alloc_explicit_encoding)
  3077. {
  3078. int i;
  3079. for (i = 0; i < 5; i++) {
  3080. allocation_count = i;
  3081. if (XML_SetEncoding(parser, "us-ascii") == XML_STATUS_OK)
  3082. break;
  3083. }
  3084. if (i == 0)
  3085. fail("Encoding set despite failing allocator");
  3086. else if (i == 5)
  3087. fail("Encoding not set at allocation count 5");
  3088. }
  3089. END_TEST
  3090. /* Test robustness of XML_SetBase against a failing allocator */
  3091. START_TEST(test_alloc_set_base)
  3092. {
  3093. const XML_Char *new_base = "/local/file/name.xml";
  3094. int i;
  3095. for (i = 0; i < 5; i++) {
  3096. allocation_count = i;
  3097. if (XML_SetBase(parser, new_base) == XML_STATUS_OK)
  3098. break;
  3099. }
  3100. if (i == 0)
  3101. fail("Base set despite failing allocator");
  3102. else if (i == 5)
  3103. fail("Base not set with allocation count 5");
  3104. }
  3105. END_TEST
  3106. static Suite *
  3107. make_suite(void)
  3108. {
  3109. Suite *s = suite_create("basic");
  3110. TCase *tc_basic = tcase_create("basic tests");
  3111. TCase *tc_namespace = tcase_create("XML namespaces");
  3112. TCase *tc_misc = tcase_create("miscellaneous tests");
  3113. TCase *tc_alloc = tcase_create("allocation tests");
  3114. suite_add_tcase(s, tc_basic);
  3115. tcase_add_checked_fixture(tc_basic, basic_setup, basic_teardown);
  3116. tcase_add_test(tc_basic, test_nul_byte);
  3117. tcase_add_test(tc_basic, test_u0000_char);
  3118. tcase_add_test(tc_basic, test_siphash_self);
  3119. tcase_add_test(tc_basic, test_siphash_spec);
  3120. tcase_add_test(tc_basic, test_bom_utf8);
  3121. tcase_add_test(tc_basic, test_bom_utf16_be);
  3122. tcase_add_test(tc_basic, test_bom_utf16_le);
  3123. tcase_add_test(tc_basic, test_illegal_utf8);
  3124. tcase_add_test(tc_basic, test_utf8_auto_align);
  3125. tcase_add_test(tc_basic, test_utf16);
  3126. tcase_add_test(tc_basic, test_utf16_le_epilog_newline);
  3127. tcase_add_test(tc_basic, test_latin1_umlauts);
  3128. /* Regression test for SF bug #491986. */
  3129. tcase_add_test(tc_basic, test_danish_latin1);
  3130. /* Regression test for SF bug #514281. */
  3131. tcase_add_test(tc_basic, test_french_charref_hexidecimal);
  3132. tcase_add_test(tc_basic, test_french_charref_decimal);
  3133. tcase_add_test(tc_basic, test_french_latin1);
  3134. tcase_add_test(tc_basic, test_french_utf8);
  3135. tcase_add_test(tc_basic, test_utf8_false_rejection);
  3136. tcase_add_test(tc_basic, test_line_number_after_parse);
  3137. tcase_add_test(tc_basic, test_column_number_after_parse);
  3138. tcase_add_test(tc_basic, test_line_and_column_numbers_inside_handlers);
  3139. tcase_add_test(tc_basic, test_line_number_after_error);
  3140. tcase_add_test(tc_basic, test_column_number_after_error);
  3141. tcase_add_test(tc_basic, test_really_long_lines);
  3142. tcase_add_test(tc_basic, test_end_element_events);
  3143. tcase_add_test(tc_basic, test_attr_whitespace_normalization);
  3144. tcase_add_test(tc_basic, test_xmldecl_misplaced);
  3145. tcase_add_test(tc_basic, test_unknown_encoding_internal_entity);
  3146. tcase_add_test(tc_basic, test_unrecognised_encoding_internal_entity);
  3147. tcase_add_test(tc_basic,
  3148. test_wfc_undeclared_entity_unread_external_subset);
  3149. tcase_add_test(tc_basic, test_wfc_undeclared_entity_no_external_subset);
  3150. tcase_add_test(tc_basic, test_wfc_undeclared_entity_standalone);
  3151. tcase_add_test(tc_basic, test_wfc_undeclared_entity_with_external_subset);
  3152. tcase_add_test(tc_basic, test_not_standalone_handler_reject);
  3153. tcase_add_test(tc_basic, test_not_standalone_handler_accept);
  3154. tcase_add_test(tc_basic,
  3155. test_wfc_undeclared_entity_with_external_subset_standalone);
  3156. tcase_add_test(tc_basic, test_wfc_no_recursive_entity_refs);
  3157. tcase_add_test(tc_basic, test_ext_entity_set_encoding);
  3158. tcase_add_test(tc_basic, test_dtd_default_handling);
  3159. tcase_add_test(tc_basic, test_empty_ns_without_namespaces);
  3160. tcase_add_test(tc_basic, test_ns_in_attribute_default_without_namespaces);
  3161. tcase_add_test(tc_basic, test_stop_parser_between_char_data_calls);
  3162. tcase_add_test(tc_basic, test_suspend_parser_between_char_data_calls);
  3163. tcase_add_test(tc_basic, test_repeated_stop_parser_between_char_data_calls);
  3164. tcase_add_test(tc_basic, test_good_cdata_ascii);
  3165. tcase_add_test(tc_basic, test_good_cdata_utf16);
  3166. tcase_add_test(tc_basic, test_bad_cdata);
  3167. tcase_add_test(tc_basic, test_memory_allocation);
  3168. tcase_add_test(tc_basic, test_default_current);
  3169. tcase_add_test(tc_basic, test_dtd_elements);
  3170. tcase_add_test(tc_basic, test_set_foreign_dtd);
  3171. tcase_add_test(tc_basic, test_set_base);
  3172. tcase_add_test(tc_basic, test_attributes);
  3173. tcase_add_test(tc_basic, test_reset_in_entity);
  3174. tcase_add_test(tc_basic, test_resume_invalid_parse);
  3175. tcase_add_test(tc_basic, test_resume_resuspended);
  3176. tcase_add_test(tc_basic, test_subordinate_reset);
  3177. tcase_add_test(tc_basic, test_subordinate_suspend);
  3178. tcase_add_test(tc_basic, test_explicit_encoding);
  3179. tcase_add_test(tc_basic, test_user_parameters);
  3180. tcase_add_test(tc_basic, test_ext_entity_ref_parameter);
  3181. tcase_add_test(tc_basic, test_empty_parse);
  3182. tcase_add_test(tc_basic, test_get_buffer_1);
  3183. tcase_add_test(tc_basic, test_get_buffer_2);
  3184. tcase_add_test(tc_basic, test_byte_info_at_end);
  3185. tcase_add_test(tc_basic, test_byte_info_at_error);
  3186. tcase_add_test(tc_basic, test_byte_info_at_cdata);
  3187. tcase_add_test(tc_basic, test_invalid_tag_in_dtd);
  3188. suite_add_tcase(s, tc_namespace);
  3189. tcase_add_checked_fixture(tc_namespace,
  3190. namespace_setup, namespace_teardown);
  3191. tcase_add_test(tc_namespace, test_return_ns_triplet);
  3192. tcase_add_test(tc_namespace, test_ns_tagname_overwrite);
  3193. tcase_add_test(tc_namespace, test_ns_tagname_overwrite_triplet);
  3194. tcase_add_test(tc_namespace, test_start_ns_clears_start_element);
  3195. tcase_add_test(tc_namespace, test_default_ns_from_ext_subset_and_ext_ge);
  3196. tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_1);
  3197. tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_2);
  3198. tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_3);
  3199. tcase_add_test(tc_namespace, test_ns_prefix_with_empty_uri_4);
  3200. tcase_add_test(tc_namespace, test_ns_default_with_empty_uri);
  3201. tcase_add_test(tc_namespace, test_ns_duplicate_attrs_diff_prefixes);
  3202. tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_attribute);
  3203. tcase_add_test(tc_namespace, test_ns_unbound_prefix_on_element);
  3204. tcase_add_test(tc_namespace, test_ns_parser_reset);
  3205. suite_add_tcase(s, tc_misc);
  3206. tcase_add_checked_fixture(tc_misc, NULL, basic_teardown);
  3207. tcase_add_test(tc_misc, test_misc_alloc_create_parser);
  3208. tcase_add_test(tc_misc, test_misc_alloc_create_parser_with_encoding);
  3209. tcase_add_test(tc_misc, test_misc_alloc_ns);
  3210. tcase_add_test(tc_misc, test_misc_null_parser);
  3211. tcase_add_test(tc_misc, test_misc_alloc_ns_parse_buffer);
  3212. tcase_add_test(tc_misc, test_misc_error_string);
  3213. tcase_add_test(tc_misc, test_misc_version);
  3214. tcase_add_test(tc_misc, test_misc_attribute_leak);
  3215. suite_add_tcase(s, tc_alloc);
  3216. tcase_add_checked_fixture(tc_alloc, alloc_setup, alloc_teardown);
  3217. tcase_add_test(tc_alloc, test_alloc_create_external_parser);
  3218. tcase_add_test(tc_alloc, test_alloc_run_external_parser);
  3219. tcase_add_test(tc_alloc, test_alloc_dtd_copy_default_atts);
  3220. tcase_add_test(tc_alloc, test_alloc_external_entity);
  3221. tcase_add_test(tc_alloc, test_alloc_internal_entity);
  3222. tcase_add_test(tc_alloc, test_alloc_dtd_default_handling);
  3223. tcase_add_test(tc_alloc, test_alloc_explicit_encoding);
  3224. tcase_add_test(tc_alloc, test_alloc_set_base);
  3225. return s;
  3226. }
  3227. int
  3228. main(int argc, char *argv[])
  3229. {
  3230. int i, nf;
  3231. int verbosity = CK_NORMAL;
  3232. Suite *s = make_suite();
  3233. SRunner *sr = srunner_create(s);
  3234. /* run the tests for internal helper functions */
  3235. testhelper_is_whitespace_normalized();
  3236. for (i = 1; i < argc; ++i) {
  3237. char *opt = argv[i];
  3238. if (strcmp(opt, "-v") == 0 || strcmp(opt, "--verbose") == 0)
  3239. verbosity = CK_VERBOSE;
  3240. else if (strcmp(opt, "-q") == 0 || strcmp(opt, "--quiet") == 0)
  3241. verbosity = CK_SILENT;
  3242. else {
  3243. fprintf(stderr, "runtests: unknown option '%s'\n", opt);
  3244. return 2;
  3245. }
  3246. }
  3247. if (verbosity != CK_SILENT)
  3248. printf("Expat version: %s\n", XML_ExpatVersion());
  3249. srunner_run_all(sr, verbosity);
  3250. nf = srunner_ntests_failed(sr);
  3251. srunner_free(sr);
  3252. return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
  3253. }