globals.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209
  1. /*
  2. * globals.c: definition and handling of the set of global variables
  3. * of the library
  4. *
  5. * See Copyright for the status of this software.
  6. *
  7. * Gary Pennington <Gary.Pennington@uk.sun.com>
  8. * daniel@veillard.com
  9. */
  10. #define IN_LIBXML
  11. #include "libxml.h"
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #define XML_GLOBALS_NO_REDEFINITION
  16. #include <libxml/globals.h>
  17. #include <libxml/xmlerror.h>
  18. #include <libxml/xmlmemory.h>
  19. #include <libxml/xmlIO.h>
  20. #include <libxml/HTMLparser.h>
  21. #include <libxml/parser.h>
  22. #include <libxml/threads.h>
  23. #include <libxml/tree.h>
  24. #include <libxml/SAX.h>
  25. #include <libxml/SAX2.h>
  26. #include "private/error.h"
  27. #include "private/globals.h"
  28. #include "private/threads.h"
  29. #include "private/tree.h"
  30. /*
  31. * Thread-local storage emulation.
  32. *
  33. * This works by replacing a global variable
  34. *
  35. * extern xmlError xmlLastError;
  36. *
  37. * with a macro that calls a function returning a pointer to the global in
  38. * thread-local storage:
  39. *
  40. * xmlError *__xmlLastError(void);
  41. * #define xmlError (*__xmlLastError());
  42. *
  43. * The code can operate in a multitude of ways depending on the environment.
  44. * First we support POSIX and Windows threads. Then we support both thread-local
  45. * storage provided by the compiler and older methods like thread-specific data
  46. * (pthreads) or TlsAlloc (Windows).
  47. *
  48. * To clean up thread-local storage, we use thread-specific data on POSIX.
  49. * On Windows, we either use DllMain when compiling a DLL or a registered wait
  50. * function for static builds.
  51. */
  52. /*
  53. * Helpful Macro
  54. */
  55. #ifdef LIBXML_THREAD_ENABLED
  56. #define IS_MAIN_THREAD (xmlIsMainThreadInternal())
  57. #else
  58. #define IS_MAIN_THREAD 1
  59. #endif
  60. #define XML_DECLARE_MEMBER(name, type, attrs) \
  61. type gs_##name;
  62. struct _xmlGlobalState {
  63. int initialized;
  64. #if defined(HAVE_WIN32_THREADS) && \
  65. defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
  66. void *threadHandle;
  67. void *waitHandle;
  68. #endif
  69. #define XML_OP XML_DECLARE_MEMBER
  70. XML_GLOBALS_ALLOC
  71. XML_GLOBALS_ERROR
  72. XML_GLOBALS_HTML
  73. XML_GLOBALS_IO
  74. XML_GLOBALS_PARSER
  75. XML_GLOBALS_TREE
  76. #undef XML_OP
  77. };
  78. static int parserInitialized;
  79. /*
  80. * Mutex to protect "ForNewThreads" variables
  81. */
  82. static xmlMutex xmlThrDefMutex;
  83. #ifdef LIBXML_THREAD_ENABLED
  84. /*
  85. * On Darwin, thread-local storage destructors seem to be run before
  86. * pthread thread-specific data destructors. This causes ASan to
  87. * report a use-after-free.
  88. *
  89. * On Windows, we can't use TLS in static builds. The RegisterWait
  90. * callback would run after TLS was deallocated.
  91. */
  92. #if defined(XML_THREAD_LOCAL) && \
  93. !defined(__APPLE__) && \
  94. (!defined(HAVE_WIN32_THREADS) || \
  95. !defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
  96. #define USE_TLS
  97. #endif
  98. #ifdef USE_TLS
  99. static XML_THREAD_LOCAL xmlGlobalState globalState;
  100. #endif
  101. #ifdef HAVE_POSIX_THREADS
  102. /*
  103. * Weak symbol hack, see threads.c
  104. */
  105. #if defined(__GNUC__) && \
  106. defined(__GLIBC__) && \
  107. __GLIBC__ * 100 + __GLIBC_MINOR__ < 234
  108. #pragma weak pthread_getspecific
  109. #pragma weak pthread_setspecific
  110. #pragma weak pthread_key_create
  111. #pragma weak pthread_key_delete
  112. #pragma weak pthread_equal
  113. #pragma weak pthread_self
  114. #define XML_PTHREAD_WEAK
  115. static int libxml_is_threaded = -1;
  116. #endif
  117. /*
  118. * On POSIX, we need thread-specific data even with thread-local storage
  119. * to destroy indirect references from global state (xmlLastError) at
  120. * thread exit.
  121. */
  122. static pthread_key_t globalkey;
  123. static pthread_t mainthread;
  124. #elif defined HAVE_WIN32_THREADS
  125. #ifndef USE_TLS
  126. static DWORD globalkey = TLS_OUT_OF_INDEXES;
  127. #endif
  128. static DWORD mainthread;
  129. #endif /* HAVE_WIN32_THREADS */
  130. static void
  131. xmlFreeGlobalState(void *state);
  132. #endif /* LIBXML_THREAD_ENABLED */
  133. /************************************************************************
  134. * *
  135. * All the user accessible global variables of the library *
  136. * *
  137. ************************************************************************/
  138. /*
  139. * Memory allocation routines
  140. */
  141. #if defined(DEBUG_MEMORY_LOCATION)
  142. xmlFreeFunc xmlFree = (xmlFreeFunc) xmlMemFree;
  143. xmlMallocFunc xmlMalloc = (xmlMallocFunc) xmlMemMalloc;
  144. xmlMallocFunc xmlMallocAtomic = (xmlMallocFunc) xmlMemMalloc;
  145. xmlReallocFunc xmlRealloc = (xmlReallocFunc) xmlMemRealloc;
  146. xmlStrdupFunc xmlMemStrdup = (xmlStrdupFunc) xmlMemoryStrdup;
  147. #else
  148. /**
  149. * xmlFree:
  150. * @mem: an already allocated block of memory
  151. *
  152. * The variable holding the libxml free() implementation
  153. */
  154. xmlFreeFunc xmlFree = free;
  155. /**
  156. * xmlMalloc:
  157. * @size: the size requested in bytes
  158. *
  159. * The variable holding the libxml malloc() implementation
  160. *
  161. * Returns a pointer to the newly allocated block or NULL in case of error
  162. */
  163. xmlMallocFunc xmlMalloc = malloc;
  164. /**
  165. * xmlMallocAtomic:
  166. * @size: the size requested in bytes
  167. *
  168. * The variable holding the libxml malloc() implementation for atomic
  169. * data (i.e. blocks not containing pointers), useful when using a
  170. * garbage collecting allocator.
  171. *
  172. * Returns a pointer to the newly allocated block or NULL in case of error
  173. */
  174. xmlMallocFunc xmlMallocAtomic = malloc;
  175. /**
  176. * xmlRealloc:
  177. * @mem: an already allocated block of memory
  178. * @size: the new size requested in bytes
  179. *
  180. * The variable holding the libxml realloc() implementation
  181. *
  182. * Returns a pointer to the newly reallocated block or NULL in case of error
  183. */
  184. xmlReallocFunc xmlRealloc = realloc;
  185. /**
  186. * xmlPosixStrdup
  187. * @cur: the input char *
  188. *
  189. * a strdup implementation with a type signature matching POSIX
  190. *
  191. * Returns a new xmlChar * or NULL
  192. */
  193. static char *
  194. xmlPosixStrdup(const char *cur) {
  195. return((char*) xmlCharStrdup(cur));
  196. }
  197. /**
  198. * xmlMemStrdup:
  199. * @str: a zero terminated string
  200. *
  201. * The variable holding the libxml strdup() implementation
  202. *
  203. * Returns the copy of the string or NULL in case of error
  204. */
  205. xmlStrdupFunc xmlMemStrdup = xmlPosixStrdup;
  206. #endif /* DEBUG_MEMORY_LOCATION */
  207. /**
  208. * xmlBufferAllocScheme:
  209. *
  210. * DEPRECATED: Don't use.
  211. *
  212. * Global setting, default allocation policy for buffers, default is
  213. * XML_BUFFER_ALLOC_EXACT
  214. */
  215. xmlBufferAllocationScheme xmlBufferAllocScheme = XML_BUFFER_ALLOC_EXACT;
  216. static xmlBufferAllocationScheme xmlBufferAllocSchemeThrDef = XML_BUFFER_ALLOC_EXACT;
  217. /**
  218. * xmlDefaultBufferSize:
  219. *
  220. * DEPRECATED: Don't use.
  221. *
  222. * Global setting, default buffer size. Default value is BASE_BUFFER_SIZE
  223. */
  224. int xmlDefaultBufferSize = BASE_BUFFER_SIZE;
  225. static int xmlDefaultBufferSizeThrDef = BASE_BUFFER_SIZE;
  226. /*
  227. * Parser defaults
  228. */
  229. /**
  230. * oldXMLWDcompatibility:
  231. *
  232. * Global setting, DEPRECATED.
  233. */
  234. int oldXMLWDcompatibility = 0; /* DEPRECATED */
  235. /**
  236. * xmlParserDebugEntities:
  237. *
  238. * DEPRECATED: Don't use
  239. *
  240. * Global setting, asking the parser to print out debugging information.
  241. * while handling entities.
  242. * Disabled by default
  243. */
  244. int xmlParserDebugEntities = 0;
  245. static int xmlParserDebugEntitiesThrDef = 0;
  246. /**
  247. * xmlDoValidityCheckingDefaultValue:
  248. *
  249. * DEPRECATED: Use the modern options API with XML_PARSE_DTDVALID.
  250. *
  251. * Global setting, indicate that the parser should work in validating mode.
  252. * Disabled by default.
  253. */
  254. int xmlDoValidityCheckingDefaultValue = 0;
  255. static int xmlDoValidityCheckingDefaultValueThrDef = 0;
  256. /**
  257. * xmlGetWarningsDefaultValue:
  258. *
  259. * DEPRECATED: Don't use
  260. *
  261. * Global setting, indicate that the DTD validation should provide warnings.
  262. * Activated by default.
  263. */
  264. int xmlGetWarningsDefaultValue = 1;
  265. static int xmlGetWarningsDefaultValueThrDef = 1;
  266. /**
  267. * xmlLoadExtDtdDefaultValue:
  268. *
  269. * DEPRECATED: Use the modern options API with XML_PARSE_DTDLOAD.
  270. *
  271. * Global setting, indicate that the parser should load DTD while not
  272. * validating.
  273. * Disabled by default.
  274. */
  275. int xmlLoadExtDtdDefaultValue = 0;
  276. static int xmlLoadExtDtdDefaultValueThrDef = 0;
  277. /**
  278. * xmlPedanticParserDefaultValue:
  279. *
  280. * DEPRECATED: Use the modern options API with XML_PARSE_PEDANTIC.
  281. *
  282. * Global setting, indicate that the parser be pedantic
  283. * Disabled by default.
  284. */
  285. int xmlPedanticParserDefaultValue = 0;
  286. static int xmlPedanticParserDefaultValueThrDef = 0;
  287. /**
  288. * xmlLineNumbersDefaultValue:
  289. *
  290. * DEPRECATED: The modern options API always enables line numbers.
  291. *
  292. * Global setting, indicate that the parser should store the line number
  293. * in the content field of elements in the DOM tree.
  294. * Disabled by default since this may not be safe for old classes of
  295. * application.
  296. */
  297. int xmlLineNumbersDefaultValue = 0;
  298. static int xmlLineNumbersDefaultValueThrDef = 0;
  299. /**
  300. * xmlKeepBlanksDefaultValue:
  301. *
  302. * DEPRECATED: Use the modern options API with XML_PARSE_NOBLANKS.
  303. *
  304. * Global setting, indicate that the parser should keep all blanks
  305. * nodes found in the content
  306. * Activated by default, this is actually needed to have the parser
  307. * conformant to the XML Recommendation, however the option is kept
  308. * for some applications since this was libxml1 default behaviour.
  309. */
  310. int xmlKeepBlanksDefaultValue = 1;
  311. static int xmlKeepBlanksDefaultValueThrDef = 1;
  312. /**
  313. * xmlSubstituteEntitiesDefaultValue:
  314. *
  315. * DEPRECATED: Use the modern options API with XML_PARSE_NOENT.
  316. *
  317. * Global setting, indicate that the parser should not generate entity
  318. * references but replace them with the actual content of the entity
  319. * Disabled by default, this should be activated when using XPath since
  320. * the XPath data model requires entities replacement and the XPath
  321. * engine does not handle entities references transparently.
  322. */
  323. int xmlSubstituteEntitiesDefaultValue = 0;
  324. static int xmlSubstituteEntitiesDefaultValueThrDef = 0;
  325. /**
  326. * xmlRegisterNodeDefaultValue:
  327. *
  328. * DEPRECATED: Don't use
  329. */
  330. xmlRegisterNodeFunc xmlRegisterNodeDefaultValue = NULL;
  331. static xmlRegisterNodeFunc xmlRegisterNodeDefaultValueThrDef = NULL;
  332. /**
  333. * xmlDeregisterNodeDefaultValue:
  334. *
  335. * DEPRECATED: Don't use
  336. */
  337. xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValue = NULL;
  338. static xmlDeregisterNodeFunc xmlDeregisterNodeDefaultValueThrDef = NULL;
  339. /**
  340. * xmlParserInputBufferCreateFilenameValue:
  341. *
  342. * DEPRECATED: Don't use
  343. */
  344. xmlParserInputBufferCreateFilenameFunc xmlParserInputBufferCreateFilenameValue = NULL;
  345. static xmlParserInputBufferCreateFilenameFunc xmlParserInputBufferCreateFilenameValueThrDef = NULL;
  346. /**
  347. * xmlOutputBufferCreateFilenameValue:
  348. *
  349. * DEPRECATED: Don't use
  350. */
  351. xmlOutputBufferCreateFilenameFunc xmlOutputBufferCreateFilenameValue = NULL;
  352. static xmlOutputBufferCreateFilenameFunc xmlOutputBufferCreateFilenameValueThrDef = NULL;
  353. /**
  354. * xmlGenericError:
  355. *
  356. * Global setting: function used for generic error callbacks
  357. */
  358. xmlGenericErrorFunc xmlGenericError = xmlGenericErrorDefaultFunc;
  359. static xmlGenericErrorFunc xmlGenericErrorThrDef = xmlGenericErrorDefaultFunc;
  360. /**
  361. * xmlStructuredError:
  362. *
  363. * Global setting: function used for structured error callbacks
  364. */
  365. xmlStructuredErrorFunc xmlStructuredError = NULL;
  366. static xmlStructuredErrorFunc xmlStructuredErrorThrDef = NULL;
  367. /**
  368. * xmlGenericErrorContext:
  369. *
  370. * Global setting passed to generic error callbacks
  371. */
  372. void *xmlGenericErrorContext = NULL;
  373. static void *xmlGenericErrorContextThrDef = NULL;
  374. /**
  375. * xmlStructuredErrorContext:
  376. *
  377. * Global setting passed to structured error callbacks
  378. */
  379. void *xmlStructuredErrorContext = NULL;
  380. static void *xmlStructuredErrorContextThrDef = NULL;
  381. xmlError xmlLastError;
  382. #ifdef LIBXML_OUTPUT_ENABLED
  383. /*
  384. * output defaults
  385. */
  386. /**
  387. * xmlIndentTreeOutput:
  388. *
  389. * Global setting, asking the serializer to indent the output tree by default
  390. * Enabled by default
  391. */
  392. int xmlIndentTreeOutput = 1;
  393. static int xmlIndentTreeOutputThrDef = 1;
  394. /**
  395. * xmlTreeIndentString:
  396. *
  397. * The string used to do one-level indent. By default is equal to " " (two spaces)
  398. */
  399. const char *xmlTreeIndentString = " ";
  400. static const char *xmlTreeIndentStringThrDef = " ";
  401. /**
  402. * xmlSaveNoEmptyTags:
  403. *
  404. * Global setting, asking the serializer to not output empty tags
  405. * as <empty/> but <empty></empty>. those two forms are indistinguishable
  406. * once parsed.
  407. * Disabled by default
  408. */
  409. int xmlSaveNoEmptyTags = 0;
  410. static int xmlSaveNoEmptyTagsThrDef = 0;
  411. #endif /* LIBXML_OUTPUT_ENABLED */
  412. #ifdef LIBXML_SAX1_ENABLED
  413. /**
  414. * xmlDefaultSAXHandler:
  415. *
  416. * DEPRECATED: This handler is unused and will be removed from future
  417. * versions.
  418. *
  419. * Default SAX version1 handler for XML, builds the DOM tree
  420. */
  421. xmlSAXHandlerV1 xmlDefaultSAXHandler = {
  422. xmlSAX2InternalSubset,
  423. xmlSAX2IsStandalone,
  424. xmlSAX2HasInternalSubset,
  425. xmlSAX2HasExternalSubset,
  426. xmlSAX2ResolveEntity,
  427. xmlSAX2GetEntity,
  428. xmlSAX2EntityDecl,
  429. xmlSAX2NotationDecl,
  430. xmlSAX2AttributeDecl,
  431. xmlSAX2ElementDecl,
  432. xmlSAX2UnparsedEntityDecl,
  433. xmlSAX2SetDocumentLocator,
  434. xmlSAX2StartDocument,
  435. xmlSAX2EndDocument,
  436. xmlSAX2StartElement,
  437. xmlSAX2EndElement,
  438. xmlSAX2Reference,
  439. xmlSAX2Characters,
  440. xmlSAX2Characters,
  441. xmlSAX2ProcessingInstruction,
  442. xmlSAX2Comment,
  443. xmlParserWarning,
  444. xmlParserError,
  445. xmlParserError,
  446. xmlSAX2GetParameterEntity,
  447. xmlSAX2CDataBlock,
  448. xmlSAX2ExternalSubset,
  449. 1,
  450. };
  451. #endif /* LIBXML_SAX1_ENABLED */
  452. /**
  453. * xmlDefaultSAXLocator:
  454. *
  455. * DEPRECATED: Don't use
  456. *
  457. * The default SAX Locator
  458. * { getPublicId, getSystemId, getLineNumber, getColumnNumber}
  459. */
  460. xmlSAXLocator xmlDefaultSAXLocator = {
  461. xmlSAX2GetPublicId,
  462. xmlSAX2GetSystemId,
  463. xmlSAX2GetLineNumber,
  464. xmlSAX2GetColumnNumber
  465. };
  466. #if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_SAX1_ENABLED)
  467. /**
  468. * htmlDefaultSAXHandler:
  469. *
  470. * DEPRECATED: This handler is unused and will be removed from future
  471. * versions.
  472. *
  473. * Default old SAX v1 handler for HTML, builds the DOM tree
  474. */
  475. xmlSAXHandlerV1 htmlDefaultSAXHandler = {
  476. xmlSAX2InternalSubset,
  477. NULL,
  478. NULL,
  479. NULL,
  480. NULL,
  481. xmlSAX2GetEntity,
  482. NULL,
  483. NULL,
  484. NULL,
  485. NULL,
  486. NULL,
  487. xmlSAX2SetDocumentLocator,
  488. xmlSAX2StartDocument,
  489. xmlSAX2EndDocument,
  490. xmlSAX2StartElement,
  491. xmlSAX2EndElement,
  492. NULL,
  493. xmlSAX2Characters,
  494. xmlSAX2IgnorableWhitespace,
  495. xmlSAX2ProcessingInstruction,
  496. xmlSAX2Comment,
  497. xmlParserWarning,
  498. xmlParserError,
  499. xmlParserError,
  500. NULL,
  501. xmlSAX2CDataBlock,
  502. NULL,
  503. 1,
  504. };
  505. #endif /* LIBXML_HTML_ENABLED */
  506. /************************************************************************
  507. * *
  508. * Per thread global state handling *
  509. * *
  510. ************************************************************************/
  511. /**
  512. * xmlInitGlobals:
  513. *
  514. * DEPRECATED: Alias for xmlInitParser.
  515. */
  516. void xmlInitGlobals(void) {
  517. xmlInitParser();
  518. }
  519. /**
  520. * xmlInitGlobalsInternal:
  521. *
  522. * Additional initialisation for multi-threading
  523. */
  524. void xmlInitGlobalsInternal(void) {
  525. xmlInitMutex(&xmlThrDefMutex);
  526. #ifdef HAVE_POSIX_THREADS
  527. #ifdef XML_PTHREAD_WEAK
  528. if (libxml_is_threaded == -1)
  529. libxml_is_threaded =
  530. (pthread_getspecific != NULL) &&
  531. (pthread_setspecific != NULL) &&
  532. (pthread_key_create != NULL) &&
  533. (pthread_key_delete != NULL) &&
  534. /*
  535. * pthread_equal can be inline, resuting in -Waddress warnings.
  536. * Let's assume it's available if all the other functions are.
  537. */
  538. /* (pthread_equal != NULL) && */
  539. (pthread_self != NULL);
  540. if (libxml_is_threaded == 0)
  541. return;
  542. #endif /* XML_PTHREAD_WEAK */
  543. pthread_key_create(&globalkey, xmlFreeGlobalState);
  544. mainthread = pthread_self();
  545. #elif defined(HAVE_WIN32_THREADS)
  546. #ifndef USE_TLS
  547. globalkey = TlsAlloc();
  548. #endif
  549. mainthread = GetCurrentThreadId();
  550. #endif
  551. }
  552. /**
  553. * xmlCleanupGlobals:
  554. *
  555. * DEPRECATED: This function is a no-op. Call xmlCleanupParser
  556. * to free global state but see the warnings there. xmlCleanupParser
  557. * should be only called once at program exit. In most cases, you don't
  558. * have call cleanup functions at all.
  559. */
  560. void xmlCleanupGlobals(void) {
  561. }
  562. /**
  563. * xmlCleanupGlobalsInternal:
  564. *
  565. * Additional cleanup for multi-threading
  566. */
  567. void xmlCleanupGlobalsInternal(void) {
  568. xmlResetError(&xmlLastError);
  569. xmlCleanupMutex(&xmlThrDefMutex);
  570. #ifdef HAVE_POSIX_THREADS
  571. #ifdef XML_PTHREAD_WEAK
  572. if (libxml_is_threaded == 0)
  573. return;
  574. #endif /* XML_PTHREAD_WEAK */
  575. pthread_key_delete(globalkey);
  576. #elif defined(HAVE_WIN32_THREADS)
  577. #ifndef USE_TLS
  578. if (globalkey != TLS_OUT_OF_INDEXES) {
  579. TlsFree(globalkey);
  580. globalkey = TLS_OUT_OF_INDEXES;
  581. }
  582. #endif
  583. #endif
  584. parserInitialized = 0;
  585. }
  586. /**
  587. * xmlInitializeGlobalState:
  588. * @gs: a pointer to a newly allocated global state
  589. *
  590. * DEPRECATED: No-op.
  591. */
  592. void
  593. xmlInitializeGlobalState(xmlGlobalStatePtr gs ATTRIBUTE_UNUSED)
  594. {
  595. }
  596. /**
  597. * xmlGetGlobalState:
  598. *
  599. * DEPRECATED
  600. *
  601. * Returns NULL.
  602. */
  603. xmlGlobalStatePtr
  604. xmlGetGlobalState(void)
  605. {
  606. return(NULL);
  607. }
  608. static int
  609. xmlIsMainThreadInternal(void) {
  610. if (parserInitialized == 0) {
  611. xmlInitParser();
  612. parserInitialized = 1;
  613. }
  614. #ifdef HAVE_POSIX_THREADS
  615. #ifdef XML_PTHREAD_WEAK
  616. if (libxml_is_threaded == 0)
  617. return (1);
  618. #endif
  619. return (pthread_equal(mainthread, pthread_self()));
  620. #elif defined HAVE_WIN32_THREADS
  621. return (mainthread == GetCurrentThreadId());
  622. #else
  623. return (1);
  624. #endif
  625. }
  626. /**
  627. * xmlIsMainThread:
  628. *
  629. * DEPRECATED: Internal function, do not use.
  630. *
  631. * Check whether the current thread is the main thread.
  632. *
  633. * Returns 1 if the current thread is the main thread, 0 otherwise
  634. */
  635. int
  636. xmlIsMainThread(void) {
  637. return(xmlIsMainThreadInternal());
  638. }
  639. #ifdef LIBXML_THREAD_ENABLED
  640. static void
  641. xmlFreeGlobalState(void *state)
  642. {
  643. xmlGlobalState *gs = (xmlGlobalState *) state;
  644. /*
  645. * Free any memory allocated in the thread's xmlLastError. If it
  646. * weren't for this indirect allocation, we wouldn't need
  647. * a destructor with thread-local storage at all!
  648. *
  649. * It would be nice if we could make xmlLastError a special error
  650. * type which uses statically allocated, fixed-size buffers.
  651. * But the xmlError struct is fully public and widely used,
  652. * so changes are dangerous.
  653. */
  654. xmlResetError(&(gs->gs_xmlLastError));
  655. #ifndef USE_TLS
  656. free(state);
  657. #endif
  658. }
  659. #if defined(HAVE_WIN32_THREADS) && \
  660. defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
  661. static void WINAPI
  662. xmlGlobalStateDtor(void *ctxt, unsigned char timedOut ATTRIBUTE_UNUSED) {
  663. xmlGlobalStatePtr gs = ctxt;
  664. UnregisterWait(gs->waitHandle);
  665. CloseHandle(gs->threadHandle);
  666. xmlFreeGlobalState(gs);
  667. }
  668. static int
  669. xmlRegisterGlobalStateDtor(xmlGlobalState *gs) {
  670. void *processHandle = GetCurrentProcess();
  671. void *threadHandle;
  672. void *waitHandle;
  673. if (DuplicateHandle(processHandle, GetCurrentThread(), processHandle,
  674. &threadHandle, 0, FALSE, DUPLICATE_SAME_ACCESS) == 0) {
  675. return(-1);
  676. }
  677. if (RegisterWaitForSingleObject(&waitHandle, threadHandle,
  678. xmlGlobalStateDtor, gs, INFINITE, WT_EXECUTEONLYONCE) == 0) {
  679. CloseHandle(threadHandle);
  680. return(-1);
  681. }
  682. gs->threadHandle = threadHandle;
  683. gs->waitHandle = waitHandle;
  684. return(0);
  685. }
  686. #endif /* LIBXML_STATIC */
  687. static void
  688. xmlInitGlobalState(xmlGlobalStatePtr gs) {
  689. xmlMutexLock(&xmlThrDefMutex);
  690. #if defined(LIBXML_HTML_ENABLED) && defined(LIBXML_LEGACY_ENABLED) && defined(LIBXML_SAX1_ENABLED)
  691. inithtmlDefaultSAXHandler(&gs->gs_htmlDefaultSAXHandler);
  692. #endif
  693. gs->gs_oldXMLWDcompatibility = 0;
  694. gs->gs_xmlBufferAllocScheme = xmlBufferAllocSchemeThrDef;
  695. gs->gs_xmlDefaultBufferSize = xmlDefaultBufferSizeThrDef;
  696. #if defined(LIBXML_SAX1_ENABLED) && defined(LIBXML_LEGACY_ENABLED)
  697. initxmlDefaultSAXHandler(&gs->gs_xmlDefaultSAXHandler, 1);
  698. #endif /* LIBXML_SAX1_ENABLED */
  699. gs->gs_xmlDefaultSAXLocator.getPublicId = xmlSAX2GetPublicId;
  700. gs->gs_xmlDefaultSAXLocator.getSystemId = xmlSAX2GetSystemId;
  701. gs->gs_xmlDefaultSAXLocator.getLineNumber = xmlSAX2GetLineNumber;
  702. gs->gs_xmlDefaultSAXLocator.getColumnNumber = xmlSAX2GetColumnNumber;
  703. gs->gs_xmlDoValidityCheckingDefaultValue =
  704. xmlDoValidityCheckingDefaultValueThrDef;
  705. #ifdef LIBXML_THREAD_ALLOC_ENABLED
  706. #ifdef DEBUG_MEMORY_LOCATION
  707. gs->gs_xmlFree = xmlMemFree;
  708. gs->gs_xmlMalloc = xmlMemMalloc;
  709. gs->gs_xmlMallocAtomic = xmlMemMalloc;
  710. gs->gs_xmlRealloc = xmlMemRealloc;
  711. gs->gs_xmlMemStrdup = xmlMemoryStrdup;
  712. #else
  713. gs->gs_xmlFree = free;
  714. gs->gs_xmlMalloc = malloc;
  715. gs->gs_xmlMallocAtomic = malloc;
  716. gs->gs_xmlRealloc = realloc;
  717. gs->gs_xmlMemStrdup = xmlPosixStrdup;
  718. #endif
  719. #endif
  720. gs->gs_xmlGetWarningsDefaultValue = xmlGetWarningsDefaultValueThrDef;
  721. #ifdef LIBXML_OUTPUT_ENABLED
  722. gs->gs_xmlIndentTreeOutput = xmlIndentTreeOutputThrDef;
  723. gs->gs_xmlTreeIndentString = xmlTreeIndentStringThrDef;
  724. gs->gs_xmlSaveNoEmptyTags = xmlSaveNoEmptyTagsThrDef;
  725. #endif
  726. gs->gs_xmlKeepBlanksDefaultValue = xmlKeepBlanksDefaultValueThrDef;
  727. gs->gs_xmlLineNumbersDefaultValue = xmlLineNumbersDefaultValueThrDef;
  728. gs->gs_xmlLoadExtDtdDefaultValue = xmlLoadExtDtdDefaultValueThrDef;
  729. gs->gs_xmlParserDebugEntities = xmlParserDebugEntitiesThrDef;
  730. gs->gs_xmlPedanticParserDefaultValue = xmlPedanticParserDefaultValueThrDef;
  731. gs->gs_xmlSubstituteEntitiesDefaultValue =
  732. xmlSubstituteEntitiesDefaultValueThrDef;
  733. gs->gs_xmlGenericError = xmlGenericErrorThrDef;
  734. gs->gs_xmlStructuredError = xmlStructuredErrorThrDef;
  735. gs->gs_xmlGenericErrorContext = xmlGenericErrorContextThrDef;
  736. gs->gs_xmlStructuredErrorContext = xmlStructuredErrorContextThrDef;
  737. gs->gs_xmlRegisterNodeDefaultValue = xmlRegisterNodeDefaultValueThrDef;
  738. gs->gs_xmlDeregisterNodeDefaultValue = xmlDeregisterNodeDefaultValueThrDef;
  739. gs->gs_xmlParserInputBufferCreateFilenameValue =
  740. xmlParserInputBufferCreateFilenameValueThrDef;
  741. gs->gs_xmlOutputBufferCreateFilenameValue =
  742. xmlOutputBufferCreateFilenameValueThrDef;
  743. memset(&gs->gs_xmlLastError, 0, sizeof(xmlError));
  744. xmlMutexUnlock(&xmlThrDefMutex);
  745. #ifdef HAVE_POSIX_THREADS
  746. pthread_setspecific(globalkey, gs);
  747. #elif defined HAVE_WIN32_THREADS
  748. #ifndef USE_TLS
  749. TlsSetValue(globalkey, gs);
  750. #endif
  751. #if defined(LIBXML_STATIC) && !defined(LIBXML_STATIC_FOR_DLL)
  752. xmlRegisterGlobalStateDtor(gs);
  753. #endif
  754. #endif
  755. gs->initialized = 1;
  756. }
  757. #ifndef USE_TLS
  758. /**
  759. * xmlNewGlobalState:
  760. *
  761. * xmlNewGlobalState() allocates a global state. This structure is used to
  762. * hold all data for use by a thread when supporting backwards compatibility
  763. * of libxml2 to pre-thread-safe behaviour.
  764. *
  765. * Returns the newly allocated xmlGlobalStatePtr or NULL in case of error
  766. */
  767. static xmlGlobalStatePtr
  768. xmlNewGlobalState(int allowFailure)
  769. {
  770. xmlGlobalState *gs;
  771. gs = malloc(sizeof(xmlGlobalState));
  772. if (gs == NULL) {
  773. if (allowFailure)
  774. return(NULL);
  775. /*
  776. * If an application didn't call xmlCheckThreadLocalStorage to make
  777. * sure that global state could be allocated, it's too late to
  778. * handle the error.
  779. */
  780. fprintf(stderr, "libxml2: Failed to allocate globals for thread\n"
  781. "libxml2: See xmlCheckThreadLocalStorage\n");
  782. abort();
  783. }
  784. memset(gs, 0, sizeof(xmlGlobalState));
  785. xmlInitGlobalState(gs);
  786. return (gs);
  787. }
  788. #endif
  789. static xmlGlobalStatePtr
  790. xmlGetThreadLocalStorage(int allowFailure) {
  791. xmlGlobalState *gs;
  792. (void) allowFailure;
  793. #ifdef USE_TLS
  794. gs = &globalState;
  795. if (gs->initialized == 0)
  796. xmlInitGlobalState(gs);
  797. #elif defined(HAVE_POSIX_THREADS)
  798. gs = (xmlGlobalState *) pthread_getspecific(globalkey);
  799. if (gs == NULL)
  800. gs = xmlNewGlobalState(allowFailure);
  801. #elif defined(HAVE_WIN32_THREADS)
  802. gs = (xmlGlobalState *) TlsGetValue(globalkey);
  803. if (gs == NULL)
  804. gs = xmlNewGlobalState(allowFailure);
  805. #else
  806. gs = NULL;
  807. #endif
  808. return(gs);
  809. }
  810. /* Define thread-local storage accessors with macro magic */
  811. #define XML_DEFINE_GLOBAL_WRAPPER(name, type, attrs) \
  812. type *__##name(void) { \
  813. if (IS_MAIN_THREAD) \
  814. return (&name); \
  815. else \
  816. return (&xmlGetThreadLocalStorage(0)->gs_##name); \
  817. }
  818. #define XML_OP XML_DEFINE_GLOBAL_WRAPPER
  819. XML_GLOBALS_ALLOC
  820. XML_GLOBALS_ERROR
  821. XML_GLOBALS_HTML
  822. XML_GLOBALS_IO
  823. XML_GLOBALS_PARSER
  824. XML_GLOBALS_TREE
  825. #undef XML_OP
  826. /* For backward compatibility */
  827. const char *const *
  828. __xmlParserVersion(void) {
  829. return &xmlParserVersion;
  830. }
  831. #endif /* LIBXML_THREAD_ENABLED */
  832. /**
  833. * xmlCheckThreadLocalStorage:
  834. *
  835. * Check whether thread-local storage could be allocated.
  836. *
  837. * In cross-platform code running in multithreaded environments, this
  838. * function should be called once in each thread before calling other
  839. * library functions to make sure that thread-local storage was
  840. * allocated properly.
  841. *
  842. * Returns 0 on success or -1 if a memory allocation failed. A failed
  843. * allocation signals a typically fatal and irrecoverable out-of-memory
  844. * situation. Don't call any library functions in this case.
  845. *
  846. * This function never fails if the library is compiled with support
  847. * for thread-local storage.
  848. *
  849. * This function never fails for the "main" thread which is the first
  850. * thread calling xmlInitParser.
  851. *
  852. * Available since v2.12.0.
  853. */
  854. int
  855. xmlCheckThreadLocalStorage(void) {
  856. #if defined(LIBXML_THREAD_ENABLED) && !defined(USE_TLS)
  857. if ((!xmlIsMainThreadInternal()) && (xmlGetThreadLocalStorage(1) == NULL))
  858. return(-1);
  859. #endif
  860. return(0);
  861. }
  862. /**
  863. * DllMain:
  864. * @hinstDLL: handle to DLL instance
  865. * @fdwReason: Reason code for entry
  866. * @lpvReserved: generic pointer (depends upon reason code)
  867. *
  868. * Entry point for Windows library. It is being used to free thread-specific
  869. * storage.
  870. *
  871. * Returns TRUE always
  872. */
  873. #if defined(HAVE_WIN32_THREADS) && \
  874. (!defined(LIBXML_STATIC) || defined(LIBXML_STATIC_FOR_DLL))
  875. #if defined(LIBXML_STATIC_FOR_DLL)
  876. int
  877. xmlDllMain(ATTRIBUTE_UNUSED void *hinstDLL, unsigned long fdwReason,
  878. ATTRIBUTE_UNUSED void *lpvReserved)
  879. #else
  880. /* declare to avoid "no previous prototype for 'DllMain'" warning */
  881. /* Note that we do NOT want to include this function declaration in
  882. a public header because it's meant to be called by Windows itself,
  883. not a program that uses this library. This also has to be exported. */
  884. XMLPUBFUN BOOL WINAPI
  885. DllMain (HINSTANCE hinstDLL,
  886. DWORD fdwReason,
  887. LPVOID lpvReserved);
  888. BOOL WINAPI
  889. DllMain(ATTRIBUTE_UNUSED HINSTANCE hinstDLL, DWORD fdwReason,
  890. ATTRIBUTE_UNUSED LPVOID lpvReserved)
  891. #endif
  892. {
  893. switch (fdwReason) {
  894. case DLL_THREAD_DETACH:
  895. #ifdef USE_TLS
  896. xmlFreeGlobalState(&globalState);
  897. #else
  898. if (globalkey != TLS_OUT_OF_INDEXES) {
  899. xmlGlobalState *globalval;
  900. globalval = (xmlGlobalState *) TlsGetValue(globalkey);
  901. if (globalval) {
  902. xmlFreeGlobalState(globalval);
  903. TlsSetValue(globalkey, NULL);
  904. }
  905. }
  906. #endif
  907. break;
  908. }
  909. return TRUE;
  910. }
  911. #endif
  912. void
  913. xmlThrDefSetGenericErrorFunc(void *ctx, xmlGenericErrorFunc handler) {
  914. xmlMutexLock(&xmlThrDefMutex);
  915. xmlGenericErrorContextThrDef = ctx;
  916. if (handler != NULL)
  917. xmlGenericErrorThrDef = handler;
  918. else
  919. xmlGenericErrorThrDef = xmlGenericErrorDefaultFunc;
  920. xmlMutexUnlock(&xmlThrDefMutex);
  921. }
  922. void
  923. xmlThrDefSetStructuredErrorFunc(void *ctx, xmlStructuredErrorFunc handler) {
  924. xmlMutexLock(&xmlThrDefMutex);
  925. xmlStructuredErrorContextThrDef = ctx;
  926. xmlStructuredErrorThrDef = handler;
  927. xmlMutexUnlock(&xmlThrDefMutex);
  928. }
  929. xmlBufferAllocationScheme xmlThrDefBufferAllocScheme(xmlBufferAllocationScheme v) {
  930. xmlBufferAllocationScheme ret;
  931. xmlMutexLock(&xmlThrDefMutex);
  932. ret = xmlBufferAllocSchemeThrDef;
  933. xmlBufferAllocSchemeThrDef = v;
  934. xmlMutexUnlock(&xmlThrDefMutex);
  935. return ret;
  936. }
  937. int xmlThrDefDefaultBufferSize(int v) {
  938. int ret;
  939. xmlMutexLock(&xmlThrDefMutex);
  940. ret = xmlDefaultBufferSizeThrDef;
  941. xmlDefaultBufferSizeThrDef = v;
  942. xmlMutexUnlock(&xmlThrDefMutex);
  943. return ret;
  944. }
  945. int xmlThrDefDoValidityCheckingDefaultValue(int v) {
  946. int ret;
  947. xmlMutexLock(&xmlThrDefMutex);
  948. ret = xmlDoValidityCheckingDefaultValueThrDef;
  949. xmlDoValidityCheckingDefaultValueThrDef = v;
  950. xmlMutexUnlock(&xmlThrDefMutex);
  951. return ret;
  952. }
  953. int xmlThrDefGetWarningsDefaultValue(int v) {
  954. int ret;
  955. xmlMutexLock(&xmlThrDefMutex);
  956. ret = xmlGetWarningsDefaultValueThrDef;
  957. xmlGetWarningsDefaultValueThrDef = v;
  958. xmlMutexUnlock(&xmlThrDefMutex);
  959. return ret;
  960. }
  961. #ifdef LIBXML_OUTPUT_ENABLED
  962. int xmlThrDefIndentTreeOutput(int v) {
  963. int ret;
  964. xmlMutexLock(&xmlThrDefMutex);
  965. ret = xmlIndentTreeOutputThrDef;
  966. xmlIndentTreeOutputThrDef = v;
  967. xmlMutexUnlock(&xmlThrDefMutex);
  968. return ret;
  969. }
  970. const char * xmlThrDefTreeIndentString(const char * v) {
  971. const char * ret;
  972. xmlMutexLock(&xmlThrDefMutex);
  973. ret = xmlTreeIndentStringThrDef;
  974. xmlTreeIndentStringThrDef = v;
  975. xmlMutexUnlock(&xmlThrDefMutex);
  976. return ret;
  977. }
  978. int xmlThrDefSaveNoEmptyTags(int v) {
  979. int ret;
  980. xmlMutexLock(&xmlThrDefMutex);
  981. ret = xmlSaveNoEmptyTagsThrDef;
  982. xmlSaveNoEmptyTagsThrDef = v;
  983. xmlMutexUnlock(&xmlThrDefMutex);
  984. return ret;
  985. }
  986. #endif
  987. int xmlThrDefKeepBlanksDefaultValue(int v) {
  988. int ret;
  989. xmlMutexLock(&xmlThrDefMutex);
  990. ret = xmlKeepBlanksDefaultValueThrDef;
  991. xmlKeepBlanksDefaultValueThrDef = v;
  992. xmlMutexUnlock(&xmlThrDefMutex);
  993. return ret;
  994. }
  995. int xmlThrDefLineNumbersDefaultValue(int v) {
  996. int ret;
  997. xmlMutexLock(&xmlThrDefMutex);
  998. ret = xmlLineNumbersDefaultValueThrDef;
  999. xmlLineNumbersDefaultValueThrDef = v;
  1000. xmlMutexUnlock(&xmlThrDefMutex);
  1001. return ret;
  1002. }
  1003. int xmlThrDefLoadExtDtdDefaultValue(int v) {
  1004. int ret;
  1005. xmlMutexLock(&xmlThrDefMutex);
  1006. ret = xmlLoadExtDtdDefaultValueThrDef;
  1007. xmlLoadExtDtdDefaultValueThrDef = v;
  1008. xmlMutexUnlock(&xmlThrDefMutex);
  1009. return ret;
  1010. }
  1011. int xmlThrDefParserDebugEntities(int v) {
  1012. int ret;
  1013. xmlMutexLock(&xmlThrDefMutex);
  1014. ret = xmlParserDebugEntitiesThrDef;
  1015. xmlParserDebugEntitiesThrDef = v;
  1016. xmlMutexUnlock(&xmlThrDefMutex);
  1017. return ret;
  1018. }
  1019. int xmlThrDefPedanticParserDefaultValue(int v) {
  1020. int ret;
  1021. xmlMutexLock(&xmlThrDefMutex);
  1022. ret = xmlPedanticParserDefaultValueThrDef;
  1023. xmlPedanticParserDefaultValueThrDef = v;
  1024. xmlMutexUnlock(&xmlThrDefMutex);
  1025. return ret;
  1026. }
  1027. int xmlThrDefSubstituteEntitiesDefaultValue(int v) {
  1028. int ret;
  1029. xmlMutexLock(&xmlThrDefMutex);
  1030. ret = xmlSubstituteEntitiesDefaultValueThrDef;
  1031. xmlSubstituteEntitiesDefaultValueThrDef = v;
  1032. xmlMutexUnlock(&xmlThrDefMutex);
  1033. return ret;
  1034. }
  1035. xmlRegisterNodeFunc
  1036. xmlThrDefRegisterNodeDefault(xmlRegisterNodeFunc func)
  1037. {
  1038. xmlRegisterNodeFunc old;
  1039. xmlMutexLock(&xmlThrDefMutex);
  1040. old = xmlRegisterNodeDefaultValueThrDef;
  1041. __xmlRegisterCallbacks = 1;
  1042. xmlRegisterNodeDefaultValueThrDef = func;
  1043. xmlMutexUnlock(&xmlThrDefMutex);
  1044. return(old);
  1045. }
  1046. xmlDeregisterNodeFunc
  1047. xmlThrDefDeregisterNodeDefault(xmlDeregisterNodeFunc func)
  1048. {
  1049. xmlDeregisterNodeFunc old;
  1050. xmlMutexLock(&xmlThrDefMutex);
  1051. old = xmlDeregisterNodeDefaultValueThrDef;
  1052. __xmlRegisterCallbacks = 1;
  1053. xmlDeregisterNodeDefaultValueThrDef = func;
  1054. xmlMutexUnlock(&xmlThrDefMutex);
  1055. return(old);
  1056. }
  1057. xmlParserInputBufferCreateFilenameFunc
  1058. xmlThrDefParserInputBufferCreateFilenameDefault(xmlParserInputBufferCreateFilenameFunc func)
  1059. {
  1060. xmlParserInputBufferCreateFilenameFunc old;
  1061. xmlMutexLock(&xmlThrDefMutex);
  1062. old = xmlParserInputBufferCreateFilenameValueThrDef;
  1063. if (old == NULL) {
  1064. old = __xmlParserInputBufferCreateFilename;
  1065. }
  1066. xmlParserInputBufferCreateFilenameValueThrDef = func;
  1067. xmlMutexUnlock(&xmlThrDefMutex);
  1068. return(old);
  1069. }
  1070. xmlOutputBufferCreateFilenameFunc
  1071. xmlThrDefOutputBufferCreateFilenameDefault(xmlOutputBufferCreateFilenameFunc func)
  1072. {
  1073. xmlOutputBufferCreateFilenameFunc old;
  1074. xmlMutexLock(&xmlThrDefMutex);
  1075. old = xmlOutputBufferCreateFilenameValueThrDef;
  1076. #ifdef LIBXML_OUTPUT_ENABLED
  1077. if (old == NULL) {
  1078. old = __xmlOutputBufferCreateFilename;
  1079. }
  1080. #endif
  1081. xmlOutputBufferCreateFilenameValueThrDef = func;
  1082. xmlMutexUnlock(&xmlThrDefMutex);
  1083. return(old);
  1084. }