react-native-nitro-xlsx 0.2.5 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (395) hide show
  1. package/NitroXlsx.podspec +26 -27
  2. package/Package.swift +31 -10
  3. package/README.md +1 -1
  4. package/android/CMakeLists.txt +20 -27
  5. package/package.json +2 -2
  6. package/scripts/run-cpp-tests.sh +1 -1
  7. package/thirdparty/OpenXLSX/.clang-format +118 -0
  8. package/thirdparty/OpenXLSX/.clang-tidy +28 -0
  9. package/thirdparty/OpenXLSX/.gitignore +130 -0
  10. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_before_XMLNode_wrappers +46 -0
  11. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_and_stripping +49 -0
  12. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_char_support +49 -0
  13. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_support +49 -0
  14. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespaced_name_disabled +49 -0
  15. package/thirdparty/OpenXLSX/Benchmarks/2024-08-11-benchmarks_post-XLCellIterator-Rework +46 -0
  16. package/thirdparty/OpenXLSX/Benchmarks/2024-08-14-benchmarks_post-default-row-column-style-support +46 -0
  17. package/thirdparty/OpenXLSX/Benchmarks/2024-09-02-benchmarks +46 -0
  18. package/thirdparty/OpenXLSX/Benchmarks/2024-12-19-benchmarks +46 -0
  19. package/thirdparty/OpenXLSX/Benchmarks/2024-12-30-benchmarks-post-XLSharedStrings-by-ref +46 -0
  20. package/thirdparty/OpenXLSX/Benchmarks/2025-01-09-benchmarks-post-conditionalFormatsAndSheetProtection +46 -0
  21. package/thirdparty/OpenXLSX/Benchmarks/2025-01-10-benchmarks-post-XLCellValue-bugfix +46 -0
  22. package/thirdparty/OpenXLSX/Benchmarks/2025-01-31-benchmarks-post-XLComments-implementation +46 -0
  23. package/thirdparty/OpenXLSX/Benchmarks/2025-02-02-benchmarks-post-XLRowIterator-Rework +46 -0
  24. package/thirdparty/OpenXLSX/Benchmarks/2025-07-20-benchmarks-after-hiding-pugixml-internals +46 -0
  25. package/thirdparty/OpenXLSX/Benchmarks/2025-08-29-benchmarks-after-code-review-with-libzip +46 -0
  26. package/thirdparty/OpenXLSX/Benchmarks/Benchmark.cpp +249 -0
  27. package/thirdparty/OpenXLSX/Benchmarks/CMakeLists.txt +19 -0
  28. package/thirdparty/OpenXLSX/CMakeLists.txt +466 -0
  29. package/thirdparty/OpenXLSX/Documentation/CMakeLists.txt +31 -0
  30. package/thirdparty/OpenXLSX/Documentation/Doxyfile.in +2471 -0
  31. package/thirdparty/OpenXLSX/Documentation/DoxygenLayout.xml +194 -0
  32. package/thirdparty/OpenXLSX/Documentation/customdoxygen.css +1355 -0
  33. package/thirdparty/OpenXLSX/Examples/CMakeLists.txt +103 -0
  34. package/thirdparty/OpenXLSX/Examples/Demo1.cpp +279 -0
  35. package/thirdparty/OpenXLSX/Examples/Demo10.cpp +545 -0
  36. package/thirdparty/OpenXLSX/Examples/Demo1A.cpp +137 -0
  37. package/thirdparty/OpenXLSX/Examples/Demo2.cpp +65 -0
  38. package/thirdparty/OpenXLSX/Examples/Demo3.cpp +89 -0
  39. package/thirdparty/OpenXLSX/Examples/Demo4.cpp +86 -0
  40. package/thirdparty/OpenXLSX/Examples/Demo5.cpp +77 -0
  41. package/thirdparty/OpenXLSX/Examples/Demo6.cpp +103 -0
  42. package/thirdparty/OpenXLSX/Examples/Demo7.cpp +79 -0
  43. package/thirdparty/OpenXLSX/Examples/Demo8.cpp +117 -0
  44. package/thirdparty/OpenXLSX/Examples/Demo9.cpp +363 -0
  45. package/thirdparty/OpenXLSX/Examples/cmake/FindLIBZIP.cmake +61 -0
  46. package/thirdparty/OpenXLSX/Examples/external/CustomZip/CustomZip.hpp +256 -0
  47. package/thirdparty/OpenXLSX/LICENSE.md +29 -0
  48. package/thirdparty/OpenXLSX/Makefile.GNU +530 -0
  49. package/thirdparty/OpenXLSX/Notes/TBDs.txt +16 -0
  50. package/thirdparty/OpenXLSX/Notes/confirmed-TBCs.txt +8 -0
  51. package/thirdparty/OpenXLSX/Notes/styles-missing-support.xml +12 -0
  52. package/thirdparty/OpenXLSX/Notes/todo-list.txt +108 -0
  53. package/thirdparty/OpenXLSX/OpenXLSX/CMakeLists.txt +631 -0
  54. package/thirdparty/OpenXLSX/OpenXLSX/OpenXLSX.hpp +63 -0
  55. package/thirdparty/OpenXLSX/OpenXLSX/OpenXLSXConfig.cmake +11 -0
  56. package/thirdparty/OpenXLSX/OpenXLSX/cmake/bundle_static_library.cmake +198 -0
  57. package/thirdparty/OpenXLSX/OpenXLSX/cmake/patch_pkg_config.cmake +69 -0
  58. package/thirdparty/OpenXLSX/OpenXLSX/headers/IZipArchive.hpp +361 -0
  59. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX-Exports.hpp +12 -0
  60. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCell.hpp +367 -0
  61. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellIterator.hpp +252 -0
  62. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellRange.hpp +223 -0
  63. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellReference.hpp +317 -0
  64. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellValue.hpp +793 -0
  65. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLColor.hpp +232 -0
  66. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLColumn.hpp +159 -0
  67. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCommandQuery.hpp +228 -0
  68. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLComments.hpp +270 -0
  69. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLConstants.hpp +18 -0
  70. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLContentTypes.hpp +264 -0
  71. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDateTime.hpp +175 -0
  72. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDocument.hpp +505 -0
  73. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDrawing.hpp +452 -0
  74. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLException.hpp +161 -0
  75. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLFormula.hpp +375 -0
  76. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLIterator.hpp +40 -0
  77. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLMergeCells.hpp +216 -0
  78. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLProperties.hpp +348 -0
  79. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRelationships.hpp +348 -0
  80. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRow.hpp +721 -0
  81. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRowData.hpp +488 -0
  82. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLSharedStrings.hpp +204 -0
  83. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLSheet.hpp +1640 -0
  84. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLStyles.hpp +2390 -0
  85. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLTables.hpp +132 -0
  86. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLWorkbook.hpp +404 -0
  87. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlData.hpp +283 -0
  88. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlFile.hpp +194 -0
  89. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlParser.hpp +282 -0
  90. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlParserForwardDeclarations.hpp +85 -0
  91. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLZipArchive.hpp +232 -0
  92. package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/LibZip.hpp +447 -0
  93. package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/OpenXLSXFileSystemTools.hpp +207 -0
  94. package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/Zippy.hpp +1375 -0
  95. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCell.cpp +340 -0
  96. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellIterator.cpp +427 -0
  97. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellRange.cpp +221 -0
  98. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellReference.cpp +408 -0
  99. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellValue.cpp +519 -0
  100. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLColor.cpp +202 -0
  101. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLColumn.cpp +141 -0
  102. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLComments.cpp +637 -0
  103. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLContentTypes.cpp +329 -0
  104. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDateTime.cpp +269 -0
  105. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDocument.cpp +1678 -0
  106. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDrawing.cpp +784 -0
  107. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLFormula.cpp +201 -0
  108. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLMergeCells.cpp +357 -0
  109. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLProperties.cpp +810 -0
  110. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRelationships.cpp +529 -0
  111. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRow.cpp +918 -0
  112. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRowData.cpp +508 -0
  113. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLSharedStrings.cpp +220 -0
  114. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLSheet.cpp +1970 -0
  115. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLStyles.cpp +3014 -0
  116. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLTables.cpp +125 -0
  117. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLWorkbook.cpp +784 -0
  118. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlData.cpp +247 -0
  119. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlFile.cpp +160 -0
  120. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlParser.cpp +261 -0
  121. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLZipArchive.cpp +266 -0
  122. package/thirdparty/OpenXLSX/OpenXLSX/sources/utilities/XLUtilities.hpp +478 -0
  123. package/thirdparty/OpenXLSX/README.md +1279 -0
  124. package/thirdparty/OpenXLSX/Scripts/cmake-cleanup.sh +102 -0
  125. package/thirdparty/OpenXLSX/Scripts/compile.sh +23 -0
  126. package/thirdparty/OpenXLSX/Scripts/demos-cleanup.sh +25 -0
  127. package/thirdparty/OpenXLSX/Scripts/demos-run-all.sh +60 -0
  128. package/thirdparty/OpenXLSX/Scripts/guarded-xml-format.sh +47 -0
  129. package/thirdparty/OpenXLSX/Scripts/make-gnu.sh +11 -0
  130. package/thirdparty/OpenXLSX/Scripts/uninstall-manifest.sh +48 -0
  131. package/thirdparty/OpenXLSX/Scripts/xml-format-all.sh +19 -0
  132. package/thirdparty/OpenXLSX/Scripts/xml-format.sh +38 -0
  133. package/thirdparty/OpenXLSX/Tests/CMakeLists.txt +37 -0
  134. package/thirdparty/OpenXLSX/Tests/catch/catch.hpp +17799 -0
  135. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_automake.hpp +68 -0
  136. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_sonarqube.hpp +182 -0
  137. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_tap.hpp +278 -0
  138. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_teamcity.hpp +212 -0
  139. package/thirdparty/OpenXLSX/Tests/main.cpp +55 -0
  140. package/thirdparty/OpenXLSX/Tests/testXLCell.cpp +176 -0
  141. package/thirdparty/OpenXLSX/Tests/testXLCellRange.cpp +180 -0
  142. package/thirdparty/OpenXLSX/Tests/testXLCellReference.cpp +160 -0
  143. package/thirdparty/OpenXLSX/Tests/testXLCellValue.cpp +366 -0
  144. package/thirdparty/OpenXLSX/Tests/testXLCellValueProxy.cpp +255 -0
  145. package/thirdparty/OpenXLSX/Tests/testXLColor.cpp +75 -0
  146. package/thirdparty/OpenXLSX/Tests/testXLDateTime.cpp +229 -0
  147. package/thirdparty/OpenXLSX/Tests/testXLDocument.cpp +197 -0
  148. package/thirdparty/OpenXLSX/Tests/testXLFormula.cpp +131 -0
  149. package/thirdparty/OpenXLSX/Tests/testXLRow.cpp +597 -0
  150. package/thirdparty/OpenXLSX/Tests/testXLSheet.cpp +77 -0
  151. package/thirdparty/OpenXLSX/Tests/ziptest-with-libs.cpp +88 -0
  152. package/thirdparty/OpenXLSX/Tests/ziptest.cpp +735 -0
  153. package/thirdparty/OpenXLSX/cmake/get-git-HEAD-ID.cmake +45 -0
  154. package/thirdparty/OpenXLSX/cmake/libopenxlsxCPackOptions.cmake.in +20 -0
  155. package/thirdparty/OpenXLSX/cmake/manage_dependency.cmake +813 -0
  156. package/thirdparty/OpenXLSX/cmake/recursive_library_type_test.cmake +52 -0
  157. package/thirdparty/OpenXLSX/gnu-make-crutch/OpenXLSX-Exports-shared.hpp +42 -0
  158. package/thirdparty/OpenXLSX/gnu-make-crutch/OpenXLSX-Exports-static.hpp +42 -0
  159. package/thirdparty/OpenXLSX/vcpkg.json +24 -0
  160. package/thirdparty/README.md +42 -0
  161. package/thirdparty/miniz/.clang-format +47 -0
  162. package/thirdparty/miniz/.travis.yml +2 -0
  163. package/thirdparty/miniz/CMakeLists.txt +333 -0
  164. package/thirdparty/miniz/CMakePresets.json +31 -0
  165. package/thirdparty/miniz/ChangeLog.md +272 -0
  166. package/thirdparty/miniz/Config.cmake.in +1 -0
  167. package/thirdparty/miniz/LICENSE +22 -0
  168. package/thirdparty/miniz/amalgamate.sh +57 -0
  169. package/thirdparty/miniz/examples/example1.c +105 -0
  170. package/thirdparty/miniz/examples/example2.c +164 -0
  171. package/thirdparty/miniz/examples/example3.c +269 -0
  172. package/thirdparty/miniz/examples/example4.c +102 -0
  173. package/thirdparty/miniz/examples/example5.c +327 -0
  174. package/thirdparty/miniz/examples/example6.c +189 -0
  175. package/thirdparty/miniz/meson.build +21 -0
  176. package/thirdparty/miniz/miniz.c +646 -0
  177. package/thirdparty/miniz/miniz.h +615 -0
  178. package/thirdparty/miniz/miniz.pc.in +13 -0
  179. package/thirdparty/miniz/miniz_common.h +89 -0
  180. package/thirdparty/miniz/miniz_export.h +20 -0
  181. package/thirdparty/miniz/miniz_tdef.c +1602 -0
  182. package/thirdparty/miniz/miniz_tdef.h +199 -0
  183. package/thirdparty/miniz/miniz_tinfl.c +778 -0
  184. package/thirdparty/miniz/miniz_tinfl.h +150 -0
  185. package/thirdparty/miniz/miniz_zip.c +4895 -0
  186. package/thirdparty/miniz/miniz_zip.h +454 -0
  187. package/thirdparty/miniz/readme.md +46 -0
  188. package/thirdparty/miniz/test.sh +36 -0
  189. package/thirdparty/miniz/tests/add_in_place_fuzzer.c +87 -0
  190. package/thirdparty/miniz/tests/catch_amalgamated.cpp +10795 -0
  191. package/thirdparty/miniz/tests/catch_amalgamated.hpp +13143 -0
  192. package/thirdparty/miniz/tests/checksum_fuzzer.c +26 -0
  193. package/thirdparty/miniz/tests/compress_fuzzer.c +91 -0
  194. package/thirdparty/miniz/tests/flush_fuzzer.c +88 -0
  195. package/thirdparty/miniz/tests/fuzz_main.c +55 -0
  196. package/thirdparty/miniz/tests/large_fuzzer.c +133 -0
  197. package/thirdparty/miniz/tests/main.cpp +185 -0
  198. package/thirdparty/miniz/tests/miniz_tdefl_fuzzer.cc +115 -0
  199. package/thirdparty/miniz/tests/miniz_tester.cpp +1881 -0
  200. package/thirdparty/miniz/tests/miniz_zip_validate_fuzzer.cc +71 -0
  201. package/thirdparty/miniz/tests/miniz_zip_writer_fuzzer.cc +96 -0
  202. package/thirdparty/miniz/tests/ossfuzz.sh +48 -0
  203. package/thirdparty/miniz/tests/small_fuzzer.c +126 -0
  204. package/thirdparty/miniz/tests/timer.cpp +152 -0
  205. package/thirdparty/miniz/tests/timer.h +40 -0
  206. package/thirdparty/miniz/tests/uncompress2_fuzzer.c +21 -0
  207. package/thirdparty/miniz/tests/uncompress_fuzzer.c +30 -0
  208. package/thirdparty/miniz/tests/zip.dict +9 -0
  209. package/thirdparty/miniz/tests/zip_fuzzer.c +63 -0
  210. package/thirdparty/pugixml/.codecov.yml +7 -0
  211. package/thirdparty/pugixml/.gitattributes +1 -0
  212. package/thirdparty/pugixml/CMakeLists.txt +330 -0
  213. package/thirdparty/pugixml/LICENSE.md +24 -0
  214. package/thirdparty/pugixml/Makefile +98 -0
  215. package/thirdparty/pugixml/README.md +81 -0
  216. package/thirdparty/pugixml/SECURITY.md +9 -0
  217. package/thirdparty/pugixml/appveyor.yml +50 -0
  218. package/thirdparty/pugixml/docs/config.adoc +7 -0
  219. package/thirdparty/pugixml/docs/images/dom_tree.png +0 -0
  220. package/thirdparty/pugixml/docs/images/vs2005_link1.png +0 -0
  221. package/thirdparty/pugixml/docs/images/vs2005_link2.png +0 -0
  222. package/thirdparty/pugixml/docs/images/vs2005_pch1.png +0 -0
  223. package/thirdparty/pugixml/docs/images/vs2005_pch2.png +0 -0
  224. package/thirdparty/pugixml/docs/images/vs2005_pch3.png +0 -0
  225. package/thirdparty/pugixml/docs/images/vs2005_pch4.png +0 -0
  226. package/thirdparty/pugixml/docs/images/vs2010_link1.png +0 -0
  227. package/thirdparty/pugixml/docs/images/vs2010_link2.png +0 -0
  228. package/thirdparty/pugixml/docs/manual.adoc +3326 -0
  229. package/thirdparty/pugixml/docs/manual.html +6395 -0
  230. package/thirdparty/pugixml/docs/quickstart.adoc +287 -0
  231. package/thirdparty/pugixml/docs/quickstart.html +1107 -0
  232. package/thirdparty/pugixml/docs/samples/character.xml +8 -0
  233. package/thirdparty/pugixml/docs/samples/custom_memory_management.cpp +27 -0
  234. package/thirdparty/pugixml/docs/samples/include.cpp +64 -0
  235. package/thirdparty/pugixml/docs/samples/load_error_handling.cpp +33 -0
  236. package/thirdparty/pugixml/docs/samples/load_file.cpp +16 -0
  237. package/thirdparty/pugixml/docs/samples/load_memory.cpp +66 -0
  238. package/thirdparty/pugixml/docs/samples/load_options.cpp +30 -0
  239. package/thirdparty/pugixml/docs/samples/load_stream.cpp +97 -0
  240. package/thirdparty/pugixml/docs/samples/modify_add.cpp +29 -0
  241. package/thirdparty/pugixml/docs/samples/modify_base.cpp +43 -0
  242. package/thirdparty/pugixml/docs/samples/modify_remove.cpp +27 -0
  243. package/thirdparty/pugixml/docs/samples/save_custom_writer.cpp +116 -0
  244. package/thirdparty/pugixml/docs/samples/save_declaration.cpp +27 -0
  245. package/thirdparty/pugixml/docs/samples/save_file.cpp +17 -0
  246. package/thirdparty/pugixml/docs/samples/save_options.cpp +48 -0
  247. package/thirdparty/pugixml/docs/samples/save_stream.cpp +18 -0
  248. package/thirdparty/pugixml/docs/samples/save_subtree.cpp +26 -0
  249. package/thirdparty/pugixml/docs/samples/text.cpp +35 -0
  250. package/thirdparty/pugixml/docs/samples/transitions.xml +7 -0
  251. package/thirdparty/pugixml/docs/samples/traverse_base.cpp +51 -0
  252. package/thirdparty/pugixml/docs/samples/traverse_iter.cpp +27 -0
  253. package/thirdparty/pugixml/docs/samples/traverse_predicate.cpp +48 -0
  254. package/thirdparty/pugixml/docs/samples/traverse_rangefor.cpp +32 -0
  255. package/thirdparty/pugixml/docs/samples/traverse_walker.cpp +35 -0
  256. package/thirdparty/pugixml/docs/samples/tree.xml +12 -0
  257. package/thirdparty/pugixml/docs/samples/weekly-shift_jis.xml +78 -0
  258. package/thirdparty/pugixml/docs/samples/weekly-utf-16.xml +0 -0
  259. package/thirdparty/pugixml/docs/samples/weekly-utf-8.xml +78 -0
  260. package/thirdparty/pugixml/docs/samples/xgconsole.xml +12 -0
  261. package/thirdparty/pugixml/docs/samples/xpath_error.cpp +43 -0
  262. package/thirdparty/pugixml/docs/samples/xpath_query.cpp +36 -0
  263. package/thirdparty/pugixml/docs/samples/xpath_select.cpp +28 -0
  264. package/thirdparty/pugixml/docs/samples/xpath_variables.cpp +38 -0
  265. package/thirdparty/pugixml/readme.txt +50 -0
  266. package/thirdparty/pugixml/scripts/archive.py +54 -0
  267. package/thirdparty/pugixml/scripts/cocoapods_push.sh +4 -0
  268. package/thirdparty/pugixml/scripts/natvis/pugixml.natvis +77 -0
  269. package/thirdparty/pugixml/scripts/natvis/pugixml_compact.natvis +506 -0
  270. package/thirdparty/pugixml/scripts/nuget/build/native/pugixml-propertiesui.xml +17 -0
  271. package/thirdparty/pugixml/scripts/nuget/build/native/pugixml.targets +28 -0
  272. package/thirdparty/pugixml/scripts/nuget/pugixml.nuspec +20 -0
  273. package/thirdparty/pugixml/scripts/nuget_build.ps1 +60 -0
  274. package/thirdparty/pugixml/scripts/premake4.lua +92 -0
  275. package/thirdparty/pugixml/scripts/pugixml-config.cmake.in +12 -0
  276. package/thirdparty/pugixml/scripts/pugixml.pc.in +11 -0
  277. package/thirdparty/pugixml/scripts/pugixml.podspec +14 -0
  278. package/thirdparty/pugixml/scripts/pugixml.xcodeproj/project.pbxproj +212 -0
  279. package/thirdparty/pugixml/scripts/pugixml_airplay.mkf +13 -0
  280. package/thirdparty/pugixml/scripts/pugixml_codeblocks.cbp +44 -0
  281. package/thirdparty/pugixml/scripts/pugixml_codelite.project +56 -0
  282. package/thirdparty/pugixml/scripts/pugixml_dll.rc +45 -0
  283. package/thirdparty/pugixml/scripts/pugixml_vs2005.vcproj +343 -0
  284. package/thirdparty/pugixml/scripts/pugixml_vs2005_static.vcproj +343 -0
  285. package/thirdparty/pugixml/scripts/pugixml_vs2008.vcproj +339 -0
  286. package/thirdparty/pugixml/scripts/pugixml_vs2008_static.vcproj +339 -0
  287. package/thirdparty/pugixml/scripts/pugixml_vs2010.vcxproj +191 -0
  288. package/thirdparty/pugixml/scripts/pugixml_vs2010_static.vcxproj +191 -0
  289. package/thirdparty/pugixml/scripts/pugixml_vs2013.vcxproj +199 -0
  290. package/thirdparty/pugixml/scripts/pugixml_vs2013_static.vcxproj +199 -0
  291. package/thirdparty/pugixml/scripts/pugixml_vs2015.vcxproj +172 -0
  292. package/thirdparty/pugixml/scripts/pugixml_vs2015_static.vcxproj +176 -0
  293. package/thirdparty/pugixml/scripts/pugixml_vs2017.vcxproj +172 -0
  294. package/thirdparty/pugixml/scripts/pugixml_vs2017_static.vcxproj +176 -0
  295. package/thirdparty/pugixml/scripts/pugixml_vs2019.vcxproj +176 -0
  296. package/thirdparty/pugixml/scripts/pugixml_vs2019_static.vcxproj +180 -0
  297. package/thirdparty/pugixml/scripts/pugixml_vs2022.vcxproj +176 -0
  298. package/thirdparty/pugixml/scripts/pugixml_vs2022_static.vcxproj +180 -0
  299. package/thirdparty/pugixml/scripts/pugixml_vs2026.vcxproj +176 -0
  300. package/thirdparty/pugixml/scripts/pugixml_vs2026_static.vcxproj +180 -0
  301. package/thirdparty/pugixml/scripts/sbom.cdx.json +47 -0
  302. package/thirdparty/pugixml/src/pugiconfig.hpp +81 -0
  303. package/thirdparty/pugixml/src/pugixml.cpp +13776 -0
  304. package/thirdparty/pugixml/src/pugixml.hpp +1604 -0
  305. package/thirdparty/pugixml/tests/allocator.cpp +175 -0
  306. package/thirdparty/pugixml/tests/allocator.hpp +10 -0
  307. package/thirdparty/pugixml/tests/autotest-appveyor.ps1 +93 -0
  308. package/thirdparty/pugixml/tests/cmake-appveyor.ps1 +57 -0
  309. package/thirdparty/pugixml/tests/data/empty.xml +0 -0
  310. package/thirdparty/pugixml/tests/data/large.xml +1 -0
  311. package/thirdparty/pugixml/tests/data/latintest_latin1.xml +1 -0
  312. package/thirdparty/pugixml/tests/data/latintest_utf8.xml +1 -0
  313. package/thirdparty/pugixml/tests/data/multiline.xml +3 -0
  314. package/thirdparty/pugixml/tests/data/small.xml +1 -0
  315. package/thirdparty/pugixml/tests/data/truncation.xml +19 -0
  316. package/thirdparty/pugixml/tests/data/utftest_utf16_be.xml +0 -0
  317. package/thirdparty/pugixml/tests/data/utftest_utf16_be_bom.xml +0 -0
  318. package/thirdparty/pugixml/tests/data/utftest_utf16_be_clean.xml +0 -0
  319. package/thirdparty/pugixml/tests/data/utftest_utf16_be_nodecl.xml +0 -0
  320. package/thirdparty/pugixml/tests/data/utftest_utf16_le.xml +0 -0
  321. package/thirdparty/pugixml/tests/data/utftest_utf16_le_bom.xml +0 -0
  322. package/thirdparty/pugixml/tests/data/utftest_utf16_le_clean.xml +0 -0
  323. package/thirdparty/pugixml/tests/data/utftest_utf16_le_nodecl.xml +0 -0
  324. package/thirdparty/pugixml/tests/data/utftest_utf32_be.xml +0 -0
  325. package/thirdparty/pugixml/tests/data/utftest_utf32_be_bom.xml +0 -0
  326. package/thirdparty/pugixml/tests/data/utftest_utf32_be_clean.xml +0 -0
  327. package/thirdparty/pugixml/tests/data/utftest_utf32_be_nodecl.xml +0 -0
  328. package/thirdparty/pugixml/tests/data/utftest_utf32_le.xml +0 -0
  329. package/thirdparty/pugixml/tests/data/utftest_utf32_le_bom.xml +0 -0
  330. package/thirdparty/pugixml/tests/data/utftest_utf32_le_clean.xml +0 -0
  331. package/thirdparty/pugixml/tests/data/utftest_utf32_le_nodecl.xml +0 -0
  332. package/thirdparty/pugixml/tests/data/utftest_utf8.xml +87 -0
  333. package/thirdparty/pugixml/tests/data/utftest_utf8_bom.xml +87 -0
  334. package/thirdparty/pugixml/tests/data/utftest_utf8_clean.xml +84 -0
  335. package/thirdparty/pugixml/tests/data/utftest_utf8_nodecl.xml +86 -0
  336. package/thirdparty/pugixml/tests/data//321/202/320/265/321/201/321/202.xml +1 -0
  337. package/thirdparty/pugixml/tests/data_fuzz_parse/basic.xml +1 -0
  338. package/thirdparty/pugixml/tests/data_fuzz_parse/doctype.xml +1 -0
  339. package/thirdparty/pugixml/tests/data_fuzz_parse/refs.xml +1 -0
  340. package/thirdparty/pugixml/tests/data_fuzz_parse/types.xml +1 -0
  341. package/thirdparty/pugixml/tests/data_fuzz_parse/utf16.xml +0 -0
  342. package/thirdparty/pugixml/tests/data_fuzz_parse/utf32.xml +0 -0
  343. package/thirdparty/pugixml/tests/data_fuzz_xpath/basic.xpath +1 -0
  344. package/thirdparty/pugixml/tests/data_fuzz_xpath/functions.xpath +1 -0
  345. package/thirdparty/pugixml/tests/data_fuzz_xpath/math.xpath +1 -0
  346. package/thirdparty/pugixml/tests/data_fuzz_xpath/path.xpath +1 -0
  347. package/thirdparty/pugixml/tests/data_fuzz_xpath/predicate.xpath +1 -0
  348. package/thirdparty/pugixml/tests/fuzz_parse.cpp +14 -0
  349. package/thirdparty/pugixml/tests/fuzz_parse.dict +72 -0
  350. package/thirdparty/pugixml/tests/fuzz_setup.sh +11 -0
  351. package/thirdparty/pugixml/tests/fuzz_xpath.cpp +46 -0
  352. package/thirdparty/pugixml/tests/fuzz_xpath.dict +72 -0
  353. package/thirdparty/pugixml/tests/helpers.hpp +114 -0
  354. package/thirdparty/pugixml/tests/main.cpp +218 -0
  355. package/thirdparty/pugixml/tests/test.cpp +220 -0
  356. package/thirdparty/pugixml/tests/test.hpp +175 -0
  357. package/thirdparty/pugixml/tests/test_compact.cpp +150 -0
  358. package/thirdparty/pugixml/tests/test_deprecated.cpp +25 -0
  359. package/thirdparty/pugixml/tests/test_document.cpp +1910 -0
  360. package/thirdparty/pugixml/tests/test_dom_modify.cpp +2122 -0
  361. package/thirdparty/pugixml/tests/test_dom_text.cpp +601 -0
  362. package/thirdparty/pugixml/tests/test_dom_traverse.cpp +1481 -0
  363. package/thirdparty/pugixml/tests/test_header_guard.cpp +3 -0
  364. package/thirdparty/pugixml/tests/test_header_iosfwd_1.cpp +3 -0
  365. package/thirdparty/pugixml/tests/test_header_iosfwd_2.cpp +3 -0
  366. package/thirdparty/pugixml/tests/test_header_iostream_1.cpp +3 -0
  367. package/thirdparty/pugixml/tests/test_header_iostream_2.cpp +3 -0
  368. package/thirdparty/pugixml/tests/test_header_only_1.cpp +21 -0
  369. package/thirdparty/pugixml/tests/test_header_only_2.cpp +21 -0
  370. package/thirdparty/pugixml/tests/test_header_string_1.cpp +3 -0
  371. package/thirdparty/pugixml/tests/test_header_string_2.cpp +3 -0
  372. package/thirdparty/pugixml/tests/test_header_string_iostream.cpp +5 -0
  373. package/thirdparty/pugixml/tests/test_memory.cpp +303 -0
  374. package/thirdparty/pugixml/tests/test_parse.cpp +1463 -0
  375. package/thirdparty/pugixml/tests/test_parse_doctype.cpp +366 -0
  376. package/thirdparty/pugixml/tests/test_unicode.cpp +152 -0
  377. package/thirdparty/pugixml/tests/test_version.cpp +5 -0
  378. package/thirdparty/pugixml/tests/test_write.cpp +757 -0
  379. package/thirdparty/pugixml/tests/test_xpath.cpp +833 -0
  380. package/thirdparty/pugixml/tests/test_xpath_api.cpp +646 -0
  381. package/thirdparty/pugixml/tests/test_xpath_functions.cpp +844 -0
  382. package/thirdparty/pugixml/tests/test_xpath_operators.cpp +566 -0
  383. package/thirdparty/pugixml/tests/test_xpath_parse.cpp +428 -0
  384. package/thirdparty/pugixml/tests/test_xpath_paths.cpp +787 -0
  385. package/thirdparty/pugixml/tests/test_xpath_paths_abbrev_w3c.cpp +219 -0
  386. package/thirdparty/pugixml/tests/test_xpath_paths_w3c.cpp +312 -0
  387. package/thirdparty/pugixml/tests/test_xpath_variables.cpp +683 -0
  388. package/thirdparty/pugixml/tests/test_xpath_xalan_1.cpp +411 -0
  389. package/thirdparty/pugixml/tests/test_xpath_xalan_2.cpp +417 -0
  390. package/thirdparty/pugixml/tests/test_xpath_xalan_3.cpp +321 -0
  391. package/thirdparty/pugixml/tests/test_xpath_xalan_4.cpp +300 -0
  392. package/thirdparty/pugixml/tests/test_xpath_xalan_5.cpp +295 -0
  393. package/thirdparty/pugixml/tests/writer_string.cpp +79 -0
  394. package/thirdparty/pugixml/tests/writer_string.hpp +27 -0
  395. package/scripts/prepare-openxlsx.js +0 -126
