parserInternals.c 57 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022
  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/valid.h>
  24. #include <libxml/entities.h>
  25. #include <libxml/xmlerror.h>
  26. #include <libxml/encoding.h>
  27. #include <libxml/valid.h>
  28. #include <libxml/xmlIO.h>
  29. #include <libxml/uri.h>
  30. #include <libxml/dict.h>
  31. #include <libxml/SAX.h>
  32. #ifdef LIBXML_CATALOG_ENABLED
  33. #include <libxml/catalog.h>
  34. #endif
  35. #include <libxml/globals.h>
  36. #include <libxml/chvalid.h>
  37. #define CUR(ctxt) ctxt->input->cur
  38. #define END(ctxt) ctxt->input->end
  39. #define VALID_CTXT(ctxt) (CUR(ctxt) <= END(ctxt))
  40. #include "buf.h"
  41. #include "enc.h"
  42. /*
  43. * Various global defaults for parsing
  44. */
  45. /**
  46. * xmlCheckVersion:
  47. * @version: the include version number
  48. *
  49. * check the compiled lib version against the include one.
  50. * This can warn or immediately kill the application
  51. */
  52. void
  53. xmlCheckVersion(int version) {
  54. int myversion = (int) LIBXML_VERSION;
  55. xmlInitParser();
  56. if ((myversion / 10000) != (version / 10000)) {
  57. xmlGenericError(xmlGenericErrorContext,
  58. "Fatal: program compiled against libxml %d using libxml %d\n",
  59. (version / 10000), (myversion / 10000));
  60. fprintf(stderr,
  61. "Fatal: program compiled against libxml %d using libxml %d\n",
  62. (version / 10000), (myversion / 10000));
  63. }
  64. if ((myversion / 100) < (version / 100)) {
  65. xmlGenericError(xmlGenericErrorContext,
  66. "Warning: program compiled against libxml %d using older %d\n",
  67. (version / 100), (myversion / 100));
  68. }
  69. }
  70. /************************************************************************
  71. * *
  72. * Some factorized error routines *
  73. * *
  74. ************************************************************************/
  75. /**
  76. * xmlErrMemory:
  77. * @ctxt: an XML parser context
  78. * @extra: extra information
  79. *
  80. * Handle a redefinition of attribute error
  81. */
  82. void
  83. xmlErrMemory(xmlParserCtxtPtr ctxt, const char *extra)
  84. {
  85. if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  86. (ctxt->instate == XML_PARSER_EOF))
  87. return;
  88. if (ctxt != NULL) {
  89. ctxt->errNo = XML_ERR_NO_MEMORY;
  90. ctxt->instate = XML_PARSER_EOF;
  91. ctxt->disableSAX = 1;
  92. }
  93. if (extra)
  94. __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
  95. XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, extra,
  96. NULL, NULL, 0, 0,
  97. "Memory allocation failed : %s\n", extra);
  98. else
  99. __xmlRaiseError(NULL, NULL, NULL, ctxt, NULL, XML_FROM_PARSER,
  100. XML_ERR_NO_MEMORY, XML_ERR_FATAL, NULL, 0, NULL,
  101. NULL, NULL, 0, 0, "Memory allocation failed\n");
  102. }
  103. /**
  104. * __xmlErrEncoding:
  105. * @ctxt: an XML parser context
  106. * @xmlerr: the error number
  107. * @msg: the error message
  108. * @str1: an string info
  109. * @str2: an string info
  110. *
  111. * Handle an encoding error
  112. */
  113. void
  114. __xmlErrEncoding(xmlParserCtxtPtr ctxt, xmlParserErrors xmlerr,
  115. const char *msg, const xmlChar * str1, const xmlChar * str2)
  116. {
  117. if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  118. (ctxt->instate == XML_PARSER_EOF))
  119. return;
  120. if (ctxt != NULL)
  121. ctxt->errNo = xmlerr;
  122. __xmlRaiseError(NULL, NULL, NULL,
  123. ctxt, NULL, XML_FROM_PARSER, xmlerr, XML_ERR_FATAL,
  124. NULL, 0, (const char *) str1, (const char *) str2,
  125. NULL, 0, 0, msg, str1, str2);
  126. if (ctxt != NULL) {
  127. ctxt->wellFormed = 0;
  128. if (ctxt->recovery == 0)
  129. ctxt->disableSAX = 1;
  130. }
  131. }
  132. /**
  133. * xmlErrInternal:
  134. * @ctxt: an XML parser context
  135. * @msg: the error message
  136. * @str: error information
  137. *
  138. * Handle an internal error
  139. */
  140. static void LIBXML_ATTR_FORMAT(2,0)
  141. xmlErrInternal(xmlParserCtxtPtr ctxt, const char *msg, const xmlChar * str)
  142. {
  143. if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  144. (ctxt->instate == XML_PARSER_EOF))
  145. return;
  146. if (ctxt != NULL)
  147. ctxt->errNo = XML_ERR_INTERNAL_ERROR;
  148. __xmlRaiseError(NULL, NULL, NULL,
  149. ctxt, NULL, XML_FROM_PARSER, XML_ERR_INTERNAL_ERROR,
  150. XML_ERR_FATAL, NULL, 0, (const char *) str, NULL, NULL,
  151. 0, 0, msg, str);
  152. if (ctxt != NULL) {
  153. ctxt->wellFormed = 0;
  154. if (ctxt->recovery == 0)
  155. ctxt->disableSAX = 1;
  156. }
  157. }
  158. /**
  159. * xmlErrEncodingInt:
  160. * @ctxt: an XML parser context
  161. * @error: the error number
  162. * @msg: the error message
  163. * @val: an integer value
  164. *
  165. * n encoding error
  166. */
  167. static void LIBXML_ATTR_FORMAT(3,0)
  168. xmlErrEncodingInt(xmlParserCtxtPtr ctxt, xmlParserErrors error,
  169. const char *msg, int val)
  170. {
  171. if ((ctxt != NULL) && (ctxt->disableSAX != 0) &&
  172. (ctxt->instate == XML_PARSER_EOF))
  173. return;
  174. if (ctxt != NULL)
  175. ctxt->errNo = error;
  176. __xmlRaiseError(NULL, NULL, NULL,
  177. ctxt, NULL, XML_FROM_PARSER, error, XML_ERR_FATAL,
  178. NULL, 0, NULL, NULL, NULL, val, 0, msg, val);
  179. if (ctxt != NULL) {
  180. ctxt->wellFormed = 0;
  181. if (ctxt->recovery == 0)
  182. ctxt->disableSAX = 1;
  183. }
  184. }
  185. /**
  186. * xmlIsLetter:
  187. * @c: an unicode character (int)
  188. *
  189. * Check whether the character is allowed by the production
  190. * [84] Letter ::= BaseChar | Ideographic
  191. *
  192. * Returns 0 if not, non-zero otherwise
  193. */
  194. int
  195. xmlIsLetter(int c) {
  196. return(IS_BASECHAR(c) || IS_IDEOGRAPHIC(c));
  197. }
  198. /************************************************************************
  199. * *
  200. * Input handling functions for progressive parsing *
  201. * *
  202. ************************************************************************/
  203. /* #define DEBUG_INPUT */
  204. /* #define DEBUG_STACK */
  205. /* #define DEBUG_PUSH */
  206. /* we need to keep enough input to show errors in context */
  207. #define LINE_LEN 80
  208. #ifdef DEBUG_INPUT
  209. #define CHECK_BUFFER(in) check_buffer(in)
  210. static
  211. void check_buffer(xmlParserInputPtr in) {
  212. if (in->base != xmlBufContent(in->buf->buffer)) {
  213. xmlGenericError(xmlGenericErrorContext,
  214. "xmlParserInput: base mismatch problem\n");
  215. }
  216. if (in->cur < in->base) {
  217. xmlGenericError(xmlGenericErrorContext,
  218. "xmlParserInput: cur < base problem\n");
  219. }
  220. if (in->cur > in->base + xmlBufUse(in->buf->buffer)) {
  221. xmlGenericError(xmlGenericErrorContext,
  222. "xmlParserInput: cur > base + use problem\n");
  223. }
  224. xmlGenericError(xmlGenericErrorContext,"buffer %x : content %x, cur %d, use %d\n",
  225. (int) in, (int) xmlBufContent(in->buf->buffer), in->cur - in->base,
  226. xmlBufUse(in->buf->buffer));
  227. }
  228. #else
  229. #define CHECK_BUFFER(in)
  230. #endif
  231. /**
  232. * xmlParserInputRead:
  233. * @in: an XML parser input
  234. * @len: an indicative size for the lookahead
  235. *
  236. * This function was internal and is deprecated.
  237. *
  238. * Returns -1 as this is an error to use it.
  239. */
  240. int
  241. xmlParserInputRead(xmlParserInputPtr in ATTRIBUTE_UNUSED, int len ATTRIBUTE_UNUSED) {
  242. return(-1);
  243. }
  244. /**
  245. * xmlParserInputGrow:
  246. * @in: an XML parser input
  247. * @len: an indicative size for the lookahead
  248. *
  249. * This function increase the input for the parser. It tries to
  250. * preserve pointers to the input buffer, and keep already read data
  251. *
  252. * Returns the amount of char read, or -1 in case of error, 0 indicate the
  253. * end of this entity
  254. */
  255. int
  256. xmlParserInputGrow(xmlParserInputPtr in, int len) {
  257. int ret;
  258. size_t indx;
  259. if ((in == NULL) || (len < 0)) return(-1);
  260. #ifdef DEBUG_INPUT
  261. xmlGenericError(xmlGenericErrorContext, "Grow\n");
  262. #endif
  263. if (in->buf == NULL) return(-1);
  264. if (in->base == NULL) return(-1);
  265. if (in->cur == NULL) return(-1);
  266. if (in->buf->buffer == NULL) return(-1);
  267. CHECK_BUFFER(in);
  268. indx = in->cur - in->base;
  269. if (xmlBufUse(in->buf->buffer) > (unsigned int) indx + INPUT_CHUNK) {
  270. CHECK_BUFFER(in);
  271. return(0);
  272. }
  273. if (in->buf->readcallback != NULL) {
  274. ret = xmlParserInputBufferGrow(in->buf, len);
  275. } else
  276. return(0);
  277. in->base = xmlBufContent(in->buf->buffer);
  278. in->cur = in->base + indx;
  279. in->end = xmlBufEnd(in->buf->buffer);
  280. CHECK_BUFFER(in);
  281. return(ret);
  282. }
  283. /**
  284. * xmlParserInputShrink:
  285. * @in: an XML parser input
  286. *
  287. * This function removes used input for the parser.
  288. */
  289. void
  290. xmlParserInputShrink(xmlParserInputPtr in) {
  291. size_t used;
  292. size_t ret;
  293. #ifdef DEBUG_INPUT
  294. xmlGenericError(xmlGenericErrorContext, "Shrink\n");
  295. #endif
  296. if (in == NULL) return;
  297. if (in->buf == NULL) return;
  298. if (in->base == NULL) return;
  299. if (in->cur == NULL) return;
  300. if (in->buf->buffer == NULL) return;
  301. CHECK_BUFFER(in);
  302. used = in->cur - in->base;
  303. /*
  304. * Do not shrink on large buffers whose only a tiny fraction
  305. * was consumed
  306. */
  307. if (used > INPUT_CHUNK) {
  308. ret = xmlBufShrink(in->buf->buffer, used - LINE_LEN);
  309. if (ret > 0) {
  310. used -= ret;
  311. in->consumed += ret;
  312. }
  313. }
  314. if (xmlBufUse(in->buf->buffer) <= INPUT_CHUNK) {
  315. xmlParserInputBufferRead(in->buf, 2 * INPUT_CHUNK);
  316. }
  317. in->base = xmlBufContent(in->buf->buffer);
  318. in->cur = in->base + used;
  319. in->end = xmlBufEnd(in->buf->buffer);
  320. CHECK_BUFFER(in);
  321. }
  322. /************************************************************************
  323. * *
  324. * UTF8 character input and related functions *
  325. * *
  326. ************************************************************************/
  327. /**
  328. * xmlNextChar:
  329. * @ctxt: the XML parser context
  330. *
  331. * Skip to the next char input char.
  332. */
  333. void
  334. xmlNextChar(xmlParserCtxtPtr ctxt)
  335. {
  336. if ((ctxt == NULL) || (ctxt->instate == XML_PARSER_EOF) ||
  337. (ctxt->input == NULL))
  338. return;
  339. if (!(VALID_CTXT(ctxt))) {
  340. xmlErrInternal(ctxt, "Parser input data memory error\n", NULL);
  341. ctxt->errNo = XML_ERR_INTERNAL_ERROR;
  342. xmlStopParser(ctxt);
  343. return;
  344. }
  345. if ((*ctxt->input->cur == 0) &&
  346. (xmlParserInputGrow(ctxt->input, INPUT_CHUNK) <= 0)) {
  347. return;
  348. }
  349. if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
  350. const unsigned char *cur;
  351. unsigned char c;
  352. /*
  353. * 2.11 End-of-Line Handling
  354. * the literal two-character sequence "#xD#xA" or a standalone
  355. * literal #xD, an XML processor must pass to the application
  356. * the single character #xA.
  357. */
  358. if (*(ctxt->input->cur) == '\n') {
  359. ctxt->input->line++; ctxt->input->col = 1;
  360. } else
  361. ctxt->input->col++;
  362. /*
  363. * We are supposed to handle UTF8, check it's valid
  364. * From rfc2044: encoding of the Unicode values on UTF-8:
  365. *
  366. * UCS-4 range (hex.) UTF-8 octet sequence (binary)
  367. * 0000 0000-0000 007F 0xxxxxxx
  368. * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
  369. * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
  370. *
  371. * Check for the 0x110000 limit too
  372. */
  373. cur = ctxt->input->cur;
  374. c = *cur;
  375. if (c & 0x80) {
  376. if (c == 0xC0)
  377. goto encoding_error;
  378. if (cur[1] == 0) {
  379. xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  380. cur = ctxt->input->cur;
  381. }
  382. if ((cur[1] & 0xc0) != 0x80)
  383. goto encoding_error;
  384. if ((c & 0xe0) == 0xe0) {
  385. unsigned int val;
  386. if (cur[2] == 0) {
  387. xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  388. cur = ctxt->input->cur;
  389. }
  390. if ((cur[2] & 0xc0) != 0x80)
  391. goto encoding_error;
  392. if ((c & 0xf0) == 0xf0) {
  393. if (cur[3] == 0) {
  394. xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  395. cur = ctxt->input->cur;
  396. }
  397. if (((c & 0xf8) != 0xf0) ||
  398. ((cur[3] & 0xc0) != 0x80))
  399. goto encoding_error;
  400. /* 4-byte code */
  401. ctxt->input->cur += 4;
  402. val = (cur[0] & 0x7) << 18;
  403. val |= (cur[1] & 0x3f) << 12;
  404. val |= (cur[2] & 0x3f) << 6;
  405. val |= cur[3] & 0x3f;
  406. } else {
  407. /* 3-byte code */
  408. ctxt->input->cur += 3;
  409. val = (cur[0] & 0xf) << 12;
  410. val |= (cur[1] & 0x3f) << 6;
  411. val |= cur[2] & 0x3f;
  412. }
  413. if (((val > 0xd7ff) && (val < 0xe000)) ||
  414. ((val > 0xfffd) && (val < 0x10000)) ||
  415. (val >= 0x110000)) {
  416. xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
  417. "Char 0x%X out of allowed range\n",
  418. val);
  419. }
  420. } else
  421. /* 2-byte code */
  422. ctxt->input->cur += 2;
  423. } else
  424. /* 1-byte code */
  425. ctxt->input->cur++;
  426. } else {
  427. /*
  428. * Assume it's a fixed length encoding (1) with
  429. * a compatible encoding for the ASCII set, since
  430. * XML constructs only use < 128 chars
  431. */
  432. if (*(ctxt->input->cur) == '\n') {
  433. ctxt->input->line++; ctxt->input->col = 1;
  434. } else
  435. ctxt->input->col++;
  436. ctxt->input->cur++;
  437. }
  438. if (*ctxt->input->cur == 0)
  439. xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  440. return;
  441. encoding_error:
  442. /*
  443. * If we detect an UTF8 error that probably mean that the
  444. * input encoding didn't get properly advertised in the
  445. * declaration header. Report the error and switch the encoding
  446. * to ISO-Latin-1 (if you don't like this policy, just declare the
  447. * encoding !)
  448. */
  449. if ((ctxt == NULL) || (ctxt->input == NULL) ||
  450. (ctxt->input->end - ctxt->input->cur < 4)) {
  451. __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
  452. "Input is not proper UTF-8, indicate encoding !\n",
  453. NULL, NULL);
  454. } else {
  455. char buffer[150];
  456. snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
  457. ctxt->input->cur[0], ctxt->input->cur[1],
  458. ctxt->input->cur[2], ctxt->input->cur[3]);
  459. __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
  460. "Input is not proper UTF-8, indicate encoding !\n%s",
  461. BAD_CAST buffer, NULL);
  462. }
  463. ctxt->charset = XML_CHAR_ENCODING_8859_1;
  464. ctxt->input->cur++;
  465. return;
  466. }
  467. /**
  468. * xmlCurrentChar:
  469. * @ctxt: the XML parser context
  470. * @len: pointer to the length of the char read
  471. *
  472. * The current char value, if using UTF-8 this may actually span multiple
  473. * bytes in the input buffer. Implement the end of line normalization:
  474. * 2.11 End-of-Line Handling
  475. * Wherever an external parsed entity or the literal entity value
  476. * of an internal parsed entity contains either the literal two-character
  477. * sequence "#xD#xA" or a standalone literal #xD, an XML processor
  478. * must pass to the application the single character #xA.
  479. * This behavior can conveniently be produced by normalizing all
  480. * line breaks to #xA on input, before parsing.)
  481. *
  482. * Returns the current char value and its length
  483. */
  484. int
  485. xmlCurrentChar(xmlParserCtxtPtr ctxt, int *len) {
  486. if ((ctxt == NULL) || (len == NULL) || (ctxt->input == NULL)) return(0);
  487. if (ctxt->instate == XML_PARSER_EOF)
  488. return(0);
  489. if ((*ctxt->input->cur >= 0x20) && (*ctxt->input->cur <= 0x7F)) {
  490. *len = 1;
  491. return((int) *ctxt->input->cur);
  492. }
  493. if (ctxt->charset == XML_CHAR_ENCODING_UTF8) {
  494. /*
  495. * We are supposed to handle UTF8, check it's valid
  496. * From rfc2044: encoding of the Unicode values on UTF-8:
  497. *
  498. * UCS-4 range (hex.) UTF-8 octet sequence (binary)
  499. * 0000 0000-0000 007F 0xxxxxxx
  500. * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
  501. * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
  502. *
  503. * Check for the 0x110000 limit too
  504. */
  505. const unsigned char *cur = ctxt->input->cur;
  506. unsigned char c;
  507. unsigned int val;
  508. c = *cur;
  509. if (c & 0x80) {
  510. if (((c & 0x40) == 0) || (c == 0xC0))
  511. goto encoding_error;
  512. if (cur[1] == 0) {
  513. xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  514. cur = ctxt->input->cur;
  515. }
  516. if ((cur[1] & 0xc0) != 0x80)
  517. goto encoding_error;
  518. if ((c & 0xe0) == 0xe0) {
  519. if (cur[2] == 0) {
  520. xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  521. cur = ctxt->input->cur;
  522. }
  523. if ((cur[2] & 0xc0) != 0x80)
  524. goto encoding_error;
  525. if ((c & 0xf0) == 0xf0) {
  526. if (cur[3] == 0) {
  527. xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  528. cur = ctxt->input->cur;
  529. }
  530. if (((c & 0xf8) != 0xf0) ||
  531. ((cur[3] & 0xc0) != 0x80))
  532. goto encoding_error;
  533. /* 4-byte code */
  534. *len = 4;
  535. val = (cur[0] & 0x7) << 18;
  536. val |= (cur[1] & 0x3f) << 12;
  537. val |= (cur[2] & 0x3f) << 6;
  538. val |= cur[3] & 0x3f;
  539. if (val < 0x10000)
  540. goto encoding_error;
  541. } else {
  542. /* 3-byte code */
  543. *len = 3;
  544. val = (cur[0] & 0xf) << 12;
  545. val |= (cur[1] & 0x3f) << 6;
  546. val |= cur[2] & 0x3f;
  547. if (val < 0x800)
  548. goto encoding_error;
  549. }
  550. } else {
  551. /* 2-byte code */
  552. *len = 2;
  553. val = (cur[0] & 0x1f) << 6;
  554. val |= cur[1] & 0x3f;
  555. if (val < 0x80)
  556. goto encoding_error;
  557. }
  558. if (!IS_CHAR(val)) {
  559. xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
  560. "Char 0x%X out of allowed range\n", val);
  561. }
  562. return(val);
  563. } else {
  564. /* 1-byte code */
  565. *len = 1;
  566. if (*ctxt->input->cur == 0)
  567. xmlParserInputGrow(ctxt->input, INPUT_CHUNK);
  568. if ((*ctxt->input->cur == 0) &&
  569. (ctxt->input->end > ctxt->input->cur)) {
  570. xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
  571. "Char 0x0 out of allowed range\n", 0);
  572. }
  573. if (*ctxt->input->cur == 0xD) {
  574. if (ctxt->input->cur[1] == 0xA) {
  575. ctxt->input->cur++;
  576. }
  577. return(0xA);
  578. }
  579. return((int) *ctxt->input->cur);
  580. }
  581. }
  582. /*
  583. * Assume it's a fixed length encoding (1) with
  584. * a compatible encoding for the ASCII set, since
  585. * XML constructs only use < 128 chars
  586. */
  587. *len = 1;
  588. if (*ctxt->input->cur == 0xD) {
  589. if (ctxt->input->cur[1] == 0xA) {
  590. ctxt->input->cur++;
  591. }
  592. return(0xA);
  593. }
  594. return((int) *ctxt->input->cur);
  595. encoding_error:
  596. /*
  597. * An encoding problem may arise from a truncated input buffer
  598. * splitting a character in the middle. In that case do not raise
  599. * an error but return 0 to indicate an end of stream problem
  600. */
  601. if (ctxt->input->end - ctxt->input->cur < 4) {
  602. *len = 0;
  603. return(0);
  604. }
  605. /*
  606. * If we detect an UTF8 error that probably mean that the
  607. * input encoding didn't get properly advertised in the
  608. * declaration header. Report the error and switch the encoding
  609. * to ISO-Latin-1 (if you don't like this policy, just declare the
  610. * encoding !)
  611. */
  612. {
  613. char buffer[150];
  614. snprintf(&buffer[0], 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
  615. ctxt->input->cur[0], ctxt->input->cur[1],
  616. ctxt->input->cur[2], ctxt->input->cur[3]);
  617. __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
  618. "Input is not proper UTF-8, indicate encoding !\n%s",
  619. BAD_CAST buffer, NULL);
  620. }
  621. ctxt->charset = XML_CHAR_ENCODING_8859_1;
  622. *len = 1;
  623. return((int) *ctxt->input->cur);
  624. }
  625. /**
  626. * xmlStringCurrentChar:
  627. * @ctxt: the XML parser context
  628. * @cur: pointer to the beginning of the char
  629. * @len: pointer to the length of the char read
  630. *
  631. * The current char value, if using UTF-8 this may actually span multiple
  632. * bytes in the input buffer.
  633. *
  634. * Returns the current char value and its length
  635. */
  636. int
  637. xmlStringCurrentChar(xmlParserCtxtPtr ctxt, const xmlChar * cur, int *len)
  638. {
  639. if ((len == NULL) || (cur == NULL)) return(0);
  640. if ((ctxt == NULL) || (ctxt->charset == XML_CHAR_ENCODING_UTF8)) {
  641. /*
  642. * We are supposed to handle UTF8, check it's valid
  643. * From rfc2044: encoding of the Unicode values on UTF-8:
  644. *
  645. * UCS-4 range (hex.) UTF-8 octet sequence (binary)
  646. * 0000 0000-0000 007F 0xxxxxxx
  647. * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
  648. * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
  649. *
  650. * Check for the 0x110000 limit too
  651. */
  652. unsigned char c;
  653. unsigned int val;
  654. c = *cur;
  655. if (c & 0x80) {
  656. if ((cur[1] & 0xc0) != 0x80)
  657. goto encoding_error;
  658. if ((c & 0xe0) == 0xe0) {
  659. if ((cur[2] & 0xc0) != 0x80)
  660. goto encoding_error;
  661. if ((c & 0xf0) == 0xf0) {
  662. if (((c & 0xf8) != 0xf0) || ((cur[3] & 0xc0) != 0x80))
  663. goto encoding_error;
  664. /* 4-byte code */
  665. *len = 4;
  666. val = (cur[0] & 0x7) << 18;
  667. val |= (cur[1] & 0x3f) << 12;
  668. val |= (cur[2] & 0x3f) << 6;
  669. val |= cur[3] & 0x3f;
  670. } else {
  671. /* 3-byte code */
  672. *len = 3;
  673. val = (cur[0] & 0xf) << 12;
  674. val |= (cur[1] & 0x3f) << 6;
  675. val |= cur[2] & 0x3f;
  676. }
  677. } else {
  678. /* 2-byte code */
  679. *len = 2;
  680. val = (cur[0] & 0x1f) << 6;
  681. val |= cur[1] & 0x3f;
  682. }
  683. if (!IS_CHAR(val)) {
  684. xmlErrEncodingInt(ctxt, XML_ERR_INVALID_CHAR,
  685. "Char 0x%X out of allowed range\n", val);
  686. }
  687. return (val);
  688. } else {
  689. /* 1-byte code */
  690. *len = 1;
  691. return ((int) *cur);
  692. }
  693. }
  694. /*
  695. * Assume it's a fixed length encoding (1) with
  696. * a compatible encoding for the ASCII set, since
  697. * XML constructs only use < 128 chars
  698. */
  699. *len = 1;
  700. return ((int) *cur);
  701. encoding_error:
  702. /*
  703. * An encoding problem may arise from a truncated input buffer
  704. * splitting a character in the middle. In that case do not raise
  705. * an error but return 0 to indicate an end of stream problem
  706. */
  707. if ((ctxt == NULL) || (ctxt->input == NULL) ||
  708. (ctxt->input->end - ctxt->input->cur < 4)) {
  709. *len = 0;
  710. return(0);
  711. }
  712. /*
  713. * If we detect an UTF8 error that probably mean that the
  714. * input encoding didn't get properly advertised in the
  715. * declaration header. Report the error and switch the encoding
  716. * to ISO-Latin-1 (if you don't like this policy, just declare the
  717. * encoding !)
  718. */
  719. {
  720. char buffer[150];
  721. snprintf(buffer, 149, "Bytes: 0x%02X 0x%02X 0x%02X 0x%02X\n",
  722. ctxt->input->cur[0], ctxt->input->cur[1],
  723. ctxt->input->cur[2], ctxt->input->cur[3]);
  724. __xmlErrEncoding(ctxt, XML_ERR_INVALID_CHAR,
  725. "Input is not proper UTF-8, indicate encoding !\n%s",
  726. BAD_CAST buffer, NULL);
  727. }
  728. *len = 1;
  729. return ((int) *cur);
  730. }
  731. /**
  732. * xmlCopyCharMultiByte:
  733. * @out: pointer to an array of xmlChar
  734. * @val: the char value
  735. *
  736. * append the char value in the array
  737. *
  738. * Returns the number of xmlChar written
  739. */
  740. int
  741. xmlCopyCharMultiByte(xmlChar *out, int val) {
  742. if (out == NULL) return(0);
  743. /*
  744. * We are supposed to handle UTF8, check it's valid
  745. * From rfc2044: encoding of the Unicode values on UTF-8:
  746. *
  747. * UCS-4 range (hex.) UTF-8 octet sequence (binary)
  748. * 0000 0000-0000 007F 0xxxxxxx
  749. * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
  750. * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
  751. */
  752. if (val >= 0x80) {
  753. xmlChar *savedout = out;
  754. int bits;
  755. if (val < 0x800) { *out++= (val >> 6) | 0xC0; bits= 0; }
  756. else if (val < 0x10000) { *out++= (val >> 12) | 0xE0; bits= 6;}
  757. else if (val < 0x110000) { *out++= (val >> 18) | 0xF0; bits= 12; }
  758. else {
  759. xmlErrEncodingInt(NULL, XML_ERR_INVALID_CHAR,
  760. "Internal error, xmlCopyCharMultiByte 0x%X out of bound\n",
  761. val);
  762. return(0);
  763. }
  764. for ( ; bits >= 0; bits-= 6)
  765. *out++= ((val >> bits) & 0x3F) | 0x80 ;
  766. return (out - savedout);
  767. }
  768. *out = (xmlChar) val;
  769. return 1;
  770. }
  771. /**
  772. * xmlCopyChar:
  773. * @len: Ignored, compatibility
  774. * @out: pointer to an array of xmlChar
  775. * @val: the char value
  776. *
  777. * append the char value in the array
  778. *
  779. * Returns the number of xmlChar written
  780. */
  781. int
  782. xmlCopyChar(int len ATTRIBUTE_UNUSED, xmlChar *out, int val) {
  783. if (out == NULL) return(0);
  784. /* the len parameter is ignored */
  785. if (val >= 0x80) {
  786. return(xmlCopyCharMultiByte (out, val));
  787. }
  788. *out = (xmlChar) val;
  789. return 1;
  790. }
  791. /************************************************************************
  792. * *
  793. * Commodity functions to switch encodings *
  794. * *
  795. ************************************************************************/
  796. static int
  797. xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
  798. xmlCharEncodingHandlerPtr handler, int len);
  799. /**
  800. * xmlSwitchEncoding:
  801. * @ctxt: the parser context
  802. * @enc: the encoding value (number)
  803. *
  804. * change the input functions when discovering the character encoding
  805. * of a given entity.
  806. *
  807. * Returns 0 in case of success, -1 otherwise
  808. */
  809. int
  810. xmlSwitchEncoding(xmlParserCtxtPtr ctxt, xmlCharEncoding enc)
  811. {
  812. xmlCharEncodingHandlerPtr handler;
  813. int len = -1;
  814. int ret;
  815. if (ctxt == NULL) return(-1);
  816. switch (enc) {
  817. case XML_CHAR_ENCODING_ERROR:
  818. __xmlErrEncoding(ctxt, XML_ERR_UNKNOWN_ENCODING,
  819. "encoding unknown\n", NULL, NULL);
  820. return(-1);
  821. case XML_CHAR_ENCODING_NONE:
  822. /* let's assume it's UTF-8 without the XML decl */
  823. ctxt->charset = XML_CHAR_ENCODING_UTF8;
  824. return(0);
  825. case XML_CHAR_ENCODING_UTF8:
  826. /* default encoding, no conversion should be needed */
  827. ctxt->charset = XML_CHAR_ENCODING_UTF8;
  828. /*
  829. * Errata on XML-1.0 June 20 2001
  830. * Specific handling of the Byte Order Mark for
  831. * UTF-8
  832. */
  833. if ((ctxt->input != NULL) &&
  834. (ctxt->input->cur[0] == 0xEF) &&
  835. (ctxt->input->cur[1] == 0xBB) &&
  836. (ctxt->input->cur[2] == 0xBF)) {
  837. ctxt->input->cur += 3;
  838. }
  839. return(0);
  840. case XML_CHAR_ENCODING_UTF16LE:
  841. case XML_CHAR_ENCODING_UTF16BE:
  842. /*The raw input characters are encoded
  843. *in UTF-16. As we expect this function
  844. *to be called after xmlCharEncInFunc, we expect
  845. *ctxt->input->cur to contain UTF-8 encoded characters.
  846. *So the raw UTF16 Byte Order Mark
  847. *has also been converted into
  848. *an UTF-8 BOM. Let's skip that BOM.
  849. */
  850. if ((ctxt->input != NULL) && (ctxt->input->cur != NULL) &&
  851. (ctxt->input->cur[0] == 0xEF) &&
  852. (ctxt->input->cur[1] == 0xBB) &&
  853. (ctxt->input->cur[2] == 0xBF)) {
  854. ctxt->input->cur += 3;
  855. }
  856. len = 90;
  857. break;
  858. case XML_CHAR_ENCODING_UCS2:
  859. len = 90;
  860. break;
  861. case XML_CHAR_ENCODING_UCS4BE:
  862. case XML_CHAR_ENCODING_UCS4LE:
  863. case XML_CHAR_ENCODING_UCS4_2143:
  864. case XML_CHAR_ENCODING_UCS4_3412:
  865. len = 180;
  866. break;
  867. case XML_CHAR_ENCODING_EBCDIC:
  868. case XML_CHAR_ENCODING_8859_1:
  869. case XML_CHAR_ENCODING_8859_2:
  870. case XML_CHAR_ENCODING_8859_3:
  871. case XML_CHAR_ENCODING_8859_4:
  872. case XML_CHAR_ENCODING_8859_5:
  873. case XML_CHAR_ENCODING_8859_6:
  874. case XML_CHAR_ENCODING_8859_7:
  875. case XML_CHAR_ENCODING_8859_8:
  876. case XML_CHAR_ENCODING_8859_9:
  877. case XML_CHAR_ENCODING_ASCII:
  878. case XML_CHAR_ENCODING_2022_JP:
  879. case XML_CHAR_ENCODING_SHIFT_JIS:
  880. case XML_CHAR_ENCODING_EUC_JP:
  881. len = 45;
  882. break;
  883. }
  884. handler = xmlGetCharEncodingHandler(enc);
  885. if (handler == NULL) {
  886. /*
  887. * Default handlers.
  888. */
  889. switch (enc) {
  890. case XML_CHAR_ENCODING_ASCII:
  891. /* default encoding, no conversion should be needed */
  892. ctxt->charset = XML_CHAR_ENCODING_UTF8;
  893. return(0);
  894. case XML_CHAR_ENCODING_8859_1:
  895. if ((ctxt->inputNr == 1) &&
  896. (ctxt->encoding == NULL) &&
  897. (ctxt->input != NULL) &&
  898. (ctxt->input->encoding != NULL)) {
  899. ctxt->encoding = xmlStrdup(ctxt->input->encoding);
  900. }
  901. ctxt->charset = enc;
  902. return(0);
  903. default:
  904. __xmlErrEncoding(ctxt, XML_ERR_UNSUPPORTED_ENCODING,
  905. "encoding not supported: %s\n",
  906. BAD_CAST xmlGetCharEncodingName(enc), NULL);
  907. /*
  908. * TODO: We could recover from errors in external entities
  909. * if we didn't stop the parser. But most callers of this
  910. * function don't check the return value.
  911. */
  912. xmlStopParser(ctxt);
  913. return(-1);
  914. }
  915. }
  916. ret = xmlSwitchInputEncodingInt(ctxt, ctxt->input, handler, len);
  917. if ((ret < 0) || (ctxt->errNo == XML_I18N_CONV_FAILED)) {
  918. /*
  919. * on encoding conversion errors, stop the parser
  920. */
  921. xmlStopParser(ctxt);
  922. ctxt->errNo = XML_I18N_CONV_FAILED;
  923. }
  924. return(ret);
  925. }
  926. /**
  927. * xmlSwitchInputEncodingInt:
  928. * @ctxt: the parser context
  929. * @input: the input stream
  930. * @handler: the encoding handler
  931. * @len: the number of bytes to convert for the first line or -1
  932. *
  933. * change the input functions when discovering the character encoding
  934. * of a given entity.
  935. *
  936. * Returns 0 in case of success, -1 otherwise
  937. */
  938. static int
  939. xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
  940. xmlCharEncodingHandlerPtr handler, int len)
  941. {
  942. int nbchars;
  943. if (handler == NULL)
  944. return (-1);
  945. if (input == NULL)
  946. return (-1);
  947. if (input->buf != NULL) {
  948. ctxt->charset = XML_CHAR_ENCODING_UTF8;
  949. if (input->buf->encoder != NULL) {
  950. /*
  951. * Check in case the auto encoding detection triggered
  952. * in already.
  953. */
  954. if (input->buf->encoder == handler)
  955. return (0);
  956. /*
  957. * "UTF-16" can be used for both LE and BE
  958. if ((!xmlStrncmp(BAD_CAST input->buf->encoder->name,
  959. BAD_CAST "UTF-16", 6)) &&
  960. (!xmlStrncmp(BAD_CAST handler->name,
  961. BAD_CAST "UTF-16", 6))) {
  962. return(0);
  963. }
  964. */
  965. /*
  966. * Note: this is a bit dangerous, but that's what it
  967. * takes to use nearly compatible signature for different
  968. * encodings.
  969. *
  970. * FIXME: Encoders might buffer partial byte sequences, so
  971. * this probably can't work. We should return an error and
  972. * make sure that callers never try to switch the encoding
  973. * twice.
  974. */
  975. xmlCharEncCloseFunc(input->buf->encoder);
  976. input->buf->encoder = handler;
  977. return (0);
  978. }
  979. input->buf->encoder = handler;
  980. /*
  981. * Is there already some content down the pipe to convert ?
  982. */
  983. if (xmlBufIsEmpty(input->buf->buffer) == 0) {
  984. int processed;
  985. unsigned int use;
  986. /*
  987. * Specific handling of the Byte Order Mark for
  988. * UTF-16
  989. */
  990. if ((handler->name != NULL) &&
  991. (!strcmp(handler->name, "UTF-16LE") ||
  992. !strcmp(handler->name, "UTF-16")) &&
  993. (input->cur[0] == 0xFF) && (input->cur[1] == 0xFE)) {
  994. input->cur += 2;
  995. }
  996. if ((handler->name != NULL) &&
  997. (!strcmp(handler->name, "UTF-16BE")) &&
  998. (input->cur[0] == 0xFE) && (input->cur[1] == 0xFF)) {
  999. input->cur += 2;
  1000. }
  1001. /*
  1002. * Errata on XML-1.0 June 20 2001
  1003. * Specific handling of the Byte Order Mark for
  1004. * UTF-8
  1005. */
  1006. if ((handler->name != NULL) &&
  1007. (!strcmp(handler->name, "UTF-8")) &&
  1008. (input->cur[0] == 0xEF) &&
  1009. (input->cur[1] == 0xBB) && (input->cur[2] == 0xBF)) {
  1010. input->cur += 3;
  1011. }
  1012. /*
  1013. * Shrink the current input buffer.
  1014. * Move it as the raw buffer and create a new input buffer
  1015. */
  1016. processed = input->cur - input->base;
  1017. xmlBufShrink(input->buf->buffer, processed);
  1018. input->buf->raw = input->buf->buffer;
  1019. input->buf->buffer = xmlBufCreate();
  1020. input->buf->rawconsumed = processed;
  1021. use = xmlBufUse(input->buf->raw);
  1022. if (ctxt->html) {
  1023. /*
  1024. * convert as much as possible of the buffer
  1025. */
  1026. nbchars = xmlCharEncInput(input->buf, 1);
  1027. } else {
  1028. /*
  1029. * convert just enough to get
  1030. * '<?xml version="1.0" encoding="xxx"?>'
  1031. * parsed with the autodetected encoding
  1032. * into the parser reading buffer.
  1033. */
  1034. nbchars = xmlCharEncFirstLineInput(input->buf, len);
  1035. }
  1036. xmlBufResetInput(input->buf->buffer, input);
  1037. if (nbchars < 0) {
  1038. xmlErrInternal(ctxt,
  1039. "switching encoding: encoder error\n",
  1040. NULL);
  1041. return (-1);
  1042. }
  1043. input->buf->rawconsumed += use - xmlBufUse(input->buf->raw);
  1044. }
  1045. return (0);
  1046. } else {
  1047. xmlErrInternal(ctxt,
  1048. "static memory buffer doesn't support encoding\n", NULL);
  1049. /*
  1050. * Callers assume that the input buffer takes ownership of the
  1051. * encoding handler. xmlCharEncCloseFunc frees unregistered
  1052. * handlers and avoids a memory leak.
  1053. */
  1054. xmlCharEncCloseFunc(handler);
  1055. return (-1);
  1056. }
  1057. }
  1058. /**
  1059. * xmlSwitchInputEncoding:
  1060. * @ctxt: the parser context
  1061. * @input: the input stream
  1062. * @handler: the encoding handler
  1063. *
  1064. * DEPRECATED: Use xmlSwitchToEncoding
  1065. *
  1066. * change the input functions when discovering the character encoding
  1067. * of a given entity.
  1068. *
  1069. * Returns 0 in case of success, -1 otherwise
  1070. */
  1071. int
  1072. xmlSwitchInputEncoding(xmlParserCtxtPtr ctxt, xmlParserInputPtr input,
  1073. xmlCharEncodingHandlerPtr handler) {
  1074. return(xmlSwitchInputEncodingInt(ctxt, input, handler, -1));
  1075. }
  1076. /**
  1077. * xmlSwitchToEncoding:
  1078. * @ctxt: the parser context
  1079. * @handler: the encoding handler
  1080. *
  1081. * change the input functions when discovering the character encoding
  1082. * of a given entity.
  1083. *
  1084. * Returns 0 in case of success, -1 otherwise
  1085. */
  1086. int
  1087. xmlSwitchToEncoding(xmlParserCtxtPtr ctxt, xmlCharEncodingHandlerPtr handler)
  1088. {
  1089. if (ctxt == NULL)
  1090. return(-1);
  1091. return(xmlSwitchInputEncodingInt(ctxt, ctxt->input, handler, -1));
  1092. }
  1093. /************************************************************************
  1094. * *
  1095. * Commodity functions to handle entities processing *
  1096. * *
  1097. ************************************************************************/
  1098. /**
  1099. * xmlFreeInputStream:
  1100. * @input: an xmlParserInputPtr
  1101. *
  1102. * Free up an input stream.
  1103. */
  1104. void
  1105. xmlFreeInputStream(xmlParserInputPtr input) {
  1106. if (input == NULL) return;
  1107. if (input->filename != NULL) xmlFree((char *) input->filename);
  1108. if (input->directory != NULL) xmlFree((char *) input->directory);
  1109. if (input->encoding != NULL) xmlFree((char *) input->encoding);
  1110. if (input->version != NULL) xmlFree((char *) input->version);
  1111. if ((input->free != NULL) && (input->base != NULL))
  1112. input->free((xmlChar *) input->base);
  1113. if (input->buf != NULL)
  1114. xmlFreeParserInputBuffer(input->buf);
  1115. xmlFree(input);
  1116. }
  1117. /**
  1118. * xmlNewInputStream:
  1119. * @ctxt: an XML parser context
  1120. *
  1121. * Create a new input stream structure.
  1122. *
  1123. * Returns the new input stream or NULL
  1124. */
  1125. xmlParserInputPtr
  1126. xmlNewInputStream(xmlParserCtxtPtr ctxt) {
  1127. xmlParserInputPtr input;
  1128. input = (xmlParserInputPtr) xmlMalloc(sizeof(xmlParserInput));
  1129. if (input == NULL) {
  1130. xmlErrMemory(ctxt, "couldn't allocate a new input stream\n");
  1131. return(NULL);
  1132. }
  1133. memset(input, 0, sizeof(xmlParserInput));
  1134. input->line = 1;
  1135. input->col = 1;
  1136. input->standalone = -1;
  1137. /*
  1138. * If the context is NULL the id cannot be initialized, but that
  1139. * should not happen while parsing which is the situation where
  1140. * the id is actually needed.
  1141. */
  1142. if (ctxt != NULL) {
  1143. if (ctxt->input_id >= INT_MAX) {
  1144. xmlErrMemory(ctxt, "Input ID overflow\n");
  1145. return(NULL);
  1146. }
  1147. input->id = ctxt->input_id++;
  1148. }
  1149. return(input);
  1150. }
  1151. /**
  1152. * xmlNewIOInputStream:
  1153. * @ctxt: an XML parser context
  1154. * @input: an I/O Input
  1155. * @enc: the charset encoding if known
  1156. *
  1157. * Create a new input stream structure encapsulating the @input into
  1158. * a stream suitable for the parser.
  1159. *
  1160. * Returns the new input stream or NULL
  1161. */
  1162. xmlParserInputPtr
  1163. xmlNewIOInputStream(xmlParserCtxtPtr ctxt, xmlParserInputBufferPtr input,
  1164. xmlCharEncoding enc) {
  1165. xmlParserInputPtr inputStream;
  1166. if (input == NULL) return(NULL);
  1167. if (xmlParserDebugEntities)
  1168. xmlGenericError(xmlGenericErrorContext, "new input from I/O\n");
  1169. inputStream = xmlNewInputStream(ctxt);
  1170. if (inputStream == NULL) {
  1171. return(NULL);
  1172. }
  1173. inputStream->filename = NULL;
  1174. inputStream->buf = input;
  1175. xmlBufResetInput(inputStream->buf->buffer, inputStream);
  1176. if (enc != XML_CHAR_ENCODING_NONE) {
  1177. xmlSwitchEncoding(ctxt, enc);
  1178. }
  1179. return(inputStream);
  1180. }
  1181. /**
  1182. * xmlNewEntityInputStream:
  1183. * @ctxt: an XML parser context
  1184. * @entity: an Entity pointer
  1185. *
  1186. * Create a new input stream based on an xmlEntityPtr
  1187. *
  1188. * Returns the new input stream or NULL
  1189. */
  1190. xmlParserInputPtr
  1191. xmlNewEntityInputStream(xmlParserCtxtPtr ctxt, xmlEntityPtr entity) {
  1192. xmlParserInputPtr input;
  1193. if (entity == NULL) {
  1194. xmlErrInternal(ctxt, "xmlNewEntityInputStream entity = NULL\n",
  1195. NULL);
  1196. return(NULL);
  1197. }
  1198. if (xmlParserDebugEntities)
  1199. xmlGenericError(xmlGenericErrorContext,
  1200. "new input from entity: %s\n", entity->name);
  1201. if (entity->content == NULL) {
  1202. switch (entity->etype) {
  1203. case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY:
  1204. xmlErrInternal(ctxt, "Cannot parse entity %s\n",
  1205. entity->name);
  1206. break;
  1207. case XML_EXTERNAL_GENERAL_PARSED_ENTITY:
  1208. case XML_EXTERNAL_PARAMETER_ENTITY:
  1209. return(xmlLoadExternalEntity((char *) entity->URI,
  1210. (char *) entity->ExternalID, ctxt));
  1211. case XML_INTERNAL_GENERAL_ENTITY:
  1212. xmlErrInternal(ctxt,
  1213. "Internal entity %s without content !\n",
  1214. entity->name);
  1215. break;
  1216. case XML_INTERNAL_PARAMETER_ENTITY:
  1217. xmlErrInternal(ctxt,
  1218. "Internal parameter entity %s without content !\n",
  1219. entity->name);
  1220. break;
  1221. case XML_INTERNAL_PREDEFINED_ENTITY:
  1222. xmlErrInternal(ctxt,
  1223. "Predefined entity %s without content !\n",
  1224. entity->name);
  1225. break;
  1226. }
  1227. return(NULL);
  1228. }
  1229. input = xmlNewInputStream(ctxt);
  1230. if (input == NULL) {
  1231. return(NULL);
  1232. }
  1233. if (entity->URI != NULL)
  1234. input->filename = (char *) xmlStrdup((xmlChar *) entity->URI);
  1235. input->base = entity->content;
  1236. if (entity->length == 0)
  1237. entity->length = xmlStrlen(entity->content);
  1238. input->cur = entity->content;
  1239. input->length = entity->length;
  1240. input->end = &entity->content[input->length];
  1241. return(input);
  1242. }
  1243. /**
  1244. * xmlNewStringInputStream:
  1245. * @ctxt: an XML parser context
  1246. * @buffer: an memory buffer
  1247. *
  1248. * Create a new input stream based on a memory buffer.
  1249. * Returns the new input stream
  1250. */
  1251. xmlParserInputPtr
  1252. xmlNewStringInputStream(xmlParserCtxtPtr ctxt, const xmlChar *buffer) {
  1253. xmlParserInputPtr input;
  1254. if (buffer == NULL) {
  1255. xmlErrInternal(ctxt, "xmlNewStringInputStream string = NULL\n",
  1256. NULL);
  1257. return(NULL);
  1258. }
  1259. if (xmlParserDebugEntities)
  1260. xmlGenericError(xmlGenericErrorContext,
  1261. "new fixed input: %.30s\n", buffer);
  1262. input = xmlNewInputStream(ctxt);
  1263. if (input == NULL) {
  1264. xmlErrMemory(ctxt, "couldn't allocate a new input stream\n");
  1265. return(NULL);
  1266. }
  1267. input->base = buffer;
  1268. input->cur = buffer;
  1269. input->length = xmlStrlen(buffer);
  1270. input->end = &buffer[input->length];
  1271. return(input);
  1272. }
  1273. /**
  1274. * xmlNewInputFromFile:
  1275. * @ctxt: an XML parser context
  1276. * @filename: the filename to use as entity
  1277. *
  1278. * Create a new input stream based on a file or an URL.
  1279. *
  1280. * Returns the new input stream or NULL in case of error
  1281. */
  1282. xmlParserInputPtr
  1283. xmlNewInputFromFile(xmlParserCtxtPtr ctxt, const char *filename) {
  1284. xmlParserInputBufferPtr buf;
  1285. xmlParserInputPtr inputStream;
  1286. char *directory = NULL;
  1287. xmlChar *URI = NULL;
  1288. if (xmlParserDebugEntities)
  1289. xmlGenericError(xmlGenericErrorContext,
  1290. "new input from file: %s\n", filename);
  1291. if (ctxt == NULL) return(NULL);
  1292. buf = xmlParserInputBufferCreateFilename(filename, XML_CHAR_ENCODING_NONE);
  1293. if (buf == NULL) {
  1294. if (filename == NULL)
  1295. __xmlLoaderErr(ctxt,
  1296. "failed to load external entity: NULL filename \n",
  1297. NULL);
  1298. else
  1299. __xmlLoaderErr(ctxt, "failed to load external entity \"%s\"\n",
  1300. (const char *) filename);
  1301. return(NULL);
  1302. }
  1303. inputStream = xmlNewInputStream(ctxt);
  1304. if (inputStream == NULL) {
  1305. xmlFreeParserInputBuffer(buf);
  1306. return(NULL);
  1307. }
  1308. inputStream->buf = buf;
  1309. inputStream = xmlCheckHTTPInput(ctxt, inputStream);
  1310. if (inputStream == NULL)
  1311. return(NULL);
  1312. if (inputStream->filename == NULL)
  1313. URI = xmlStrdup((xmlChar *) filename);
  1314. else
  1315. URI = xmlStrdup((xmlChar *) inputStream->filename);
  1316. directory = xmlParserGetDirectory((const char *) URI);
  1317. if (inputStream->filename != NULL) xmlFree((char *)inputStream->filename);
  1318. inputStream->filename = (char *) xmlCanonicPath((const xmlChar *) URI);
  1319. if (URI != NULL) xmlFree((char *) URI);
  1320. inputStream->directory = directory;
  1321. xmlBufResetInput(inputStream->buf->buffer, inputStream);
  1322. if ((ctxt->directory == NULL) && (directory != NULL))
  1323. ctxt->directory = (char *) xmlStrdup((const xmlChar *) directory);
  1324. return(inputStream);
  1325. }
  1326. /************************************************************************
  1327. * *
  1328. * Commodity functions to handle parser contexts *
  1329. * *
  1330. ************************************************************************/
  1331. /**
  1332. * xmlInitParserCtxt:
  1333. * @ctxt: an XML parser context
  1334. *
  1335. * Initialize a parser context
  1336. *
  1337. * Returns 0 in case of success and -1 in case of error
  1338. */
  1339. int
  1340. xmlInitParserCtxt(xmlParserCtxtPtr ctxt)
  1341. {
  1342. xmlParserInputPtr input;
  1343. if(ctxt==NULL) {
  1344. xmlErrInternal(NULL, "Got NULL parser context\n", NULL);
  1345. return(-1);
  1346. }
  1347. xmlInitParser();
  1348. if (ctxt->dict == NULL)
  1349. ctxt->dict = xmlDictCreate();
  1350. if (ctxt->dict == NULL) {
  1351. xmlErrMemory(NULL, "cannot initialize parser context\n");
  1352. return(-1);
  1353. }
  1354. xmlDictSetLimit(ctxt->dict, XML_MAX_DICTIONARY_LIMIT);
  1355. if (ctxt->sax == NULL)
  1356. ctxt->sax = (xmlSAXHandler *) xmlMalloc(sizeof(xmlSAXHandler));
  1357. if (ctxt->sax == NULL) {
  1358. xmlErrMemory(NULL, "cannot initialize parser context\n");
  1359. return(-1);
  1360. }
  1361. else
  1362. xmlSAXVersion(ctxt->sax, 2);
  1363. ctxt->maxatts = 0;
  1364. ctxt->atts = NULL;
  1365. /* Allocate the Input stack */
  1366. if (ctxt->inputTab == NULL) {
  1367. ctxt->inputTab = (xmlParserInputPtr *)
  1368. xmlMalloc(5 * sizeof(xmlParserInputPtr));
  1369. ctxt->inputMax = 5;
  1370. }
  1371. if (ctxt->inputTab == NULL) {
  1372. xmlErrMemory(NULL, "cannot initialize parser context\n");
  1373. ctxt->inputNr = 0;
  1374. ctxt->inputMax = 0;
  1375. ctxt->input = NULL;
  1376. return(-1);
  1377. }
  1378. while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
  1379. xmlFreeInputStream(input);
  1380. }
  1381. ctxt->inputNr = 0;
  1382. ctxt->input = NULL;
  1383. ctxt->version = NULL;
  1384. ctxt->encoding = NULL;
  1385. ctxt->standalone = -1;
  1386. ctxt->hasExternalSubset = 0;
  1387. ctxt->hasPErefs = 0;
  1388. ctxt->html = 0;
  1389. ctxt->external = 0;
  1390. ctxt->instate = XML_PARSER_START;
  1391. ctxt->token = 0;
  1392. ctxt->directory = NULL;
  1393. /* Allocate the Node stack */
  1394. if (ctxt->nodeTab == NULL) {
  1395. ctxt->nodeTab = (xmlNodePtr *) xmlMalloc(10 * sizeof(xmlNodePtr));
  1396. ctxt->nodeMax = 10;
  1397. }
  1398. if (ctxt->nodeTab == NULL) {
  1399. xmlErrMemory(NULL, "cannot initialize parser context\n");
  1400. ctxt->nodeNr = 0;
  1401. ctxt->nodeMax = 0;
  1402. ctxt->node = NULL;
  1403. ctxt->inputNr = 0;
  1404. ctxt->inputMax = 0;
  1405. ctxt->input = NULL;
  1406. return(-1);
  1407. }
  1408. ctxt->nodeNr = 0;
  1409. ctxt->node = NULL;
  1410. /* Allocate the Name stack */
  1411. if (ctxt->nameTab == NULL) {
  1412. ctxt->nameTab = (const xmlChar **) xmlMalloc(10 * sizeof(xmlChar *));
  1413. ctxt->nameMax = 10;
  1414. }
  1415. if (ctxt->nameTab == NULL) {
  1416. xmlErrMemory(NULL, "cannot initialize parser context\n");
  1417. ctxt->nodeNr = 0;
  1418. ctxt->nodeMax = 0;
  1419. ctxt->node = NULL;
  1420. ctxt->inputNr = 0;
  1421. ctxt->inputMax = 0;
  1422. ctxt->input = NULL;
  1423. ctxt->nameNr = 0;
  1424. ctxt->nameMax = 0;
  1425. ctxt->name = NULL;
  1426. return(-1);
  1427. }
  1428. ctxt->nameNr = 0;
  1429. ctxt->name = NULL;
  1430. /* Allocate the space stack */
  1431. if (ctxt->spaceTab == NULL) {
  1432. ctxt->spaceTab = (int *) xmlMalloc(10 * sizeof(int));
  1433. ctxt->spaceMax = 10;
  1434. }
  1435. if (ctxt->spaceTab == NULL) {
  1436. xmlErrMemory(NULL, "cannot initialize parser context\n");
  1437. ctxt->nodeNr = 0;
  1438. ctxt->nodeMax = 0;
  1439. ctxt->node = NULL;
  1440. ctxt->inputNr = 0;
  1441. ctxt->inputMax = 0;
  1442. ctxt->input = NULL;
  1443. ctxt->nameNr = 0;
  1444. ctxt->nameMax = 0;
  1445. ctxt->name = NULL;
  1446. ctxt->spaceNr = 0;
  1447. ctxt->spaceMax = 0;
  1448. ctxt->space = NULL;
  1449. return(-1);
  1450. }
  1451. ctxt->spaceNr = 1;
  1452. ctxt->spaceMax = 10;
  1453. ctxt->spaceTab[0] = -1;
  1454. ctxt->space = &ctxt->spaceTab[0];
  1455. ctxt->userData = ctxt;
  1456. ctxt->myDoc = NULL;
  1457. ctxt->wellFormed = 1;
  1458. ctxt->nsWellFormed = 1;
  1459. ctxt->valid = 1;
  1460. ctxt->loadsubset = xmlLoadExtDtdDefaultValue;
  1461. if (ctxt->loadsubset) {
  1462. ctxt->options |= XML_PARSE_DTDLOAD;
  1463. }
  1464. ctxt->validate = xmlDoValidityCheckingDefaultValue;
  1465. ctxt->pedantic = xmlPedanticParserDefaultValue;
  1466. if (ctxt->pedantic) {
  1467. ctxt->options |= XML_PARSE_PEDANTIC;
  1468. }
  1469. ctxt->linenumbers = xmlLineNumbersDefaultValue;
  1470. ctxt->keepBlanks = xmlKeepBlanksDefaultValue;
  1471. if (ctxt->keepBlanks == 0) {
  1472. ctxt->sax->ignorableWhitespace = xmlSAX2IgnorableWhitespace;
  1473. ctxt->options |= XML_PARSE_NOBLANKS;
  1474. }
  1475. ctxt->vctxt.flags = XML_VCTXT_USE_PCTXT;
  1476. ctxt->vctxt.userData = ctxt;
  1477. ctxt->vctxt.error = xmlParserValidityError;
  1478. ctxt->vctxt.warning = xmlParserValidityWarning;
  1479. if (ctxt->validate) {
  1480. if (xmlGetWarningsDefaultValue == 0)
  1481. ctxt->vctxt.warning = NULL;
  1482. else
  1483. ctxt->vctxt.warning = xmlParserValidityWarning;
  1484. ctxt->vctxt.nodeMax = 0;
  1485. ctxt->options |= XML_PARSE_DTDVALID;
  1486. }
  1487. ctxt->replaceEntities = xmlSubstituteEntitiesDefaultValue;
  1488. if (ctxt->replaceEntities) {
  1489. ctxt->options |= XML_PARSE_NOENT;
  1490. }
  1491. ctxt->record_info = 0;
  1492. ctxt->checkIndex = 0;
  1493. ctxt->inSubset = 0;
  1494. ctxt->errNo = XML_ERR_OK;
  1495. ctxt->depth = 0;
  1496. ctxt->charset = XML_CHAR_ENCODING_UTF8;
  1497. ctxt->catalogs = NULL;
  1498. ctxt->nbentities = 0;
  1499. ctxt->sizeentities = 0;
  1500. ctxt->sizeentcopy = 0;
  1501. ctxt->input_id = 1;
  1502. xmlInitNodeInfoSeq(&ctxt->node_seq);
  1503. return(0);
  1504. }
  1505. /**
  1506. * xmlFreeParserCtxt:
  1507. * @ctxt: an XML parser context
  1508. *
  1509. * Free all the memory used by a parser context. However the parsed
  1510. * document in ctxt->myDoc is not freed.
  1511. */
  1512. void
  1513. xmlFreeParserCtxt(xmlParserCtxtPtr ctxt)
  1514. {
  1515. xmlParserInputPtr input;
  1516. if (ctxt == NULL) return;
  1517. while ((input = inputPop(ctxt)) != NULL) { /* Non consuming */
  1518. xmlFreeInputStream(input);
  1519. }
  1520. if (ctxt->spaceTab != NULL) xmlFree(ctxt->spaceTab);
  1521. if (ctxt->nameTab != NULL) xmlFree((xmlChar * *)ctxt->nameTab);
  1522. if (ctxt->nodeTab != NULL) xmlFree(ctxt->nodeTab);
  1523. if (ctxt->nodeInfoTab != NULL) xmlFree(ctxt->nodeInfoTab);
  1524. if (ctxt->inputTab != NULL) xmlFree(ctxt->inputTab);
  1525. if (ctxt->version != NULL) xmlFree((char *) ctxt->version);
  1526. if (ctxt->encoding != NULL) xmlFree((char *) ctxt->encoding);
  1527. if (ctxt->extSubURI != NULL) xmlFree((char *) ctxt->extSubURI);
  1528. if (ctxt->extSubSystem != NULL) xmlFree((char *) ctxt->extSubSystem);
  1529. #ifdef LIBXML_SAX1_ENABLED
  1530. if ((ctxt->sax != NULL) &&
  1531. (ctxt->sax != (xmlSAXHandlerPtr) &xmlDefaultSAXHandler))
  1532. #else
  1533. if (ctxt->sax != NULL)
  1534. #endif /* LIBXML_SAX1_ENABLED */
  1535. xmlFree(ctxt->sax);
  1536. if (ctxt->directory != NULL) xmlFree((char *) ctxt->directory);
  1537. if (ctxt->vctxt.nodeTab != NULL) xmlFree(ctxt->vctxt.nodeTab);
  1538. if (ctxt->atts != NULL) xmlFree((xmlChar * *)ctxt->atts);
  1539. if (ctxt->dict != NULL) xmlDictFree(ctxt->dict);
  1540. if (ctxt->nsTab != NULL) xmlFree((char *) ctxt->nsTab);
  1541. if (ctxt->pushTab != NULL) xmlFree(ctxt->pushTab);
  1542. if (ctxt->attallocs != NULL) xmlFree(ctxt->attallocs);
  1543. if (ctxt->attsDefault != NULL)
  1544. xmlHashFree(ctxt->attsDefault, xmlHashDefaultDeallocator);
  1545. if (ctxt->attsSpecial != NULL)
  1546. xmlHashFree(ctxt->attsSpecial, NULL);
  1547. if (ctxt->freeElems != NULL) {
  1548. xmlNodePtr cur, next;
  1549. cur = ctxt->freeElems;
  1550. while (cur != NULL) {
  1551. next = cur->next;
  1552. xmlFree(cur);
  1553. cur = next;
  1554. }
  1555. }
  1556. if (ctxt->freeAttrs != NULL) {
  1557. xmlAttrPtr cur, next;
  1558. cur = ctxt->freeAttrs;
  1559. while (cur != NULL) {
  1560. next = cur->next;
  1561. xmlFree(cur);
  1562. cur = next;
  1563. }
  1564. }
  1565. /*
  1566. * cleanup the error strings
  1567. */
  1568. if (ctxt->lastError.message != NULL)
  1569. xmlFree(ctxt->lastError.message);
  1570. if (ctxt->lastError.file != NULL)
  1571. xmlFree(ctxt->lastError.file);
  1572. if (ctxt->lastError.str1 != NULL)
  1573. xmlFree(ctxt->lastError.str1);
  1574. if (ctxt->lastError.str2 != NULL)
  1575. xmlFree(ctxt->lastError.str2);
  1576. if (ctxt->lastError.str3 != NULL)
  1577. xmlFree(ctxt->lastError.str3);
  1578. #ifdef LIBXML_CATALOG_ENABLED
  1579. if (ctxt->catalogs != NULL)
  1580. xmlCatalogFreeLocal(ctxt->catalogs);
  1581. #endif
  1582. xmlFree(ctxt);
  1583. }
  1584. /**
  1585. * xmlNewParserCtxt:
  1586. *
  1587. * Allocate and initialize a new parser context.
  1588. *
  1589. * Returns the xmlParserCtxtPtr or NULL
  1590. */
  1591. xmlParserCtxtPtr
  1592. xmlNewParserCtxt(void)
  1593. {
  1594. xmlParserCtxtPtr ctxt;
  1595. ctxt = (xmlParserCtxtPtr) xmlMalloc(sizeof(xmlParserCtxt));
  1596. if (ctxt == NULL) {
  1597. xmlErrMemory(NULL, "cannot allocate parser context\n");
  1598. return(NULL);
  1599. }
  1600. memset(ctxt, 0, sizeof(xmlParserCtxt));
  1601. if (xmlInitParserCtxt(ctxt) < 0) {
  1602. xmlFreeParserCtxt(ctxt);
  1603. return(NULL);
  1604. }
  1605. return(ctxt);
  1606. }
  1607. /************************************************************************
  1608. * *
  1609. * Handling of node information *
  1610. * *
  1611. ************************************************************************/
  1612. /**
  1613. * xmlClearParserCtxt:
  1614. * @ctxt: an XML parser context
  1615. *
  1616. * Clear (release owned resources) and reinitialize a parser context
  1617. */
  1618. void
  1619. xmlClearParserCtxt(xmlParserCtxtPtr ctxt)
  1620. {
  1621. if (ctxt==NULL)
  1622. return;
  1623. xmlClearNodeInfoSeq(&ctxt->node_seq);
  1624. xmlCtxtReset(ctxt);
  1625. }
  1626. /**
  1627. * xmlParserFindNodeInfo:
  1628. * @ctx: an XML parser context
  1629. * @node: an XML node within the tree
  1630. *
  1631. * Find the parser node info struct for a given node
  1632. *
  1633. * Returns an xmlParserNodeInfo block pointer or NULL
  1634. */
  1635. const xmlParserNodeInfo *
  1636. xmlParserFindNodeInfo(const xmlParserCtxtPtr ctx, const xmlNodePtr node)
  1637. {
  1638. unsigned long pos;
  1639. if ((ctx == NULL) || (node == NULL))
  1640. return (NULL);
  1641. /* Find position where node should be at */
  1642. pos = xmlParserFindNodeInfoIndex(&ctx->node_seq, node);
  1643. if (pos < ctx->node_seq.length
  1644. && ctx->node_seq.buffer[pos].node == node)
  1645. return &ctx->node_seq.buffer[pos];
  1646. else
  1647. return NULL;
  1648. }
  1649. /**
  1650. * xmlInitNodeInfoSeq:
  1651. * @seq: a node info sequence pointer
  1652. *
  1653. * -- Initialize (set to initial state) node info sequence
  1654. */
  1655. void
  1656. xmlInitNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
  1657. {
  1658. if (seq == NULL)
  1659. return;
  1660. seq->length = 0;
  1661. seq->maximum = 0;
  1662. seq->buffer = NULL;
  1663. }
  1664. /**
  1665. * xmlClearNodeInfoSeq:
  1666. * @seq: a node info sequence pointer
  1667. *
  1668. * -- Clear (release memory and reinitialize) node
  1669. * info sequence
  1670. */
  1671. void
  1672. xmlClearNodeInfoSeq(xmlParserNodeInfoSeqPtr seq)
  1673. {
  1674. if (seq == NULL)
  1675. return;
  1676. if (seq->buffer != NULL)
  1677. xmlFree(seq->buffer);
  1678. xmlInitNodeInfoSeq(seq);
  1679. }
  1680. /**
  1681. * xmlParserFindNodeInfoIndex:
  1682. * @seq: a node info sequence pointer
  1683. * @node: an XML node pointer
  1684. *
  1685. *
  1686. * xmlParserFindNodeInfoIndex : Find the index that the info record for
  1687. * the given node is or should be at in a sorted sequence
  1688. *
  1689. * Returns a long indicating the position of the record
  1690. */
  1691. unsigned long
  1692. xmlParserFindNodeInfoIndex(const xmlParserNodeInfoSeqPtr seq,
  1693. const xmlNodePtr node)
  1694. {
  1695. unsigned long upper, lower, middle;
  1696. int found = 0;
  1697. if ((seq == NULL) || (node == NULL))
  1698. return ((unsigned long) -1);
  1699. /* Do a binary search for the key */
  1700. lower = 1;
  1701. upper = seq->length;
  1702. middle = 0;
  1703. while (lower <= upper && !found) {
  1704. middle = lower + (upper - lower) / 2;
  1705. if (node == seq->buffer[middle - 1].node)
  1706. found = 1;
  1707. else if (node < seq->buffer[middle - 1].node)
  1708. upper = middle - 1;
  1709. else
  1710. lower = middle + 1;
  1711. }
  1712. /* Return position */
  1713. if (middle == 0 || seq->buffer[middle - 1].node < node)
  1714. return middle;
  1715. else
  1716. return middle - 1;
  1717. }
  1718. /**
  1719. * xmlParserAddNodeInfo:
  1720. * @ctxt: an XML parser context
  1721. * @info: a node info sequence pointer
  1722. *
  1723. * Insert node info record into the sorted sequence
  1724. */
  1725. void
  1726. xmlParserAddNodeInfo(xmlParserCtxtPtr ctxt,
  1727. const xmlParserNodeInfoPtr info)
  1728. {
  1729. unsigned long pos;
  1730. if ((ctxt == NULL) || (info == NULL)) return;
  1731. /* Find pos and check to see if node is already in the sequence */
  1732. pos = xmlParserFindNodeInfoIndex(&ctxt->node_seq, (xmlNodePtr)
  1733. info->node);
  1734. if ((pos < ctxt->node_seq.length) &&
  1735. (ctxt->node_seq.buffer != NULL) &&
  1736. (ctxt->node_seq.buffer[pos].node == info->node)) {
  1737. ctxt->node_seq.buffer[pos] = *info;
  1738. }
  1739. /* Otherwise, we need to add new node to buffer */
  1740. else {
  1741. if ((ctxt->node_seq.length + 1 > ctxt->node_seq.maximum) ||
  1742. (ctxt->node_seq.buffer == NULL)) {
  1743. xmlParserNodeInfo *tmp_buffer;
  1744. unsigned int byte_size;
  1745. if (ctxt->node_seq.maximum == 0)
  1746. ctxt->node_seq.maximum = 2;
  1747. byte_size = (sizeof(*ctxt->node_seq.buffer) *
  1748. (2 * ctxt->node_seq.maximum));
  1749. if (ctxt->node_seq.buffer == NULL)
  1750. tmp_buffer = (xmlParserNodeInfo *) xmlMalloc(byte_size);
  1751. else
  1752. tmp_buffer =
  1753. (xmlParserNodeInfo *) xmlRealloc(ctxt->node_seq.buffer,
  1754. byte_size);
  1755. if (tmp_buffer == NULL) {
  1756. xmlErrMemory(ctxt, "failed to allocate buffer\n");
  1757. return;
  1758. }
  1759. ctxt->node_seq.buffer = tmp_buffer;
  1760. ctxt->node_seq.maximum *= 2;
  1761. }
  1762. /* If position is not at end, move elements out of the way */
  1763. if (pos != ctxt->node_seq.length) {
  1764. unsigned long i;
  1765. for (i = ctxt->node_seq.length; i > pos; i--)
  1766. ctxt->node_seq.buffer[i] = ctxt->node_seq.buffer[i - 1];
  1767. }
  1768. /* Copy element and increase length */
  1769. ctxt->node_seq.buffer[pos] = *info;
  1770. ctxt->node_seq.length++;
  1771. }
  1772. }
  1773. /************************************************************************
  1774. * *
  1775. * Defaults settings *
  1776. * *
  1777. ************************************************************************/
  1778. /**
  1779. * xmlPedanticParserDefault:
  1780. * @val: int 0 or 1
  1781. *
  1782. * Set and return the previous value for enabling pedantic warnings.
  1783. *
  1784. * Returns the last value for 0 for no substitution, 1 for substitution.
  1785. */
  1786. int
  1787. xmlPedanticParserDefault(int val) {
  1788. int old = xmlPedanticParserDefaultValue;
  1789. xmlPedanticParserDefaultValue = val;
  1790. return(old);
  1791. }
  1792. /**
  1793. * xmlLineNumbersDefault:
  1794. * @val: int 0 or 1
  1795. *
  1796. * Set and return the previous value for enabling line numbers in elements
  1797. * contents. This may break on old application and is turned off by default.
  1798. *
  1799. * Returns the last value for 0 for no substitution, 1 for substitution.
  1800. */
  1801. int
  1802. xmlLineNumbersDefault(int val) {
  1803. int old = xmlLineNumbersDefaultValue;
  1804. xmlLineNumbersDefaultValue = val;
  1805. return(old);
  1806. }
  1807. /**
  1808. * xmlSubstituteEntitiesDefault:
  1809. * @val: int 0 or 1
  1810. *
  1811. * Set and return the previous value for default entity support.
  1812. * Initially the parser always keep entity references instead of substituting
  1813. * entity values in the output. This function has to be used to change the
  1814. * default parser behavior
  1815. * SAX::substituteEntities() has to be used for changing that on a file by
  1816. * file basis.
  1817. *
  1818. * Returns the last value for 0 for no substitution, 1 for substitution.
  1819. */
  1820. int
  1821. xmlSubstituteEntitiesDefault(int val) {
  1822. int old = xmlSubstituteEntitiesDefaultValue;
  1823. xmlSubstituteEntitiesDefaultValue = val;
  1824. return(old);
  1825. }
  1826. /**
  1827. * xmlKeepBlanksDefault:
  1828. * @val: int 0 or 1
  1829. *
  1830. * Set and return the previous value for default blanks text nodes support.
  1831. * The 1.x version of the parser used an heuristic to try to detect
  1832. * ignorable white spaces. As a result the SAX callback was generating
  1833. * xmlSAX2IgnorableWhitespace() callbacks instead of characters() one, and when
  1834. * using the DOM output text nodes containing those blanks were not generated.
  1835. * The 2.x and later version will switch to the XML standard way and
  1836. * ignorableWhitespace() are only generated when running the parser in
  1837. * validating mode and when the current element doesn't allow CDATA or
  1838. * mixed content.
  1839. * This function is provided as a way to force the standard behavior
  1840. * on 1.X libs and to switch back to the old mode for compatibility when
  1841. * running 1.X client code on 2.X . Upgrade of 1.X code should be done
  1842. * by using xmlIsBlankNode() commodity function to detect the "empty"
  1843. * nodes generated.
  1844. * This value also affect autogeneration of indentation when saving code
  1845. * if blanks sections are kept, indentation is not generated.
  1846. *
  1847. * Returns the last value for 0 for no substitution, 1 for substitution.
  1848. */
  1849. int
  1850. xmlKeepBlanksDefault(int val) {
  1851. int old = xmlKeepBlanksDefaultValue;
  1852. xmlKeepBlanksDefaultValue = val;
  1853. if (!val) xmlIndentTreeOutput = 1;
  1854. return(old);
  1855. }