runtests.c 122 KB

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