@@ -0,0 +1,1463 @@
1
+ #include "test.hpp"
2
+
3
+ #include "writer_string.hpp"
4
+
5
+ using namespace pugi;
6
+
7
+ TEST(parse_pi_skip)
8
+ {
9
+ xml_document doc;
10
+
11
+ unsigned int flag_sets[] = {parse_fragment, parse_fragment | parse_declaration};
12
+
13
+ for (unsigned int i = 0; i < sizeof(flag_sets) / sizeof(flag_sets[0]); ++i)
14
+ {
15
+ unsigned int flags = flag_sets[i];
16
+
17
+ CHECK(doc.load_string(STR("<?pi?><?pi value?>"), flags));
18
+ CHECK(!doc.first_child());
19
+
20
+ CHECK(doc.load_string(STR("<?pi <tag/> value?>"), flags));
21
+ CHECK(!doc.first_child());
22
+ }
23
+ }
24
+
25
+ TEST(parse_pi_parse)
26
+ {
27
+ xml_document doc;
28
+ CHECK(doc.load_string(STR("<?pi1?><?pi2 value?>"), parse_fragment | parse_pi));
29
+
30
+ xml_node pi1 = doc.first_child();
31
+ xml_node pi2 = doc.last_child();
32
+
33
+ CHECK(pi1 != pi2);
34
+ CHECK(pi1.type() == node_pi);
35
+ CHECK_STRING(pi1.name(), STR("pi1"));
36
+ CHECK_STRING(pi1.value(), STR(""));
37
+ CHECK(pi2.type() == node_pi);
38
+ CHECK_STRING(pi2.name(), STR("pi2"));
39
+ CHECK_STRING(pi2.value(), STR("value"));
40
+ }
41
+
42
+ TEST(parse_pi_parse_spaces)
43
+ {
44
+ xml_document doc;
45
+ CHECK(doc.load_string(STR("<?target \r\n\t value ?>"), parse_fragment | parse_pi));
46
+
47
+ xml_node pi = doc.first_child();
48
+
49
+ CHECK(pi.type() == node_pi);
50
+ CHECK_STRING(pi.name(), STR("target"));
51
+ CHECK_STRING(pi.value(), STR("value "));
52
+ }
53
+
54
+ TEST(parse_pi_error)
55
+ {
56
+ xml_document doc;
57
+
58
+ unsigned int flag_sets[] = {parse_fragment, parse_fragment | parse_pi};
59
+
60
+ for (unsigned int i = 0; i < sizeof(flag_sets) / sizeof(flag_sets[0]); ++i)
61
+ {
62
+ unsigned int flags = flag_sets[i];
63
+
64
+ CHECK(doc.load_string(STR("<?"), flags).status == status_bad_pi);
65
+ CHECK(doc.load_string(STR("<??"), flags).status == status_bad_pi);
66
+ CHECK(doc.load_string(STR("<?>"), flags).status == status_bad_pi);
67
+ CHECK(doc.load_string(STR("<?#?>"), flags).status == status_bad_pi);
68
+ CHECK(doc.load_string(STR("<?name"), flags).status == status_bad_pi);
69
+ CHECK(doc.load_string(STR("<?name>"), flags).status == status_bad_pi);
70
+ CHECK(doc.load_string(STR("<?name ?"), flags).status == status_bad_pi);
71
+ CHECK(doc.load_string(STR("<?name?"), flags).status == status_bad_pi);
72
+ CHECK(doc.load_string(STR("<?name? "), flags).status == status_bad_pi);
73
+ CHECK(doc.load_string(STR("<?name? "), flags).status == status_bad_pi);
74
+ CHECK(doc.load_string(STR("<?name "), flags).status == status_bad_pi);
75
+ CHECK(doc.load_string(STR("<?name "), flags).status == status_bad_pi);
76
+ CHECK(doc.load_string(STR("<?name "), flags).status == status_bad_pi);
77
+ CHECK(doc.load_string(STR("<?name value"), flags).status == status_bad_pi);
78
+ CHECK(doc.load_string(STR("<?name value "), flags).status == status_bad_pi);
79
+ CHECK(doc.load_string(STR("<?name value "), flags).status == status_bad_pi);
80
+ CHECK(doc.load_string(STR("<?name value ?"), flags).status == status_bad_pi);
81
+ CHECK(doc.load_string(STR("<?name value ? "), flags).status == status_bad_pi);
82
+ CHECK(doc.load_string(STR("<?name value ? >"), flags).status == status_bad_pi);
83
+ CHECK(doc.load_string(STR("<?name value ? > "), flags).status == status_bad_pi);
84
+ CHECK(doc.load_string(STR("<?name&"), flags).status == status_bad_pi);
85
+ CHECK(doc.load_string(STR("<?name&?"), flags).status == status_bad_pi);
86
+ }
87
+
88
+ CHECK(doc.load_string(STR("<?xx#?>"), parse_fragment | parse_pi).status == status_bad_pi);
89
+ CHECK(doc.load_string(STR("<?name&?>"), parse_fragment | parse_pi).status == status_bad_pi);
90
+ CHECK(doc.load_string(STR("<?name& x?>"), parse_fragment | parse_pi).status == status_bad_pi);
91
+ }
92
+
93
+ TEST(parse_pi_error_buffer_boundary)
94
+ {
95
+ char buf1[] = "<?name?>";
96
+ char buf2[] = "<?name?x";
97
+
98
+ xml_document doc;
99
+ CHECK(doc.load_buffer_inplace(buf1, 8, parse_fragment | parse_pi));
100
+ CHECK(doc.load_buffer_inplace(buf2, 8, parse_fragment | parse_pi).status == status_bad_pi);
101
+ }
102
+
103
+ TEST(parse_comments_skip)
104
+ {
105
+ xml_document doc;
106
+ CHECK(doc.load_string(STR("<!----><!--value-->"), parse_fragment));
107
+ CHECK(!doc.first_child());
108
+ }
109
+
110
+ TEST(parse_comments_parse)
111
+ {
112
+ xml_document doc;
113
+ CHECK(doc.load_string(STR("<!----><!--value-->"), parse_fragment | parse_comments));
114
+
115
+ xml_node c1 = doc.first_child();
116
+ xml_node c2 = doc.last_child();
117
+
118
+ CHECK(c1 != c2);
119
+ CHECK(c1.type() == node_comment);
120
+ CHECK_STRING(c1.name(), STR(""));
121
+ CHECK_STRING(c1.value(), STR(""));
122
+ CHECK(c2.type() == node_comment);
123
+ CHECK_STRING(c2.name(), STR(""));
124
+ CHECK_STRING(c2.value(), STR("value"));
125
+ }
126
+
127
+ TEST(parse_comments_parse_no_eol)
128
+ {
129
+ xml_document doc;
130
+ CHECK(doc.load_string(STR("<!--\r\rval1\rval2\r\nval3\nval4\r\r-->"), parse_fragment | parse_comments));
131
+
132
+ xml_node c = doc.first_child();
133
+ CHECK(c.type() == node_comment);
134
+ CHECK_STRING(c.value(), STR("\r\rval1\rval2\r\nval3\nval4\r\r"));
135
+ }
136
+
137
+ TEST(parse_comments_parse_eol)
138
+ {
139
+ xml_document doc;
140
+ CHECK(doc.load_string(STR("<!--\r\rval1\rval2\r\nval3\nval4\r\r-->"), parse_fragment | parse_comments | parse_eol));
141
+
142
+ xml_node c = doc.first_child();
143
+ CHECK(c.type() == node_comment);
144
+ CHECK_STRING(c.value(), STR("\n\nval1\nval2\nval3\nval4\n\n"));
145
+ }
146
+
147
+ TEST(parse_comments_error)
148
+ {
149
+ xml_document doc;
150
+
151
+ unsigned int flag_sets[] = {parse_fragment, parse_fragment | parse_comments, parse_fragment | parse_comments | parse_eol};
152
+
153
+ for (unsigned int i = 0; i < sizeof(flag_sets) / sizeof(flag_sets[0]); ++i)
154
+ {
155
+ unsigned int flags = flag_sets[i];
156
+
157
+ CHECK(doc.load_string(STR("<!-"), flags).status == status_bad_comment);
158
+ CHECK(doc.load_string(STR("<!--"), flags).status == status_bad_comment);
159
+ CHECK(doc.load_string(STR("<!--v"), flags).status == status_bad_comment);
160
+ CHECK(doc.load_string(STR("<!-->"), flags).status == status_bad_comment);
161
+ CHECK(doc.load_string(STR("<!--->"), flags).status == status_bad_comment);
162
+ CHECK(doc.load_string(STR("<!-- <!-- --><!- -->"), flags).status == status_bad_comment);
163
+ }
164
+ }
165
+
166
+ TEST(parse_cdata_skip)
167
+ {
168
+ xml_document doc;
169
+ CHECK(doc.load_string(STR("<![CDATA[]]><![CDATA[value]]>"), parse_fragment));
170
+ CHECK(!doc.first_child());
171
+ }
172
+
173
+ TEST(parse_cdata_skip_contents)
174
+ {
175
+ xml_document doc;
176
+ CHECK(doc.load_string(STR("<node><![CDATA[]]>hello<![CDATA[value]]>, world!</node>"), parse_fragment));
177
+ CHECK_NODE(doc, STR("<node>hello, world!</node>"));
178
+ }
179
+
180
+ TEST(parse_cdata_parse)
181
+ {
182
+ xml_document doc;
183
+ CHECK(doc.load_string(STR("<![CDATA[]]><![CDATA[value]]>"), parse_fragment | parse_cdata));
184
+
185
+ xml_node c1 = doc.first_child();
186
+ xml_node c2 = doc.last_child();
187
+
188
+ CHECK(c1 != c2);
189
+ CHECK(c1.type() == node_cdata);
190
+ CHECK_STRING(c1.name(), STR(""));
191
+ CHECK_STRING(c1.value(), STR(""));
192
+ CHECK(c2.type() == node_cdata);
193
+ CHECK_STRING(c2.name(), STR(""));
194
+ CHECK_STRING(c2.value(), STR("value"));
195
+ }
196
+
197
+ TEST(parse_cdata_parse_no_eol)
198
+ {
199
+ xml_document doc;
200
+ CHECK(doc.load_string(STR("<![CDATA[\r\rval1\rval2\r\nval3\nval4\r\r]]>"), parse_fragment | parse_cdata));
201
+
202
+ xml_node c = doc.first_child();
203
+ CHECK(c.type() == node_cdata);
204
+ CHECK_STRING(c.value(), STR("\r\rval1\rval2\r\nval3\nval4\r\r"));
205
+ }
206
+
207
+ TEST(parse_cdata_parse_eol)
208
+ {
209
+ xml_document doc;
210
+ CHECK(doc.load_string(STR("<![CDATA[\r\rval1\rval2\r\nval3\nval4\r\r]]>"), parse_fragment | parse_cdata | parse_eol));
211
+
212
+ xml_node c = doc.first_child();
213
+ CHECK(c.type() == node_cdata);
214
+ CHECK_STRING(c.value(), STR("\n\nval1\nval2\nval3\nval4\n\n"));
215
+ }
216
+
217
+ TEST(parse_cdata_error)
218
+ {
219
+ xml_document doc;
220
+
221
+ unsigned int flag_sets[] = {parse_fragment, parse_fragment | parse_cdata, parse_fragment | parse_cdata | parse_eol};
222
+
223
+ for (unsigned int i = 0; i < sizeof(flag_sets) / sizeof(flag_sets[0]); ++i)
224
+ {
225
+ unsigned int flags = flag_sets[i];
226
+
227
+ CHECK(doc.load_string(STR("<!["), flags).status == status_bad_cdata);
228
+ CHECK(doc.load_string(STR("<![C"), flags).status == status_bad_cdata);
229
+ CHECK(doc.load_string(STR("<![CD"), flags).status == status_bad_cdata);
230
+ CHECK(doc.load_string(STR("<![CDA"), flags).status == status_bad_cdata);
231
+ CHECK(doc.load_string(STR("<![CDAT"), flags).status == status_bad_cdata);
232
+ CHECK(doc.load_string(STR("<![CDATA"), flags).status == status_bad_cdata);
233
+ CHECK(doc.load_string(STR("<![CDATA["), flags).status == status_bad_cdata);
234
+ CHECK(doc.load_string(STR("<![CDATA[]"), flags).status == status_bad_cdata);
235
+ CHECK(doc.load_string(STR("<![CDATA[data"), flags).status == status_bad_cdata);
236
+ CHECK(doc.load_string(STR("<![CDATA[data]"), flags).status == status_bad_cdata);
237
+ CHECK(doc.load_string(STR("<![CDATA[data]]"), flags).status == status_bad_cdata);
238
+ CHECK(doc.load_string(STR("<![CDATA[>"), flags).status == status_bad_cdata);
239
+ CHECK(doc.load_string(STR("<![CDATA[ <![CDATA[]]><![CDATA ]]>"), flags).status == status_bad_cdata);
240
+ }
241
+ }
242
+
243
+ TEST(parse_ws_pcdata_skip)
244
+ {
245
+ xml_document doc;
246
+ CHECK(doc.load_string(STR(" "), parse_fragment));
247
+ CHECK(!doc.first_child());
248
+
249
+ CHECK(doc.load_string(STR("<root> <node> </node> </root>"), parse_minimal));
250
+
251
+ xml_node root = doc.child(STR("root"));
252
+
253
+ CHECK(root.first_child() == root.last_child());
254
+ CHECK(!root.first_child().first_child());
255
+ }
256
+
257
+ TEST(parse_ws_pcdata_parse)
258
+ {
259
+ xml_document doc;
260
+ CHECK(doc.load_string(STR("<root> <node> </node> </root>"), parse_minimal | parse_ws_pcdata));
261
+
262
+ xml_node root = doc.child(STR("root"));
263
+
264
+ xml_node c1 = root.first_child();
265
+ xml_node c2 = c1.next_sibling();
266
+ xml_node c3 = c2.next_sibling();
267
+
268
+ CHECK(c3 == root.last_child());
269
+
270
+ CHECK(c1.type() == node_pcdata);
271
+ CHECK_STRING(c1.value(), STR(" "));
272
+ CHECK(c3.type() == node_pcdata);
273
+ CHECK_STRING(c3.value(), STR(" "));
274
+
275
+ CHECK(c2.first_child() == c2.last_child());
276
+ CHECK(c2.first_child().type() == node_pcdata);
277
+ CHECK_STRING(c2.first_child().value(), STR(" "));
278
+ }
279
+
280
+ static int get_tree_node_count(xml_node n)
281
+ {
282
+ int result = 1;
283
+
284
+ for (xml_node c = n.first_child(); c; c = c.next_sibling())
285
+ result += get_tree_node_count(c);
286
+
287
+ return result;
288
+ }
289
+
290
+ TEST(parse_ws_pcdata_permutations)
291
+ {
292
+ struct test_data_t
293
+ {
294
+ unsigned int mask; // 1 = default flags, 2 = parse_ws_pcdata, 4 = parse_ws_pcdata_single
295
+ const char_t* source;
296
+ const char_t* result;
297
+ int nodes; // negative if parsing should fail
298
+ };
299
+
300
+ test_data_t test_data[] =
301
+ {
302
+ // external pcdata should be discarded (whitespace or not)
303
+ {7, STR("ext1<node/>"), STR("<node/>"), 2},
304
+ {7, STR("ext1<node/>ext2"), STR("<node/>"), 2},
305
+ {7, STR(" <node/>"), STR("<node/>"), 2},
306
+ {7, STR("<node/> "), STR("<node/>"), 2},
307
+ {7, STR(" <node/> "), STR("<node/>"), 2},
308
+ // inner pcdata should be preserved
309
+ {7, STR("<node>inner</node>"), STR("<node>inner</node>"), 3},
310
+ {7, STR("<node>inner1<child/>inner2</node>"), STR("<node>inner1<child/>inner2</node>"), 5},
311
+ {7, STR("<node>inner1<child>deep</child>inner2</node>"), STR("<node>inner1<child>deep</child>inner2</node>"), 6},
312
+ // empty pcdata nodes should never be created
313
+ {7, STR("<node>inner1<child></child>inner2</node>"), STR("<node>inner1<child/>inner2</node>"), 5},
314
+ {7, STR("<node><child></child>inner2</node>"), STR("<node><child/>inner2</node>"), 4},
315
+ {7, STR("<node>inner1<child></child></node>"), STR("<node>inner1<child/></node>"), 4},
316
+ {7, STR("<node><child></child></node>"), STR("<node><child/></node>"), 3},
317
+ // comments, pi or other nodes should not cause pcdata creation either
318
+ {7, STR("<node><!----><child><?pi?></child><![CDATA[x]]></node>"), STR("<node><child/><![CDATA[x]]></node>"), 4},
319
+ // leading/trailing pcdata whitespace should be preserved (note: this will change if parse_ws_pcdata_trim is introduced)
320
+ {7, STR("<node>\t \tinner1<child> deep </child>\t\ninner2\n\t</node>"), STR("<node>\t \tinner1<child> deep </child>\t\ninner2\n\t</node>"), 6},
321
+ // whitespace-only pcdata preservation depends on the parsing mode
322
+ {1, STR("<node>\n\t<child> </child>\n\t<child> <deep> </deep> </child>\n\t<!---->\n\t</node>"), STR("<node><child/><child><deep/></child></node>"), 5},
323
+ {2, STR("<node>\n\t<child> </child>\n\t<child> <deep> </deep> </child>\n\t<!---->\n\t</node>"), STR("<node>\n\t<child> </child>\n\t<child> <deep> </deep> </child>\n\t\n\t</node>"), 13},
324
+ {4, STR("<node>\n\t<child> </child>\n\t<child> <deep> </deep> </child>\n\t<!---->\n\t</node>"), STR("<node><child> </child><child><deep> </deep></child></node>"), 7},
325
+ // current implementation of parse_ws_pcdata_single has an unfortunate bug; reproduce it here
326
+ {4, STR("<node>\t\t<!---->\n\n</node>"), STR("<node>\n\n</node>"), 3},
327
+ // error case: terminate PCDATA in the middle
328
+ {7, STR("<node>abcdef"), STR("<node>abcdef</node>"), -3},
329
+ {5, STR("<node> "), STR("<node/>"), -2},
330
+ {2, STR("<node> "), STR("<node> </node>"), -3},
331
+ // error case: terminate PCDATA as early as possible
332
+ {7, STR("<node>"), STR("<node/>"), -2},
333
+ {7, STR("<node>a"), STR("<node>a</node>"), -3},
334
+ {5, STR("<node> "), STR("<node/>"), -2},
335
+ {2, STR("<node> "), STR("<node> </node>"), -3},
336
+ };
337
+
338
+ for (size_t i = 0; i < sizeof(test_data) / sizeof(test_data[0]); ++i)
339
+ {
340
+ const test_data_t& td = test_data[i];
341
+
342
+ for (int flag = 0; flag < 3; ++flag)
343
+ {
344
+ if (td.mask & (1 << flag))
345
+ {
346
+ unsigned int flags[] = {parse_default, parse_default | parse_ws_pcdata, parse_default | parse_ws_pcdata_single};
347
+
348
+ xml_document doc;
349
+ CHECK((td.nodes > 0) == doc.load_string(td.source, flags[flag]));
350
+ CHECK_NODE(doc, td.result);
351
+
352
+ int nodes = get_tree_node_count(doc);
353
+ CHECK((td.nodes < 0 ? -td.nodes : td.nodes) == nodes);
354
+ }
355
+ }
356
+ }
357
+ }
358
+
359
+ TEST(parse_ws_pcdata_fragment_permutations)
360
+ {
361
+ struct test_data_t
362
+ {
363
+ unsigned int mask; // 1 = default flags, 2 = parse_ws_pcdata, 4 = parse_ws_pcdata_single
364
+ const char_t* source;
365
+ const char_t* result;
366
+ int nodes; // negative if parsing should fail
367
+ };
368
+
369
+ test_data_t test_data[] =
370
+ {
371
+ // external pcdata should be preserved
372
+ {7, STR("ext1"), STR("ext1"), 2},
373
+ {5, STR(" "), STR(""), 1},
374
+ {2, STR(" "), STR(" "), 2},
375
+ {7, STR("ext1<node/>"), STR("ext1<node/>"), 3},
376
+ {7, STR("<node/>ext2"), STR("<node/>ext2"), 3},
377
+ {7, STR("ext1<node/>ext2"), STR("ext1<node/>ext2"), 4},
378
+ {7, STR("ext1<node1/>ext2<node2/>ext3"), STR("ext1<node1/>ext2<node2/>ext3"), 6},
379
+ {5, STR(" <node/>"), STR("<node/>"), 2},
380
+ {2, STR(" <node/>"), STR(" <node/>"), 3},
381
+ {5, STR("<node/> "), STR("<node/>"), 2},
382
+ {2, STR("<node/> "), STR("<node/> "), 3},
383
+ {5, STR(" <node/> "), STR("<node/>"), 2},
384
+ {2, STR(" <node/> "), STR(" <node/> "), 4},
385
+ {5, STR(" <node1/> <node2/> "), STR("<node1/><node2/>"), 3},
386
+ {2, STR(" <node1/> <node2/> "), STR(" <node1/> <node2/> "), 6},
387
+ };
388
+
389
+ for (size_t i = 0; i < sizeof(test_data) / sizeof(test_data[0]); ++i)
390
+ {
391
+ const test_data_t& td = test_data[i];
392
+
393
+ for (int flag = 0; flag < 3; ++flag)
394
+ {
395
+ if (td.mask & (1 << flag))
396
+ {
397
+ unsigned int flags[] = {parse_default, parse_default | parse_ws_pcdata, parse_default | parse_ws_pcdata_single};
398
+
399
+ xml_document doc;
400
+ CHECK((td.nodes > 0) == doc.load_string(td.source, flags[flag] | parse_fragment));
401
+ CHECK_NODE(doc, td.result);
402
+
403
+ int nodes = get_tree_node_count(doc);
404
+ CHECK((td.nodes < 0 ? -td.nodes : td.nodes) == nodes);
405
+ }
406
+ }
407
+ }
408
+ }
409
+
410
+ TEST(parse_pcdata_no_eol)
411
+ {
412
+ xml_document doc;
413
+ CHECK(doc.load_string(STR("<root>\r\rval1\rval2\r\nval3\nval4\r\r</root>"), parse_minimal));
414
+
415
+ CHECK_STRING(doc.child_value(STR("root")), STR("\r\rval1\rval2\r\nval3\nval4\r\r"));
416
+ }
417
+
418
+ TEST(parse_pcdata_eol)
419
+ {
420
+ xml_document doc;
421
+ CHECK(doc.load_string(STR("<root>\r\rval1\rval2\r\nval3\nval4\r\r</root>"), parse_minimal | parse_eol));
422
+
423
+ CHECK_STRING(doc.child_value(STR("root")), STR("\n\nval1\nval2\nval3\nval4\n\n"));
424
+ }
425
+
426
+ TEST(parse_pcdata_skip_ext)
427
+ {
428
+ xml_document doc;
429
+ CHECK(doc.load_string(STR("pre<root/>post"), parse_minimal));
430
+ CHECK(doc.first_child() == doc.last_child());
431
+ CHECK(doc.first_child().type() == node_element);
432
+ }
433
+
434
+ TEST(parse_pcdata_error)
435
+ {
436
+ xml_document doc;
437
+ CHECK(doc.load_string(STR("<root>pcdata"), parse_minimal).status == status_end_element_mismatch);
438
+ }
439
+
440
+ TEST(parse_pcdata_trim)
441
+ {
442
+ struct test_data_t
443
+ {
444
+ const char_t* source;
445
+ const char_t* result;
446
+ unsigned int flags;
447
+ };
448
+
449
+ test_data_t test_data[] =
450
+ {
451
+ { STR("<node> text</node>"), STR("text"), 0 },
452
+ { STR("<node>\t\n text</node>"), STR("text"), 0 },
453
+ { STR("<node>text </node>"), STR("text"), 0 },
454
+ { STR("<node>text \t\n</node>"), STR("text"), 0 },
455
+ { STR("<node>\r\n\t text \t\n\r</node>"), STR("text"), 0 },
456
+ { STR(" text"), STR("text"), parse_fragment },
457
+ { STR("\t\n text"), STR("text"), parse_fragment },
458
+ { STR("text "), STR("text"), parse_fragment },
459
+ { STR("text \t\n"), STR("text"), parse_fragment },
460
+ { STR("\r\n\t text \t\n\r"), STR("text"), parse_fragment },
461
+ { STR("<node>\r\n\t text \t\n\r more \r\n\t</node>"), STR("text \t\n\r more"), 0 },
462
+ { STR("<node>\r\n\t text \t\n\r more \r\n\t</node>"), STR("text \t\n\n more"), parse_eol },
463
+ { STR("<node>\r\n\t text \r\n\r\n\r\n\r\n\r\n\r\n\r\n more \r\n\t</node>"), STR("text \n\n\n\n\n\n\n more"), parse_eol },
464
+ { STR("<node> test&amp;&amp;&amp;&amp;&amp;&amp;&amp; </node>"), STR("test&amp;&amp;&amp;&amp;&amp;&amp;&amp;"), 0 },
465
+ { STR("<node> test&amp;&amp;&amp;&amp;&amp;&amp;&amp; </node>"), STR("test&&&&&&&"), parse_escapes },
466
+ { STR(" test&amp;&amp;&amp;&amp;&amp;&amp;&amp; "), STR("test&&&&&&&"), parse_fragment | parse_escapes },
467
+ { STR("<node>\r\n\t text \t\n\r m&amp;&amp;e \r\n\t</node>"), STR("text \t\n\n m&&e"), parse_eol | parse_escapes }
468
+ };
469
+
470
+ for (size_t i = 0; i < sizeof(test_data) / sizeof(test_data[0]); ++i)
471
+ {
472
+ const test_data_t& td = test_data[i];
473
+
474
+ xml_document doc;
475
+ CHECK(doc.load_string(td.source, td.flags | parse_trim_pcdata));
476
+
477
+ const char_t* value = doc.child(STR("node")) ? doc.child_value(STR("node")) : doc.text().get();
478
+ CHECK_STRING(value, td.result);
479
+ }
480
+ }
481
+
482
+ TEST(parse_pcdata_trim_empty)
483
+ {
484
+ unsigned int flags[] = { 0, parse_ws_pcdata, parse_ws_pcdata_single, parse_ws_pcdata | parse_ws_pcdata_single };
485
+
486
+ for (size_t i = 0; i < sizeof(flags) / sizeof(flags[0]); ++i)
487
+ {
488
+ xml_document doc;
489
+ CHECK(doc.load_string(STR("<node> </node>"), flags[i] | parse_trim_pcdata));
490
+
491
+ xml_node node = doc.child(STR("node"));
492
+ CHECK(node);
493
+ CHECK(!node.first_child());
494
+ }
495
+ }
496
+
497
+ TEST(parse_escapes_skip)
498
+ {
499
+ xml_document doc;
500
+ CHECK(doc.load_string(STR("<node id='&lt;&gt;&amp;&apos;&quot;'>&lt;&gt;&amp;&apos;&quot;</node>"), parse_minimal));
501
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR("&lt;&gt;&amp;&apos;&quot;"));
502
+ }
503
+
504
+ TEST(parse_escapes_parse)
505
+ {
506
+ xml_document doc;
507
+ CHECK(doc.load_string(STR("<node id='&lt;&gt;&amp;&apos;&quot;'>&lt;&gt;&amp;&apos;&quot;</node>"), parse_minimal | parse_escapes));
508
+ CHECK_STRING(doc.child_value(STR("node")), STR("<>&'\""));
509
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR("<>&'\""));
510
+ }
511
+
512
+ TEST(parse_escapes_code)
513
+ {
514
+ xml_document doc;
515
+ CHECK(doc.load_string(STR("<node>&#1;&#32;&#x20;</node>"), parse_minimal | parse_escapes));
516
+ CHECK_STRING(doc.child_value(STR("node")), STR("\01 "));
517
+ }
518
+
519
+ TEST(parse_escapes_code_exhaustive_dec)
520
+ {
521
+ xml_document doc;
522
+ CHECK(doc.load_string(STR("<node>&#/;&#01;&#2;&#3;&#4;&#5;&#6;&#7;&#8;&#9;&#:;&#a;&#A;&#XA;</node>"), parse_minimal | parse_escapes));
523
+ CHECK_STRING(doc.child_value(STR("node")), STR("&#/;\x1\x2\x3\x4\x5\x6\x7\x8\x9&#:;&#a;&#A;&#XA;"));
524
+ }
525
+
526
+ TEST(parse_escapes_code_exhaustive_hex)
527
+ {
528
+ xml_document doc;
529
+ CHECK(doc.load_string(STR("<node>&#x/;&#x01;&#x2;&#x3;&#x4;&#x5;&#x6;&#x7;&#x8;&#x9;&#x:;&#x@;&#xA;&#xB;&#xC;&#xD;&#xE;&#xF;&#xG;&#x`;&#xa;&#xb;&#xc;&#xd;&#xe;&#xf;&#xg;</node>"), parse_minimal | parse_escapes));
530
+ CHECK_STRING(doc.child_value(STR("node")), STR("&#x/;\x1\x2\x3\x4\x5\x6\x7\x8\x9&#x:;&#x@;\xa\xb\xc\xd\xe\xf&#xG;&#x`;\xa\xb\xc\xd\xe\xf&#xg;"));
531
+ }
532
+
533
+ TEST(parse_escapes_code_restore)
534
+ {
535
+ xml_document doc;
536
+ CHECK(doc.load_string(STR("<node>&#1&#32;&#x1&#32;&#1-&#32;&#x1-&#32;</node>"), parse_minimal | parse_escapes));
537
+ CHECK_STRING(doc.child_value(STR("node")), STR("&#1 &#x1 &#1- &#x1- "));
538
+ }
539
+
540
+ TEST(parse_escapes_char_restore)
541
+ {
542
+ xml_document doc;
543
+
544
+ CHECK(doc.load_string(STR("<node>&q&#32;&qu&#32;&quo&#32;&quot&#32;</node>"), parse_minimal | parse_escapes));
545
+ CHECK_STRING(doc.child_value(STR("node")), STR("&q &qu &quo &quot "));
546
+
547
+ CHECK(doc.load_string(STR("<node>&a&#32;&ap&#32;&apo&#32;&apos&#32;</node>"), parse_minimal | parse_escapes));
548
+ CHECK_STRING(doc.child_value(STR("node")), STR("&a &ap &apo &apos "));
549
+
550
+ CHECK(doc.load_string(STR("<node>&a&#32;&am&#32;&amp&#32;</node>"), parse_minimal | parse_escapes));
551
+ CHECK_STRING(doc.child_value(STR("node")), STR("&a &am &amp "));
552
+
553
+ CHECK(doc.load_string(STR("<node>&l&#32;&lt&#32;</node>"), parse_minimal | parse_escapes));
554
+ CHECK_STRING(doc.child_value(STR("node")), STR("&l &lt "));
555
+
556
+ CHECK(doc.load_string(STR("<node>&g&#32;&gt&#32;</node>"), parse_minimal | parse_escapes));
557
+ CHECK_STRING(doc.child_value(STR("node")), STR("&g &gt "));
558
+ }
559
+
560
+ TEST(parse_escapes_unicode)
561
+ {
562
+ xml_document doc;
563
+ CHECK(doc.load_string(STR("<node>&#x03B3;&#x03b3;&#x24B62;</node>"), parse_minimal | parse_escapes));
564
+
565
+ #ifdef PUGIXML_WCHAR_MODE
566
+ const char_t* v = doc.child_value(STR("node"));
567
+
568
+ size_t wcharsize = sizeof(wchar_t);
569
+
570
+ CHECK(v[0] == 0x3b3 && v[1] == 0x3b3 && (wcharsize == 2 ? v[2] == wchar_cast(0xd852) && v[3] == wchar_cast(0xdf62) : v[2] == wchar_cast(0x24b62)));
571
+ #else
572
+ CHECK_STRING(doc.child_value(STR("node")), "\xce\xb3\xce\xb3\xf0\xa4\xad\xa2");
573
+ #endif
574
+ }
575
+
576
+ TEST(parse_escapes_error)
577
+ {
578
+ xml_document doc;
579
+ CHECK(doc.load_string(STR("<node>&#x03g;&#ab;&quot</node>"), parse_minimal | parse_escapes));
580
+ CHECK_STRING(doc.child_value(STR("node")), STR("&#x03g;&#ab;&quot"));
581
+
582
+ CHECK(!doc.load_string(STR("<node id='&#x12")));
583
+ CHECK(!doc.load_string(STR("<node id='&g")));
584
+ CHECK(!doc.load_string(STR("<node id='&gt")));
585
+ CHECK(!doc.load_string(STR("<node id='&l")));
586
+ CHECK(!doc.load_string(STR("<node id='&lt")));
587
+ CHECK(!doc.load_string(STR("<node id='&a")));
588
+ CHECK(!doc.load_string(STR("<node id='&amp")));
589
+ CHECK(!doc.load_string(STR("<node id='&apos")));
590
+ }
591
+
592
+ TEST(parse_escapes_code_invalid)
593
+ {
594
+ xml_document doc;
595
+ CHECK(doc.load_string(STR("<node>&#;&#x;&;&#x-;&#-;</node>"), parse_minimal | parse_escapes));
596
+ CHECK_STRING(doc.child_value(STR("node")), STR("&#;&#x;&;&#x-;&#-;"));
597
+ }
598
+
599
+ TEST(parse_escapes_attribute)
600
+ {
601
+ xml_document doc;
602
+
603
+ for (int wnorm = 0; wnorm < 2; ++wnorm)
604
+ for (int eol = 0; eol < 2; ++eol)
605
+ for (int wconv = 0; wconv < 2; ++wconv)
606
+ {
607
+ unsigned int flags = parse_escapes;
608
+
609
+ flags |= (wnorm ? parse_wnorm_attribute : 0);
610
+ flags |= (eol ? parse_eol : 0);
611
+ flags |= (wconv ? parse_wconv_attribute : 0);
612
+
613
+ CHECK(doc.load_string(STR("<node id='&quot;'/>"), flags));
614
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR("\""));
615
+ }
616
+ }
617
+
618
+ TEST(parse_attribute_spaces)
619
+ {
620
+ xml_document doc;
621
+ CHECK(doc.load_string(STR("<node id1='v1' id2 ='v2' id3= 'v3' id4 = 'v4' id5 \n\r\t = \r\t\n 'v5' />"), parse_minimal));
622
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id1")).value(), STR("v1"));
623
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id2")).value(), STR("v2"));
624
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id3")).value(), STR("v3"));
625
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id4")).value(), STR("v4"));
626
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id5")).value(), STR("v5"));
627
+ }
628
+
629
+ TEST(parse_attribute_quot)
630
+ {
631
+ xml_document doc;
632
+ CHECK(doc.load_string(STR("<node id1='v1' id2=\"v2\"/>"), parse_minimal));
633
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id1")).value(), STR("v1"));
634
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id2")).value(), STR("v2"));
635
+ }
636
+
637
+ TEST(parse_attribute_no_eol_no_wconv)
638
+ {
639
+ xml_document doc;
640
+ CHECK(doc.load_string(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal));
641
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR(" \t\r\rval1 \rval2\r\nval3\nval4\r\r"));
642
+ }
643
+
644
+ TEST(parse_attribute_eol_no_wconv)
645
+ {
646
+ xml_document doc;
647
+ CHECK(doc.load_string(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal | parse_eol));
648
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR(" \t\n\nval1 \nval2\nval3\nval4\n\n"));
649
+ }
650
+
651
+ TEST(parse_attribute_no_eol_wconv)
652
+ {
653
+ xml_document doc;
654
+ CHECK(doc.load_string(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal | parse_wconv_attribute));
655
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR(" val1 val2 val3 val4 "));
656
+ }
657
+
658
+ TEST(parse_attribute_eol_wconv)
659
+ {
660
+ xml_document doc;
661
+ CHECK(doc.load_string(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), parse_minimal | parse_eol | parse_wconv_attribute));
662
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR(" val1 val2 val3 val4 "));
663
+ }
664
+
665
+ TEST(parse_attribute_wnorm)
666
+ {
667
+ xml_document doc;
668
+
669
+ for (int eol = 0; eol < 2; ++eol)
670
+ for (int wconv = 0; wconv < 2; ++wconv)
671
+ {
672
+ unsigned int flags = parse_minimal | parse_wnorm_attribute | (eol ? parse_eol : 0) | (wconv ? parse_wconv_attribute : 0);
673
+ CHECK(doc.load_string(STR("<node id=' \t\r\rval1 \rval2\r\nval3\nval4\r\r'/>"), flags));
674
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR("val1 val2 val3 val4"));
675
+ }
676
+ }
677
+
678
+ TEST(parse_attribute_variations)
679
+ {
680
+ xml_document doc;
681
+
682
+ for (int wnorm = 0; wnorm < 2; ++wnorm)
683
+ for (int eol = 0; eol < 2; ++eol)
684
+ for (int wconv = 0; wconv < 2; ++wconv)
685
+ for (int escapes = 0; escapes < 2; ++escapes)
686
+ {
687
+ unsigned int flags = parse_minimal;
688
+
689
+ flags |= (wnorm ? parse_wnorm_attribute : 0);
690
+ flags |= (eol ? parse_eol : 0);
691
+ flags |= (wconv ? parse_wconv_attribute : 0);
692
+ flags |= (escapes ? parse_escapes : 0);
693
+
694
+ CHECK(doc.load_string(STR("<node id='1'/>"), flags));
695
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id")).value(), STR("1"));
696
+ }
697
+ }
698
+
699
+
700
+ TEST(parse_attribute_error)
701
+ {
702
+ xml_document doc;
703
+ CHECK(doc.load_string(STR("<node id"), parse_minimal).status == status_bad_attribute);
704
+ CHECK(doc.load_string(STR("<node id "), parse_minimal).status == status_bad_attribute);
705
+ CHECK(doc.load_string(STR("<node id "), parse_minimal).status == status_bad_attribute);
706
+ CHECK(doc.load_string(STR("<node id "), parse_minimal).status == status_bad_attribute);
707
+ CHECK(doc.load_string(STR("<node id/"), parse_minimal).status == status_bad_attribute);
708
+ CHECK(doc.load_string(STR("<node id/>"), parse_minimal).status == status_bad_attribute);
709
+ CHECK(doc.load_string(STR("<node id?/>"), parse_minimal).status == status_bad_attribute);
710
+ CHECK(doc.load_string(STR("<node id=/>"), parse_minimal).status == status_bad_attribute);
711
+ CHECK(doc.load_string(STR("<node id='/>"), parse_minimal).status == status_bad_attribute);
712
+ CHECK(doc.load_string(STR("<node id=\"/>"), parse_minimal).status == status_bad_attribute);
713
+ CHECK(doc.load_string(STR("<node id=\"'/>"), parse_minimal).status == status_bad_attribute);
714
+ CHECK(doc.load_string(STR("<node id='\"/>"), parse_minimal).status == status_bad_attribute);
715
+ CHECK(doc.load_string(STR("<node id='\"/>"), parse_minimal).status == status_bad_attribute);
716
+ CHECK(doc.load_string(STR("<node #/>"), parse_minimal).status == status_bad_start_element);
717
+ CHECK(doc.load_string(STR("<node#/>"), parse_minimal).status == status_bad_start_element);
718
+ CHECK(doc.load_string(STR("<node id1='1'id2='2'/>"), parse_minimal).status == status_bad_attribute);
719
+ CHECK(doc.load_string(STR("<node id&='1'/>"), parse_minimal).status == status_bad_attribute);
720
+ CHECK(doc.load_string(STR("<node &='1'/>"), parse_minimal).status == status_bad_start_element);
721
+ }
722
+
723
+ TEST(parse_attribute_termination_error)
724
+ {
725
+ xml_document doc;
726
+
727
+ for (int wnorm = 0; wnorm < 2; ++wnorm)
728
+ for (int eol = 0; eol < 2; ++eol)
729
+ for (int wconv = 0; wconv < 2; ++wconv)
730
+ {
731
+ unsigned int flags = parse_minimal;
732
+
733
+ flags |= (wnorm ? parse_wnorm_attribute : 0);
734
+ flags |= (eol ? parse_eol : 0);
735
+ flags |= (wconv ? parse_wconv_attribute : 0);
736
+
737
+ CHECK(doc.load_string(STR("<node id='value"), flags).status == status_bad_attribute);
738
+ }
739
+ }
740
+
741
+ TEST(parse_attribute_quot_inside)
742
+ {
743
+ xml_document doc;
744
+
745
+ for (int wnorm = 0; wnorm < 2; ++wnorm)
746
+ for (int eol = 0; eol < 2; ++eol)
747
+ for (int wconv = 0; wconv < 2; ++wconv)
748
+ {
749
+ unsigned int flags = parse_escapes;
750
+
751
+ flags |= (wnorm ? parse_wnorm_attribute : 0);
752
+ flags |= (eol ? parse_eol : 0);
753
+ flags |= (wconv ? parse_wconv_attribute : 0);
754
+
755
+ CHECK(doc.load_string(STR("<node id1='\"' id2=\"'\"/>"), flags));
756
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id1")).value(), STR("\""));
757
+ CHECK_STRING(doc.child(STR("node")).attribute(STR("id2")).value(), STR("'"));
758
+ }
759
+ }
760
+
761
+ TEST(parse_attribute_wnorm_coverage)
762
+ {
763
+ xml_document doc;
764
+ CHECK(doc.load_string(STR("<n a1='v' a2=' ' a3='x y' a4='x y' a5='x y' />"), parse_wnorm_attribute));
765
+ CHECK_NODE(doc, STR("<n a1=\"v\" a2=\"\" a3=\"x y\" a4=\"x y\" a5=\"x y\"/>"));
766
+
767
+ CHECK(doc.load_string(STR("<n a1='v' a2=' ' a3='x y' a4='x y' a5='x y' />"), parse_wnorm_attribute | parse_escapes));
768
+ CHECK_NODE(doc, STR("<n a1=\"v\" a2=\"\" a3=\"x y\" a4=\"x y\" a5=\"x y\"/>"));
769
+ }
770
+
771
+ TEST(parse_attribute_wconv_coverage)
772
+ {
773
+ xml_document doc;
774
+ CHECK(doc.load_string(STR("<n a1='v' a2='\r' a3='\r\n\n' a4='\n' />"), parse_wconv_attribute));
775
+ CHECK_NODE(doc, STR("<n a1=\"v\" a2=\" \" a3=\" \" a4=\" \"/>"));
776
+
777
+ CHECK(doc.load_string(STR("<n a1='v' a2='\r' a3='\r\n\n' a4='\n' />"), parse_wconv_attribute | parse_escapes));
778
+ CHECK_NODE(doc, STR("<n a1=\"v\" a2=\" \" a3=\" \" a4=\" \"/>"));
779
+ }
780
+
781
+ TEST(parse_attribute_eol_coverage)
782
+ {
783
+ xml_document doc;
784
+ CHECK(doc.load_string(STR("<n a1='v' a2='\r' a3='\r\n\n' a4='\n' />"), parse_eol));
785
+ CHECK_NODE(doc, STR("<n a1=\"v\" a2=\"&#10;\" a3=\"&#10;&#10;\" a4=\"&#10;\"/>"));
786
+
787
+ CHECK(doc.load_string(STR("<n a1='v' a2='\r' a3='\r\n\n' a4='\n' />"), parse_eol | parse_escapes));
788
+ CHECK_NODE(doc, STR("<n a1=\"v\" a2=\"&#10;\" a3=\"&#10;&#10;\" a4=\"&#10;\"/>"));
789
+ }
790
+
791
+ TEST(parse_tag_single)
792
+ {
793
+ xml_document doc;
794
+ CHECK(doc.load_string(STR("<node/><node /><node\n/>"), parse_minimal));
795
+ CHECK_NODE(doc, STR("<node/><node/><node/>"));
796
+ }
797
+
798
+ TEST(parse_tag_hierarchy)
799
+ {
800
+ xml_document doc;
801
+ CHECK(doc.load_string(STR("<node><n1><n2/></n1><n3><n4><n5></n5></n4></n3 \r\n></node>"), parse_minimal));
802
+ CHECK_NODE(doc, STR("<node><n1><n2/></n1><n3><n4><n5/></n4></n3></node>"));
803
+ }
804
+
805
+ TEST(parse_tag_error)
806
+ {
807
+ xml_document doc;
808
+ CHECK(doc.load_string(STR("<"), parse_minimal).status == status_unrecognized_tag);
809
+ CHECK(doc.load_string(STR("<!"), parse_minimal).status == status_unrecognized_tag);
810
+ CHECK(doc.load_string(STR("<!D"), parse_minimal).status == status_unrecognized_tag);
811
+ CHECK(doc.load_string(STR("<#"), parse_minimal).status == status_unrecognized_tag);
812
+ CHECK(doc.load_string(STR("<node#"), parse_minimal).status == status_bad_start_element);
813
+ CHECK(doc.load_string(STR("<node"), parse_minimal).status == status_bad_start_element);
814
+ CHECK(doc.load_string(STR("<node/"), parse_minimal).status == status_bad_start_element);
815
+ CHECK(doc.load_string(STR("<node /"), parse_minimal).status == status_bad_start_element);
816
+ CHECK(doc.load_string(STR("<node / "), parse_minimal).status == status_bad_start_element);
817
+ CHECK(doc.load_string(STR("<node / >"), parse_minimal).status == status_bad_start_element);
818
+ CHECK(doc.load_string(STR("<node/ >"), parse_minimal).status == status_bad_start_element);
819
+ CHECK(doc.load_string(STR("</ node>"), parse_minimal).status == status_end_element_mismatch);
820
+ CHECK(doc.load_string(STR("</node"), parse_minimal).status == status_end_element_mismatch);
821
+ CHECK(doc.load_string(STR("</node "), parse_minimal).status == status_end_element_mismatch);
822
+ CHECK(doc.load_string(STR("<node></ node>"), parse_minimal).status == status_end_element_mismatch);
823
+ CHECK(doc.load_string(STR("<node></node"), parse_minimal).status == status_bad_end_element);
824
+ CHECK(doc.load_string(STR("<node></node "), parse_minimal).status == status_bad_end_element);
825
+ CHECK(doc.load_string(STR("<node></nodes>"), parse_minimal).status == status_end_element_mismatch);
826
+ CHECK(doc.load_string(STR("<node>"), parse_minimal).status == status_end_element_mismatch);
827
+ CHECK(doc.load_string(STR("<node/><"), parse_minimal).status == status_unrecognized_tag);
828
+ CHECK(doc.load_string(STR("<node attr='value'>"), parse_minimal).status == status_end_element_mismatch);
829
+ CHECK(doc.load_string(STR("</></node>"), parse_minimal).status == status_end_element_mismatch);
830
+ CHECK(doc.load_string(STR("</node>"), parse_minimal).status == status_end_element_mismatch);
831
+ CHECK(doc.load_string(STR("</>"), parse_minimal).status == status_end_element_mismatch);
832
+ CHECK(doc.load_string(STR("<node></node v>"), parse_minimal).status == status_bad_end_element);
833
+ CHECK(doc.load_string(STR("<node&/>"), parse_minimal).status == status_bad_start_element);
834
+ CHECK(doc.load_string(STR("<node& v='1'/>"), parse_minimal).status == status_bad_start_element);
835
+ }
836
+
837
+ TEST(parse_declaration_cases)
838
+ {
839
+ xml_document doc;
840
+ CHECK(doc.load_string(STR("<?xml?><?xmL?><?xMl?><?xML?><?Xml?><?XmL?><?XMl?><?XML?>"), parse_fragment | parse_pi));
841
+ CHECK(!doc.first_child());
842
+ }
843
+
844
+ TEST(parse_declaration_attr_cases)
845
+ {
846
+ xml_document doc;
847
+ CHECK(doc.load_string(STR("<?xml ?><?xmL ?><?xMl ?><?xML ?><?Xml ?><?XmL ?><?XMl ?><?XML ?>"), parse_fragment | parse_pi));
848
+ CHECK(!doc.first_child());
849
+ }
850
+
851
+ TEST(parse_declaration_skip)
852
+ {
853
+ xml_document doc;
854
+
855
+ unsigned int flag_sets[] = {parse_fragment, parse_fragment | parse_pi};
856
+
857
+ for (unsigned int i = 0; i < sizeof(flag_sets) / sizeof(flag_sets[0]); ++i)
858
+ {
859
+ unsigned int flags = flag_sets[i];
860
+
861
+ CHECK(doc.load_string(STR("<?xml?><?xml version='1.0'?>"), flags));
862
+ CHECK(!doc.first_child());
863
+
864
+ CHECK(doc.load_string(STR("<?xml <tag/> ?>"), flags));
865
+ CHECK(!doc.first_child());
866
+ }
867
+ }
868
+
869
+ TEST(parse_declaration_parse)
870
+ {
871
+ xml_document doc;
872
+ CHECK(doc.load_string(STR("<?xml?><?xml version='1.0'?>"), parse_fragment | parse_declaration));
873
+
874
+ xml_node d1 = doc.first_child();
875
+ xml_node d2 = doc.last_child();
876
+
877
+ CHECK(d1 != d2);
878
+ CHECK(d1.type() == node_declaration);
879
+ CHECK_STRING(d1.name(), STR("xml"));
880
+ CHECK(d2.type() == node_declaration);
881
+ CHECK_STRING(d2.name(), STR("xml"));
882
+ CHECK_STRING(d2.attribute(STR("version")).value(), STR("1.0"));
883
+ }
884
+
885
+ TEST(parse_declaration_error)
886
+ {
887
+ xml_document doc;
888
+
889
+ unsigned int flag_sets[] = {parse_fragment, parse_fragment | parse_declaration};
890
+
891
+ for (unsigned int i = 0; i < sizeof(flag_sets) / sizeof(flag_sets[0]); ++i)
892
+ {
893
+ unsigned int flags = flag_sets[i];
894
+
895
+ CHECK(doc.load_string(STR("<?xml"), flags).status == status_bad_pi);
896
+ CHECK(doc.load_string(STR("<?xml?"), flags).status == status_bad_pi);
897
+ CHECK(doc.load_string(STR("<?xml>"), flags).status == status_bad_pi);
898
+ CHECK(doc.load_string(STR("<?xml version='1>"), flags).status == status_bad_pi);
899
+ }
900
+
901
+ CHECK(doc.load_string(STR("<?xml version='1?>"), parse_fragment | parse_declaration).status == status_bad_attribute);
902
+ CHECK(doc.load_string(STR("<foo><?xml version='1'?></foo>"), parse_fragment | parse_declaration).status == status_bad_pi);
903
+ }
904
+
905
+ TEST(parse_empty)
906
+ {
907
+ xml_document doc;
908
+
909
+ CHECK(doc.load_string(STR("")).status == status_no_document_element && !doc.first_child());
910
+ CHECK(doc.load_string(STR(""), parse_fragment) && !doc.first_child());
911
+ }
912
+
913
+ TEST(parse_out_of_memory)
914
+ {
915
+ test_runner::_memory_fail_threshold = 256;
916
+
917
+ xml_document doc;
918
+ CHECK_ALLOC_FAIL(CHECK(doc.load_string(STR("<foo a='1'/>")).status == status_out_of_memory));
919
+ CHECK(!doc.first_child());
920
+ }
921
+
922
+ TEST(parse_out_of_memory_halfway_node)
923
+ {
924
+ const unsigned int count = 10000;
925
+ static char_t text[count * 4];
926
+
927
+ for (unsigned int i = 0; i < count; ++i)
928
+ {
929
+ text[4*i + 0] = '<';
930
+ text[4*i + 1] = 'n';
931
+ text[4*i + 2] = '/';
932
+ text[4*i + 3] = '>';
933
+ }
934
+
935
+ test_runner::_memory_fail_threshold = 65536;
936
+
937
+ xml_document doc;
938
+ CHECK_ALLOC_FAIL(CHECK(doc.load_buffer_inplace(text, sizeof(text)).status == status_out_of_memory));
939
+ CHECK_NODE(doc.first_child(), STR("<n/>"));
940
+ }
941
+
942
+ TEST(parse_out_of_memory_halfway_attr)
943
+ {
944
+ const unsigned int count = 10000;
945
+ static char_t text[count * 5 + 4];
946
+
947
+ text[0] = '<';
948
+ text[1] = 'n';
949
+
950
+ for (unsigned int i = 0; i < count; ++i)
951
+ {
952
+ text[5*i + 2] = ' ';
953
+ text[5*i + 3] = 'a';
954
+ text[5*i + 4] = '=';
955
+ text[5*i + 5] = '"';
956
+ text[5*i + 6] = '"';
957
+ }
958
+
959
+ text[5 * count + 2] = '/';
960
+ text[5 * count + 3] = '>';
961
+
962
+ test_runner::_memory_fail_threshold = 65536;
963
+
964
+ xml_document doc;
965
+ CHECK_ALLOC_FAIL(CHECK(doc.load_buffer_inplace(text, sizeof(text)).status == status_out_of_memory));
966
+ CHECK_STRING(doc.first_child().name(), STR("n"));
967
+ CHECK_STRING(doc.first_child().first_attribute().name(), STR("a"));
968
+ CHECK_STRING(doc.first_child().last_attribute().name(), STR("a"));
969
+ }
970
+
971
+ TEST(parse_out_of_memory_conversion)
972
+ {
973
+ test_runner::_memory_fail_threshold = 1;
974
+
975
+ xml_document doc;
976
+ CHECK_ALLOC_FAIL(CHECK(doc.load_buffer("<foo\x90/>", 7, parse_default, encoding_latin1).status == status_out_of_memory));
977
+ CHECK(!doc.first_child());
978
+ }
979
+
980
+ TEST(parse_out_of_memory_allocator_state_sync)
981
+ {
982
+ const unsigned int count = 10000;
983
+ static char_t text[count * 4];
984
+
985
+ for (unsigned int i = 0; i < count; ++i)
986
+ {
987
+ text[4*i + 0] = '<';
988
+ text[4*i + 1] = 'n';
989
+ text[4*i + 2] = '/';
990
+ text[4*i + 3] = '>';
991
+ }
992
+
993
+ test_runner::_memory_fail_threshold = 65536;
994
+
995
+ xml_document doc;
996
+ CHECK_ALLOC_FAIL(CHECK(doc.load_buffer_inplace(text, sizeof(text)).status == status_out_of_memory));
997
+ CHECK_NODE(doc.first_child(), STR("<n/>"));
998
+
999
+ test_runner::_memory_fail_threshold = 0;
1000
+
1001
+ for (unsigned int j = 0; j < count; ++j)
1002
+ CHECK(doc.append_child(STR("n")));
1003
+ }
1004
+
1005
+ static bool test_offset(const char_t* contents, unsigned int options, xml_parse_status status, ptrdiff_t offset)
1006
+ {
1007
+ xml_document doc;
1008
+ xml_parse_result res = doc.load_string(contents, options);
1009
+
1010
+ return res.status == status && res.offset == offset;
1011
+ }
1012
+
1013
+ #define CHECK_OFFSET(contents, options, status, offset) CHECK(test_offset(STR(contents), options, status, offset))
1014
+
1015
+ TEST(parse_error_offset)
1016
+ {
1017
+ CHECK_OFFSET("<node/>", parse_default, status_ok, 0);
1018
+
1019
+ test_runner::_memory_fail_threshold = 1;
1020
+ CHECK_ALLOC_FAIL(CHECK_OFFSET("<node/>", parse_default, status_out_of_memory, 0));
1021
+ test_runner::_memory_fail_threshold = 0;
1022
+
1023
+ CHECK_OFFSET("<3d/>", parse_default, status_unrecognized_tag, 1);
1024
+ CHECK_OFFSET(" <3d/>", parse_default, status_unrecognized_tag, 2);
1025
+ CHECK_OFFSET(" <", parse_default, status_unrecognized_tag, 1);
1026
+
1027
+ CHECK_OFFSET("<?pi", parse_default, status_bad_pi, 3);
1028
+ CHECK_OFFSET("<?pi", parse_default | parse_pi, status_bad_pi, 3);
1029
+ CHECK_OFFSET("<?xml", parse_default | parse_declaration, status_bad_pi, 4);
1030
+
1031
+ CHECK_OFFSET("<!----", parse_default, status_bad_comment, 5);
1032
+ CHECK_OFFSET("<!----", parse_default | parse_comments, status_bad_comment, 4);
1033
+
1034
+ CHECK_OFFSET("<![CDA", parse_default, status_bad_cdata, 5);
1035
+ CHECK_OFFSET("<![CDATA[non-terminated]]", parse_default, status_bad_cdata, 9);
1036
+
1037
+ CHECK_OFFSET("<!DOCTYPE doc", parse_default, status_bad_doctype, 12);
1038
+ CHECK_OFFSET("<!DOCTYPE greeting [ <!ATTLIST list type (bullets|ordered|glossary) \"orde", parse_default, status_bad_doctype, 76);
1039
+
1040
+ CHECK_OFFSET("<node", parse_default, status_bad_start_element, 4);
1041
+ CHECK_OFFSET("<node ", parse_default, status_bad_start_element, 5);
1042
+ CHECK_OFFSET("<nod%>", parse_default, status_bad_start_element, 5);
1043
+
1044
+ CHECK_OFFSET("<node a=2>", parse_default, status_bad_attribute, 8);
1045
+ CHECK_OFFSET("<node a='2>", parse_default, status_bad_attribute, 9);
1046
+
1047
+ CHECK_OFFSET("<n></n $>", parse_default, status_bad_end_element, 7);
1048
+ CHECK_OFFSET("<n></n", parse_default, status_bad_end_element, 5);
1049
+
1050
+ CHECK_OFFSET("<no></na>", parse_default, status_end_element_mismatch, 6);
1051
+ CHECK_OFFSET("<no></nod>", parse_default, status_end_element_mismatch, 6);
1052
+ }
1053
+
1054
+ TEST(parse_result_default)
1055
+ {
1056
+ xml_parse_result result;
1057
+
1058
+ CHECK(!result);
1059
+ CHECK(result.status == status_internal_error);
1060
+ CHECK(result.offset == 0);
1061
+ CHECK(result.encoding == encoding_auto);
1062
+ }
1063
+
1064
+ TEST(parse_bom_fragment)
1065
+ {
1066
+ struct test_data_t
1067
+ {
1068
+ xml_encoding encoding;
1069
+ const char* data;
1070
+ size_t size;
1071
+ const char_t* text;
1072
+ };
1073
+
1074
+ const test_data_t data[] =
1075
+ {
1076
+ { encoding_utf8, "\xef\xbb\xbf", 3, STR("") },
1077
+ { encoding_utf8, "\xef\xbb\xbftest", 7, STR("test") },
1078
+ { encoding_utf16_be, "\xfe\xff", 2, STR("") },
1079
+ { encoding_utf16_be, "\xfe\xff\x00t\x00o\x00s\x00t", 10, STR("tost") },
1080
+ { encoding_utf16_le, "\xff\xfe", 2, STR("") },
1081
+ { encoding_utf16_le, "\xff\xfet\x00o\x00s\x00t\x00", 10, STR("tost") },
1082
+ { encoding_utf32_be, "\x00\x00\xfe\xff", 4, STR("") },
1083
+ { encoding_utf32_be, "\x00\x00\xfe\xff\x00\x00\x00t\x00\x00\x00o\x00\x00\x00s\x00\x00\x00t", 20, STR("tost") },
1084
+ { encoding_utf32_le, "\xff\xfe\x00\x00", 4, STR("") },
1085
+ { encoding_utf32_le, "\xff\xfe\x00\x00t\x00\x00\x00o\x00\x00\x00s\x00\x00\x00t\x00\x00\x00", 20, STR("tost") },
1086
+ };
1087
+
1088
+ for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i)
1089
+ {
1090
+ xml_document doc;
1091
+ CHECK(doc.load_buffer(data[i].data, data[i].size, parse_fragment, data[i].encoding));
1092
+ CHECK_STRING(doc.text().get(), data[i].text);
1093
+ CHECK(save_narrow(doc, format_no_declaration | format_raw | format_write_bom, data[i].encoding) == std::string(data[i].data, data[i].size));
1094
+ }
1095
+ }
1096
+
1097
+ TEST(parse_bom_fragment_invalid_utf8)
1098
+ {
1099
+ xml_document doc;
1100
+
1101
+ CHECK(doc.load_buffer("\xef\xbb\xbb", 3, parse_fragment, encoding_utf8));
1102
+
1103
+ const char_t* value = doc.text().get();
1104
+
1105
+ #ifdef PUGIXML_WCHAR_MODE
1106
+ CHECK(value[0] == wchar_cast(0xfefb) && value[1] == 0);
1107
+ #else
1108
+ CHECK_STRING(value, "\xef\xbb\xbb");
1109
+ #endif
1110
+ }
1111
+
1112
+ TEST(parse_bom_fragment_invalid_utf16)
1113
+ {
1114
+ xml_document doc;
1115
+
1116
+ CHECK(doc.load_buffer("\xff\xfe", 2, parse_fragment, encoding_utf16_be));
1117
+
1118
+ const char_t* value = doc.text().get();
1119
+
1120
+ #ifdef PUGIXML_WCHAR_MODE
1121
+ CHECK(value[0] == wchar_cast(0xfffe) && value[1] == 0);
1122
+ #else
1123
+ CHECK_STRING(value, "\xef\xbf\xbe");
1124
+ #endif
1125
+ }
1126
+
1127
+ TEST(parse_bom_fragment_invalid_utf32)
1128
+ {
1129
+ xml_document doc;
1130
+
1131
+ CHECK(doc.load_buffer("\xff\xff\x00\x00", 4, parse_fragment, encoding_utf32_le));
1132
+
1133
+ const char_t* value = doc.text().get();
1134
+
1135
+ #ifdef PUGIXML_WCHAR_MODE
1136
+ CHECK(value[0] == wchar_cast(0xffff) && value[1] == 0);
1137
+ #else
1138
+ CHECK_STRING(value, "\xef\xbf\xbf");
1139
+ #endif
1140
+ }
1141
+
1142
+ TEST(parse_pcdata_gap_fragment)
1143
+ {
1144
+ xml_document doc;
1145
+ CHECK(doc.load_string(STR("a&amp;b"), parse_fragment | parse_escapes));
1146
+ CHECK_STRING(doc.text().get(), STR("a&b"));
1147
+ }
1148
+
1149
+ TEST(parse_name_end_eof)
1150
+ {
1151
+ char_t test[] = STR("<node>");
1152
+
1153
+ xml_document doc;
1154
+ CHECK(doc.load_buffer_inplace(test, 6 * sizeof(char_t)).status == status_end_element_mismatch);
1155
+ CHECK_STRING(doc.first_child().name(), STR("node"));
1156
+ }
1157
+
1158
+ TEST(parse_close_tag_eof)
1159
+ {
1160
+ char_t test1[] = STR("<node></node");
1161
+ char_t test2[] = STR("<node></nodx");
1162
+
1163
+ xml_document doc;
1164
+ CHECK(doc.load_buffer_inplace(test1, 12 * sizeof(char_t)).status == status_bad_end_element);
1165
+ CHECK_STRING(doc.first_child().name(), STR("node"));
1166
+
1167
+ CHECK(doc.load_buffer_inplace(test2, 12 * sizeof(char_t)).status == status_end_element_mismatch);
1168
+ CHECK_STRING(doc.first_child().name(), STR("node"));
1169
+ }
1170
+
1171
+ TEST(parse_fuzz_doctype)
1172
+ {
1173
+ unsigned char data[] =
1174
+ {
1175
+ 0x3b, 0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0xef, 0xbb, 0xbf, 0x3c, 0x3f, 0x78,
1176
+ 0x6d, 0x6c, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x3d, 0x22, 0x31, 0x2e, 0x30, 0x22,
1177
+ 0x3f, 0x3e, 0x3c, 0x21, 0x2d, 0x2d, 0x20, 0xe9, 0x80, 0xb1, 0xe5, 0xa0, 0xb1, 0xe3, 0x82, 0xb4,
1178
+ 0xe3, 0x83, 0xb3, 0x20, 0xef, 0x83, 0x97, 0xe3, 0xa9, 0x2a, 0x20, 0x2d, 0x2d, 0x3e
1179
+ };
1180
+
1181
+ xml_document doc;
1182
+ CHECK(doc.load_buffer(data, sizeof(data)).status == status_bad_doctype);
1183
+ }
1184
+
1185
+ TEST(parse_embed_pcdata)
1186
+ {
1187
+ // parse twice - once with default and once with embed_pcdata flags
1188
+ for (int i = 0; i < 2; ++i)
1189
+ {
1190
+ unsigned int flags = (i == 0) ? parse_default : parse_default | parse_embed_pcdata;
1191
+
1192
+ xml_document doc;
1193
+ xml_parse_result res = doc.load_string(STR("<node><key>value</key><child><inner1>value1</inner1><inner2>value2</inner2>outer</child><two>text<data /></two></node>"), flags);
1194
+ CHECK(res);
1195
+
1196
+ xml_node child = doc.child(STR("node")).child(STR("child"));
1197
+
1198
+ // parse_embed_pcdata omits PCDATA nodes so DOM is different
1199
+ if (flags & parse_embed_pcdata)
1200
+ {
1201
+ CHECK_STRING(doc.child(STR("node")).child(STR("key")).value(), STR("value"));
1202
+ CHECK(!doc.child(STR("node")).child(STR("key")).first_child());
1203
+ }
1204
+ else
1205
+ {
1206
+ CHECK_STRING(doc.child(STR("node")).child(STR("key")).value(), STR(""));
1207
+ CHECK(doc.child(STR("node")).child(STR("key")).first_child());
1208
+ CHECK_STRING(doc.child(STR("node")).child(STR("key")).first_child().value(), STR("value"));
1209
+ }
1210
+
1211
+ // higher-level APIs work the same though
1212
+ CHECK_STRING(child.text().get(), STR("outer"));
1213
+ CHECK_STRING(child.child(STR("inner1")).text().get(), STR("value1"));
1214
+
1215
+ CHECK_STRING(child.child_value(), STR("outer"));
1216
+ CHECK_STRING(child.child_value(STR("inner2")), STR("value2"));
1217
+
1218
+ #ifndef PUGIXML_NO_XPATH
1219
+ CHECK_XPATH_NUMBER(doc, STR("count(node/child/*[starts-with(., 'value')])"), 2);
1220
+ #endif
1221
+
1222
+ CHECK_NODE(doc, STR("<node><key>value</key><child><inner1>value1</inner1><inner2>value2</inner2>outer</child><two>text<data/></two></node>"));
1223
+ CHECK_NODE_EX(doc, STR("<node>\n<key>value</key>\n<child>\n<inner1>value1</inner1>\n<inner2>value2</inner2>outer</child>\n<two>text<data />\n</two>\n</node>\n"), STR("\t"), 0);
1224
+ CHECK_NODE_EX(doc, STR("<node>\n\t<key>value</key>\n\t<child>\n\t\t<inner1>value1</inner1>\n\t\t<inner2>value2</inner2>outer</child>\n\t<two>text<data />\n\t</two>\n</node>\n"), STR("\t"), format_indent);
1225
+ }
1226
+ }
1227
+
1228
+ TEST_XML_FLAGS(parse_embed_pcdata_fragment, "text", parse_fragment | parse_embed_pcdata)
1229
+ {
1230
+ CHECK_NODE(doc, STR("text"));
1231
+ CHECK(doc.first_child().type() == node_pcdata);
1232
+ CHECK_STRING(doc.first_child().value(), STR("text"));
1233
+ }
1234
+
1235
+ TEST_XML_FLAGS(parse_embed_pcdata_child, "<n><child/>text</n>", parse_embed_pcdata)
1236
+ {
1237
+ xml_node n = doc.child(STR("n"));
1238
+
1239
+ CHECK_NODE(doc, STR("<n><child/>text</n>"));
1240
+ CHECK(n.last_child().type() == node_pcdata);
1241
+ CHECK_STRING(n.last_child().value(), STR("text"));
1242
+ }
1243
+
1244
+ TEST_XML_FLAGS(parse_embed_pcdata_comment, "<n>text1<!---->text2</n>", parse_embed_pcdata)
1245
+ {
1246
+ xml_node n = doc.child(STR("n"));
1247
+
1248
+ CHECK_NODE(doc, STR("<n>text1text2</n>"));
1249
+ CHECK_STRING(n.value(), STR("text1"));
1250
+ CHECK(n.first_child() == n.last_child());
1251
+ CHECK(n.last_child().type() == node_pcdata);
1252
+ CHECK_STRING(n.last_child().value(), STR("text2"));
1253
+ }
1254
+
1255
+ TEST(parse_merge_pcdata)
1256
+ {
1257
+ unsigned int flag_sets[] = {parse_cdata, parse_pi, parse_comments, parse_declaration};
1258
+
1259
+ for (unsigned int i = 0; i < sizeof(flag_sets) / sizeof(flag_sets[0]); ++i)
1260
+ {
1261
+ unsigned int flags = parse_merge_pcdata | flag_sets[i];
1262
+
1263
+ xml_document doc;
1264
+ xml_parse_result res = doc.load_string(STR("<node>First text<!-- here is a mesh node -->Second text<![CDATA[someothertext]]>some more text<?include somedata?>Last text</node>"), flags);
1265
+ CHECK(res);
1266
+
1267
+ xml_node child = doc.child(STR("node"));
1268
+
1269
+ if (flags & parse_comments)
1270
+ {
1271
+ CHECK_STRING(child.first_child().value(), STR("First text"));
1272
+ CHECK(child.first_child().next_sibling().type() == node_comment);
1273
+ CHECK_NODE(doc, STR("<node>First text<!-- here is a mesh node -->Second textsome more textLast text</node>"));
1274
+ }
1275
+ else if (flags & parse_cdata)
1276
+ {
1277
+ CHECK_STRING(child.first_child().value(), STR("First textSecond text"));
1278
+ CHECK(child.first_child().next_sibling().type() == node_cdata);
1279
+ CHECK_NODE(doc, STR("<node>First textSecond text<![CDATA[someothertext]]>some more textLast text</node>"));
1280
+ }
1281
+ else if (flags & parse_pi)
1282
+ {
1283
+ CHECK_STRING(child.first_child().value(), STR("First textSecond textsome more text"));
1284
+ CHECK(child.first_child().next_sibling().type() == node_pi);
1285
+ CHECK_NODE(doc, STR("<node>First textSecond textsome more text<?include somedata?>Last text</node>"));
1286
+ }
1287
+ else
1288
+ {
1289
+ CHECK(child.first_child() == child.last_child());
1290
+ CHECK(child.first_child().type() == node_pcdata);
1291
+ CHECK_NODE(doc, STR("<node>First textSecond textsome more textLast text</node>"));
1292
+ }
1293
+
1294
+ CHECK(child.last_child().type() == node_pcdata);
1295
+ }
1296
+ }
1297
+
1298
+ TEST(parse_merge_pcdata_escape)
1299
+ {
1300
+ xml_document doc;
1301
+ xml_parse_result res = doc.load_string(STR("<node>First &amp;lt; <!-- comment 1 --> Second &amp;gt; <!-- comment 2 --> Third &amp;quot;</node>"), parse_default | parse_merge_pcdata);
1302
+ CHECK(res);
1303
+
1304
+ CHECK_STRING(doc.child(STR("node")).child_value(), STR("First &lt; Second &gt; Third &quot;"));
1305
+ }
1306
+
1307
+ TEST(parse_merge_pcdata_whitespace)
1308
+ {
1309
+ unsigned int flag_sets[] = {0, parse_ws_pcdata, parse_ws_pcdata_single};
1310
+
1311
+ for (unsigned int i = 0; i < sizeof(flag_sets) / sizeof(flag_sets[0]); ++i)
1312
+ {
1313
+ unsigned int flags = parse_merge_pcdata | flag_sets[i];
1314
+
1315
+ xml_document doc;
1316
+ xml_parse_result res = doc.load_string(STR("<node><child1> <!-- comment 1 -->\t<!-- comment 2 -->\n</child1><child2>text<!-- comment 1-->\t<!-- comment2 --> end</child2></node>"), flags);
1317
+ CHECK(res);
1318
+
1319
+ if (flags & parse_ws_pcdata)
1320
+ {
1321
+ CHECK_STRING(doc.child(STR("node")).child(STR("child1")).child_value(), STR(" \t\n"));
1322
+ CHECK_STRING(doc.child(STR("node")).child(STR("child2")).child_value(), STR("text\t end"));
1323
+ }
1324
+ else if (flags & parse_ws_pcdata_single)
1325
+ {
1326
+ CHECK_STRING(doc.child(STR("node")).child(STR("child1")).child_value(), STR("\n"));
1327
+ CHECK_STRING(doc.child(STR("node")).child(STR("child2")).child_value(), STR("text end"));
1328
+ }
1329
+ else
1330
+ {
1331
+ CHECK(!doc.child(STR("node")).child(STR("child1")).first_child());
1332
+ CHECK_STRING(doc.child(STR("node")).child(STR("child2")).child_value(), STR("text end"));
1333
+ }
1334
+ }
1335
+ }
1336
+
1337
+ TEST(parse_merge_pcdata_append)
1338
+ {
1339
+ xml_document doc;
1340
+ doc.append_child(STR("node")).append_child(node_pcdata);
1341
+ xml_parse_result res = doc.child(STR("node")).append_buffer("hello <!--comment-->world", 25, parse_merge_pcdata | parse_fragment);
1342
+
1343
+ CHECK(res.status == status_append_invalid_root);
1344
+ CHECK_STRING(doc.child(STR("node")).first_child().value(), STR(""));
1345
+
1346
+ doc.child(STR("node")).remove_children();
1347
+ res = doc.child(STR("node")).append_buffer("hello <!--comment-->world", 25, parse_merge_pcdata | parse_fragment);
1348
+
1349
+ CHECK(res.status == status_ok);
1350
+ CHECK_STRING(doc.child(STR("node")).first_child().value(), STR("hello world"));
1351
+ }
1352
+
1353
+ TEST(parse_merge_pcdata_overlap)
1354
+ {
1355
+ xml_document doc;
1356
+ xml_parse_result res = doc.load_string(STR("<node>short <!-- --> this string is very long so long that copying it will overlap itself</node>"), parse_merge_pcdata);
1357
+ CHECK(res);
1358
+ CHECK_STRING(doc.child_value(STR("node")), STR("short this string is very long so long that copying it will overlap itself"));
1359
+ }
1360
+
1361
+ TEST(parse_encoding_detect)
1362
+ {
1363
+ char test[] = "<?xml version='1.0' encoding='utf-8'?><n/>";
1364
+
1365
+ xml_document doc;
1366
+ CHECK(doc.load_buffer(test, sizeof(test)));
1367
+ }
1368
+
1369
+ TEST(parse_encoding_detect_latin1)
1370
+ {
1371
+ char test0[] = "<?xml version='1.0' encoding='utf-8'?><n/>";
1372
+ char test1[] = "<?xml version='1.0' encoding='iso-8859-1'?><n/>";
1373
+ char test2[] = "<?xml version='1.0' encoding = \"latin1\"?><n/>";
1374
+ char test3[] = "<?xml version='1.0' encoding='ISO-8859-1'?><n/>";
1375
+ char test4[] = "<?xml version='1.0' encoding = \"LATIN1\"?><n/>";
1376
+
1377
+ xml_document doc;
1378
+ CHECK(doc.load_buffer(test0, sizeof(test0)).encoding == encoding_utf8);
1379
+ CHECK(doc.load_buffer(test1, sizeof(test1)).encoding == encoding_latin1);
1380
+ CHECK(doc.load_buffer(test2, sizeof(test2)).encoding == encoding_latin1);
1381
+ CHECK(doc.load_buffer(test3, sizeof(test3)).encoding == encoding_latin1);
1382
+ CHECK(doc.load_buffer(test4, sizeof(test4)).encoding == encoding_latin1);
1383
+ }
1384
+
1385
+ TEST(parse_encoding_detect_auto)
1386
+ {
1387
+ struct data_t
1388
+ {
1389
+ const char* contents;
1390
+ size_t size;
1391
+ xml_encoding encoding;
1392
+ };
1393
+
1394
+ const data_t data[] =
1395
+ {
1396
+ // BOM
1397
+ { "\x00\x00\xfe\xff", 4, encoding_utf32_be },
1398
+ { "\xff\xfe\x00\x00", 4, encoding_utf32_le },
1399
+ { "\xfe\xff ", 4, encoding_utf16_be },
1400
+ { "\xff\xfe ", 4, encoding_utf16_le },
1401
+ { "\xef\xbb\xbf ", 4, encoding_utf8 },
1402
+ // automatic tag detection for < or <?
1403
+ { "\x00\x00\x00<\x00\x00\x00n\x00\x00\x00/\x00\x00\x00>", 16, encoding_utf32_be },
1404
+ { "<\x00\x00\x00n\x00\x00\x00/\x00\x00\x00>\x00\x00\x00", 16, encoding_utf32_le },
1405
+ { "\x00<\x00?\x00n\x00?\x00>", 10, encoding_utf16_be },
1406
+ { "<\x00?\x00n\x00?\x00>\x00", 10, encoding_utf16_le },
1407
+ { "\x00<\x00n\x00/\x00>", 8, encoding_utf16_be },
1408
+ { "<\x00n\x00/\x00>\x00", 8, encoding_utf16_le },
1409
+ // <?xml encoding
1410
+ { "<?xml encoding='latin1'?>", 25, encoding_latin1 },
1411
+ };
1412
+
1413
+ for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i)
1414
+ {
1415
+ xml_document doc;
1416
+ xml_parse_result result = doc.load_buffer(data[i].contents, data[i].size, parse_fragment);
1417
+
1418
+ CHECK(result);
1419
+ CHECK(result.encoding == data[i].encoding);
1420
+ }
1421
+ }
1422
+
1423
+ TEST(parse_encoding_detect_auto_incomplete)
1424
+ {
1425
+ struct data_t
1426
+ {
1427
+ const char* contents;
1428
+ size_t size;
1429
+ xml_encoding encoding;
1430
+ };
1431
+
1432
+ const data_t data[] =
1433
+ {
1434
+ // BOM
1435
+ { "\x00\x00\xfe ", 4, encoding_utf8 },
1436
+ { "\x00\x00 ", 4, encoding_utf8 },
1437
+ { "\xff\xfe\x00 ", 4, encoding_utf16_le },
1438
+ { "\xfe ", 4, encoding_utf8 },
1439
+ { "\xff ", 4, encoding_utf8 },
1440
+ { "\xef\xbb ", 4, encoding_utf8 },
1441
+ { "\xef ", 4, encoding_utf8 },
1442
+ // automatic tag detection for < or <?
1443
+ { "\x00\x00\x00 ", 4, encoding_utf8 },
1444
+ { "<\x00\x00n/\x00>\x00", 8, encoding_utf16_le },
1445
+ { "\x00<n\x00\x00/\x00>", 8, encoding_utf16_be },
1446
+ { "<\x00?n/\x00>\x00", 8, encoding_utf16_le },
1447
+ { "\x00 ", 2, encoding_utf8 },
1448
+ // <?xml encoding
1449
+ { "<?xmC encoding='latin1'?>", 25, encoding_utf8 },
1450
+ { "<?xBC encoding='latin1'?>", 25, encoding_utf8 },
1451
+ { "<?ABC encoding='latin1'?>", 25, encoding_utf8 },
1452
+ { "<_ABC encoding='latin1'/>", 25, encoding_utf8 },
1453
+ };
1454
+
1455
+ for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i)
1456
+ {
1457
+ xml_document doc;
1458
+ xml_parse_result result = doc.load_buffer(data[i].contents, data[i].size, parse_fragment);
1459
+
1460
+ CHECK(result);
1461
+ CHECK(result.encoding == data[i].encoding);
1462
+ }
1463
+ }