parserInternals.c 69 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436
  1. /*
  2. * parserInternals.c : Internal routines (and obsolete ones) needed for the
  3. * XML and HTML parsers.
  4. *
  5. * See Copyright for the status of this software.
  6. *
  7. * daniel@veillard.com
  8. */
  9. #define IN_LIBXML
  10. #include "libxml.h"
  11. #if defined(_WIN32)
  12. #define XML_DIR_SEP '\\'
  13. #else
  14. #define XML_DIR_SEP '/'
  15. #endif
  16. #include <string.h>
  17. #include <ctype.h>
  18. #include <stdlib.h>
  19. #include <libxml/xmlmemory.h>
  20. #include <libxml/tree.h>
  21. #include <libxml/parser.h>
  22. #include <libxml/parserInternals.h>
  23. #include <libxml/entities.h>
  24. #include <libxml/xmlerror.h>
  25. #include <libxml/encoding.h>
  26. #include <libxml/xmlIO.h>
  27. #include <libxml/uri.h>
  28. #include <libxml/dict.h>
  29. #include <libxml/xmlsave.h>
  30. #ifdef LIBXML_CATALOG_ENABLED
  31. #include <libxml/catalog.h>
  32. #endif
  33. #include <libxml/chvalid.h>
  34. #define CUR(ctxt) ctxt->input->cur
  35. #define END(ctxt) ctxt->input->end
  36. #include "private/buf.h"
  37. #include "private/enc.h"
  38. #include "private/error.h"
  39. #include "private/io.h"
  40. #include "private/parser.h"
  41. /*
  42. * XML_MAX_AMPLIFICATION_DEFAULT is the default maximum allowed amplification
  43. * factor of serialized output after entity expansion.
  44. */
  45. #define XML_MAX_AMPLIFICATION_DEFAULT 5
  46. /*
  47. * Various global defaults for parsing
  48. */
  49. /**
  50. * xmlCheckVersion:
  51. * @version: the include version number
  52. *
  53. * check the compiled lib version against the include one.
  54. * This can warn or immediately kill the application
  55. */
  56. void
  57. xmlCheckVersion(int version) {
  58. int myversion = LIBXML_VERSION;
  59. xmlInitParser();
  60. if ((myversion / 10000) != (version / 10000)) {
  61. xmlGenericError(xmlGenericErrorContext,
  62. "Fatal: program compiled against libxml %d using libxml %d\n",
  63. (version / 10000), (myversion / 10000));
  64. fprintf(stderr,
  65. "Fatal: program compiled against libxml %d using libxml %d\n",
  66. (version / 10000), (myversion / 10000));
  67. }
  68. if ((myversion / 100) < (version / 100)) {
  69. xmlGenericError(xmlGenericErrorContext,
  70. "Warning: program compiled against libxml %d using older %d\n",
  71. (version / 100), (myversion / 100));
  72. }
  73. }
  74. /************************************************************************
  75. * *
  76. * Some factorized error routines *
  77. * *
  78. ************************************************************************/
  79. /**
  80. * xmlErrMemory:
  81. * @ctxt: an XML parser context
  82. * @extra: extra information
  83. *
  84. * Handle a redefinition of attribute error
  85. */
  86. void
  87. xmlErrMemory(xmlParserCtxtPtr ctxt, const char *extra)
  88. {
  89. if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  90. (ctxt->instate == XML_PARSER_EOF))
  91. return;
  92. if (ctxt != NULL) {
  93. ctxt->errNo = XML_ERR_NO_MEMORY;
  94. ctxt->instate = XML_PARSER_EOF;
  95. ctxt->disableSAX = 1;
  96. }
  97. if (extra)
  98. __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
  99. XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
  100. NULL, NULL, 0, 0,
  101. "Memory allocation failed : %s\n", extra);
  102. else
  103. __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
  104. XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
  105. NULL, NULL, 0, 0, "Memory allocation failed\n");
  106. }
  107. /**
  108. * __xmlErrEncoding:
  109. * @ctxt: an XML parser context
  110. * @xmlerr: the error number
  111. * @msg: the error message
  112. * @str1: an string info
  113. * @str2: an string info
  114. *
  115. * Handle an encoding error
  116. */
  117. void
  118. __xmlErrEncoding(xmlParserCtxtPtr ctxt, xmlParserErrors xmlerr,
  119. const char *msg, const xmlChar * str1, const xmlChar * str2)
  120. {
  121. if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  122. (ctxt->instate == XML_PARSER_EOF))
  123. return;
  124. if (ctxt != NULL)
  125. ctxt->errNo = xmlerr;
  126. __xmlRaiseError(NULL, NULL, NULL,
  127. ctxt, NULL, XML_FROM_PARSER, xmlerr, XML_ERR_FATAL,
  128. NULL, 0, (const char *) str1, (const char *) str2,
  129. NULL, 0, 0, msg, str1, str2);
  130. if (ctxt != NULL) {
  131. ctxt->wellFormed = 0;
  132. if (ctxt->recovery == 0)
  133. ctxt->disableSAX = 1;
  134. }
  135. }
  136. /**
  137. * xmlErrInternal:
  138. * @ctxt: an XML parser context
  139. * @msg: the error message
  140. * @str: error information
  141. *
  142. * Handle an internal error
  143. */
  144. static void LIBXML_ATTR_FORMAT(2,0)
  145. xmlErrInternal(xmlParserCtxtPtr ctxt, const char *msg, const xmlChar * str)
  146. {
  147. if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  148. (ctxt->instate == XML_PARSER_EOF))
  149. return;
  150. if (ctxt != NULL)
  151. ctxt->errNo = XML_ERR_INTERNAL_ERROR;
  152. __xmlRaiseError(NULL, NULL, NULL,
  153. ctxt, NULL, XML_FROM_PARSER, XML_ERR_INTERNAL_ERROR,
  154. XML_ERR_FATAL, NULL, 0, (const char *) str, NULL, NULL,
  155. 0, 0, msg, str);
  156. if (ctxt != NULL) {
  157. ctxt->wellFormed = 0;
  158. if (ctxt->recovery == 0)
  159. ctxt->disableSAX = 1;
  160. }
  161. }
  162. /**
  163. * xmlFatalErr:
  164. * @ctxt: an XML parser context
  165. * @error: the error number
  166. * @info: extra information string
  167. *
  168. * Handle a fatal parser error, i.e. violating Well-Formedness constraints
  169. */
  170. void
  171. xmlFatalErr(xmlParserCtxtPtr ctxt, xmlParserErrors error, const char *info)
  172. {
  173. const char *errmsg;
  174. if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  175. (ctxt->instate == XML_PARSER_EOF))
  176. return;
  177. switch (error) {
  178. case XML_ERR_INVALID_HEX_CHARREF:
  179. errmsg = "CharRef: invalid hexadecimal value";
  180. break;
  181. case XML_ERR_INVALID_DEC_CHARREF:
  182. errmsg = "CharRef: invalid decimal value";
  183. break;
  184. case XML_ERR_INVALID_CHARREF:
  185. errmsg = "CharRef: invalid value";
  186. break;
  187. case XML_ERR_INTERNAL_ERROR:
  188. errmsg = "internal error";
  189. break;
  190. case XML_ERR_PEREF_AT_EOF:
  191. errmsg = "PEReference at end of document";
  192. break;
  193. case XML_ERR_PEREF_IN_PROLOG:
  194. errmsg = "PEReference in prolog";
  195. break;
  196. case XML_ERR_PEREF_IN_EPILOG:
  197. errmsg = "PEReference in epilog";
  198. break;
  199. case XML_ERR_PEREF_NO_NAME:
  200. errmsg = "PEReference: no name";
  201. break;
  202. case XML_ERR_PEREF_SEMICOL_MISSING:
  203. errmsg = "PEReference: expecting ';'";
  204. break;
  205. case XML_ERR_ENTITY_LOOP:
  206. errmsg = "Detected an entity reference loop";
  207. break;
  208. case XML_ERR_ENTITY_NOT_STARTED:
  209. errmsg = "EntityValue: \" or ' expected";
  210. break;
  211. case XML_ERR_ENTITY_PE_INTERNAL:
  212. errmsg = "PEReferences forbidden in internal subset";
  213. break;
  214. case XML_ERR_ENTITY_NOT_FINISHED:
  215. errmsg = "EntityValue: \" or ' expected";
  216. break;
  217. case XML_ERR_ATTRIBUTE_NOT_STARTED:
  218. errmsg = "AttValue: \" or ' expected";
  219. break;
  220. case XML_ERR_LT_IN_ATTRIBUTE:
  221. errmsg = "Unescaped '<' not allowed in attributes values";
  222. break;
  223. case XML_ERR_LITERAL_NOT_STARTED:
  224. errmsg = "SystemLiteral \" or ' expected";
  225. break;
  226. case XML_ERR_LITERAL_NOT_FINISHED:
  227. errmsg = "Unfinished System or Public ID \" or ' expected";
  228. break;
  229. case XML_ERR_MISPLACED_CDATA_END:
  230. errmsg = "Sequence ']]>' not allowed in content";
  231. break;
  232. case XML_ERR_URI_REQUIRED:
  233. errmsg = "SYSTEM or PUBLIC, the URI is missing";
  234. break;
  235. case XML_ERR_PUBID_REQUIRED:
  236. errmsg = "PUBLIC, the Public Identifier is missing";
  237. break;
  238. case XML_ERR_HYPHEN_IN_COMMENT:
  239. errmsg = "Comment must not contain '--' (double-hyphen)";
  240. break;
  241. case XML_ERR_PI_NOT_STARTED:
  242. errmsg = "xmlParsePI : no target name";
  243. break;
  244. case XML_ERR_RESERVED_XML_NAME:
  245. errmsg = "Invalid PI name";
  246. break;
  247. case XML_ERR_NOTATION_NOT_STARTED:
  248. errmsg = "NOTATION: Name expected here";
  249. break;
  250. case XML_ERR_NOTATION_NOT_FINISHED:
  251. errmsg = "'>' required to close NOTATION declaration";
  252. break;
  253. case XML_ERR_VALUE_REQUIRED:
  254. errmsg = "Entity value required";
  255. break;
  256. case XML_ERR_URI_FRAGMENT:
  257. errmsg = "Fragment not allowed";
  258. break;
  259. case XML_ERR_ATTLIST_NOT_STARTED:
  260. errmsg = "'(' required to start ATTLIST enumeration";
  261. break;
  262. case XML_ERR_NMTOKEN_REQUIRED:
  263. errmsg = "NmToken expected in ATTLIST enumeration";
  264. break;
  265. case XML_ERR_ATTLIST_NOT_FINISHED:
  266. errmsg = "')' required to finish ATTLIST enumeration";
  267. break;
  268. case XML_ERR_MIXED_NOT_STARTED:
  269. errmsg = "MixedContentDecl : '|' or ')*' expected";
  270. break;
  271. case XML_ERR_PCDATA_REQUIRED:
  272. errmsg = "MixedContentDecl : '#PCDATA' expected";
  273. break;
  274. case XML_ERR_ELEMCONTENT_NOT_STARTED:
  275. errmsg = "ContentDecl : Name or '(' expected";
  276. break;
  277. case XML_ERR_ELEMCONTENT_NOT_FINISHED:
  278. errmsg = "ContentDecl : ',' '|' or ')' expected";
  279. break;
  280. case XML_ERR_PEREF_IN_INT_SUBSET:
  281. errmsg =
  282. "PEReference: forbidden within markup decl in internal subset";
  283. break;
  284. case XML_ERR_GT_REQUIRED:
  285. errmsg = "expected '>'";
  286. break;
  287. case XML_ERR_CONDSEC_INVALID:
  288. errmsg = "XML conditional section '[' expected";
  289. break;
  290. case XML_ERR_EXT_SUBSET_NOT_FINISHED:
  291. errmsg = "Content error in the external subset";
  292. break;
  293. case XML_ERR_CONDSEC_INVALID_KEYWORD:
  294. errmsg =
  295. "conditional section INCLUDE or IGNORE keyword expected";
  296. break;
  297. case XML_ERR_CONDSEC_NOT_FINISHED:
  298. errmsg = "XML conditional section not closed";
  299. break;
  300. case XML_ERR_XMLDECL_NOT_STARTED:
  301. errmsg = "Text declaration '<?xml' required";
  302. break;
  303. case XML_ERR_XMLDECL_NOT_FINISHED:
  304. errmsg = "parsing XML declaration: '?>' expected";
  305. break;
  306. case XML_ERR_EXT_ENTITY_STANDALONE:
  307. errmsg = "external parsed entities cannot be standalone";
  308. break;
  309. case XML_ERR_ENTITYREF_SEMICOL_MISSING:
  310. errmsg = "EntityRef: expecting ';'";
  311. break;
  312. case XML_ERR_DOCTYPE_NOT_FINISHED:
  313. errmsg = "DOCTYPE improperly terminated";
  314. break;
  315. case XML_ERR_LTSLASH_REQUIRED:
  316. errmsg = "EndTag: '</' not found";
  317. break;
  318. case XML_ERR_EQUAL_REQUIRED:
  319. errmsg = "expected '='";
  320. break;
  321. case XML_ERR_STRING_NOT_CLOSED:
  322. errmsg = "String not closed expecting \" or '";
  323. break;
  324. case XML_ERR_STRING_NOT_STARTED:
  325. errmsg = "String not started expecting ' or \"";
  326. break;
  327. case XML_ERR_ENCODING_NAME:
  328. errmsg = "Invalid XML encoding name";
  329. break;
  330. case XML_ERR_STANDALONE_VALUE:
  331. errmsg = "standalone accepts only 'yes' or 'no'";
  332. break;
  333. case XML_ERR_DOCUMENT_EMPTY:
  334. errmsg = "Document is empty";
  335. break;
  336. case XML_ERR_DOCUMENT_END:
  337. errmsg = "Extra content at the end of the document";
  338. break;
  339. case XML_ERR_NOT_WELL_BALANCED:
  340. errmsg = "chunk is not well balanced";
  341. break;
  342. case XML_ERR_EXTRA_CONTENT:
  343. errmsg = "extra content at the end of well balanced chunk";
  344. break;
  345. case XML_ERR_VERSION_MISSING:
  346. errmsg = "Malformed declaration expecting version";
  347. break;
  348. case XML_ERR_NAME_TOO_LONG:
  349. errmsg = "Name too long";
  350. break;
  351. case XML_ERR_INVALID_ENCODING:
  352. errmsg = "Invalid bytes in character encoding";
  353. break;
  354. case XML_IO_UNKNOWN:
  355. errmsg = "I/O error";
  356. break;
  357. #if 0
  358. case:
  359. errmsg = "";
  360. break;
  361. #endif
  362. default:
  363. errmsg = "Unregistered error message";
  364. }
  365. if (ctxt != NULL)
  366. ctxt->errNo = error;
  367. if (info == NULL) {
  368. __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
  369. XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s\n",
  370. errmsg);
  371. } else {
  372. __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER, error,
  373. XML_ERR_FATAL, NULL, 0, info, NULL, NULL, 0, 0, "%s: %s\n",
  374. errmsg, info);
  375. }
  376. if (ctxt != NULL) {
  377. ctxt->wellFormed = 0;
  378. if (ctxt->recovery == 0)
  379. ctxt->disableSAX = 1;
  380. }
  381. }
  382. /**
  383. * xmlErrEncodingInt:
  384. * @ctxt: an XML parser context
  385. * @error: the error number
  386. * @msg: the error message
  387. * @val: an integer value
  388. *
  389. * n encoding error
  390. */
  391. static void LIBXML_ATTR_FORMAT(3,0)
  392. xmlErrEncodingInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  393. const char *msg, int val)
  394. {
  395. if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  396. (ctxt->instate == XML_PARSER_EOF))
  397. return;
  398. if (ctxt != NULL)
  399. ctxt->errNo = error;
  400. __xmlRaiseError(NULL, NULL, NULL,
  401. ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
  402. NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
  403. if (ctxt != NULL) {
  404. ctxt->wellFormed = 0;
  405. if (ctxt->recovery == 0)
  406. ctxt->disableSAX = 1;
  407. }
  408. }
  409. /**
  410. * xmlIsLetter:
  411. * @c: an unicode character (int)
  412. *
  413. * Check whether the character is allowed by the production
  414. * [84] Letter ::= BaseChar | Ideographic
  415. *
  416. * Returns 0 if not, non-zero otherwise
  417. */
  418. int
  419. xmlIsLetter(int c) {
  420. return(IS_BASECHAR(c) || IS_IDEOGRAPHIC(c));
  421. }
  422. /************************************************************************
  423. * *
  424. * Input handling functions for progressive parsing *
  425. * *
  426. ************************************************************************/
  427. /* we need to keep enough input to show errors in context */
  428. #define LINE_LEN 80
  429. /**
  430. * xmlHaltParser:
  431. * @ctxt: an XML parser context
  432. *
  433. * Blocks further parser processing don't override error
  434. * for internal use
  435. */
  436. void
  437. xmlHaltParser(xmlParserCtxtPtr ctxt) {
  438. if (ctxt == NULL)
  439. return;
  440. ctxt->instate = XML_PARSER_EOF;
  441. ctxt->disableSAX = 1;
  442. while (ctxt->inputNr > 1)
  443. xmlFreeInputStream(inputPop(ctxt));
  444. if (ctxt->input != NULL) {
  445. /*
  446. * in case there was a specific allocation deallocate before
  447. * overriding base
  448. */
  449. if (ctxt->input->free != NULL) {
  450. ctxt->input->free((xmlChar *) ctxt->input->base);
  451. ctxt->input->free = NULL;
  452. }
  453. if (ctxt->input->buf != NULL) {
  454. xmlFreeParserInputBuffer(ctxt->input->buf);
  455. ctxt->input->buf = NULL;
  456. }
  457. ctxt->input->cur = BAD_CAST"";
  458. ctxt->input->length = 0;
  459. ctxt->input->base = ctxt->input->cur;
  460. ctxt->input->end = ctxt->input->cur;
  461. }
  462. }
  463. /**
  464. * xmlParserInputRead:
  465. * @in: an XML parser input
  466. * @len: an indicative size for the lookahead
  467. *
  468. * DEPRECATED: This function was internal and is deprecated.
  469. *
  470. * Returns -1 as this is an error to use it.
  471. */
  472. int
  473. xmlParserInputRead(xmlParserInputPtr in ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED) {
  474. return(-1);
  475. }
  476. /**
  477. * xmlParserGrow:
  478. * @ctxt: an XML parser context
  479. *
  480. * Grow the input buffer.
  481. *
  482. * Returns the number of bytes read or -1 in case of error.
  483. */
  484. int
  485. xmlParserGrow(xmlParserCtxtPtr ctxt) {
  486. xmlParserInputPtr in = ctxt->input;
  487. xmlParserInputBufferPtr buf = in->buf;
  488. ptrdiff_t curEnd = in->end - in->cur;
  489. ptrdiff_t curBase = in->cur - in->base;
  490. int ret;
  491. if (buf == NULL)
  492. return(0);
  493. /* Don't grow push parser buffer. */
  494. if ((ctxt->progressive) && (ctxt->inputNr <= 1))
  495. return(0);
  496. /* Don't grow memory buffers. */
  497. if ((buf->encoder == NULL) && (buf->readcallback == NULL))
  498. return(0);
  499. if (buf->error != 0)
  500. return(-1);
  501. if (((curEnd > XML_MAX_LOOKUP_LIMIT) ||
  502. (curBase > XML_MAX_LOOKUP_LIMIT)) &&
  503. ((ctxt->options & XML_PARSE_HUGE) == 0)) {
  504. xmlErrMemory(ctxt, "Huge input lookup");
  505. xmlHaltParser(ctxt);
  506. return(-1);
  507. }
  508. if (curEnd >= INPUT_CHUNK)
  509. return(0);
  510. ret = xmlParserInputBufferGrow(buf, INPUT_CHUNK);
  511. xmlBufUpdateInput(buf->buffer, in, curBase);
  512. if (ret < 0) {
  513. xmlFatalErr(ctxt, buf->error, NULL);
  514. /* Buffer contents may be lost in case of memory errors. */
  515. if (buf->error == XML_ERR_NO_MEMORY)
  516. xmlHaltParser(ctxt);
  517. }
  518. return(ret);
  519. }
  520. /**
  521. * xmlParserInputGrow:
  522. * @in: an XML parser input
  523. * @len: an indicative size for the lookahead
  524. *
  525. * DEPRECATED: Don't use.
  526. *
  527. * This function increase the input for the parser. It tries to
  528. * preserve pointers to the input buffer, and keep already read data
  529. *
  530. * Returns the amount of char read, or -1 in case of error, 0 indicate the
  531. * end of this entity
  532. */
  533. int
  534. xmlParserInputGrow(xmlParserInputPtr in, int len) {
  535. int ret;
  536. size_t indx;
  537. if ((in == NULL) || (len < 0)) return(-1);
  538. if (in->buf == NULL) return(-1);
  539. if (in->base == NULL) return(-1);
  540. if (in->cur == NULL) return(-1);
  541. if (in->buf->buffer == NULL) return(-1);
  542. /* Don't grow memory buffers. */
  543. if ((in->buf->encoder == NULL) && (in->buf->readcallback == NULL))
  544. return(0);
  545. indx = in->cur - in->base;
  546. if (xmlBufUse(in->buf->buffer) > (unsigned int) indx + INPUT_CHUNK) {
  547. return(0);
  548. }
  549. ret = xmlParserInputBufferGrow(in->buf, len);
  550. in->base = xmlBufContent(in->buf->buffer);
  551. if (in->base == NULL) {
  552. in->base = BAD_CAST "";
  553. in->cur = in->base;
  554. in->end = in->base;
  555. return(-1);
  556. }
  557. in->cur = in->base + indx;
  558. in->end = xmlBufEnd(in->buf->buffer);
  559. return(ret);
  560. }
  561. /**
  562. * xmlParserShrink:
  563. * @ctxt: an XML parser context
  564. *
  565. * Shrink the input buffer.
  566. */
  567. void
  568. xmlParserShrink(xmlParserCtxtPtr ctxt) {
  569. xmlParserInputPtr in = ctxt->input;
  570. xmlParserInputBufferPtr buf = in->buf;
  571. size_t used;
  572. if (buf == NULL)
  573. return;
  574. /* Don't shrink pull parser memory buffers. */
  575. if (((ctxt->progressive == 0) || (ctxt->inputNr > 1)) &&
  576. (buf->encoder == NULL) &&
  577. (buf->readcallback == NULL))
  578. return;
  579. used = in->cur - in->base;
  580. /*
  581. * Do not shrink on large buffers whose only a tiny fraction
  582. * was consumed
  583. */
  584. if (used > INPUT_CHUNK) {
  585. size_t res = xmlBufShrink(buf->buffer, used - LINE_LEN);
  586. if (res > 0) {
  587. used -= res;
  588. if ((res > ULONG_MAX) ||
  589. (in->consumed > ULONG_MAX - (unsigned long)res))
  590. in->consumed = ULONG_MAX;
  591. else
  592. in->consumed += res;
  593. }
  594. }
  595. xmlBufUpdateInput(buf->buffer, in, used);
  596. }
  597. /**
  598. * xmlParserInputShrink:
  599. * @in: an XML parser input
  600. *
  601. * DEPRECATED: Don't use.
  602. *
  603. * This function removes used input for the parser.
  604. */
  605. void
  606. xmlParserInputShrink(xmlParserInputPtr in) {
  607. size_t used;
  608. size_t ret;
  609. if (in == NULL) return;
  610. if (in->buf == NULL) return;
  611. if (in->base == NULL) return;
  612. if (in->cur == NULL) return;
  613. if (in->buf->buffer == NULL) return;
  614. used = in->cur - in->base;
  615. /*
  616. * Do not shrink on large buffers whose only a tiny fraction
  617. * was consumed
  618. */
  619. if (used > INPUT_CHUNK) {
  620. ret = xmlBufShrink(in->buf->buffer, used - LINE_LEN);
  621. if (ret > 0) {
  622. used -= ret;
  623. if ((ret > ULONG_MAX) ||
  624. (in->consumed > ULONG_MAX - (unsigned long)ret))
  625. in->consumed = ULONG_MAX;
  626. else
  627. in->consumed += ret;
  628. }
  629. }
  630. if (xmlBufUse(in->buf->buffer) <= INPUT_CHUNK) {
  631. xmlParserInputBufferRead(in->buf, 2 * INPUT_CHUNK);
  632. }
  633. in->base = xmlBufContent(in->buf->buffer);
  634. if (in->base == NULL) {
  635. /* TODO: raise error */
  636. in->base = BAD_CAST "";
  637. in->cur = in->base;
  638. in->end = in->base;
  639. return;
  640. }
  641. in->cur = in->base + used;
  642. in->end = xmlBufEnd(in->buf->buffer);
  643. }
  644. /************************************************************************
  645. * *
  646. * UTF8 character input and related functions *
  647. * *
  648. ************************************************************************/
  649. /**
  650. * xmlNextChar:
  651. * @ctxt: the XML parser context
  652. *
  653. * DEPRECATED: Internal function, do not use.
  654. *
  655. * Skip to the next char input char.
  656. */
  657. void
  658. xmlNextChar(xmlParserCtxtPtr ctxt)
  659. {
  660. const unsigned char *cur;
  661. size_t avail;
  662. int c;
  663. if ((ctxt == NULL) || (ctxt->instate == XML_PARSER_EOF) ||
  664. (ctxt->input == NULL))
  665. return;
  666. avail = ctxt->input->end - ctxt->input->cur;
  667. if (avail < INPUT_CHUNK) {
  668. xmlParserGrow(ctxt);
  669. if ((ctxt->instate == XML_PARSER_EOF) ||
  670. (ctxt->input->cur >= ctxt->input->end))
  671. return;
  672. avail = ctxt->input->end - ctxt->input->cur;
  673. }
  674. cur = ctxt->input->cur;
  675. c = *cur;
  676. if (c < 0x80) {
  677. if (c == '\n') {
  678. ctxt->input->cur++;
  679. ctxt->input->line++;
  680. ctxt->input->col = 1;
  681. } else if (c == '\r') {
  682. /*
  683. * 2.11 End-of-Line Handling
  684. * the literal two-character sequence "#xD#xA" or a standalone
  685. * literal #xD, an XML processor must pass to the application
  686. * the single character #xA.
  687. */
  688. ctxt->input->cur += ((cur[1] == '\n') ? 2 : 1);
  689. ctxt->input->line++;
  690. ctxt->input->col = 1;
  691. return;
  692. } else {
  693. ctxt->input->cur++;
  694. ctxt->input->col++;
  695. }
  696. } else {
  697. ctxt->input->col++;
  698. if ((avail < 2) || (cur[1] & 0xc0) != 0x80)
  699. goto encoding_error;
  700. if (c < 0xe0) {
  701. /* 2-byte code */
  702. if (c < 0xc2)
  703. goto encoding_error;
  704. ctxt->input->cur += 2;
  705. } else {
  706. unsigned int val = (c << 8) | cur[1];
  707. if ((avail < 3) || (cur[2] & 0xc0) != 0x80)
  708. goto encoding_error;
  709. if (c < 0xf0) {
  710. /* 3-byte code */
  711. if ((val < 0xe0a0) || ((val >= 0xeda0) && (val < 0xee00)))
  712. goto encoding_error;
  713. ctxt->input->cur += 3;
  714. } else {
  715. if ((avail < 4) || ((cur[3] & 0xc0) != 0x80))
  716. goto encoding_error;
  717. /* 4-byte code */
  718. if ((val < 0xf090) || (val >= 0xf490))
  719. goto encoding_error;
  720. ctxt->input->cur += 4;
  721. }
  722. }
  723. }
  724. return;
  725. encoding_error:
  726. /* Only report the first error */
  727. if ((ctxt->input->flags & XML_INPUT_ENCODING_ERROR) == 0) {
  728. if ((ctxt == NULL) || (ctxt->input == NULL) ||
  729. (ctxt->input->end - ctxt->input->cur < 4)) {
  730. __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
  731. "Input is not proper UTF-8, indicate encoding !\n",
  732. NULL, NULL);
  733. } else {
  734. char buffer[150];
  735. snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
  736. ctxt->input->cur[0], ctxt->input->cur[1],
  737. ctxt->input->cur[2], ctxt->input->cur[3]);
  738. __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
  739. "Input is not proper UTF-8, indicate encoding !\n%s",
  740. BAD_CAST buffer, NULL);
  741. }
  742. ctxt->input->flags |= XML_INPUT_ENCODING_ERROR;
  743. }
  744. ctxt->input->cur++;
  745. return;
  746. }
  747. /**
  748. * xmlCurrentChar:
  749. * @ctxt: the XML parser context
  750. * @len: pointer to the length of the char read
  751. *
  752. * DEPRECATED: Internal function, do not use.
  753. *
  754. * The current char value, if using UTF-8 this may actually span multiple
  755. * bytes in the input buffer. Implement the end of line normalization:
  756. * 2.11 End-of-Line Handling
  757. * Wherever an external parsed entity or the literal entity value
  758. * of an internal parsed entity contains either the literal two-character
  759. * sequence "#xD#xA" or a standalone literal #xD, an XML processor
  760. * must pass to the application the single character #xA.
  761. * This behavior can conveniently be produced by normalizing all
  762. * line breaks to #xA on input, before parsing.)
  763. *
  764. * Returns the current char value and its length
  765. */
  766. int
  767. xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
  768. const unsigned char *cur;
  769. size_t avail;
  770. int c;
  771. if ((ctxt == NULL) || (len == NULL) || (ctxt->input == NULL)) return(0);
  772. if (ctxt->instate == XML_PARSER_EOF)
  773. return(0);
  774. avail = ctxt->input->end - ctxt->input->cur;
  775. if (avail < INPUT_CHUNK) {
  776. xmlParserGrow(ctxt);
  777. if (ctxt->instate == XML_PARSER_EOF)
  778. return(0);
  779. avail = ctxt->input->end - ctxt->input->cur;
  780. }
  781. cur = ctxt->input->cur;
  782. c = *cur;
  783. if (c < 0x80) {
  784. /* 1-byte code */
  785. if (c < 0x20) {
  786. /*
  787. * 2.11 End-of-Line Handling
  788. * the literal two-character sequence "#xD#xA" or a standalone
  789. * literal #xD, an XML processor must pass to the application
  790. * the single character #xA.
  791. */
  792. if (c == '\r') {
  793. /*
  794. * TODO: This function shouldn't change the 'cur' pointer
  795. * as side effect, but the NEXTL macro in parser.c relies
  796. * on this behavior when incrementing line numbers.
  797. */
  798. if (cur[1] == '\n')
  799. ctxt->input->cur++;
  800. *len = 1;
  801. c = '\n';
  802. } else if (c == 0) {
  803. if (ctxt->input->cur >= ctxt->input->end) {
  804. *len = 0;
  805. } else {
  806. *len = 1;
  807. /*
  808. * TODO: Null bytes should be handled by callers,
  809. * but this can be tricky.
  810. */
  811. xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
  812. "Char 0x0 out of allowed range\n", c);
  813. }
  814. } else {
  815. *len = 1;
  816. }
  817. } else {
  818. *len = 1;
  819. }
  820. return(c);
  821. } else {
  822. int val;
  823. if (avail < 2)
  824. goto incomplete_sequence;
  825. if ((cur[1] & 0xc0) != 0x80)
  826. goto encoding_error;
  827. if (c < 0xe0) {
  828. /* 2-byte code */
  829. if (c < 0xc2)
  830. goto encoding_error;
  831. val = (c & 0x1f) << 6;
  832. val |= cur[1] & 0x3f;
  833. *len = 2;
  834. } else {
  835. if (avail < 3)
  836. goto incomplete_sequence;
  837. if ((cur[2] & 0xc0) != 0x80)
  838. goto encoding_error;
  839. if (c < 0xf0) {
  840. /* 3-byte code */
  841. val = (c & 0xf) << 12;
  842. val |= (cur[1] & 0x3f) << 6;
  843. val |= cur[2] & 0x3f;
  844. if ((val < 0x800) || ((val >= 0xd800) && (val < 0xe000)))
  845. goto encoding_error;
  846. *len = 3;
  847. } else {
  848. if (avail < 4)
  849. goto incomplete_sequence;
  850. if ((cur[3] & 0xc0) != 0x80)
  851. goto encoding_error;
  852. /* 4-byte code */
  853. val = (c & 0x0f) << 18;
  854. val |= (cur[1] & 0x3f) << 12;
  855. val |= (cur[2] & 0x3f) << 6;
  856. val |= cur[3] & 0x3f;
  857. if ((val < 0x10000) || (val >= 0x110000))
  858. goto encoding_error;
  859. *len = 4;
  860. }
  861. }
  862. return(val);
  863. }
  864. encoding_error:
  865. /* Only report the first error */
  866. if ((ctxt->input->flags & XML_INPUT_ENCODING_ERROR) == 0) {
  867. if (ctxt->input->end - ctxt->input->cur < 4) {
  868. __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
  869. "Input is not proper UTF-8, indicate encoding !\n",
  870. NULL, NULL);
  871. } else {
  872. char buffer[150];
  873. snprintf(&buffer[0], 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
  874. ctxt->input->cur[0], ctxt->input->cur[1],
  875. ctxt->input->cur[2], ctxt->input->cur[3]);
  876. __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
  877. "Input is not proper UTF-8, indicate encoding !\n%s",
  878. BAD_CAST buffer, NULL);
  879. }
  880. ctxt->input->flags |= XML_INPUT_ENCODING_ERROR;
  881. }
  882. *len = 1;
  883. return(0xFFFD); /* U+FFFD Replacement Character */
  884. incomplete_sequence:
  885. /*
  886. * An encoding problem may arise from a truncated input buffer
  887. * splitting a character in the middle. In that case do not raise
  888. * an error but return 0. This should only happen when push parsing
  889. * char data.
  890. */
  891. *len = 0;
  892. return(0);
  893. }
  894. /**
  895. * xmlStringCurrentChar:
  896. * @ctxt: the XML parser context
  897. * @cur: pointer to the beginning of the char
  898. * @len: pointer to the length of the char read
  899. *
  900. * DEPRECATED: Internal function, do not use.
  901. *
  902. * The current char value, if using UTF-8 this may actually span multiple
  903. * bytes in the input buffer.
  904. *
  905. * Returns the current char value and its length
  906. */
  907. int
  908. xmlStringCurrentChar(xmlParserCtxtPtr ctxt ATTRIBUTE_UNUSED,
  909. const xmlChar *cur, int *len) {
  910. int c;
  911. if ((cur == NULL) || (len == NULL))
  912. return(0);
  913. /* cur is zero-terminated, so we can lie about its length. */
  914. *len = 4;
  915. c = xmlGetUTF8Char(cur, len);
  916. return((c < 0) ? 0 : c);
  917. }
  918. /**
  919. * xmlCopyCharMultiByte:
  920. * @out: pointer to an array of xmlChar
  921. * @val: the char value
  922. *
  923. * append the char value in the array
  924. *
  925. * Returns the number of xmlChar written
  926. */
  927. int
  928. xmlCopyCharMultiByte(xmlChar *out, int val) {
  929. if ((out == NULL) || (val < 0)) return(0);
  930. /*
  931. * We are supposed to handle UTF8, check it's valid
  932. * From rfc2044: encoding of the Unicode values on UTF-8:
  933. *
  934. * UCS-4 range (hex.) UTF-8 octet sequence (binary)
  935. * 0000 0000-0000 007F 0xxxxxxx
  936. * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
  937. * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
  938. */
  939. if (val >= 0x80) {
  940. xmlChar *savedout = out;
  941. int bits;
  942. if (val < 0x800) { *out++= (val >> 6) | 0xC0; bits= 0; }
  943. else if (val < 0x10000) { *out++= (val >> 12) | 0xE0; bits= 6;}
  944. else if (val < 0x110000) { *out++= (val >> 18) | 0xF0; bits= 12; }
  945. else {
  946. xmlErrEncodingInt(NULL, XML_ERR_INVALID_CHAR,
  947. "Internal error, xmlCopyCharMultiByte 0x%X out of bound\n",
  948. val);
  949. return(0);
  950. }
  951. for ( ; bits >= 0; bits-= 6)
  952. *out++= ((val >> bits) & 0x3F) | 0x80 ;
  953. return (out - savedout);
  954. }
  955. *out = val;
  956. return 1;
  957. }
  958. /**
  959. * xmlCopyChar:
  960. * @len: Ignored, compatibility
  961. * @out: pointer to an array of xmlChar
  962. * @val: the char value
  963. *
  964. * append the char value in the array
  965. *
  966. * Returns the number of xmlChar written
  967. */
  968. int
  969. xmlCopyChar(int len ATTRIBUTE_UNUSED, xmlChar *out, int val) {
  970. if ((out == NULL) || (val < 0)) return(0);
  971. /* the len parameter is ignored */
  972. if (val >= 0x80) {
  973. return(xmlCopyCharMultiByte (out, val));
  974. }
  975. *out = val;
  976. return 1;
  977. }
  978. /************************************************************************
  979. * *
  980. * Commodity functions to switch encodings *
  981. * *
  982. ************************************************************************/
  983. static xmlCharEncodingHandlerPtr
  984. xmlDetectEBCDIC(xmlParserInputPtr input) {
  985. xmlChar out[200];
  986. xmlCharEncodingHandlerPtr handler;
  987. int inlen, outlen, res, i;
  988. /*
  989. * To detect the EBCDIC code page, we convert the first 200 bytes
  990. * to EBCDIC-US and try to find the encoding declaration.
  991. */
  992. handler = xmlGetCharEncodingHandler(XML_CHAR_ENCODING_EBCDIC);
  993. if (handler == NULL)
  994. return(NULL);
  995. outlen = sizeof(out) - 1;
  996. inlen = input->end - input->cur;
  997. res = xmlEncInputChunk(handler, out, &outlen, input->cur, &inlen);
  998. if (res < 0)
  999. return(handler);
  1000. out[outlen] = 0;
  1001. for (i = 0; i < outlen; i++) {
  1002. if (out[i] == '>')
  1003. break;
  1004. if ((out[i] == 'e') &&
  1005. (xmlStrncmp(out + i, BAD_CAST "encoding", 8) == 0)) {
  1006. int start, cur, quote;
  1007. i += 8;
  1008. while (IS_BLANK_CH(out[i]))
  1009. i += 1;
  1010. if (out[i++] != '=')
  1011. break;
  1012. while (IS_BLANK_CH(out[i]))
  1013. i += 1;
  1014. quote = out[i++];
  1015. if ((quote != '\'') && (quote != '"'))
  1016. break;
  1017. start = i;
  1018. cur = out[i];
  1019. while (((cur >= 'a') && (cur <= 'z')) ||
  1020. ((cur >= 'A') && (cur <= 'Z')) ||
  1021. ((cur >= '0') && (cur <= '9')) ||
  1022. (cur == '.') || (cur == '_') ||
  1023. (cur == '-'))
  1024. cur = out[++i];
  1025. if (cur != quote)
  1026. break;
  1027. out[i] = 0;
  1028. xmlCharEncCloseFunc(handler);
  1029. return(xmlFindCharEncodingHandler((char *) out + start));
  1030. }
  1031. }
  1032. /*
  1033. * ICU handlers are stateful, so we have to recreate them.
  1034. */
  1035. xmlCharEncCloseFunc(handler);
  1036. return(xmlGetCharEncodingHandler(XML_CHAR_ENCODING_EBCDIC));
  1037. }
  1038. /**
  1039. * xmlSwitchEncoding:
  1040. * @ctxt: the parser context
  1041. * @enc: the encoding value (number)
  1042. *
  1043. * Use encoding specified by enum to decode input data.
  1044. *
  1045. * This function can be used to enforce the encoding of chunks passed
  1046. * to xmlParseChunk.
  1047. *
  1048. * Returns 0 in case of success, -1 otherwise
  1049. */
  1050. int
  1051. xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
  1052. {
  1053. xmlCharEncodingHandlerPtr handler = NULL;
  1054. int check = 1;
  1055. int ret;
  1056. if ((ctxt == NULL) || (ctxt->input == NULL))
  1057. return(-1);
  1058. switch (enc) {
  1059. case XML_CHAR_ENCODING_NONE:
  1060. case XML_CHAR_ENCODING_UTF8:
  1061. case XML_CHAR_ENCODING_ASCII:
  1062. check = 0;
  1063. break;
  1064. case XML_CHAR_ENCODING_EBCDIC:
  1065. handler = xmlDetectEBCDIC(ctxt->input);
  1066. break;
  1067. default:
  1068. handler = xmlGetCharEncodingHandler(enc);
  1069. break;
  1070. }
  1071. if ((check) && (handler == NULL)) {
  1072. const char *name = xmlGetCharEncodingName(enc);
  1073. __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
  1074. "encoding not supported: %s\n",
  1075. BAD_CAST (name ? name : "<null>"), NULL);
  1076. /*
  1077. * TODO: We could recover from errors in external entities
  1078. * if we didn't stop the parser. But most callers of this
  1079. * function don't check the return value.
  1080. */
  1081. xmlStopParser(ctxt);
  1082. return(-1);
  1083. }
  1084. ret = xmlSwitchInputEncoding(ctxt, ctxt->input, handler);
  1085. if ((ret >= 0) && (enc == XML_CHAR_ENCODING_NONE)) {
  1086. ctxt->input->flags &= ~XML_INPUT_HAS_ENCODING;
  1087. }
  1088. return(ret);
  1089. }
  1090. /**
  1091. * xmlSwitchInputEncoding:
  1092. * @ctxt: the parser context
  1093. * @input: the input stream
  1094. * @handler: the encoding handler
  1095. *
  1096. * DEPRECATED: Internal function, don't use.
  1097. *
  1098. * Use encoding handler to decode input data.
  1099. *
  1100. * Returns 0 in case of success, -1 otherwise
  1101. */
  1102. int
  1103. xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
  1104. xmlCharEncodingHandlerPtr handler)
  1105. {
  1106. int nbchars;
  1107. xmlParserInputBufferPtr in;
  1108. if ((input == NULL) || (input->buf == NULL)) {
  1109. xmlCharEncCloseFunc(handler);
  1110. return (-1);
  1111. }
  1112. in = input->buf;
  1113. input->flags |= XML_INPUT_HAS_ENCODING;
  1114. /*
  1115. * UTF-8 requires no encoding handler.
  1116. */
  1117. if ((handler != NULL) &&
  1118. (xmlStrcasecmp(BAD_CAST handler->name, BAD_CAST "UTF-8") == 0)) {
  1119. xmlCharEncCloseFunc(handler);
  1120. handler = NULL;
  1121. }
  1122. if (in->encoder == handler)
  1123. return (0);
  1124. if (in->encoder != NULL) {
  1125. /*
  1126. * Switching encodings during parsing is a really bad idea,
  1127. * but Chromium can switch between ISO-8859-1 and UTF-16 before
  1128. * separate calls to xmlParseChunk.
  1129. *
  1130. * TODO: We should check whether the "raw" input buffer is empty and
  1131. * convert the old content using the old encoder.
  1132. */
  1133. xmlCharEncCloseFunc(in->encoder);
  1134. in->encoder = handler;
  1135. return (0);
  1136. }
  1137. in->encoder = handler;
  1138. /*
  1139. * Is there already some content down the pipe to convert ?
  1140. */
  1141. if (xmlBufIsEmpty(in->buffer) == 0) {
  1142. size_t processed;
  1143. /*
  1144. * Shrink the current input buffer.
  1145. * Move it as the raw buffer and create a new input buffer
  1146. */
  1147. processed = input->cur - input->base;
  1148. xmlBufShrink(in->buffer, processed);
  1149. input->consumed += processed;
  1150. in->raw = in->buffer;
  1151. in->buffer = xmlBufCreate();
  1152. in->rawconsumed = processed;
  1153. nbchars = xmlCharEncInput(in);
  1154. xmlBufResetInput(in->buffer, input);
  1155. if (nbchars < 0) {
  1156. /* TODO: This could be an out of memory or an encoding error. */
  1157. xmlErrInternal(ctxt,
  1158. "switching encoding: encoder error\n",
  1159. NULL);
  1160. xmlHaltParser(ctxt);
  1161. return (-1);
  1162. }
  1163. }
  1164. return (0);
  1165. }
  1166. /**
  1167. * xmlSwitchToEncoding:
  1168. * @ctxt: the parser context
  1169. * @handler: the encoding handler
  1170. *
  1171. * Use encoding handler to decode input data.
  1172. *
  1173. * This function can be used to enforce the encoding of chunks passed
  1174. * to xmlParseChunk.
  1175. *
  1176. * Returns 0 in case of success, -1 otherwise
  1177. */
  1178. int
  1179. xmlSwitchToEncoding(xmlParserCtxtPtr ctxt, xmlCharEncodingHandlerPtr handler)
  1180. {
  1181. if (ctxt == NULL)
  1182. return(-1);
  1183. return(xmlSwitchInputEncoding(ctxt, ctxt->input, handler));
  1184. }
  1185. /**
  1186. * xmlDetectEncoding:
  1187. * @ctxt: the parser context
  1188. *
  1189. * Handle optional BOM, detect and switch to encoding.
  1190. *
  1191. * Assumes that there are at least four bytes in the input buffer.
  1192. */
  1193. void
  1194. xmlDetectEncoding(xmlParserCtxtPtr ctxt) {
  1195. const xmlChar *in;
  1196. xmlCharEncoding enc;
  1197. int bomSize;
  1198. int autoFlag = 0;
  1199. if (xmlParserGrow(ctxt) < 0)
  1200. return;
  1201. in = ctxt->input->cur;
  1202. if (ctxt->input->end - in < 4)
  1203. return;
  1204. if (ctxt->input->flags & XML_INPUT_HAS_ENCODING) {
  1205. /*
  1206. * If the encoding was already set, only skip the BOM which was
  1207. * possibly decoded to UTF-8.
  1208. */
  1209. if ((in[0] == 0xEF) && (in[1] == 0xBB) && (in[2] == 0xBF)) {
  1210. ctxt->input->cur += 3;
  1211. }
  1212. return;
  1213. }
  1214. enc = XML_CHAR_ENCODING_NONE;
  1215. bomSize = 0;
  1216. switch (in[0]) {
  1217. case 0x00:
  1218. if ((in[1] == 0x00) && (in[2] == 0x00) && (in[3] == 0x3C)) {
  1219. enc = XML_CHAR_ENCODING_UCS4BE;
  1220. autoFlag = XML_INPUT_AUTO_OTHER;
  1221. } else if ((in[1] == 0x3C) && (in[2] == 0x00) && (in[3] == 0x3F)) {
  1222. enc = XML_CHAR_ENCODING_UTF16BE;
  1223. autoFlag = XML_INPUT_AUTO_UTF16BE;
  1224. }
  1225. break;
  1226. case 0x3C:
  1227. if (in[1] == 0x00) {
  1228. if ((in[2] == 0x00) && (in[3] == 0x00)) {
  1229. enc = XML_CHAR_ENCODING_UCS4LE;
  1230. autoFlag = XML_INPUT_AUTO_OTHER;
  1231. } else if ((in[2] == 0x3F) && (in[3] == 0x00)) {
  1232. enc = XML_CHAR_ENCODING_UTF16LE;
  1233. autoFlag = XML_INPUT_AUTO_UTF16LE;
  1234. }
  1235. }
  1236. break;
  1237. case 0x4C:
  1238. if ((in[1] == 0x6F) && (in[2] == 0xA7) && (in[3] == 0x94)) {
  1239. enc = XML_CHAR_ENCODING_EBCDIC;
  1240. autoFlag = XML_INPUT_AUTO_OTHER;
  1241. }
  1242. break;
  1243. case 0xEF:
  1244. if ((in[1] == 0xBB) && (in[2] == 0xBF)) {
  1245. enc = XML_CHAR_ENCODING_UTF8;
  1246. autoFlag = XML_INPUT_AUTO_UTF8;
  1247. bomSize = 3;
  1248. }
  1249. break;
  1250. case 0xFE:
  1251. if (in[1] == 0xFF) {
  1252. enc = XML_CHAR_ENCODING_UTF16BE;
  1253. autoFlag = XML_INPUT_AUTO_UTF16BE;
  1254. bomSize = 2;
  1255. }
  1256. break;
  1257. case 0xFF:
  1258. if (in[1] == 0xFE) {
  1259. enc = XML_CHAR_ENCODING_UTF16LE;
  1260. autoFlag = XML_INPUT_AUTO_UTF16LE;
  1261. bomSize = 2;
  1262. }
  1263. break;
  1264. }
  1265. if (bomSize > 0) {
  1266. ctxt->input->cur += bomSize;
  1267. }
  1268. if (enc != XML_CHAR_ENCODING_NONE) {
  1269. ctxt->input->flags |= autoFlag;
  1270. xmlSwitchEncoding(ctxt, enc);
  1271. }
  1272. }
  1273. /**
  1274. * xmlSetDeclaredEncoding:
  1275. * @ctxt: the parser context
  1276. * @encoding: declared encoding
  1277. *
  1278. * Set the encoding from a declaration in the document.
  1279. *
  1280. * If no encoding was set yet, switch the encoding. Otherwise, only warn
  1281. * about encoding mismatches.
  1282. *
  1283. * Takes ownership of 'encoding'.
  1284. */
  1285. void
  1286. xmlSetDeclaredEncoding(xmlParserCtxtPtr ctxt, xmlChar *encoding) {
  1287. if (ctxt->encoding != NULL)
  1288. xmlFree((xmlChar *) ctxt->encoding);
  1289. ctxt->encoding = encoding;
  1290. if (((ctxt->input->flags & XML_INPUT_HAS_ENCODING) == 0) &&
  1291. ((ctxt->options & XML_PARSE_IGNORE_ENC) == 0)) {
  1292. xmlCharEncodingHandlerPtr handler;
  1293. handler = xmlFindCharEncodingHandler((const char *) encoding);
  1294. if (handler == NULL) {
  1295. __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
  1296. "Unsupported encoding: %s\n",
  1297. encoding, NULL);
  1298. return;
  1299. }
  1300. xmlSwitchToEncoding(ctxt, handler);
  1301. ctxt->input->flags |= XML_INPUT_USES_ENC_DECL;
  1302. } else if (ctxt->input->flags & XML_INPUT_AUTO_ENCODING) {
  1303. static const char *allowedUTF8[] = {
  1304. "UTF-8", "UTF8", NULL
  1305. };
  1306. static const char *allowedUTF16LE[] = {
  1307. "UTF-16", "UTF-16LE", "UTF16", NULL
  1308. };
  1309. static const char *allowedUTF16BE[] = {
  1310. "UTF-16", "UTF-16BE", "UTF16", NULL
  1311. };
  1312. const char **allowed = NULL;
  1313. const char *autoEnc = NULL;
  1314. switch (ctxt->input->flags & XML_INPUT_AUTO_ENCODING) {
  1315. case XML_INPUT_AUTO_UTF8:
  1316. allowed = allowedUTF8;
  1317. autoEnc = "UTF-8";
  1318. break;
  1319. case XML_INPUT_AUTO_UTF16LE:
  1320. allowed = allowedUTF16LE;
  1321. autoEnc = "UTF-16LE";
  1322. break;
  1323. case XML_INPUT_AUTO_UTF16BE:
  1324. allowed = allowedUTF16BE;
  1325. autoEnc = "UTF-16BE";
  1326. break;
  1327. }
  1328. if (allowed != NULL) {
  1329. const char **p;
  1330. int match = 0;
  1331. for (p = allowed; *p != NULL; p++) {
  1332. if (xmlStrcasecmp(encoding, BAD_CAST *p) == 0) {
  1333. match = 1;
  1334. break;
  1335. }
  1336. }
  1337. if (match == 0) {
  1338. xmlWarningMsg(ctxt, XML_WAR_ENCODING_MISMATCH,
  1339. "Encoding '%s' doesn't match "
  1340. "auto-detected '%s'\n",
  1341. encoding, BAD_CAST autoEnc);
  1342. }
  1343. }
  1344. }
  1345. }
  1346. /**
  1347. * xmlGetActualEncoding:
  1348. * @ctxt: the parser context
  1349. *
  1350. * Returns the actual used to parse the document. This can differ from
  1351. * the declared encoding.
  1352. */
  1353. const xmlChar *
  1354. xmlGetActualEncoding(xmlParserCtxtPtr ctxt) {
  1355. const xmlChar *encoding = NULL;
  1356. if ((ctxt->input->flags & XML_INPUT_USES_ENC_DECL) ||
  1357. (ctxt->input->flags & XML_INPUT_AUTO_ENCODING)) {
  1358. /* Preserve encoding exactly */
  1359. encoding = ctxt->encoding;
  1360. } else if ((ctxt->input->buf) && (ctxt->input->buf->encoder)) {
  1361. encoding = BAD_CAST ctxt->input->buf->encoder->name;
  1362. } else if (ctxt->input->flags & XML_INPUT_HAS_ENCODING) {
  1363. encoding = BAD_CAST "UTF-8";
  1364. }
  1365. return(encoding);
  1366. }
  1367. /************************************************************************
  1368. * *
  1369. * Commodity functions to handle entities processing *
  1370. * *
  1371. ************************************************************************/
  1372. /**
  1373. * xmlFreeInputStream:
  1374. * @input: an xmlParserInputPtr
  1375. *
  1376. * Free up an input stream.
  1377. */
  1378. void
  1379. xmlFreeInputStream(xmlParserInputPtr input) {
  1380. if (input == NULL) return;
  1381. if (input->filename != NULL) xmlFree((char *) input->filename);
  1382. if (input->directory != NULL) xmlFree((char *) input->directory);
  1383. if (input->version != NULL) xmlFree((char *) input->version);
  1384. if ((input->free != NULL) && (input->base != NULL))
  1385. input->free((xmlChar *) input->base);
  1386. if (input->buf != NULL)
  1387. xmlFreeParserInputBuffer(input->buf);
  1388. xmlFree(input);
  1389. }
  1390. /**
  1391. * xmlNewInputStream:
  1392. * @ctxt: an XML parser context
  1393. *
  1394. * Create a new input stream structure.
  1395. *
  1396. * Returns the new input stream or NULL
  1397. */
  1398. xmlParserInputPtr
  1399. xmlNewInputStream(xmlParserCtxtPtr ctxt) {
  1400. xmlParserInputPtr input;
  1401. input = (xmlParserInputPtr) xmlMalloc(sizeof(xmlParserInput));
  1402. if (input == NULL) {
  1403. xmlErrMemory(ctxt, "couldn't allocate a new input stream\n");
  1404. return(NULL);
  1405. }
  1406. memset(input, 0, sizeof(xmlParserInput));
  1407. input->line = 1;
  1408. input->col = 1;
  1409. /*
  1410. * If the context is NULL the id cannot be initialized, but that
  1411. * should not happen while parsing which is the situation where
  1412. * the id is actually needed.
  1413. */
  1414. if (ctxt != NULL) {
  1415. if (input->id >= INT_MAX) {
  1416. xmlErrMemory(ctxt, "Input ID overflow\n");
  1417. return(NULL);
  1418. }
  1419. input->id = ctxt->input_id++;
  1420. }
  1421. return(input);
  1422. }
  1423. /**
  1424. * xmlNewIOInputStream:
  1425. * @ctxt: an XML parser context
  1426. * @input: an I/O Input
  1427. * @enc: the charset encoding if known
  1428. *
  1429. * Create a new input stream structure encapsulating the @input into
  1430. * a stream suitable for the parser.
  1431. *
  1432. * Returns the new input stream or NULL
  1433. */
  1434. xmlParserInputPtr
  1435. xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr input,
  1436. xmlCharEncoding enc) {
  1437. xmlParserInputPtr inputStream;
  1438. if (input == NULL) return(NULL);
  1439. if (xmlParserDebugEntities)
  1440. xmlGenericError(xmlGenericErrorContext, "new input from I/O\n");
  1441. inputStream = xmlNewInputStream(ctxt);
  1442. if (inputStream == NULL) {
  1443. return(NULL);
  1444. }
  1445. inputStream->filename = NULL;
  1446. inputStream->buf = input;
  1447. xmlBufResetInput(inputStream->buf->buffer, inputStream);
  1448. if (enc != XML_CHAR_ENCODING_NONE) {
  1449. xmlSwitchEncoding(ctxt, enc);
  1450. }
  1451. return(inputStream);
  1452. }
  1453. /**
  1454. * xmlNewEntityInputStream:
  1455. * @ctxt: an XML parser context
  1456. * @entity: an Entity pointer
  1457. *
  1458. * DEPRECATED: Internal function, do not use.
  1459. *
  1460. * Create a new input stream based on an xmlEntityPtr
  1461. *
  1462. * Returns the new input stream or NULL
  1463. */
  1464. xmlParserInputPtr
  1465. xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
  1466. xmlParserInputPtr input;
  1467. if (entity == NULL) {
  1468. xmlErrInternal(ctxt, "xmlNewEntityInputStream entity = NULL\n",
  1469. NULL);
  1470. return(NULL);
  1471. }
  1472. if (xmlParserDebugEntities)
  1473. xmlGenericError(xmlGenericErrorContext,
  1474. "new input from entity: %s\n", entity->name);
  1475. if (entity->content == NULL) {
  1476. switch (entity->etype) {
  1477. case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
  1478. xmlErrInternal(ctxt, "Cannot parse entity %s\n",
  1479. entity->name);
  1480. break;
  1481. case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
  1482. case XML_EXTERNAL_PARAMETER_ENTITY:
  1483. input = xmlLoadExternalEntity((char *) entity->URI,
  1484. (char *) entity->ExternalID, ctxt);
  1485. if (input != NULL)
  1486. input->entity = entity;
  1487. return(input);
  1488. case XML_INTERNAL_GENERAL_ENTITY:
  1489. xmlErrInternal(ctxt,
  1490. "Internal entity %s without content !\n",
  1491. entity->name);
  1492. break;
  1493. case XML_INTERNAL_PARAMETER_ENTITY:
  1494. xmlErrInternal(ctxt,
  1495. "Internal parameter entity %s without content !\n",
  1496. entity->name);
  1497. break;
  1498. case XML_INTERNAL_PREDEFINED_ENTITY:
  1499. xmlErrInternal(ctxt,
  1500. "Predefined entity %s without content !\n",
  1501. entity->name);
  1502. break;
  1503. }
  1504. return(NULL);
  1505. }
  1506. input = xmlNewInputStream(ctxt);
  1507. if (input == NULL) {
  1508. return(NULL);
  1509. }
  1510. if (entity->URI != NULL)
  1511. input->filename = (char *) xmlStrdup((xmlChar *) entity->URI);
  1512. input->base = entity->content;
  1513. if (entity->length == 0)
  1514. entity->length = xmlStrlen(entity->content);
  1515. input->cur = entity->content;
  1516. input->length = entity->length;
  1517. input->end = &entity->content[input->length];
  1518. input->entity = entity;
  1519. return(input);
  1520. }
  1521. /**
  1522. * xmlNewStringInputStream:
  1523. * @ctxt: an XML parser context
  1524. * @buffer: an memory buffer
  1525. *
  1526. * Create a new input stream based on a memory buffer.
  1527. * Returns the new input stream
  1528. */
  1529. xmlParserInputPtr
  1530. xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
  1531. xmlParserInputPtr input;
  1532. xmlParserInputBufferPtr buf;
  1533. if (buffer == NULL) {
  1534. xmlErrInternal(ctxt, "xmlNewStringInputStream string = NULL\n",
  1535. NULL);
  1536. return(NULL);
  1537. }
  1538. if (xmlParserDebugEntities)
  1539. xmlGenericError(xmlGenericErrorContext,
  1540. "new fixed input: %.30s\n", buffer);
  1541. buf = xmlParserInputBufferCreateString(buffer);
  1542. if (buf == NULL) {
  1543. xmlErrMemory(ctxt, NULL);
  1544. return(NULL);
  1545. }
  1546. input = xmlNewInputStream(ctxt);
  1547. if (input == NULL) {
  1548. xmlErrMemory(ctxt, "couldn't allocate a new input stream\n");
  1549. xmlFreeParserInputBuffer(buf);
  1550. return(NULL);
  1551. }
  1552. input->buf = buf;
  1553. xmlBufResetInput(input->buf->buffer, input);
  1554. return(input);
  1555. }
  1556. /**
  1557. * xmlNewInputFromFile:
  1558. * @ctxt: an XML parser context
  1559. * @filename: the filename to use as entity
  1560. *
  1561. * Create a new input stream based on a file or an URL.
  1562. *
  1563. * Returns the new input stream or NULL in case of error
  1564. */
  1565. xmlParserInputPtr
  1566. xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
  1567. xmlParserInputBufferPtr buf;
  1568. xmlParserInputPtr inputStream;
  1569. char *directory = NULL;
  1570. xmlChar *URI = NULL;
  1571. if (xmlParserDebugEntities)
  1572. xmlGenericError(xmlGenericErrorContext,
  1573. "new input from file: %s\n", filename);
  1574. if (ctxt == NULL) return(NULL);
  1575. buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
  1576. if (buf == NULL) {
  1577. if (filename == NULL)
  1578. __xmlLoaderErr(ctxt,
  1579. "failed to load external entity: NULL filename \n",
  1580. NULL);
  1581. else
  1582. __xmlLoaderErr(ctxt, "failed to load external entity \"%s\"\n",
  1583. (const char *) filename);
  1584. return(NULL);
  1585. }
  1586. inputStream = xmlNewInputStream(ctxt);
  1587. if (inputStream == NULL) {
  1588. xmlFreeParserInputBuffer(buf);
  1589. return(NULL);
  1590. }
  1591. inputStream->buf = buf;
  1592. inputStream = xmlCheckHTTPInput(ctxt, inputStream);
  1593. if (inputStream == NULL)
  1594. return(NULL);
  1595. if (inputStream->filename == NULL)
  1596. URI = xmlStrdup((xmlChar *) filename);
  1597. else
  1598. URI = xmlStrdup((xmlChar *) inputStream->filename);
  1599. directory = xmlParserGetDirectory((const char *) URI);
  1600. if (inputStream->filename != NULL) xmlFree((char *)inputStream->filename);
  1601. inputStream->filename = (char *) xmlCanonicPath((const xmlChar *) URI);
  1602. if (URI != NULL) xmlFree((char *) URI);
  1603. inputStream->directory = directory;
  1604. xmlBufResetInput(inputStream->buf->buffer, inputStream);
  1605. if ((ctxt->directory == NULL) && (directory != NULL))
  1606. ctxt->directory = (char *) xmlStrdup((const xmlChar *) directory);
  1607. return(inputStream);
  1608. }
  1609. /************************************************************************
  1610. * *
  1611. * Commodity functions to handle parser contexts *
  1612. * *
  1613. ************************************************************************/
  1614. /**
  1615. * xmlInitSAXParserCtxt:
  1616. * @ctxt: XML parser context
  1617. * @sax: SAX handlert
  1618. * @userData: user data
  1619. *
  1620. * Initialize a SAX parser context
  1621. *
  1622. * Returns 0 in case of success and -1 in case of error
  1623. */
  1624. static int
  1625. xmlInitSAXParserCtxt(xmlParserCtxtPtr ctxt, const xmlSAXHandler *sax,
  1626. void *userData)
  1627. {
  1628. xmlParserInputPtr input;
  1629. if(ctxt==NULL) {
  1630. xmlErrInternal(NULL, "Got NULL parser context\n", NULL);
  1631. return(-1);
  1632. }
  1633. xmlInitParser();
  1634. if (ctxt->dict == NULL)
  1635. ctxt->dict = xmlDictCreate();
  1636. if (ctxt->dict == NULL) {
  1637. xmlErrMemory(NULL, "cannot initialize parser context\n");
  1638. return(-1);
  1639. }
  1640. xmlDictSetLimit(ctxt->dict, XML_MAX_DICTIONARY_LIMIT);
  1641. if (ctxt->sax == NULL)
  1642. ctxt->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
  1643. if (ctxt->sax == NULL) {
  1644. xmlErrMemory(NULL, "cannot initialize parser context\n");
  1645. return(-1);
  1646. }
  1647. if (sax == NULL) {
  1648. memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
  1649. xmlSAXVersion(ctxt->sax, 2);
  1650. ctxt->userData = ctxt;
  1651. } else {
  1652. if (sax->initialized == XML_SAX2_MAGIC) {
  1653. memcpy(ctxt->sax, sax, sizeof(xmlSAXHandler));
  1654. } else {
  1655. memset(ctxt->sax, 0, sizeof(xmlSAXHandler));
  1656. memcpy(ctxt->sax, sax, sizeof(xmlSAXHandlerV1));
  1657. }
  1658. ctxt->userData = userData ? userData : ctxt;
  1659. }
  1660. ctxt->maxatts = 0;
  1661. ctxt->atts = NULL;
  1662. /* Allocate the Input stack */
  1663. if (ctxt->inputTab == NULL) {
  1664. ctxt->inputTab = (xmlParserInputPtr *)
  1665. xmlMalloc(5 * sizeof(xmlParserInputPtr));
  1666. ctxt->inputMax = 5;
  1667. }
  1668. if (ctxt->inputTab == NULL) {
  1669. xmlErrMemory(NULL, "cannot initialize parser context\n");
  1670. ctxt->inputNr = 0;
  1671. ctxt->inputMax = 0;
  1672. ctxt->input = NULL;
  1673. return(-1);
  1674. }
  1675. while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
  1676. xmlFreeInputStream(input);
  1677. }
  1678. ctxt->inputNr = 0;
  1679. ctxt->input = NULL;
  1680. ctxt->version = NULL;
  1681. ctxt->encoding = NULL;
  1682. ctxt->standalone = -1;
  1683. ctxt->hasExternalSubset = 0;
  1684. ctxt->hasPErefs = 0;
  1685. ctxt->html = 0;
  1686. ctxt->external = 0;
  1687. ctxt->instate = XML_PARSER_START;
  1688. ctxt->token = 0;
  1689. ctxt->directory = NULL;
  1690. /* Allocate the Node stack */
  1691. if (ctxt->nodeTab == NULL) {
  1692. ctxt->nodeTab = (xmlNodePtr *) xmlMalloc(10 * sizeof(xmlNodePtr));
  1693. ctxt->nodeMax = 10;
  1694. }
  1695. if (ctxt->nodeTab == NULL) {
  1696. xmlErrMemory(NULL, "cannot initialize parser context\n");
  1697. ctxt->nodeNr = 0;
  1698. ctxt->nodeMax = 0;
  1699. ctxt->node = NULL;
  1700. ctxt->inputNr = 0;
  1701. ctxt->inputMax = 0;
  1702. ctxt->input = NULL;
  1703. return(-1);
  1704. }
  1705. ctxt->nodeNr = 0;
  1706. ctxt->node = NULL;
  1707. /* Allocate the Name stack */
  1708. if (ctxt->nameTab == NULL) {
  1709. ctxt->nameTab = (const xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
  1710. ctxt->nameMax = 10;
  1711. }
  1712. if (ctxt->nameTab == NULL) {
  1713. xmlErrMemory(NULL, "cannot initialize parser context\n");
  1714. ctxt->nodeNr = 0;
  1715. ctxt->nodeMax = 0;
  1716. ctxt->node = NULL;
  1717. ctxt->inputNr = 0;
  1718. ctxt->inputMax = 0;
  1719. ctxt->input = NULL;
  1720. ctxt->nameNr = 0;
  1721. ctxt->nameMax = 0;
  1722. ctxt->name = NULL;
  1723. return(-1);
  1724. }
  1725. ctxt->nameNr = 0;
  1726. ctxt->name = NULL;
  1727. /* Allocate the space stack */
  1728. if (ctxt->spaceTab == NULL) {
  1729. ctxt->spaceTab = (int *) xmlMalloc(10 * sizeof(int));
  1730. ctxt->spaceMax = 10;
  1731. }
  1732. if (ctxt->spaceTab == NULL) {
  1733. xmlErrMemory(NULL, "cannot initialize parser context\n");
  1734. ctxt->nodeNr = 0;
  1735. ctxt->nodeMax = 0;
  1736. ctxt->node = NULL;
  1737. ctxt->inputNr = 0;
  1738. ctxt->inputMax = 0;
  1739. ctxt->input = NULL;
  1740. ctxt->nameNr = 0;
  1741. ctxt->nameMax = 0;
  1742. ctxt->name = NULL;
  1743. ctxt->spaceNr = 0;
  1744. ctxt->spaceMax = 0;
  1745. ctxt->space = NULL;
  1746. return(-1);
  1747. }
  1748. ctxt->spaceNr = 1;
  1749. ctxt->spaceMax = 10;
  1750. ctxt->spaceTab[0] = -1;
  1751. ctxt->space = &ctxt->spaceTab[0];
  1752. ctxt->myDoc = NULL;
  1753. ctxt->wellFormed = 1;
  1754. ctxt->nsWellFormed = 1;
  1755. ctxt->valid = 1;
  1756. ctxt->loadsubset = xmlLoadExtDtdDefaultValue;
  1757. if (ctxt->loadsubset) {
  1758. ctxt->options |= XML_PARSE_DTDLOAD;
  1759. }
  1760. ctxt->validate = xmlDoValidityCheckingDefaultValue;
  1761. ctxt->pedantic = xmlPedanticParserDefaultValue;
  1762. if (ctxt->pedantic) {
  1763. ctxt->options |= XML_PARSE_PEDANTIC;
  1764. }
  1765. ctxt->linenumbers = xmlLineNumbersDefaultValue;
  1766. ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
  1767. if (ctxt->keepBlanks == 0) {
  1768. ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
  1769. ctxt->options |= XML_PARSE_NOBLANKS;
  1770. }
  1771. ctxt->vctxt.flags = XML_VCTXT_USE_PCTXT;
  1772. ctxt->vctxt.userData = ctxt;
  1773. ctxt->vctxt.error = xmlParserValidityError;
  1774. ctxt->vctxt.warning = xmlParserValidityWarning;
  1775. if (ctxt->validate) {
  1776. if (xmlGetWarningsDefaultValue == 0)
  1777. ctxt->vctxt.warning = NULL;
  1778. else
  1779. ctxt->vctxt.warning = xmlParserValidityWarning;
  1780. ctxt->vctxt.nodeMax = 0;
  1781. ctxt->options |= XML_PARSE_DTDVALID;
  1782. }
  1783. ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
  1784. if (ctxt->replaceEntities) {
  1785. ctxt->options |= XML_PARSE_NOENT;
  1786. }
  1787. ctxt->record_info = 0;
  1788. ctxt->checkIndex = 0;
  1789. ctxt->inSubset = 0;
  1790. ctxt->errNo = XML_ERR_OK;
  1791. ctxt->depth = 0;
  1792. ctxt->catalogs = NULL;
  1793. ctxt->sizeentities = 0;
  1794. ctxt->sizeentcopy = 0;
  1795. ctxt->input_id = 1;
  1796. ctxt->maxAmpl = XML_MAX_AMPLIFICATION_DEFAULT;
  1797. xmlInitNodeInfoSeq(&ctxt->node_seq);
  1798. if (ctxt->nsdb == NULL) {
  1799. ctxt->nsdb = xmlParserNsCreate();
  1800. if (ctxt->nsdb == NULL) {
  1801. xmlErrMemory(ctxt, NULL);
  1802. return(-1);
  1803. }
  1804. }
  1805. return(0);
  1806. }
  1807. /**
  1808. * xmlInitParserCtxt:
  1809. * @ctxt: an XML parser context
  1810. *
  1811. * DEPRECATED: Internal function which will be made private in a future
  1812. * version.
  1813. *
  1814. * Initialize a parser context
  1815. *
  1816. * Returns 0 in case of success and -1 in case of error
  1817. */
  1818. int
  1819. xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
  1820. {
  1821. return(xmlInitSAXParserCtxt(ctxt, NULL, NULL));
  1822. }
  1823. /**
  1824. * xmlFreeParserCtxt:
  1825. * @ctxt: an XML parser context
  1826. *
  1827. * Free all the memory used by a parser context. However the parsed
  1828. * document in ctxt->myDoc is not freed.
  1829. */
  1830. void
  1831. xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
  1832. {
  1833. xmlParserInputPtr input;
  1834. if (ctxt == NULL) return;
  1835. while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
  1836. xmlFreeInputStream(input);
  1837. }
  1838. if (ctxt->spaceTab != NULL) xmlFree(ctxt->spaceTab);
  1839. if (ctxt->nameTab != NULL) xmlFree((xmlChar * *)ctxt->nameTab);
  1840. if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab);
  1841. if (ctxt->nodeInfoTab != NULL) xmlFree(ctxt->nodeInfoTab);
  1842. if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab);
  1843. if (ctxt->version != NULL) xmlFree((char *) ctxt->version);
  1844. if (ctxt->encoding != NULL) xmlFree((char *) ctxt->encoding);
  1845. if (ctxt->extSubURI != NULL) xmlFree((char *) ctxt->extSubURI);
  1846. if (ctxt->extSubSystem != NULL) xmlFree((char *) ctxt->extSubSystem);
  1847. #ifdef LIBXML_SAX1_ENABLED
  1848. if ((ctxt->sax != NULL) &&
  1849. (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler))
  1850. #else
  1851. if (ctxt->sax != NULL)
  1852. #endif /* LIBXML_SAX1_ENABLED */
  1853. xmlFree(ctxt->sax);
  1854. if (ctxt->directory != NULL) xmlFree((char *) ctxt->directory);
  1855. if (ctxt->vctxt.nodeTab != NULL) xmlFree(ctxt->vctxt.nodeTab);
  1856. if (ctxt->atts != NULL) xmlFree((xmlChar * *)ctxt->atts);
  1857. if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
  1858. if (ctxt->nsTab != NULL) xmlFree(ctxt->nsTab);
  1859. if (ctxt->nsdb != NULL) xmlParserNsFree(ctxt->nsdb);
  1860. if (ctxt->attrHash != NULL) xmlFree(ctxt->attrHash);
  1861. if (ctxt->pushTab != NULL) xmlFree(ctxt->pushTab);
  1862. if (ctxt->attallocs != NULL) xmlFree(ctxt->attallocs);
  1863. if (ctxt->attsDefault != NULL)
  1864. xmlHashFree(ctxt->attsDefault, xmlHashDefaultDeallocator);
  1865. if (ctxt->attsSpecial != NULL)
  1866. xmlHashFree(ctxt->attsSpecial, NULL);
  1867. if (ctxt->freeElems != NULL) {
  1868. xmlNodePtr cur, next;
  1869. cur = ctxt->freeElems;
  1870. while (cur != NULL) {
  1871. next = cur->next;
  1872. xmlFree(cur);
  1873. cur = next;
  1874. }
  1875. }
  1876. if (ctxt->freeAttrs != NULL) {
  1877. xmlAttrPtr cur, next;
  1878. cur = ctxt->freeAttrs;
  1879. while (cur != NULL) {
  1880. next = cur->next;
  1881. xmlFree(cur);
  1882. cur = next;
  1883. }
  1884. }
  1885. /*
  1886. * cleanup the error strings
  1887. */
  1888. if (ctxt->lastError.message != NULL)
  1889. xmlFree(ctxt->lastError.message);
  1890. if (ctxt->lastError.file != NULL)
  1891. xmlFree(ctxt->lastError.file);
  1892. if (ctxt->lastError.str1 != NULL)
  1893. xmlFree(ctxt->lastError.str1);
  1894. if (ctxt->lastError.str2 != NULL)
  1895. xmlFree(ctxt->lastError.str2);
  1896. if (ctxt->lastError.str3 != NULL)
  1897. xmlFree(ctxt->lastError.str3);
  1898. #ifdef LIBXML_CATALOG_ENABLED
  1899. if (ctxt->catalogs != NULL)
  1900. xmlCatalogFreeLocal(ctxt->catalogs);
  1901. #endif
  1902. xmlFree(ctxt);
  1903. }
  1904. /**
  1905. * xmlNewParserCtxt:
  1906. *
  1907. * Allocate and initialize a new parser context.
  1908. *
  1909. * Returns the xmlParserCtxtPtr or NULL
  1910. */
  1911. xmlParserCtxtPtr
  1912. xmlNewParserCtxt(void)
  1913. {
  1914. return(xmlNewSAXParserCtxt(NULL, NULL));
  1915. }
  1916. /**
  1917. * xmlNewSAXParserCtxt:
  1918. * @sax: SAX handler
  1919. * @userData: user data
  1920. *
  1921. * Allocate and initialize a new SAX parser context. If userData is NULL,
  1922. * the parser context will be passed as user data.
  1923. *
  1924. * Returns the xmlParserCtxtPtr or NULL if memory allocation failed.
  1925. */
  1926. xmlParserCtxtPtr
  1927. xmlNewSAXParserCtxt(const xmlSAXHandler *sax, void *userData)
  1928. {
  1929. xmlParserCtxtPtr ctxt;
  1930. ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
  1931. if (ctxt == NULL) {
  1932. xmlErrMemory(NULL, "cannot allocate parser context\n");
  1933. return(NULL);
  1934. }
  1935. memset(ctxt, 0, sizeof(xmlParserCtxt));
  1936. if (xmlInitSAXParserCtxt(ctxt, sax, userData) < 0) {
  1937. xmlFreeParserCtxt(ctxt);
  1938. return(NULL);
  1939. }
  1940. return(ctxt);
  1941. }
  1942. /************************************************************************
  1943. * *
  1944. * Handling of node information *
  1945. * *
  1946. ************************************************************************/
  1947. /**
  1948. * xmlClearParserCtxt:
  1949. * @ctxt: an XML parser context
  1950. *
  1951. * Clear (release owned resources) and reinitialize a parser context
  1952. */
  1953. void
  1954. xmlClearParserCtxt(xmlParserCtxtPtr ctxt)
  1955. {
  1956. if (ctxt==NULL)
  1957. return;
  1958. xmlClearNodeInfoSeq(&ctxt->node_seq);
  1959. xmlCtxtReset(ctxt);
  1960. }
  1961. /**
  1962. * xmlParserFindNodeInfo:
  1963. * @ctx: an XML parser context
  1964. * @node: an XML node within the tree
  1965. *
  1966. * DEPRECATED: Don't use.
  1967. *
  1968. * Find the parser node info struct for a given node
  1969. *
  1970. * Returns an xmlParserNodeInfo block pointer or NULL
  1971. */
  1972. const xmlParserNodeInfo *
  1973. xmlParserFindNodeInfo(const xmlParserCtxtPtr ctx, const xmlNodePtr node)
  1974. {
  1975. unsigned long pos;
  1976. if ((ctx == NULL) || (node == NULL))
  1977. return (NULL);
  1978. /* Find position where node should be at */
  1979. pos = xmlParserFindNodeInfoIndex(&ctx->node_seq, node);
  1980. if (pos < ctx->node_seq.length
  1981. && ctx->node_seq.buffer[pos].node == node)
  1982. return &ctx->node_seq.buffer[pos];
  1983. else
  1984. return NULL;
  1985. }
  1986. /**
  1987. * xmlInitNodeInfoSeq:
  1988. * @seq: a node info sequence pointer
  1989. *
  1990. * DEPRECATED: Don't use.
  1991. *
  1992. * -- Initialize (set to initial state) node info sequence
  1993. */
  1994. void
  1995. xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
  1996. {
  1997. if (seq == NULL)
  1998. return;
  1999. seq->length = 0;
  2000. seq->maximum = 0;
  2001. seq->buffer = NULL;
  2002. }
  2003. /**
  2004. * xmlClearNodeInfoSeq:
  2005. * @seq: a node info sequence pointer
  2006. *
  2007. * DEPRECATED: Don't use.
  2008. *
  2009. * -- Clear (release memory and reinitialize) node
  2010. * info sequence
  2011. */
  2012. void
  2013. xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
  2014. {
  2015. if (seq == NULL)
  2016. return;
  2017. if (seq->buffer != NULL)
  2018. xmlFree(seq->buffer);
  2019. xmlInitNodeInfoSeq(seq);
  2020. }
  2021. /**
  2022. * xmlParserFindNodeInfoIndex:
  2023. * @seq: a node info sequence pointer
  2024. * @node: an XML node pointer
  2025. *
  2026. * DEPRECATED: Don't use.
  2027. *
  2028. * xmlParserFindNodeInfoIndex : Find the index that the info record for
  2029. * the given node is or should be at in a sorted sequence
  2030. *
  2031. * Returns a long indicating the position of the record
  2032. */
  2033. unsigned long
  2034. xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeqPtr seq,
  2035. const xmlNodePtr node)
  2036. {
  2037. unsigned long upper, lower, middle;
  2038. int found = 0;
  2039. if ((seq == NULL) || (node == NULL))
  2040. return ((unsigned long) -1);
  2041. /* Do a binary search for the key */
  2042. lower = 1;
  2043. upper = seq->length;
  2044. middle = 0;
  2045. while (lower <= upper && !found) {
  2046. middle = lower + (upper - lower) / 2;
  2047. if (node == seq->buffer[middle - 1].node)
  2048. found = 1;
  2049. else if (node < seq->buffer[middle - 1].node)
  2050. upper = middle - 1;
  2051. else
  2052. lower = middle + 1;
  2053. }
  2054. /* Return position */
  2055. if (middle == 0 || seq->buffer[middle - 1].node < node)
  2056. return middle;
  2057. else
  2058. return middle - 1;
  2059. }
  2060. /**
  2061. * xmlParserAddNodeInfo:
  2062. * @ctxt: an XML parser context
  2063. * @info: a node info sequence pointer
  2064. *
  2065. * DEPRECATED: Don't use.
  2066. *
  2067. * Insert node info record into the sorted sequence
  2068. */
  2069. void
  2070. xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt,
  2071. const xmlParserNodeInfoPtr info)
  2072. {
  2073. unsigned long pos;
  2074. if ((ctxt == NULL) || (info == NULL)) return;
  2075. /* Find pos and check to see if node is already in the sequence */
  2076. pos = xmlParserFindNodeInfoIndex(&ctxt->node_seq, (xmlNodePtr)
  2077. info->node);
  2078. if ((pos < ctxt->node_seq.length) &&
  2079. (ctxt->node_seq.buffer != NULL) &&
  2080. (ctxt->node_seq.buffer[pos].node == info->node)) {
  2081. ctxt->node_seq.buffer[pos] = *info;
  2082. }
  2083. /* Otherwise, we need to add new node to buffer */
  2084. else {
  2085. if ((ctxt->node_seq.length + 1 > ctxt->node_seq.maximum) ||
  2086. (ctxt->node_seq.buffer == NULL)) {
  2087. xmlParserNodeInfo *tmp_buffer;
  2088. unsigned int byte_size;
  2089. if (ctxt->node_seq.maximum == 0)
  2090. ctxt->node_seq.maximum = 2;
  2091. byte_size = (sizeof(*ctxt->node_seq.buffer) *
  2092. (2 * ctxt->node_seq.maximum));
  2093. if (ctxt->node_seq.buffer == NULL)
  2094. tmp_buffer = (xmlParserNodeInfo *) xmlMalloc(byte_size);
  2095. else
  2096. tmp_buffer =
  2097. (xmlParserNodeInfo *) xmlRealloc(ctxt->node_seq.buffer,
  2098. byte_size);
  2099. if (tmp_buffer == NULL) {
  2100. xmlErrMemory(ctxt, "failed to allocate buffer\n");
  2101. return;
  2102. }
  2103. ctxt->node_seq.buffer = tmp_buffer;
  2104. ctxt->node_seq.maximum *= 2;
  2105. }
  2106. /* If position is not at end, move elements out of the way */
  2107. if (pos != ctxt->node_seq.length) {
  2108. unsigned long i;
  2109. for (i = ctxt->node_seq.length; i > pos; i--)
  2110. ctxt->node_seq.buffer[i] = ctxt->node_seq.buffer[i - 1];
  2111. }
  2112. /* Copy element and increase length */
  2113. ctxt->node_seq.buffer[pos] = *info;
  2114. ctxt->node_seq.length++;
  2115. }
  2116. }
  2117. /************************************************************************
  2118. * *
  2119. * Defaults settings *
  2120. * *
  2121. ************************************************************************/
  2122. /**
  2123. * xmlPedanticParserDefault:
  2124. * @val: int 0 or 1
  2125. *
  2126. * DEPRECATED: Use the modern options API with XML_PARSE_PEDANTIC.
  2127. *
  2128. * Set and return the previous value for enabling pedantic warnings.
  2129. *
  2130. * Returns the last value for 0 for no substitution, 1 for substitution.
  2131. */
  2132. int
  2133. xmlPedanticParserDefault(int val) {
  2134. int old = xmlPedanticParserDefaultValue;
  2135. xmlPedanticParserDefaultValue = val;
  2136. return(old);
  2137. }
  2138. /**
  2139. * xmlLineNumbersDefault:
  2140. * @val: int 0 or 1
  2141. *
  2142. * DEPRECATED: The modern options API always enables line numbers.
  2143. *
  2144. * Set and return the previous value for enabling line numbers in elements
  2145. * contents. This may break on old application and is turned off by default.
  2146. *
  2147. * Returns the last value for 0 for no substitution, 1 for substitution.
  2148. */
  2149. int
  2150. xmlLineNumbersDefault(int val) {
  2151. int old = xmlLineNumbersDefaultValue;
  2152. xmlLineNumbersDefaultValue = val;
  2153. return(old);
  2154. }
  2155. /**
  2156. * xmlSubstituteEntitiesDefault:
  2157. * @val: int 0 or 1
  2158. *
  2159. * DEPRECATED: Use the modern options API with XML_PARSE_NOENT.
  2160. *
  2161. * Set and return the previous value for default entity support.
  2162. * Initially the parser always keep entity references instead of substituting
  2163. * entity values in the output. This function has to be used to change the
  2164. * default parser behavior
  2165. * SAX::substituteEntities() has to be used for changing that on a file by
  2166. * file basis.
  2167. *
  2168. * Returns the last value for 0 for no substitution, 1 for substitution.
  2169. */
  2170. int
  2171. xmlSubstituteEntitiesDefault(int val) {
  2172. int old = xmlSubstituteEntitiesDefaultValue;
  2173. xmlSubstituteEntitiesDefaultValue = val;
  2174. return(old);
  2175. }
  2176. /**
  2177. * xmlKeepBlanksDefault:
  2178. * @val: int 0 or 1
  2179. *
  2180. * DEPRECATED: Use the modern options API with XML_PARSE_NOBLANKS.
  2181. *
  2182. * Set and return the previous value for default blanks text nodes support.
  2183. * The 1.x version of the parser used an heuristic to try to detect
  2184. * ignorable white spaces. As a result the SAX callback was generating
  2185. * xmlSAX2IgnorableWhitespace() callbacks instead of characters() one, and when
  2186. * using the DOM output text nodes containing those blanks were not generated.
  2187. * The 2.x and later version will switch to the XML standard way and
  2188. * ignorableWhitespace() are only generated when running the parser in
  2189. * validating mode and when the current element doesn't allow CDATA or
  2190. * mixed content.
  2191. * This function is provided as a way to force the standard behavior
  2192. * on 1.X libs and to switch back to the old mode for compatibility when
  2193. * running 1.X client code on 2.X . Upgrade of 1.X code should be done
  2194. * by using xmlIsBlankNode() commodity function to detect the "empty"
  2195. * nodes generated.
  2196. * This value also affect autogeneration of indentation when saving code
  2197. * if blanks sections are kept, indentation is not generated.
  2198. *
  2199. * Returns the last value for 0 for no substitution, 1 for substitution.
  2200. */
  2201. int
  2202. xmlKeepBlanksDefault(int val) {
  2203. int old = xmlKeepBlanksDefaultValue;
  2204. xmlKeepBlanksDefaultValue = val;
  2205. #ifdef LIBXML_OUTPUT_ENABLED
  2206. if (!val)
  2207. xmlIndentTreeOutput = 1;
  2208. #endif
  2209. return(old);
  2210. }