react-native-nitro-xlsx 0.2.5 → 0.2.7

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 (449) hide show
  1. package/NitroXlsx.podspec +26 -27
  2. package/Package.swift +31 -10
  3. package/README.md +21 -9
  4. package/android/CMakeLists.txt +20 -27
  5. package/cpp/HybridNitroXlsx.cpp +25 -1
  6. package/cpp/HybridXlsxCellFormat.cpp +46 -146
  7. package/cpp/HybridXlsxCellFormat.hpp +9 -41
  8. package/cpp/HybridXlsxConditionalFormat.cpp +4 -1
  9. package/cpp/HybridXlsxConditionalFormats.cpp +5 -1
  10. package/cpp/HybridXlsxWorkbook.cpp +38 -8
  11. package/cpp/HybridXlsxWorkbook.hpp +10 -1
  12. package/cpp/HybridXlsxWorksheet.cpp +422 -141
  13. package/cpp/HybridXlsxWorksheet.hpp +4 -1
  14. package/cpp/XlsxCacheDir.cpp +25 -2
  15. package/cpp/XlsxCacheDir.hpp +3 -1
  16. package/cpp/XlsxCellStyle.hpp +360 -0
  17. package/cpp/XlsxJson.cpp +29 -8
  18. package/package.json +2 -2
  19. package/scripts/run-cpp-tests.sh +1 -1
  20. package/scripts/sync-openxlsx-headers.sh +34 -0
  21. package/src/__mocks__/react-native-nitro-modules.ts +523 -20
  22. package/src/__tests__/index.test.ts +124 -16
  23. package/src/index.ts +13 -13
  24. package/thirdparty/OpenXLSX/.clang-format +118 -0
  25. package/thirdparty/OpenXLSX/.clang-tidy +28 -0
  26. package/thirdparty/OpenXLSX/.gitignore +130 -0
  27. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_before_XMLNode_wrappers +46 -0
  28. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_and_stripping +49 -0
  29. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_char_support +49 -0
  30. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespace_support +49 -0
  31. package/thirdparty/OpenXLSX/Benchmarks/2024-07-29-benchmarks_with_XMLNode_wrappers_and_namespaced_name_disabled +49 -0
  32. package/thirdparty/OpenXLSX/Benchmarks/2024-08-11-benchmarks_post-XLCellIterator-Rework +46 -0
  33. package/thirdparty/OpenXLSX/Benchmarks/2024-08-14-benchmarks_post-default-row-column-style-support +46 -0
  34. package/thirdparty/OpenXLSX/Benchmarks/2024-09-02-benchmarks +46 -0
  35. package/thirdparty/OpenXLSX/Benchmarks/2024-12-19-benchmarks +46 -0
  36. package/thirdparty/OpenXLSX/Benchmarks/2024-12-30-benchmarks-post-XLSharedStrings-by-ref +46 -0
  37. package/thirdparty/OpenXLSX/Benchmarks/2025-01-09-benchmarks-post-conditionalFormatsAndSheetProtection +46 -0
  38. package/thirdparty/OpenXLSX/Benchmarks/2025-01-10-benchmarks-post-XLCellValue-bugfix +46 -0
  39. package/thirdparty/OpenXLSX/Benchmarks/2025-01-31-benchmarks-post-XLComments-implementation +46 -0
  40. package/thirdparty/OpenXLSX/Benchmarks/2025-02-02-benchmarks-post-XLRowIterator-Rework +46 -0
  41. package/thirdparty/OpenXLSX/Benchmarks/2025-07-20-benchmarks-after-hiding-pugixml-internals +46 -0
  42. package/thirdparty/OpenXLSX/Benchmarks/2025-08-29-benchmarks-after-code-review-with-libzip +46 -0
  43. package/thirdparty/OpenXLSX/Benchmarks/Benchmark.cpp +249 -0
  44. package/thirdparty/OpenXLSX/Benchmarks/CMakeLists.txt +19 -0
  45. package/thirdparty/OpenXLSX/CMakeLists.txt +466 -0
  46. package/thirdparty/OpenXLSX/Documentation/CMakeLists.txt +31 -0
  47. package/thirdparty/OpenXLSX/Documentation/Doxyfile.in +2471 -0
  48. package/thirdparty/OpenXLSX/Documentation/DoxygenLayout.xml +194 -0
  49. package/thirdparty/OpenXLSX/Documentation/customdoxygen.css +1355 -0
  50. package/thirdparty/OpenXLSX/Examples/CMakeLists.txt +103 -0
  51. package/thirdparty/OpenXLSX/Examples/Demo1.cpp +279 -0
  52. package/thirdparty/OpenXLSX/Examples/Demo10.cpp +545 -0
  53. package/thirdparty/OpenXLSX/Examples/Demo1A.cpp +137 -0
  54. package/thirdparty/OpenXLSX/Examples/Demo2.cpp +65 -0
  55. package/thirdparty/OpenXLSX/Examples/Demo3.cpp +89 -0
  56. package/thirdparty/OpenXLSX/Examples/Demo4.cpp +86 -0
  57. package/thirdparty/OpenXLSX/Examples/Demo5.cpp +77 -0
  58. package/thirdparty/OpenXLSX/Examples/Demo6.cpp +103 -0
  59. package/thirdparty/OpenXLSX/Examples/Demo7.cpp +79 -0
  60. package/thirdparty/OpenXLSX/Examples/Demo8.cpp +117 -0
  61. package/thirdparty/OpenXLSX/Examples/Demo9.cpp +363 -0
  62. package/thirdparty/OpenXLSX/Examples/cmake/FindLIBZIP.cmake +61 -0
  63. package/thirdparty/OpenXLSX/Examples/external/CustomZip/CustomZip.hpp +256 -0
  64. package/thirdparty/OpenXLSX/LICENSE.md +29 -0
  65. package/thirdparty/OpenXLSX/Makefile.GNU +530 -0
  66. package/thirdparty/OpenXLSX/Notes/TBDs.txt +16 -0
  67. package/thirdparty/OpenXLSX/Notes/confirmed-TBCs.txt +8 -0
  68. package/thirdparty/OpenXLSX/Notes/styles-missing-support.xml +12 -0
  69. package/thirdparty/OpenXLSX/Notes/todo-list.txt +108 -0
  70. package/thirdparty/OpenXLSX/OpenXLSX/CMakeLists.txt +631 -0
  71. package/thirdparty/OpenXLSX/OpenXLSX/OpenXLSX.hpp +63 -0
  72. package/thirdparty/OpenXLSX/OpenXLSX/OpenXLSXConfig.cmake +11 -0
  73. package/thirdparty/OpenXLSX/OpenXLSX/cmake/bundle_static_library.cmake +198 -0
  74. package/thirdparty/OpenXLSX/OpenXLSX/cmake/patch_pkg_config.cmake +69 -0
  75. package/thirdparty/OpenXLSX/OpenXLSX/headers/IZipArchive.hpp +361 -0
  76. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/IZipArchive.hpp +361 -0
  77. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/OpenXLSX-Exports.hpp +12 -0
  78. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCell.hpp +367 -0
  79. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCellIterator.hpp +252 -0
  80. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCellRange.hpp +223 -0
  81. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCellReference.hpp +317 -0
  82. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCellValue.hpp +793 -0
  83. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLColor.hpp +232 -0
  84. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLColumn.hpp +159 -0
  85. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLCommandQuery.hpp +228 -0
  86. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLComments.hpp +270 -0
  87. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLConstants.hpp +18 -0
  88. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLContentTypes.hpp +264 -0
  89. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLDateTime.hpp +175 -0
  90. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLDocument.hpp +505 -0
  91. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLDrawing.hpp +452 -0
  92. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLException.hpp +161 -0
  93. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLFormula.hpp +375 -0
  94. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLIterator.hpp +40 -0
  95. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLMergeCells.hpp +216 -0
  96. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLProperties.hpp +348 -0
  97. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLRelationships.hpp +348 -0
  98. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLRow.hpp +721 -0
  99. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLRowData.hpp +488 -0
  100. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLSharedStrings.hpp +204 -0
  101. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLSheet.hpp +1640 -0
  102. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLStyles.hpp +2390 -0
  103. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLTables.hpp +132 -0
  104. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLWorkbook.hpp +404 -0
  105. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLXmlData.hpp +283 -0
  106. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLXmlFile.hpp +194 -0
  107. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLXmlParser.hpp +282 -0
  108. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLXmlParserForwardDeclarations.hpp +85 -0
  109. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/XLZipArchive.hpp +232 -0
  110. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/detail/LibZip.hpp +447 -0
  111. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/detail/OpenXLSXFileSystemTools.hpp +207 -0
  112. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX/detail/Zippy.hpp +1375 -0
  113. package/thirdparty/OpenXLSX/OpenXLSX/headers/OpenXLSX-Exports.hpp +12 -0
  114. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCell.hpp +367 -0
  115. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellIterator.hpp +252 -0
  116. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellRange.hpp +223 -0
  117. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellReference.hpp +317 -0
  118. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCellValue.hpp +793 -0
  119. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLColor.hpp +232 -0
  120. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLColumn.hpp +159 -0
  121. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLCommandQuery.hpp +228 -0
  122. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLComments.hpp +270 -0
  123. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLConstants.hpp +18 -0
  124. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLContentTypes.hpp +264 -0
  125. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDateTime.hpp +175 -0
  126. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDocument.hpp +505 -0
  127. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLDrawing.hpp +452 -0
  128. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLException.hpp +161 -0
  129. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLFormula.hpp +375 -0
  130. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLIterator.hpp +40 -0
  131. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLMergeCells.hpp +216 -0
  132. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLProperties.hpp +348 -0
  133. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRelationships.hpp +348 -0
  134. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRow.hpp +721 -0
  135. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLRowData.hpp +488 -0
  136. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLSharedStrings.hpp +204 -0
  137. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLSheet.hpp +1640 -0
  138. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLStyles.hpp +2390 -0
  139. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLTables.hpp +132 -0
  140. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLWorkbook.hpp +404 -0
  141. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlData.hpp +283 -0
  142. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlFile.hpp +194 -0
  143. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlParser.hpp +282 -0
  144. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLXmlParserForwardDeclarations.hpp +85 -0
  145. package/thirdparty/OpenXLSX/OpenXLSX/headers/XLZipArchive.hpp +232 -0
  146. package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/LibZip.hpp +447 -0
  147. package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/OpenXLSXFileSystemTools.hpp +207 -0
  148. package/thirdparty/OpenXLSX/OpenXLSX/headers/detail/Zippy.hpp +1375 -0
  149. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCell.cpp +340 -0
  150. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellIterator.cpp +427 -0
  151. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellRange.cpp +221 -0
  152. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellReference.cpp +408 -0
  153. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLCellValue.cpp +519 -0
  154. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLColor.cpp +202 -0
  155. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLColumn.cpp +141 -0
  156. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLComments.cpp +637 -0
  157. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLContentTypes.cpp +329 -0
  158. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDateTime.cpp +269 -0
  159. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDocument.cpp +1678 -0
  160. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLDrawing.cpp +784 -0
  161. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLFormula.cpp +201 -0
  162. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLMergeCells.cpp +357 -0
  163. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLProperties.cpp +810 -0
  164. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRelationships.cpp +529 -0
  165. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRow.cpp +918 -0
  166. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLRowData.cpp +508 -0
  167. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLSharedStrings.cpp +220 -0
  168. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLSheet.cpp +1970 -0
  169. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLStyles.cpp +3014 -0
  170. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLTables.cpp +125 -0
  171. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLWorkbook.cpp +784 -0
  172. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlData.cpp +247 -0
  173. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlFile.cpp +160 -0
  174. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLXmlParser.cpp +261 -0
  175. package/thirdparty/OpenXLSX/OpenXLSX/sources/XLZipArchive.cpp +266 -0
  176. package/thirdparty/OpenXLSX/OpenXLSX/sources/utilities/XLUtilities.hpp +478 -0
  177. package/thirdparty/OpenXLSX/README.md +1279 -0
  178. package/thirdparty/OpenXLSX/Scripts/cmake-cleanup.sh +102 -0
  179. package/thirdparty/OpenXLSX/Scripts/compile.sh +23 -0
  180. package/thirdparty/OpenXLSX/Scripts/demos-cleanup.sh +25 -0
  181. package/thirdparty/OpenXLSX/Scripts/demos-run-all.sh +60 -0
  182. package/thirdparty/OpenXLSX/Scripts/guarded-xml-format.sh +47 -0
  183. package/thirdparty/OpenXLSX/Scripts/make-gnu.sh +11 -0
  184. package/thirdparty/OpenXLSX/Scripts/uninstall-manifest.sh +48 -0
  185. package/thirdparty/OpenXLSX/Scripts/xml-format-all.sh +19 -0
  186. package/thirdparty/OpenXLSX/Scripts/xml-format.sh +38 -0
  187. package/thirdparty/OpenXLSX/Tests/CMakeLists.txt +37 -0
  188. package/thirdparty/OpenXLSX/Tests/catch/catch.hpp +17799 -0
  189. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_automake.hpp +68 -0
  190. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_sonarqube.hpp +182 -0
  191. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_tap.hpp +278 -0
  192. package/thirdparty/OpenXLSX/Tests/catch/catch_reporter_teamcity.hpp +212 -0
  193. package/thirdparty/OpenXLSX/Tests/main.cpp +55 -0
  194. package/thirdparty/OpenXLSX/Tests/testXLCell.cpp +176 -0
  195. package/thirdparty/OpenXLSX/Tests/testXLCellRange.cpp +180 -0
  196. package/thirdparty/OpenXLSX/Tests/testXLCellReference.cpp +160 -0
  197. package/thirdparty/OpenXLSX/Tests/testXLCellValue.cpp +366 -0
  198. package/thirdparty/OpenXLSX/Tests/testXLCellValueProxy.cpp +255 -0
  199. package/thirdparty/OpenXLSX/Tests/testXLColor.cpp +75 -0
  200. package/thirdparty/OpenXLSX/Tests/testXLDateTime.cpp +229 -0
  201. package/thirdparty/OpenXLSX/Tests/testXLDocument.cpp +197 -0
  202. package/thirdparty/OpenXLSX/Tests/testXLFormula.cpp +131 -0
  203. package/thirdparty/OpenXLSX/Tests/testXLRow.cpp +597 -0
  204. package/thirdparty/OpenXLSX/Tests/testXLSheet.cpp +77 -0
  205. package/thirdparty/OpenXLSX/Tests/ziptest-with-libs.cpp +88 -0
  206. package/thirdparty/OpenXLSX/Tests/ziptest.cpp +735 -0
  207. package/thirdparty/OpenXLSX/cmake/get-git-HEAD-ID.cmake +45 -0
  208. package/thirdparty/OpenXLSX/cmake/libopenxlsxCPackOptions.cmake.in +20 -0
  209. package/thirdparty/OpenXLSX/cmake/manage_dependency.cmake +813 -0
  210. package/thirdparty/OpenXLSX/cmake/recursive_library_type_test.cmake +52 -0
  211. package/thirdparty/OpenXLSX/gnu-make-crutch/OpenXLSX-Exports-shared.hpp +42 -0
  212. package/thirdparty/OpenXLSX/gnu-make-crutch/OpenXLSX-Exports-static.hpp +42 -0
  213. package/thirdparty/OpenXLSX/vcpkg.json +24 -0
  214. package/thirdparty/README.md +46 -0
  215. package/thirdparty/miniz/.clang-format +47 -0
  216. package/thirdparty/miniz/.travis.yml +2 -0
  217. package/thirdparty/miniz/CMakeLists.txt +333 -0
  218. package/thirdparty/miniz/CMakePresets.json +31 -0
  219. package/thirdparty/miniz/ChangeLog.md +272 -0
  220. package/thirdparty/miniz/Config.cmake.in +1 -0
  221. package/thirdparty/miniz/LICENSE +22 -0
  222. package/thirdparty/miniz/amalgamate.sh +57 -0
  223. package/thirdparty/miniz/examples/example1.c +105 -0
  224. package/thirdparty/miniz/examples/example2.c +164 -0
  225. package/thirdparty/miniz/examples/example3.c +269 -0
  226. package/thirdparty/miniz/examples/example4.c +102 -0
  227. package/thirdparty/miniz/examples/example5.c +327 -0
  228. package/thirdparty/miniz/examples/example6.c +189 -0
  229. package/thirdparty/miniz/meson.build +21 -0
  230. package/thirdparty/miniz/miniz.c +646 -0
  231. package/thirdparty/miniz/miniz.h +615 -0
  232. package/thirdparty/miniz/miniz.pc.in +13 -0
  233. package/thirdparty/miniz/miniz_common.h +89 -0
  234. package/thirdparty/miniz/miniz_export.h +20 -0
  235. package/thirdparty/miniz/miniz_tdef.c +1602 -0
  236. package/thirdparty/miniz/miniz_tdef.h +199 -0
  237. package/thirdparty/miniz/miniz_tinfl.c +778 -0
  238. package/thirdparty/miniz/miniz_tinfl.h +150 -0
  239. package/thirdparty/miniz/miniz_zip.c +4895 -0
  240. package/thirdparty/miniz/miniz_zip.h +454 -0
  241. package/thirdparty/miniz/readme.md +46 -0
  242. package/thirdparty/miniz/test.sh +36 -0
  243. package/thirdparty/miniz/tests/add_in_place_fuzzer.c +87 -0
  244. package/thirdparty/miniz/tests/catch_amalgamated.cpp +10795 -0
  245. package/thirdparty/miniz/tests/catch_amalgamated.hpp +13143 -0
  246. package/thirdparty/miniz/tests/checksum_fuzzer.c +26 -0
  247. package/thirdparty/miniz/tests/compress_fuzzer.c +91 -0
  248. package/thirdparty/miniz/tests/flush_fuzzer.c +88 -0
  249. package/thirdparty/miniz/tests/fuzz_main.c +55 -0
  250. package/thirdparty/miniz/tests/large_fuzzer.c +133 -0
  251. package/thirdparty/miniz/tests/main.cpp +185 -0
  252. package/thirdparty/miniz/tests/miniz_tdefl_fuzzer.cc +115 -0
  253. package/thirdparty/miniz/tests/miniz_tester.cpp +1881 -0
  254. package/thirdparty/miniz/tests/miniz_zip_validate_fuzzer.cc +71 -0
  255. package/thirdparty/miniz/tests/miniz_zip_writer_fuzzer.cc +96 -0
  256. package/thirdparty/miniz/tests/ossfuzz.sh +48 -0
  257. package/thirdparty/miniz/tests/small_fuzzer.c +126 -0
  258. package/thirdparty/miniz/tests/timer.cpp +152 -0
  259. package/thirdparty/miniz/tests/timer.h +40 -0
  260. package/thirdparty/miniz/tests/uncompress2_fuzzer.c +21 -0
  261. package/thirdparty/miniz/tests/uncompress_fuzzer.c +30 -0
  262. package/thirdparty/miniz/tests/zip.dict +9 -0
  263. package/thirdparty/miniz/tests/zip_fuzzer.c +63 -0
  264. package/thirdparty/pugixml/.codecov.yml +7 -0
  265. package/thirdparty/pugixml/.gitattributes +1 -0
  266. package/thirdparty/pugixml/CMakeLists.txt +330 -0
  267. package/thirdparty/pugixml/LICENSE.md +24 -0
  268. package/thirdparty/pugixml/Makefile +98 -0
  269. package/thirdparty/pugixml/README.md +81 -0
  270. package/thirdparty/pugixml/SECURITY.md +9 -0
  271. package/thirdparty/pugixml/appveyor.yml +50 -0
  272. package/thirdparty/pugixml/docs/config.adoc +7 -0
  273. package/thirdparty/pugixml/docs/images/dom_tree.png +0 -0
  274. package/thirdparty/pugixml/docs/images/vs2005_link1.png +0 -0
  275. package/thirdparty/pugixml/docs/images/vs2005_link2.png +0 -0
  276. package/thirdparty/pugixml/docs/images/vs2005_pch1.png +0 -0
  277. package/thirdparty/pugixml/docs/images/vs2005_pch2.png +0 -0
  278. package/thirdparty/pugixml/docs/images/vs2005_pch3.png +0 -0
  279. package/thirdparty/pugixml/docs/images/vs2005_pch4.png +0 -0
  280. package/thirdparty/pugixml/docs/images/vs2010_link1.png +0 -0
  281. package/thirdparty/pugixml/docs/images/vs2010_link2.png +0 -0
  282. package/thirdparty/pugixml/docs/manual.adoc +3326 -0
  283. package/thirdparty/pugixml/docs/manual.html +6395 -0
  284. package/thirdparty/pugixml/docs/quickstart.adoc +287 -0
  285. package/thirdparty/pugixml/docs/quickstart.html +1107 -0
  286. package/thirdparty/pugixml/docs/samples/character.xml +8 -0
  287. package/thirdparty/pugixml/docs/samples/custom_memory_management.cpp +27 -0
  288. package/thirdparty/pugixml/docs/samples/include.cpp +64 -0
  289. package/thirdparty/pugixml/docs/samples/load_error_handling.cpp +33 -0
  290. package/thirdparty/pugixml/docs/samples/load_file.cpp +16 -0
  291. package/thirdparty/pugixml/docs/samples/load_memory.cpp +66 -0
  292. package/thirdparty/pugixml/docs/samples/load_options.cpp +30 -0
  293. package/thirdparty/pugixml/docs/samples/load_stream.cpp +97 -0
  294. package/thirdparty/pugixml/docs/samples/modify_add.cpp +29 -0
  295. package/thirdparty/pugixml/docs/samples/modify_base.cpp +43 -0
  296. package/thirdparty/pugixml/docs/samples/modify_remove.cpp +27 -0
  297. package/thirdparty/pugixml/docs/samples/save_custom_writer.cpp +116 -0
  298. package/thirdparty/pugixml/docs/samples/save_declaration.cpp +27 -0
  299. package/thirdparty/pugixml/docs/samples/save_file.cpp +17 -0
  300. package/thirdparty/pugixml/docs/samples/save_options.cpp +48 -0
  301. package/thirdparty/pugixml/docs/samples/save_stream.cpp +18 -0
  302. package/thirdparty/pugixml/docs/samples/save_subtree.cpp +26 -0
  303. package/thirdparty/pugixml/docs/samples/text.cpp +35 -0
  304. package/thirdparty/pugixml/docs/samples/transitions.xml +7 -0
  305. package/thirdparty/pugixml/docs/samples/traverse_base.cpp +51 -0
  306. package/thirdparty/pugixml/docs/samples/traverse_iter.cpp +27 -0
  307. package/thirdparty/pugixml/docs/samples/traverse_predicate.cpp +48 -0
  308. package/thirdparty/pugixml/docs/samples/traverse_rangefor.cpp +32 -0
  309. package/thirdparty/pugixml/docs/samples/traverse_walker.cpp +35 -0
  310. package/thirdparty/pugixml/docs/samples/tree.xml +12 -0
  311. package/thirdparty/pugixml/docs/samples/weekly-shift_jis.xml +78 -0
  312. package/thirdparty/pugixml/docs/samples/weekly-utf-16.xml +0 -0
  313. package/thirdparty/pugixml/docs/samples/weekly-utf-8.xml +78 -0
  314. package/thirdparty/pugixml/docs/samples/xgconsole.xml +12 -0
  315. package/thirdparty/pugixml/docs/samples/xpath_error.cpp +43 -0
  316. package/thirdparty/pugixml/docs/samples/xpath_query.cpp +36 -0
  317. package/thirdparty/pugixml/docs/samples/xpath_select.cpp +28 -0
  318. package/thirdparty/pugixml/docs/samples/xpath_variables.cpp +38 -0
  319. package/thirdparty/pugixml/readme.txt +50 -0
  320. package/thirdparty/pugixml/scripts/archive.py +54 -0
  321. package/thirdparty/pugixml/scripts/cocoapods_push.sh +4 -0
  322. package/thirdparty/pugixml/scripts/natvis/pugixml.natvis +77 -0
  323. package/thirdparty/pugixml/scripts/natvis/pugixml_compact.natvis +506 -0
  324. package/thirdparty/pugixml/scripts/nuget/build/native/pugixml-propertiesui.xml +17 -0
  325. package/thirdparty/pugixml/scripts/nuget/build/native/pugixml.targets +28 -0
  326. package/thirdparty/pugixml/scripts/nuget/pugixml.nuspec +20 -0
  327. package/thirdparty/pugixml/scripts/nuget_build.ps1 +60 -0
  328. package/thirdparty/pugixml/scripts/premake4.lua +92 -0
  329. package/thirdparty/pugixml/scripts/pugixml-config.cmake.in +12 -0
  330. package/thirdparty/pugixml/scripts/pugixml.pc.in +11 -0
  331. package/thirdparty/pugixml/scripts/pugixml.podspec +14 -0
  332. package/thirdparty/pugixml/scripts/pugixml.xcodeproj/project.pbxproj +212 -0
  333. package/thirdparty/pugixml/scripts/pugixml_airplay.mkf +13 -0
  334. package/thirdparty/pugixml/scripts/pugixml_codeblocks.cbp +44 -0
  335. package/thirdparty/pugixml/scripts/pugixml_codelite.project +56 -0
  336. package/thirdparty/pugixml/scripts/pugixml_dll.rc +45 -0
  337. package/thirdparty/pugixml/scripts/pugixml_vs2005.vcproj +343 -0
  338. package/thirdparty/pugixml/scripts/pugixml_vs2005_static.vcproj +343 -0
  339. package/thirdparty/pugixml/scripts/pugixml_vs2008.vcproj +339 -0
  340. package/thirdparty/pugixml/scripts/pugixml_vs2008_static.vcproj +339 -0
  341. package/thirdparty/pugixml/scripts/pugixml_vs2010.vcxproj +191 -0
  342. package/thirdparty/pugixml/scripts/pugixml_vs2010_static.vcxproj +191 -0
  343. package/thirdparty/pugixml/scripts/pugixml_vs2013.vcxproj +199 -0
  344. package/thirdparty/pugixml/scripts/pugixml_vs2013_static.vcxproj +199 -0
  345. package/thirdparty/pugixml/scripts/pugixml_vs2015.vcxproj +172 -0
  346. package/thirdparty/pugixml/scripts/pugixml_vs2015_static.vcxproj +176 -0
  347. package/thirdparty/pugixml/scripts/pugixml_vs2017.vcxproj +172 -0
  348. package/thirdparty/pugixml/scripts/pugixml_vs2017_static.vcxproj +176 -0
  349. package/thirdparty/pugixml/scripts/pugixml_vs2019.vcxproj +176 -0
  350. package/thirdparty/pugixml/scripts/pugixml_vs2019_static.vcxproj +180 -0
  351. package/thirdparty/pugixml/scripts/pugixml_vs2022.vcxproj +176 -0
  352. package/thirdparty/pugixml/scripts/pugixml_vs2022_static.vcxproj +180 -0
  353. package/thirdparty/pugixml/scripts/pugixml_vs2026.vcxproj +176 -0
  354. package/thirdparty/pugixml/scripts/pugixml_vs2026_static.vcxproj +180 -0
  355. package/thirdparty/pugixml/scripts/sbom.cdx.json +47 -0
  356. package/thirdparty/pugixml/src/pugiconfig.hpp +81 -0
  357. package/thirdparty/pugixml/src/pugixml.cpp +13776 -0
  358. package/thirdparty/pugixml/src/pugixml.hpp +1604 -0
  359. package/thirdparty/pugixml/tests/allocator.cpp +175 -0
  360. package/thirdparty/pugixml/tests/allocator.hpp +10 -0
  361. package/thirdparty/pugixml/tests/autotest-appveyor.ps1 +93 -0
  362. package/thirdparty/pugixml/tests/cmake-appveyor.ps1 +57 -0
  363. package/thirdparty/pugixml/tests/data/empty.xml +0 -0
  364. package/thirdparty/pugixml/tests/data/large.xml +1 -0
  365. package/thirdparty/pugixml/tests/data/latintest_latin1.xml +1 -0
  366. package/thirdparty/pugixml/tests/data/latintest_utf8.xml +1 -0
  367. package/thirdparty/pugixml/tests/data/multiline.xml +3 -0
  368. package/thirdparty/pugixml/tests/data/small.xml +1 -0
  369. package/thirdparty/pugixml/tests/data/truncation.xml +19 -0
  370. package/thirdparty/pugixml/tests/data/utftest_utf16_be.xml +0 -0
  371. package/thirdparty/pugixml/tests/data/utftest_utf16_be_bom.xml +0 -0
  372. package/thirdparty/pugixml/tests/data/utftest_utf16_be_clean.xml +0 -0
  373. package/thirdparty/pugixml/tests/data/utftest_utf16_be_nodecl.xml +0 -0
  374. package/thirdparty/pugixml/tests/data/utftest_utf16_le.xml +0 -0
  375. package/thirdparty/pugixml/tests/data/utftest_utf16_le_bom.xml +0 -0
  376. package/thirdparty/pugixml/tests/data/utftest_utf16_le_clean.xml +0 -0
  377. package/thirdparty/pugixml/tests/data/utftest_utf16_le_nodecl.xml +0 -0
  378. package/thirdparty/pugixml/tests/data/utftest_utf32_be.xml +0 -0
  379. package/thirdparty/pugixml/tests/data/utftest_utf32_be_bom.xml +0 -0
  380. package/thirdparty/pugixml/tests/data/utftest_utf32_be_clean.xml +0 -0
  381. package/thirdparty/pugixml/tests/data/utftest_utf32_be_nodecl.xml +0 -0
  382. package/thirdparty/pugixml/tests/data/utftest_utf32_le.xml +0 -0
  383. package/thirdparty/pugixml/tests/data/utftest_utf32_le_bom.xml +0 -0
  384. package/thirdparty/pugixml/tests/data/utftest_utf32_le_clean.xml +0 -0
  385. package/thirdparty/pugixml/tests/data/utftest_utf32_le_nodecl.xml +0 -0
  386. package/thirdparty/pugixml/tests/data/utftest_utf8.xml +87 -0
  387. package/thirdparty/pugixml/tests/data/utftest_utf8_bom.xml +87 -0
  388. package/thirdparty/pugixml/tests/data/utftest_utf8_clean.xml +84 -0
  389. package/thirdparty/pugixml/tests/data/utftest_utf8_nodecl.xml +86 -0
  390. package/thirdparty/pugixml/tests/data//321/202/320/265/321/201/321/202.xml +1 -0
  391. package/thirdparty/pugixml/tests/data_fuzz_parse/basic.xml +1 -0
  392. package/thirdparty/pugixml/tests/data_fuzz_parse/doctype.xml +1 -0
  393. package/thirdparty/pugixml/tests/data_fuzz_parse/refs.xml +1 -0
  394. package/thirdparty/pugixml/tests/data_fuzz_parse/types.xml +1 -0
  395. package/thirdparty/pugixml/tests/data_fuzz_parse/utf16.xml +0 -0
  396. package/thirdparty/pugixml/tests/data_fuzz_parse/utf32.xml +0 -0
  397. package/thirdparty/pugixml/tests/data_fuzz_xpath/basic.xpath +1 -0
  398. package/thirdparty/pugixml/tests/data_fuzz_xpath/functions.xpath +1 -0
  399. package/thirdparty/pugixml/tests/data_fuzz_xpath/math.xpath +1 -0
  400. package/thirdparty/pugixml/tests/data_fuzz_xpath/path.xpath +1 -0
  401. package/thirdparty/pugixml/tests/data_fuzz_xpath/predicate.xpath +1 -0
  402. package/thirdparty/pugixml/tests/fuzz_parse.cpp +14 -0
  403. package/thirdparty/pugixml/tests/fuzz_parse.dict +72 -0
  404. package/thirdparty/pugixml/tests/fuzz_setup.sh +11 -0
  405. package/thirdparty/pugixml/tests/fuzz_xpath.cpp +46 -0
  406. package/thirdparty/pugixml/tests/fuzz_xpath.dict +72 -0
  407. package/thirdparty/pugixml/tests/helpers.hpp +114 -0
  408. package/thirdparty/pugixml/tests/main.cpp +218 -0
  409. package/thirdparty/pugixml/tests/test.cpp +220 -0
  410. package/thirdparty/pugixml/tests/test.hpp +175 -0
  411. package/thirdparty/pugixml/tests/test_compact.cpp +150 -0
  412. package/thirdparty/pugixml/tests/test_deprecated.cpp +25 -0
  413. package/thirdparty/pugixml/tests/test_document.cpp +1910 -0
  414. package/thirdparty/pugixml/tests/test_dom_modify.cpp +2122 -0
  415. package/thirdparty/pugixml/tests/test_dom_text.cpp +601 -0
  416. package/thirdparty/pugixml/tests/test_dom_traverse.cpp +1481 -0
  417. package/thirdparty/pugixml/tests/test_header_guard.cpp +3 -0
  418. package/thirdparty/pugixml/tests/test_header_iosfwd_1.cpp +3 -0
  419. package/thirdparty/pugixml/tests/test_header_iosfwd_2.cpp +3 -0
  420. package/thirdparty/pugixml/tests/test_header_iostream_1.cpp +3 -0
  421. package/thirdparty/pugixml/tests/test_header_iostream_2.cpp +3 -0
  422. package/thirdparty/pugixml/tests/test_header_only_1.cpp +21 -0
  423. package/thirdparty/pugixml/tests/test_header_only_2.cpp +21 -0
  424. package/thirdparty/pugixml/tests/test_header_string_1.cpp +3 -0
  425. package/thirdparty/pugixml/tests/test_header_string_2.cpp +3 -0
  426. package/thirdparty/pugixml/tests/test_header_string_iostream.cpp +5 -0
  427. package/thirdparty/pugixml/tests/test_memory.cpp +303 -0
  428. package/thirdparty/pugixml/tests/test_parse.cpp +1463 -0
  429. package/thirdparty/pugixml/tests/test_parse_doctype.cpp +366 -0
  430. package/thirdparty/pugixml/tests/test_unicode.cpp +152 -0
  431. package/thirdparty/pugixml/tests/test_version.cpp +5 -0
  432. package/thirdparty/pugixml/tests/test_write.cpp +757 -0
  433. package/thirdparty/pugixml/tests/test_xpath.cpp +833 -0
  434. package/thirdparty/pugixml/tests/test_xpath_api.cpp +646 -0
  435. package/thirdparty/pugixml/tests/test_xpath_functions.cpp +844 -0
  436. package/thirdparty/pugixml/tests/test_xpath_operators.cpp +566 -0
  437. package/thirdparty/pugixml/tests/test_xpath_parse.cpp +428 -0
  438. package/thirdparty/pugixml/tests/test_xpath_paths.cpp +787 -0
  439. package/thirdparty/pugixml/tests/test_xpath_paths_abbrev_w3c.cpp +219 -0
  440. package/thirdparty/pugixml/tests/test_xpath_paths_w3c.cpp +312 -0
  441. package/thirdparty/pugixml/tests/test_xpath_variables.cpp +683 -0
  442. package/thirdparty/pugixml/tests/test_xpath_xalan_1.cpp +411 -0
  443. package/thirdparty/pugixml/tests/test_xpath_xalan_2.cpp +417 -0
  444. package/thirdparty/pugixml/tests/test_xpath_xalan_3.cpp +321 -0
  445. package/thirdparty/pugixml/tests/test_xpath_xalan_4.cpp +300 -0
  446. package/thirdparty/pugixml/tests/test_xpath_xalan_5.cpp +295 -0
  447. package/thirdparty/pugixml/tests/writer_string.cpp +79 -0
  448. package/thirdparty/pugixml/tests/writer_string.hpp +27 -0
  449. package/scripts/prepare-openxlsx.js +0 -126
@@ -0,0 +1,1910 @@
1
+ #define _CRT_SECURE_NO_WARNINGS
2
+ #define _SCL_SECURE_NO_WARNINGS
3
+ #define _SCL_SECURE_NO_DEPRECATE
4
+ #define _CRT_NONSTDC_NO_DEPRECATE 0
5
+
6
+ #include <string.h> // because Borland's STL is braindead, we have to include <string.h> _before_ <string> in order to get memcpy
7
+
8
+ #include "test.hpp"
9
+
10
+ #include "writer_string.hpp"
11
+
12
+ #include <stdio.h>
13
+ #include <stdlib.h>
14
+
15
+ #include <fstream>
16
+ #include <sstream>
17
+
18
+ #include <string>
19
+ #include <algorithm>
20
+
21
+ #ifndef PUGIXML_NO_EXCEPTIONS
22
+ # include <stdexcept>
23
+ #endif
24
+
25
+ // for unlink
26
+ #ifdef _WIN32
27
+ # include <io.h>
28
+ #else
29
+ # include <unistd.h>
30
+ #endif
31
+
32
+ using namespace pugi;
33
+
34
+ static bool load_file_in_memory(const char* path, char*& data, size_t& size)
35
+ {
36
+ FILE* file = fopen(path, "rb");
37
+ if (!file) return false;
38
+
39
+ fseek(file, 0, SEEK_END);
40
+ long length = ftell(file);
41
+ fseek(file, 0, SEEK_SET);
42
+
43
+ CHECK(length >= 0);
44
+ size = static_cast<size_t>(length);
45
+ data = new char[size];
46
+
47
+ CHECK(fread(data, 1, size, file) == size);
48
+ fclose(file);
49
+
50
+ return true;
51
+ }
52
+
53
+ static bool test_file_contents(const char* path, const char* data, size_t size)
54
+ {
55
+ char* fdata;
56
+ size_t fsize;
57
+ if (!load_file_in_memory(path, fdata, fsize)) return false;
58
+
59
+ bool result = (size == fsize && memcmp(data, fdata, size) == 0);
60
+
61
+ delete[] fdata;
62
+
63
+ return result;
64
+ }
65
+
66
+ TEST(document_create_empty)
67
+ {
68
+ xml_document doc;
69
+ CHECK_NODE(doc, STR(""));
70
+ }
71
+
72
+ TEST(document_create)
73
+ {
74
+ xml_document doc;
75
+ doc.append_child().set_name(STR("node"));
76
+ CHECK_NODE(doc, STR("<node/>"));
77
+ }
78
+
79
+ #ifndef PUGIXML_NO_STL
80
+ TEST(document_load_stream)
81
+ {
82
+ xml_document doc;
83
+
84
+ std::istringstream iss("<node/>");
85
+ CHECK(doc.load(iss));
86
+ CHECK_NODE(doc, STR("<node/>"));
87
+ }
88
+
89
+ TEST(document_load_stream_offset)
90
+ {
91
+ xml_document doc;
92
+
93
+ std::istringstream iss("<foobar> <node/>");
94
+
95
+ std::string s;
96
+ iss >> s;
97
+
98
+ CHECK(doc.load(iss));
99
+ CHECK_NODE(doc, STR("<node/>"));
100
+ }
101
+
102
+ TEST(document_load_stream_text)
103
+ {
104
+ xml_document doc;
105
+
106
+ std::ifstream iss("tests/data/multiline.xml");
107
+ CHECK(doc.load(iss));
108
+ CHECK_NODE(doc, STR("<node1/><node2/><node3/>"));
109
+ }
110
+
111
+ TEST(document_load_stream_error)
112
+ {
113
+ xml_document doc;
114
+
115
+ std::ifstream fs("filedoesnotexist");
116
+ CHECK(doc.load(fs).status == status_io_error);
117
+ }
118
+
119
+ TEST(document_load_stream_out_of_memory)
120
+ {
121
+ xml_document doc;
122
+
123
+ std::istringstream iss("<node/>");
124
+ test_runner::_memory_fail_threshold = 1;
125
+ CHECK_ALLOC_FAIL(CHECK(doc.load(iss).status == status_out_of_memory));
126
+ }
127
+
128
+ TEST(document_load_stream_wide_out_of_memory)
129
+ {
130
+ xml_document doc;
131
+
132
+ std::basic_istringstream<wchar_t> iss(L"<node/>");
133
+ test_runner::_memory_fail_threshold = 1;
134
+ CHECK_ALLOC_FAIL(CHECK(doc.load(iss).status == status_out_of_memory));
135
+ }
136
+
137
+ TEST(document_load_stream_empty)
138
+ {
139
+ std::istringstream iss;
140
+
141
+ xml_document doc;
142
+ doc.load(iss); // parse result depends on STL implementation
143
+ CHECK(!doc.first_child());
144
+ }
145
+
146
+ TEST(document_load_stream_wide)
147
+ {
148
+ xml_document doc;
149
+
150
+ std::basic_istringstream<wchar_t> iss(L"<node/>");
151
+ CHECK(doc.load(iss));
152
+ CHECK_NODE(doc, STR("<node/>"));
153
+ }
154
+
155
+ #ifndef PUGIXML_NO_EXCEPTIONS
156
+ TEST(document_load_stream_exceptions)
157
+ {
158
+ xml_document doc;
159
+
160
+ // Windows has newline translation for text-mode files, so reading from this stream reaches eof and sets fail|eof bits.
161
+ // This test does not cause stream to throw an exception on Linux - I have no idea how to get read() to fail except
162
+ // newline translation.
163
+ std::ifstream iss("tests/data/multiline.xml");
164
+ iss.exceptions(std::ios::eofbit | std::ios::badbit | std::ios::failbit);
165
+
166
+ try
167
+ {
168
+ doc.load(iss);
169
+
170
+ CHECK(iss.good()); // if the exception was not thrown, stream reading should succeed without errors
171
+ }
172
+ catch (const std::ios_base::failure&)
173
+ {
174
+ CHECK(!doc.first_child());
175
+ }
176
+ }
177
+ #endif
178
+
179
+ TEST(document_load_stream_error_previous)
180
+ {
181
+ xml_document doc;
182
+ CHECK(doc.load_string(STR("<node/>")));
183
+ CHECK(doc.first_child());
184
+
185
+ std::ifstream fs1("filedoesnotexist");
186
+ CHECK(doc.load(fs1).status == status_io_error);
187
+ CHECK(!doc.first_child());
188
+ }
189
+
190
+ TEST(document_load_stream_wide_error_previous)
191
+ {
192
+ xml_document doc;
193
+ CHECK(doc.load_string(STR("<node/>")));
194
+ CHECK(doc.first_child());
195
+
196
+ std::basic_ifstream<wchar_t> fs1("filedoesnotexist");
197
+ CHECK(doc.load(fs1).status == status_io_error);
198
+ CHECK(!doc.first_child());
199
+ }
200
+
201
+ template <typename T> class char_array_buffer: public std::basic_streambuf<T>
202
+ {
203
+ public:
204
+ char_array_buffer(T* begin, T* end)
205
+ {
206
+ this->setg(begin, begin, end);
207
+ }
208
+ };
209
+
210
+ TEST(document_load_stream_nonseekable)
211
+ {
212
+ char contents[] = "<node />";
213
+ char_array_buffer<char> buffer(contents, contents + sizeof(contents) / sizeof(contents[0]));
214
+ std::istream in(&buffer);
215
+
216
+ xml_document doc;
217
+ CHECK(doc.load(in));
218
+ CHECK_NODE(doc, STR("<node/>"));
219
+ }
220
+
221
+ TEST(document_load_stream_wide_nonseekable)
222
+ {
223
+ wchar_t contents[] = L"<node />";
224
+ char_array_buffer<wchar_t> buffer(contents, contents + sizeof(contents) / sizeof(contents[0]));
225
+ std::basic_istream<wchar_t> in(&buffer);
226
+
227
+ xml_document doc;
228
+ CHECK(doc.load(in));
229
+ CHECK_NODE(doc, STR("<node/>"));
230
+ }
231
+
232
+ TEST(document_load_stream_nonseekable_large)
233
+ {
234
+ std::basic_string<char_t> str;
235
+ str += STR("<node>");
236
+ for (int i = 0; i < 10000; ++i) str += STR("<node/>");
237
+ str += STR("</node>");
238
+
239
+ char_array_buffer<char_t> buffer(&str[0], &str[0] + str.length());
240
+ std::basic_istream<char_t> in(&buffer);
241
+
242
+ xml_document doc;
243
+ CHECK(doc.load(in));
244
+ CHECK_NODE(doc, str.c_str());
245
+ }
246
+
247
+ TEST(document_load_stream_nonseekable_out_of_memory)
248
+ {
249
+ char contents[] = "<node />";
250
+ char_array_buffer<char> buffer(contents, contents + sizeof(contents) / sizeof(contents[0]));
251
+ std::istream in(&buffer);
252
+
253
+ test_runner::_memory_fail_threshold = 1;
254
+
255
+ xml_document doc;
256
+ CHECK_ALLOC_FAIL(CHECK(doc.load(in).status == status_out_of_memory));
257
+ }
258
+
259
+ TEST(document_load_stream_wide_nonseekable_out_of_memory)
260
+ {
261
+ wchar_t contents[] = L"<node />";
262
+ char_array_buffer<wchar_t> buffer(contents, contents + sizeof(contents) / sizeof(contents[0]));
263
+ std::basic_istream<wchar_t> in(&buffer);
264
+
265
+ test_runner::_memory_fail_threshold = 1;
266
+
267
+ xml_document doc;
268
+ CHECK_ALLOC_FAIL(CHECK(doc.load(in).status == status_out_of_memory));
269
+ }
270
+
271
+ TEST(document_load_stream_nonseekable_out_of_memory_large)
272
+ {
273
+ std::basic_string<char> str;
274
+ str += "<node>";
275
+ for (int i = 0; i < 10000; ++i) str += "<node />";
276
+ str += "</node>";
277
+
278
+ char_array_buffer<char> buffer(&str[0], &str[0] + str.length());
279
+ std::basic_istream<char> in(&buffer);
280
+
281
+ test_runner::_memory_fail_threshold = 32768 * 3 + 4096;
282
+
283
+ xml_document doc;
284
+ CHECK_ALLOC_FAIL(CHECK(doc.load(in).status == status_out_of_memory));
285
+ }
286
+
287
+ TEST(document_load_stream_wide_nonseekable_out_of_memory_large)
288
+ {
289
+ std::basic_string<wchar_t> str;
290
+ str += L"<node>";
291
+ for (int i = 0; i < 10000; ++i) str += L"<node />";
292
+ str += L"</node>";
293
+
294
+ char_array_buffer<wchar_t> buffer(&str[0], &str[0] + str.length());
295
+ std::basic_istream<wchar_t> in(&buffer);
296
+
297
+ test_runner::_memory_fail_threshold = 32768 * 3 * sizeof(wchar_t) + 4096;
298
+
299
+ xml_document doc;
300
+ CHECK_ALLOC_FAIL(CHECK(doc.load(in).status == status_out_of_memory));
301
+ }
302
+
303
+ template <typename T> class seek_fail_buffer: public std::basic_streambuf<T>
304
+ {
305
+ public:
306
+ int seeks;
307
+
308
+ seek_fail_buffer(): seeks(0)
309
+ {
310
+ }
311
+
312
+ typename std::basic_streambuf<T>::pos_type seekoff(typename std::basic_streambuf<T>::off_type, std::ios_base::seekdir, std::ios_base::openmode) PUGIXML_OVERRIDE
313
+ {
314
+ seeks++;
315
+
316
+ // pretend that our buffer is seekable (this is called by tellg)
317
+ return seeks == 1 ? 0 : -1;
318
+ }
319
+ };
320
+
321
+ TEST(document_load_stream_seekable_fail_seek)
322
+ {
323
+ seek_fail_buffer<char> buffer;
324
+ std::basic_istream<char> in(&buffer);
325
+
326
+ xml_document doc;
327
+ CHECK(doc.load(in).status == status_io_error);
328
+ }
329
+
330
+ TEST(document_load_stream_wide_seekable_fail_seek)
331
+ {
332
+ seek_fail_buffer<wchar_t> buffer;
333
+ std::basic_istream<wchar_t> in(&buffer);
334
+
335
+ xml_document doc;
336
+ CHECK(doc.load(in).status == status_io_error);
337
+ }
338
+
339
+ template <typename T> class tell_fail_buffer: public std::basic_streambuf<T>
340
+ {
341
+ public:
342
+ int seeks;
343
+
344
+ tell_fail_buffer(): seeks(0)
345
+ {
346
+ }
347
+
348
+ typename std::basic_streambuf<T>::pos_type seekoff(typename std::basic_streambuf<T>::off_type, std::ios_base::seekdir dir, std::ios_base::openmode) PUGIXML_OVERRIDE
349
+ {
350
+ seeks++;
351
+
352
+ return seeks > 1 && dir == std::ios_base::cur ? -1 : 0;
353
+ }
354
+
355
+ typename std::basic_streambuf<T>::pos_type seekpos(typename std::basic_streambuf<T>::pos_type, std::ios_base::openmode) PUGIXML_OVERRIDE
356
+ {
357
+ return 0;
358
+ }
359
+ };
360
+
361
+ TEST(document_load_stream_seekable_fail_tell)
362
+ {
363
+ tell_fail_buffer<char> buffer;
364
+ std::basic_istream<char> in(&buffer);
365
+
366
+ xml_document doc;
367
+ CHECK(doc.load(in).status == status_io_error);
368
+ }
369
+
370
+ TEST(document_load_stream_wide_seekable_fail_tell)
371
+ {
372
+ tell_fail_buffer<wchar_t> buffer;
373
+ std::basic_istream<wchar_t> in(&buffer);
374
+
375
+ xml_document doc;
376
+ CHECK(doc.load(in).status == status_io_error);
377
+ }
378
+
379
+ #ifndef PUGIXML_NO_EXCEPTIONS
380
+ template <typename T> class read_fail_buffer: public std::basic_streambuf<T>
381
+ {
382
+ public:
383
+ typename std::basic_streambuf<T>::int_type underflow() PUGIXML_OVERRIDE
384
+ {
385
+ throw std::runtime_error("underflow failed");
386
+
387
+ #ifdef __DMC__
388
+ return 0;
389
+ #endif
390
+ }
391
+ };
392
+
393
+ TEST(document_load_stream_nonseekable_fail_read)
394
+ {
395
+ read_fail_buffer<char> buffer;
396
+ std::basic_istream<char> in(&buffer);
397
+
398
+ xml_document doc;
399
+ CHECK(doc.load(in).status == status_io_error);
400
+ }
401
+
402
+ TEST(document_load_stream_wide_nonseekable_fail_read)
403
+ {
404
+ read_fail_buffer<wchar_t> buffer;
405
+ std::basic_istream<wchar_t> in(&buffer);
406
+
407
+ xml_document doc;
408
+ CHECK(doc.load(in).status == status_io_error);
409
+ }
410
+
411
+ template <typename T> class read_fail_seekable_buffer: public std::basic_streambuf<T>
412
+ {
413
+ public:
414
+ typename std::basic_streambuf<T>::pos_type offset;
415
+
416
+ read_fail_seekable_buffer(): offset(0)
417
+ {
418
+ }
419
+
420
+ typename std::basic_streambuf<T>::int_type underflow() PUGIXML_OVERRIDE
421
+ {
422
+ throw std::runtime_error("underflow failed");
423
+
424
+ #ifdef __DMC__
425
+ return 0;
426
+ #endif
427
+ }
428
+
429
+ typename std::basic_streambuf<T>::pos_type seekoff(typename std::basic_streambuf<T>::off_type off, std::ios_base::seekdir dir, std::ios_base::openmode) PUGIXML_OVERRIDE
430
+ {
431
+ switch (dir)
432
+ {
433
+ case std::ios_base::beg: offset = off; break;
434
+ case std::ios_base::cur: offset += off; break;
435
+ case std::ios_base::end: offset = 16 + off; break;
436
+ default: ;
437
+ }
438
+ return offset;
439
+ }
440
+
441
+ typename std::basic_streambuf<T>::pos_type seekpos(typename std::basic_streambuf<T>::pos_type pos, std::ios_base::openmode) PUGIXML_OVERRIDE
442
+ {
443
+ offset = pos;
444
+ return pos;
445
+ }
446
+ };
447
+
448
+ TEST(document_load_stream_seekable_fail_read)
449
+ {
450
+ read_fail_seekable_buffer<char> buffer;
451
+ std::basic_istream<char> in(&buffer);
452
+
453
+ xml_document doc;
454
+ CHECK(doc.load(in).status == status_io_error);
455
+ }
456
+
457
+ TEST(document_load_stream_wide_seekable_fail_read)
458
+ {
459
+ read_fail_seekable_buffer<wchar_t> buffer;
460
+ std::basic_istream<wchar_t> in(&buffer);
461
+
462
+ xml_document doc;
463
+ CHECK(doc.load(in).status == status_io_error);
464
+ }
465
+ #endif
466
+ #endif
467
+
468
+ TEST(document_load_string)
469
+ {
470
+ xml_document doc;
471
+
472
+ CHECK(doc.load_string(STR("<node/>")));
473
+ CHECK_NODE(doc, STR("<node/>"));
474
+ }
475
+
476
+ TEST(document_load_string_empty)
477
+ {
478
+ xml_document doc;
479
+
480
+ CHECK(doc.load_string(STR("")).status == status_no_document_element);
481
+ CHECK(!doc.first_child());
482
+
483
+ CHECK(doc.load_string(STR(""), parse_fragment));
484
+ CHECK(!doc.first_child());
485
+ }
486
+
487
+ TEST(document_load_file)
488
+ {
489
+ xml_document doc;
490
+
491
+ CHECK(doc.load_file("tests/data/small.xml"));
492
+ CHECK_NODE(doc, STR("<node/>"));
493
+ }
494
+
495
+ TEST(document_load_file_empty)
496
+ {
497
+ xml_document doc;
498
+
499
+ CHECK(doc.load_file("tests/data/empty.xml").status == status_no_document_element);
500
+ CHECK(!doc.first_child());
501
+ }
502
+
503
+ TEST(document_load_file_large)
504
+ {
505
+ xml_document doc;
506
+
507
+ CHECK(doc.load_file("tests/data/large.xml"));
508
+
509
+ std::basic_string<char_t> str;
510
+ str += STR("<node>");
511
+ for (int i = 0; i < 10000; ++i) str += STR("<node/>");
512
+ str += STR("</node>");
513
+
514
+ CHECK_NODE(doc, str.c_str());
515
+ }
516
+
517
+ TEST(document_load_file_error)
518
+ {
519
+ xml_document doc;
520
+
521
+ CHECK(doc.load_file("filedoesnotexist").status == status_file_not_found);
522
+ }
523
+
524
+ TEST(document_load_file_out_of_memory)
525
+ {
526
+ test_runner::_memory_fail_threshold = 1;
527
+
528
+ xml_document doc;
529
+ CHECK_ALLOC_FAIL(CHECK(doc.load_file("tests/data/small.xml").status == status_out_of_memory));
530
+ }
531
+
532
+ TEST(document_load_file_out_of_memory_file_leak)
533
+ {
534
+ test_runner::_memory_fail_threshold = 1;
535
+
536
+ xml_document doc;
537
+
538
+ for (int i = 0; i < 256; ++i)
539
+ CHECK_ALLOC_FAIL(CHECK(doc.load_file("tests/data/small.xml").status == status_out_of_memory));
540
+
541
+ test_runner::_memory_fail_threshold = 0;
542
+
543
+ CHECK(doc.load_file("tests/data/small.xml"));
544
+ CHECK_NODE(doc, STR("<node/>"));
545
+ }
546
+
547
+ TEST(document_load_file_wide_out_of_memory_file_leak)
548
+ {
549
+ test_runner::_memory_fail_threshold = 256;
550
+
551
+ xml_document doc;
552
+
553
+ for (int i = 0; i < 256; ++i)
554
+ CHECK_ALLOC_FAIL(CHECK(doc.load_file(L"tests/data/small.xml").status == status_out_of_memory));
555
+
556
+ test_runner::_memory_fail_threshold = 0;
557
+
558
+ CHECK(doc.load_file(L"tests/data/small.xml"));
559
+ CHECK_NODE(doc, STR("<node/>"));
560
+ }
561
+
562
+ TEST(document_load_file_error_previous)
563
+ {
564
+ xml_document doc;
565
+ CHECK(doc.load_string(STR("<node/>")));
566
+ CHECK(doc.first_child());
567
+
568
+ CHECK(doc.load_file("filedoesnotexist").status == status_file_not_found);
569
+ CHECK(!doc.first_child());
570
+ }
571
+
572
+ TEST(document_load_file_wide_ascii)
573
+ {
574
+ xml_document doc;
575
+
576
+ CHECK(doc.load_file(L"tests/data/small.xml"));
577
+ CHECK_NODE(doc, STR("<node/>"));
578
+ }
579
+
580
+ #if !defined(__DMC__) && !defined(__MWERKS__) && !(defined(__MINGW32__) && defined(__STRICT_ANSI__) && !defined(__MINGW64_VERSION_MAJOR)) && !defined(__BORLANDC__)
581
+ TEST(document_load_file_wide_unicode)
582
+ {
583
+ xml_document doc;
584
+
585
+ CHECK(doc.load_file(L"tests/data/\x0442\x0435\x0441\x0442.xml"));
586
+ CHECK_NODE(doc, STR("<node/>"));
587
+ }
588
+ #endif
589
+
590
+ TEST(document_load_file_wide_out_of_memory)
591
+ {
592
+ test_runner::_memory_fail_threshold = 1;
593
+
594
+ xml_document doc;
595
+
596
+ xml_parse_result result;
597
+ result.status = status_out_of_memory;
598
+ CHECK_ALLOC_FAIL(result = doc.load_file(L"tests/data/small.xml"));
599
+
600
+ CHECK(result.status == status_out_of_memory || result.status == status_file_not_found);
601
+ }
602
+
603
+ #if defined(__linux__) || defined(__APPLE__)
604
+ TEST(document_load_file_special_folder)
605
+ {
606
+ xml_document doc;
607
+ xml_parse_result result = doc.load_file(".");
608
+ CHECK(result.status == status_io_error);
609
+ }
610
+ #endif
611
+
612
+ #if defined(__linux__)
613
+ TEST(document_load_file_special_device)
614
+ {
615
+ xml_document doc;
616
+ xml_parse_result result = doc.load_file("/dev/tty");
617
+ CHECK(result.status == status_file_not_found || result.status == status_io_error);
618
+ }
619
+
620
+ TEST(document_load_file_special_sysfs)
621
+ {
622
+ xml_document doc;
623
+ xml_parse_result result = doc.load_file("/sys/kernel/fscaps");
624
+ CHECK(result.status == status_file_not_found || result.status == status_io_error);
625
+ }
626
+ #endif
627
+
628
+ TEST_XML(document_save, "<node/>")
629
+ {
630
+ xml_writer_string writer;
631
+
632
+ doc.save(writer, STR(""), format_no_declaration | format_raw, get_native_encoding());
633
+
634
+ CHECK(writer.as_string() == STR("<node/>"));
635
+ }
636
+
637
+ #ifndef PUGIXML_NO_STL
638
+ TEST_XML(document_save_stream, "<node/>")
639
+ {
640
+ std::ostringstream oss;
641
+
642
+ doc.save(oss, STR(""), format_no_declaration | format_raw);
643
+
644
+ CHECK(oss.str() == "<node/>");
645
+ }
646
+
647
+ TEST_XML(document_save_stream_wide, "<node/>")
648
+ {
649
+ std::basic_ostringstream<wchar_t> oss;
650
+
651
+ doc.save(oss, STR(""), format_no_declaration | format_raw);
652
+
653
+ CHECK(oss.str() == L"<node/>");
654
+ }
655
+ #endif
656
+
657
+ TEST_XML(document_save_bom, "<n/>")
658
+ {
659
+ unsigned int flags = format_no_declaration | format_raw | format_write_bom;
660
+
661
+ // specific encodings
662
+ CHECK(test_save_narrow(doc, flags, encoding_utf8, "\xef\xbb\xbf<n/>", 7));
663
+ CHECK(test_save_narrow(doc, flags, encoding_utf16_be, "\xfe\xff\x00<\x00n\x00/\x00>", 10));
664
+ CHECK(test_save_narrow(doc, flags, encoding_utf16_le, "\xff\xfe<\x00n\x00/\x00>\x00", 10));
665
+ CHECK(test_save_narrow(doc, flags, encoding_utf32_be, "\x00\x00\xfe\xff\x00\x00\x00<\x00\x00\x00n\x00\x00\x00/\x00\x00\x00>", 20));
666
+ CHECK(test_save_narrow(doc, flags, encoding_utf32_le, "\xff\xfe\x00\x00<\x00\x00\x00n\x00\x00\x00/\x00\x00\x00>\x00\x00\x00", 20));
667
+ CHECK(test_save_narrow(doc, flags, encoding_latin1, "<n/>", 4));
668
+
669
+ // encodings synonyms
670
+ CHECK(save_narrow(doc, flags, encoding_utf16) == save_narrow(doc, flags, (is_little_endian() ? encoding_utf16_le : encoding_utf16_be)));
671
+ CHECK(save_narrow(doc, flags, encoding_utf32) == save_narrow(doc, flags, (is_little_endian() ? encoding_utf32_le : encoding_utf32_be)));
672
+
673
+ size_t wcharsize = sizeof(wchar_t);
674
+ CHECK(save_narrow(doc, flags, encoding_wchar) == save_narrow(doc, flags, (wcharsize == 2 ? encoding_utf16 : encoding_utf32)));
675
+ }
676
+
677
+ TEST_XML(document_save_declaration, "<node/>")
678
+ {
679
+ xml_writer_string writer;
680
+
681
+ doc.save(writer, STR(""), format_default, get_native_encoding());
682
+
683
+ CHECK(writer.as_string() == STR("<?xml version=\"1.0\"?>\n<node />\n"));
684
+ }
685
+
686
+ TEST(document_save_declaration_empty)
687
+ {
688
+ xml_document doc;
689
+
690
+ xml_writer_string writer;
691
+
692
+ doc.save(writer, STR(""), format_default, get_native_encoding());
693
+
694
+ CHECK(writer.as_string() == STR("<?xml version=\"1.0\"?>\n"));
695
+ }
696
+
697
+ TEST_XML(document_save_declaration_present_first, "<node/>")
698
+ {
699
+ doc.insert_child_before(node_declaration, doc.first_child()).append_attribute(STR("encoding")) = STR("utf8");
700
+
701
+ xml_writer_string writer;
702
+
703
+ doc.save(writer, STR(""), format_default, get_native_encoding());
704
+
705
+ CHECK(writer.as_string() == STR("<?xml encoding=\"utf8\"?>\n<node />\n"));
706
+ }
707
+
708
+ TEST_XML(document_save_declaration_present_second, "<node/>")
709
+ {
710
+ doc.insert_child_before(node_declaration, doc.first_child()).append_attribute(STR("encoding")) = STR("utf8");
711
+ doc.insert_child_before(node_comment, doc.first_child()).set_value(STR("text"));
712
+
713
+ xml_writer_string writer;
714
+
715
+ doc.save(writer, STR(""), format_default, get_native_encoding());
716
+
717
+ CHECK(writer.as_string() == STR("<!--text-->\n<?xml encoding=\"utf8\"?>\n<node />\n"));
718
+ }
719
+
720
+ TEST_XML(document_save_declaration_present_last, "<node/>")
721
+ {
722
+ doc.append_child(node_declaration).append_attribute(STR("encoding")) = STR("utf8");
723
+
724
+ xml_writer_string writer;
725
+
726
+ doc.save(writer, STR(""), format_default, get_native_encoding());
727
+
728
+ // node writer only looks for declaration before the first element child
729
+ CHECK(writer.as_string() == STR("<?xml version=\"1.0\"?>\n<node />\n<?xml encoding=\"utf8\"?>\n"));
730
+ }
731
+
732
+ TEST_XML(document_save_declaration_latin1, "<node/>")
733
+ {
734
+ xml_writer_string writer;
735
+
736
+ doc.save(writer, STR(""), format_default, encoding_latin1);
737
+
738
+ CHECK(writer.as_narrow() == "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n<node />\n");
739
+ }
740
+
741
+ TEST_XML(document_save_declaration_raw, "<node/>")
742
+ {
743
+ xml_writer_string writer;
744
+
745
+ doc.save(writer, STR(""), format_raw, get_native_encoding());
746
+
747
+ CHECK(writer.as_string() == STR("<?xml version=\"1.0\"?><node/>"));
748
+ }
749
+
750
+ struct temp_file
751
+ {
752
+ char path[512];
753
+
754
+ temp_file()
755
+ {
756
+ static int index = 0;
757
+
758
+ #if __cplusplus >= 201103 || defined(__APPLE__) // Xcode 14 warns about use of sprintf in C++98 builds
759
+ snprintf(path, sizeof(path), "%stempfile%d", test_runner::_temp_path, index++);
760
+ #else
761
+ sprintf(path, "%stempfile%d", test_runner::_temp_path, index++);
762
+ #endif
763
+ }
764
+
765
+ ~temp_file()
766
+ {
767
+ #ifndef _WIN32_WCE
768
+ CHECK(unlink(path) == 0);
769
+ #endif
770
+ }
771
+ };
772
+
773
+ TEST_XML(document_save_file, "<node/>")
774
+ {
775
+ temp_file f;
776
+
777
+ CHECK(doc.save_file(f.path));
778
+
779
+ CHECK(doc.load_file(f.path, parse_default | parse_declaration));
780
+ CHECK_NODE(doc, STR("<?xml version=\"1.0\"?><node/>"));
781
+ }
782
+
783
+ TEST_XML(document_save_file_wide, "<node/>")
784
+ {
785
+ temp_file f;
786
+
787
+ // widen the path
788
+ wchar_t wpath[sizeof(f.path)];
789
+ std::copy(f.path, f.path + strlen(f.path) + 1, wpath + 0);
790
+
791
+ CHECK(doc.save_file(wpath));
792
+
793
+ CHECK(doc.load_file(f.path, parse_default | parse_declaration));
794
+ CHECK_NODE(doc, STR("<?xml version=\"1.0\"?><node/>"));
795
+ }
796
+
797
+ TEST_XML(document_save_file_error, "<node/>")
798
+ {
799
+ CHECK(!doc.save_file("tests/data/unknown/output.xml"));
800
+ }
801
+
802
+ TEST_XML(document_save_file_text, "<node/>")
803
+ {
804
+ temp_file f;
805
+
806
+ CHECK(doc.save_file(f.path, STR(""), format_no_declaration | format_save_file_text));
807
+ CHECK(test_file_contents(f.path, "<node />\n", 9) || test_file_contents(f.path, "<node />\r\n", 10));
808
+
809
+ CHECK(doc.save_file(f.path, STR(""), format_no_declaration));
810
+ CHECK(test_file_contents(f.path, "<node />\n", 9));
811
+ }
812
+
813
+ TEST_XML(document_save_file_wide_text, "<node/>")
814
+ {
815
+ temp_file f;
816
+
817
+ // widen the path
818
+ wchar_t wpath[sizeof(f.path)];
819
+ std::copy(f.path, f.path + strlen(f.path) + 1, wpath + 0);
820
+
821
+ CHECK(doc.save_file(wpath, STR(""), format_no_declaration | format_save_file_text));
822
+ CHECK(test_file_contents(f.path, "<node />\n", 9) || test_file_contents(f.path, "<node />\r\n", 10));
823
+
824
+ CHECK(doc.save_file(wpath, STR(""), format_no_declaration));
825
+ CHECK(test_file_contents(f.path, "<node />\n", 9));
826
+ }
827
+
828
+ TEST_XML(document_save_file_leak, "<node/>")
829
+ {
830
+ temp_file f;
831
+
832
+ for (int i = 0; i < 256; ++i)
833
+ CHECK(doc.save_file(f.path));
834
+ }
835
+
836
+ TEST_XML(document_save_file_wide_leak, "<node/>")
837
+ {
838
+ temp_file f;
839
+
840
+ // widen the path
841
+ wchar_t wpath[sizeof(f.path)];
842
+ std::copy(f.path, f.path + strlen(f.path) + 1, wpath + 0);
843
+
844
+ for (int i = 0; i < 256; ++i)
845
+ CHECK(doc.save_file(wpath));
846
+ }
847
+
848
+ TEST(document_load_buffer)
849
+ {
850
+ const char_t text[] = STR("<?xml?><node/>");
851
+
852
+ xml_document doc;
853
+
854
+ CHECK(doc.load_buffer(text, sizeof(text)));
855
+ CHECK_NODE(doc, STR("<node/>"));
856
+ }
857
+
858
+ TEST(document_load_buffer_inplace)
859
+ {
860
+ char_t text[] = STR("<?xml?><node/>");
861
+
862
+ xml_document doc;
863
+
864
+ CHECK(doc.load_buffer_inplace(text, sizeof(text)));
865
+ CHECK_NODE(doc, STR("<node/>"));
866
+ }
867
+
868
+ TEST(document_load_buffer_inplace_own)
869
+ {
870
+ allocation_function alloc = get_memory_allocation_function();
871
+
872
+ size_t size = strlen("<?xml?><node/>") * sizeof(char_t);
873
+
874
+ char_t* text = static_cast<char_t*>(alloc(size));
875
+ CHECK(text);
876
+
877
+ memcpy(text, STR("<?xml?><node/>"), size);
878
+
879
+ xml_document doc;
880
+
881
+ CHECK(doc.load_buffer_inplace_own(text, size));
882
+ CHECK_NODE(doc, STR("<node/>"));
883
+ }
884
+
885
+ TEST(document_load_buffer_inplace_own_empty)
886
+ {
887
+ allocation_function alloc = get_memory_allocation_function();
888
+
889
+ void* text1 = alloc(1);
890
+ void* text2 = alloc(1);
891
+ CHECK(text1 && text2);
892
+
893
+ xml_document doc;
894
+ CHECK(doc.load_buffer_inplace_own(text1, 0, parse_fragment));
895
+ CHECK(doc.load_buffer_inplace_own(text2, 0).status == status_no_document_element);
896
+ }
897
+
898
+ TEST(document_parse_result_bool)
899
+ {
900
+ xml_parse_result result;
901
+
902
+ result.status = status_ok;
903
+ CHECK(result);
904
+ CHECK(!!result);
905
+ CHECK(result == true);
906
+
907
+ for (int i = 1; i < 20; ++i)
908
+ {
909
+ result.status = static_cast<xml_parse_status>(i);
910
+ CHECK(!result);
911
+ CHECK(result == false);
912
+ }
913
+ }
914
+
915
+ TEST(document_parse_result_description)
916
+ {
917
+ xml_parse_result result;
918
+
919
+ for (int i = 0; i < 20; ++i)
920
+ {
921
+ result.status = static_cast<xml_parse_status>(i);
922
+
923
+ CHECK(result.description() != 0);
924
+ CHECK(result.description()[0] != 0);
925
+ }
926
+ }
927
+
928
+ TEST(document_load_fail)
929
+ {
930
+ xml_document doc;
931
+ CHECK(!doc.load_string(STR("<foo><bar/>")));
932
+ CHECK(doc.child(STR("foo")).child(STR("bar")));
933
+ }
934
+
935
+ inline void check_utftest_document(const xml_document& doc)
936
+ {
937
+ // ascii text
938
+ CHECK_STRING(doc.last_child().first_child().name(), STR("English"));
939
+
940
+ // check that we have parsed some non-ascii text
941
+ CHECK(static_cast<unsigned int>(doc.last_child().last_child().name()[0]) >= 0x80);
942
+
943
+ // check magic string
944
+ const char_t* v = doc.last_child().child(STR("Heavy")).previous_sibling().child_value();
945
+
946
+ #ifdef PUGIXML_WCHAR_MODE
947
+ CHECK(v[0] == 0x4e16 && v[1] == 0x754c && v[2] == 0x6709 && v[3] == 0x5f88 && v[4] == 0x591a && v[5] == wchar_cast(0x8bed) && v[6] == wchar_cast(0x8a00));
948
+
949
+ // last character is a surrogate pair
950
+ size_t wcharsize = sizeof(wchar_t);
951
+
952
+ CHECK(wcharsize == 2 ? (v[7] == wchar_cast(0xd852) && v[8] == wchar_cast(0xdf62)) : (v[7] == wchar_cast(0x24b62)));
953
+ #else
954
+ // unicode string
955
+ CHECK_STRING(v, "\xe4\xb8\x96\xe7\x95\x8c\xe6\x9c\x89\xe5\xbe\x88\xe5\xa4\x9a\xe8\xaf\xad\xe8\xa8\x80\xf0\xa4\xad\xa2");
956
+ #endif
957
+ }
958
+
959
+ TEST(document_load_file_convert_auto)
960
+ {
961
+ const char* files[] =
962
+ {
963
+ "tests/data/utftest_utf16_be.xml",
964
+ "tests/data/utftest_utf16_be_bom.xml",
965
+ "tests/data/utftest_utf16_be_nodecl.xml",
966
+ "tests/data/utftest_utf16_le.xml",
967
+ "tests/data/utftest_utf16_le_bom.xml",
968
+ "tests/data/utftest_utf16_le_nodecl.xml",
969
+ "tests/data/utftest_utf32_be.xml",
970
+ "tests/data/utftest_utf32_be_bom.xml",
971
+ "tests/data/utftest_utf32_be_nodecl.xml",
972
+ "tests/data/utftest_utf32_le.xml",
973
+ "tests/data/utftest_utf32_le_bom.xml",
974
+ "tests/data/utftest_utf32_le_nodecl.xml",
975
+ "tests/data/utftest_utf8.xml",
976
+ "tests/data/utftest_utf8_bom.xml",
977
+ "tests/data/utftest_utf8_nodecl.xml"
978
+ };
979
+
980
+ xml_encoding encodings[] =
981
+ {
982
+ encoding_utf16_be, encoding_utf16_be, encoding_utf16_be,
983
+ encoding_utf16_le, encoding_utf16_le, encoding_utf16_le,
984
+ encoding_utf32_be, encoding_utf32_be, encoding_utf32_be,
985
+ encoding_utf32_le, encoding_utf32_le, encoding_utf32_le,
986
+ encoding_utf8, encoding_utf8, encoding_utf8
987
+ };
988
+
989
+ for (unsigned int i = 0; i < sizeof(files) / sizeof(files[0]); ++i)
990
+ {
991
+ xml_document doc;
992
+ xml_parse_result res = doc.load_file(files[i]);
993
+
994
+ CHECK(res);
995
+ CHECK(res.encoding == encodings[i]);
996
+ check_utftest_document(doc);
997
+ }
998
+ }
999
+
1000
+ TEST(document_load_file_convert_specific)
1001
+ {
1002
+ const char* files[] =
1003
+ {
1004
+ "tests/data/utftest_utf16_be.xml",
1005
+ "tests/data/utftest_utf16_be_bom.xml",
1006
+ "tests/data/utftest_utf16_be_nodecl.xml",
1007
+ "tests/data/utftest_utf16_le.xml",
1008
+ "tests/data/utftest_utf16_le_bom.xml",
1009
+ "tests/data/utftest_utf16_le_nodecl.xml",
1010
+ "tests/data/utftest_utf32_be.xml",
1011
+ "tests/data/utftest_utf32_be_bom.xml",
1012
+ "tests/data/utftest_utf32_be_nodecl.xml",
1013
+ "tests/data/utftest_utf32_le.xml",
1014
+ "tests/data/utftest_utf32_le_bom.xml",
1015
+ "tests/data/utftest_utf32_le_nodecl.xml",
1016
+ "tests/data/utftest_utf8.xml",
1017
+ "tests/data/utftest_utf8_bom.xml",
1018
+ "tests/data/utftest_utf8_nodecl.xml"
1019
+ };
1020
+
1021
+ xml_encoding encodings[] =
1022
+ {
1023
+ encoding_utf16_be, encoding_utf16_be, encoding_utf16_be,
1024
+ encoding_utf16_le, encoding_utf16_le, encoding_utf16_le,
1025
+ encoding_utf32_be, encoding_utf32_be, encoding_utf32_be,
1026
+ encoding_utf32_le, encoding_utf32_le, encoding_utf32_le,
1027
+ encoding_utf8, encoding_utf8, encoding_utf8
1028
+ };
1029
+
1030
+ for (unsigned int i = 0; i < sizeof(files) / sizeof(files[0]); ++i)
1031
+ {
1032
+ for (unsigned int j = 0; j < sizeof(files) / sizeof(files[0]); ++j)
1033
+ {
1034
+ xml_encoding encoding = encodings[j];
1035
+
1036
+ xml_document doc;
1037
+ xml_parse_result res = doc.load_file(files[i], parse_default, encoding);
1038
+
1039
+ if (encoding == encodings[i])
1040
+ {
1041
+ CHECK(res);
1042
+ CHECK(res.encoding == encoding);
1043
+ check_utftest_document(doc);
1044
+ }
1045
+ else
1046
+ {
1047
+ // should not get past first tag
1048
+ CHECK(!doc.first_child());
1049
+ }
1050
+ }
1051
+ }
1052
+ }
1053
+
1054
+ TEST(document_load_file_convert_native_endianness)
1055
+ {
1056
+ const char* files[2][6] =
1057
+ {
1058
+ {
1059
+ "tests/data/utftest_utf16_be.xml",
1060
+ "tests/data/utftest_utf16_be_bom.xml",
1061
+ "tests/data/utftest_utf16_be_nodecl.xml",
1062
+ "tests/data/utftest_utf32_be.xml",
1063
+ "tests/data/utftest_utf32_be_bom.xml",
1064
+ "tests/data/utftest_utf32_be_nodecl.xml",
1065
+ },
1066
+ {
1067
+ "tests/data/utftest_utf16_le.xml",
1068
+ "tests/data/utftest_utf16_le_bom.xml",
1069
+ "tests/data/utftest_utf16_le_nodecl.xml",
1070
+ "tests/data/utftest_utf32_le.xml",
1071
+ "tests/data/utftest_utf32_le_bom.xml",
1072
+ "tests/data/utftest_utf32_le_nodecl.xml",
1073
+ }
1074
+ };
1075
+
1076
+ xml_encoding encodings[] =
1077
+ {
1078
+ encoding_utf16, encoding_utf16, encoding_utf16,
1079
+ encoding_utf32, encoding_utf32, encoding_utf32
1080
+ };
1081
+
1082
+ for (unsigned int i = 0; i < sizeof(files[0]) / sizeof(files[0][0]); ++i)
1083
+ {
1084
+ const char* right_file = files[is_little_endian()][i];
1085
+ const char* wrong_file = files[!is_little_endian()][i];
1086
+
1087
+ for (unsigned int j = 0; j < sizeof(encodings) / sizeof(encodings[0]); ++j)
1088
+ {
1089
+ xml_encoding encoding = encodings[j];
1090
+
1091
+ // check file with right endianness
1092
+ {
1093
+ xml_document doc;
1094
+ xml_parse_result res = doc.load_file(right_file, parse_default, encoding);
1095
+
1096
+ if (encoding == encodings[i])
1097
+ {
1098
+ CHECK(res);
1099
+ check_utftest_document(doc);
1100
+ }
1101
+ else
1102
+ {
1103
+ // should not get past first tag
1104
+ CHECK(!doc.first_child());
1105
+ }
1106
+ }
1107
+
1108
+ // check file with wrong endianness
1109
+ {
1110
+ xml_document doc;
1111
+ doc.load_file(wrong_file, parse_default, encoding);
1112
+ CHECK(!doc.first_child());
1113
+ }
1114
+ }
1115
+ }
1116
+ }
1117
+
1118
+ struct file_data_t
1119
+ {
1120
+ const char* path;
1121
+ xml_encoding encoding;
1122
+
1123
+ char* data;
1124
+ size_t size;
1125
+ };
1126
+
1127
+
1128
+ TEST(document_contents_preserve)
1129
+ {
1130
+ file_data_t files[] =
1131
+ {
1132
+ {"tests/data/utftest_utf16_be_clean.xml", encoding_utf16_be, 0, 0},
1133
+ {"tests/data/utftest_utf16_le_clean.xml", encoding_utf16_le, 0, 0},
1134
+ {"tests/data/utftest_utf32_be_clean.xml", encoding_utf32_be, 0, 0},
1135
+ {"tests/data/utftest_utf32_le_clean.xml", encoding_utf32_le, 0, 0},
1136
+ {"tests/data/utftest_utf8_clean.xml", encoding_utf8, 0, 0}
1137
+ };
1138
+
1139
+ // load files in memory
1140
+ for (unsigned int i = 0; i < sizeof(files) / sizeof(files[0]); ++i)
1141
+ {
1142
+ CHECK(load_file_in_memory(files[i].path, files[i].data, files[i].size));
1143
+ }
1144
+
1145
+ // convert each file to each format and compare bitwise
1146
+ for (unsigned int src = 0; src < sizeof(files) / sizeof(files[0]); ++src)
1147
+ {
1148
+ for (unsigned int dst = 0; dst < sizeof(files) / sizeof(files[0]); ++dst)
1149
+ {
1150
+ // parse into document (preserve comments, declaration and whitespace pcdata)
1151
+ xml_document doc;
1152
+ CHECK(doc.load_buffer(files[src].data, files[src].size, parse_default | parse_ws_pcdata | parse_declaration | parse_comments));
1153
+
1154
+ // compare saved document with the original (raw formatting, without extra declaration, write bom if it was in original file)
1155
+ CHECK(test_save_narrow(doc, format_raw | format_no_declaration | format_write_bom, files[dst].encoding, files[dst].data, files[dst].size));
1156
+ }
1157
+ }
1158
+
1159
+ // cleanup
1160
+ for (unsigned int j = 0; j < sizeof(files) / sizeof(files[0]); ++j)
1161
+ {
1162
+ delete[] files[j].data;
1163
+ }
1164
+ }
1165
+
1166
+ TEST(document_contents_preserve_latin1)
1167
+ {
1168
+ file_data_t files[] =
1169
+ {
1170
+ {"tests/data/latintest_utf8.xml", encoding_utf8, 0, 0},
1171
+ {"tests/data/latintest_latin1.xml", encoding_latin1, 0, 0}
1172
+ };
1173
+
1174
+ // load files in memory
1175
+ for (unsigned int i = 0; i < sizeof(files) / sizeof(files[0]); ++i)
1176
+ {
1177
+ CHECK(load_file_in_memory(files[i].path, files[i].data, files[i].size));
1178
+ }
1179
+
1180
+ // convert each file to each format and compare bitwise
1181
+ for (unsigned int src = 0; src < sizeof(files) / sizeof(files[0]); ++src)
1182
+ {
1183
+ for (unsigned int dst = 0; dst < sizeof(files) / sizeof(files[0]); ++dst)
1184
+ {
1185
+ // parse into document (preserve comments, declaration and whitespace pcdata)
1186
+ xml_document doc;
1187
+ CHECK(doc.load_buffer(files[src].data, files[src].size, parse_default | parse_ws_pcdata | parse_declaration | parse_comments));
1188
+
1189
+ // compare saved document with the original (raw formatting, without extra declaration, write bom if it was in original file)
1190
+ CHECK(test_save_narrow(doc, format_raw | format_no_declaration | format_write_bom, files[dst].encoding, files[dst].data, files[dst].size));
1191
+ }
1192
+ }
1193
+
1194
+ // cleanup
1195
+ for (unsigned int j = 0; j < sizeof(files) / sizeof(files[0]); ++j)
1196
+ {
1197
+ delete[] files[j].data;
1198
+ }
1199
+ }
1200
+
1201
+ static bool test_parse_fail(const void* buffer, size_t size, xml_encoding encoding = encoding_utf8)
1202
+ {
1203
+ // copy buffer to heap (to enable out-of-bounds checks)
1204
+ void* temp = malloc(size);
1205
+ memcpy(temp, buffer, size);
1206
+
1207
+ // check that this parses without buffer overflows (yielding an error)
1208
+ xml_document doc;
1209
+ bool result = doc.load_buffer_inplace(temp, size, parse_default, encoding);
1210
+
1211
+ free(temp);
1212
+
1213
+ return !result;
1214
+ }
1215
+
1216
+ TEST(document_convert_invalid_utf8)
1217
+ {
1218
+ // invalid 1-byte input
1219
+ CHECK(test_parse_fail("<\xb0", 2));
1220
+
1221
+ // invalid 2-byte input
1222
+ CHECK(test_parse_fail("<\xc0", 2));
1223
+ CHECK(test_parse_fail("<\xd0", 2));
1224
+
1225
+ // invalid 3-byte input
1226
+ CHECK(test_parse_fail("<\xe2\x80", 3));
1227
+ CHECK(test_parse_fail("<\xe2", 2));
1228
+
1229
+ // invalid 4-byte input
1230
+ CHECK(test_parse_fail("<\xf2\x97\x98", 4));
1231
+ CHECK(test_parse_fail("<\xf2\x97", 3));
1232
+ CHECK(test_parse_fail("<\xf2", 2));
1233
+
1234
+ // invalid 5-byte input
1235
+ CHECK(test_parse_fail("<\xf8", 2));
1236
+ }
1237
+
1238
+ TEST(document_convert_invalid_utf16)
1239
+ {
1240
+ // check non-terminated degenerate handling
1241
+ CHECK(test_parse_fail("\x00<\xda\x1d", 4, encoding_utf16_be));
1242
+ CHECK(test_parse_fail("<\x00\x1d\xda", 4, encoding_utf16_le));
1243
+
1244
+ // check incorrect leading code
1245
+ CHECK(test_parse_fail("\x00<\xde\x24", 4, encoding_utf16_be));
1246
+ CHECK(test_parse_fail("<\x00\x24\xde", 4, encoding_utf16_le));
1247
+ }
1248
+
1249
+ TEST(document_load_buffer_empty)
1250
+ {
1251
+ xml_encoding encodings[] =
1252
+ {
1253
+ encoding_auto,
1254
+ encoding_utf8,
1255
+ encoding_utf16_le,
1256
+ encoding_utf16_be,
1257
+ encoding_utf16,
1258
+ encoding_utf32_le,
1259
+ encoding_utf32_be,
1260
+ encoding_utf32,
1261
+ encoding_wchar,
1262
+ encoding_latin1
1263
+ };
1264
+
1265
+ char buffer[1];
1266
+
1267
+ for (unsigned int i = 0; i < sizeof(encodings) / sizeof(encodings[0]); ++i)
1268
+ {
1269
+ xml_encoding encoding = encodings[i];
1270
+
1271
+ xml_document doc;
1272
+ CHECK(doc.load_buffer(buffer, 0, parse_default, encoding).status == status_no_document_element && !doc.first_child());
1273
+ CHECK(doc.load_buffer(0, 0, parse_default, encoding).status == status_no_document_element && !doc.first_child());
1274
+
1275
+ CHECK(doc.load_buffer_inplace(buffer, 0, parse_default, encoding).status == status_no_document_element && !doc.first_child());
1276
+ CHECK(doc.load_buffer_inplace(0, 0, parse_default, encoding).status == status_no_document_element && !doc.first_child());
1277
+
1278
+ void* own_buffer = get_memory_allocation_function()(1);
1279
+
1280
+ CHECK(doc.load_buffer_inplace_own(own_buffer, 0, parse_default, encoding).status == status_no_document_element && !doc.first_child());
1281
+ CHECK(doc.load_buffer_inplace_own(0, 0, parse_default, encoding).status == status_no_document_element && !doc.first_child());
1282
+ }
1283
+ }
1284
+
1285
+ TEST(document_load_buffer_empty_fragment)
1286
+ {
1287
+ xml_encoding encodings[] =
1288
+ {
1289
+ encoding_auto,
1290
+ encoding_utf8,
1291
+ encoding_utf16_le,
1292
+ encoding_utf16_be,
1293
+ encoding_utf16,
1294
+ encoding_utf32_le,
1295
+ encoding_utf32_be,
1296
+ encoding_utf32,
1297
+ encoding_wchar,
1298
+ encoding_latin1
1299
+ };
1300
+
1301
+ char buffer[1];
1302
+
1303
+ for (unsigned int i = 0; i < sizeof(encodings) / sizeof(encodings[0]); ++i)
1304
+ {
1305
+ xml_encoding encoding = encodings[i];
1306
+
1307
+ xml_document doc;
1308
+ CHECK(doc.load_buffer(buffer, 0, parse_fragment, encoding) && !doc.first_child());
1309
+ CHECK(doc.load_buffer(0, 0, parse_fragment, encoding) && !doc.first_child());
1310
+
1311
+ CHECK(doc.load_buffer_inplace(buffer, 0, parse_fragment, encoding) && !doc.first_child());
1312
+ CHECK(doc.load_buffer_inplace(0, 0, parse_fragment, encoding) && !doc.first_child());
1313
+
1314
+ void* own_buffer = get_memory_allocation_function()(1);
1315
+
1316
+ CHECK(doc.load_buffer_inplace_own(own_buffer, 0, parse_fragment, encoding) && !doc.first_child());
1317
+ CHECK(doc.load_buffer_inplace_own(0, 0, parse_fragment, encoding) && !doc.first_child());
1318
+ }
1319
+ }
1320
+
1321
+ TEST(document_load_buffer_empty_encoding)
1322
+ {
1323
+ xml_document doc;
1324
+ xml_parse_result result = doc.load_buffer(0, 0, parse_fragment);
1325
+
1326
+ CHECK(result.status == status_ok);
1327
+ CHECK(result.encoding == encoding_utf8);
1328
+ }
1329
+
1330
+ TEST(document_load_buffer_null)
1331
+ {
1332
+ xml_document doc;
1333
+
1334
+ CHECK(doc.load_buffer(0, 12).status == status_io_error && !doc.first_child());
1335
+ CHECK(doc.load_buffer(0, 12, parse_fragment).status == status_io_error && !doc.first_child());
1336
+
1337
+ CHECK(doc.load_buffer_inplace(0, 12).status == status_io_error && !doc.first_child());
1338
+ CHECK(doc.load_buffer_inplace_own(0, 12).status == status_io_error && !doc.first_child());
1339
+ }
1340
+
1341
+ TEST(document_progressive_truncation)
1342
+ {
1343
+ char* original_data;
1344
+ size_t original_size;
1345
+
1346
+ CHECK(load_file_in_memory("tests/data/truncation.xml", original_data, original_size));
1347
+
1348
+ char* buffer = new char[original_size];
1349
+
1350
+ for (size_t i = 1; i <= original_size; ++i)
1351
+ {
1352
+ char* truncated_data = buffer + original_size - i;
1353
+
1354
+ // default flags
1355
+ {
1356
+ memcpy(truncated_data, original_data, i);
1357
+
1358
+ xml_document doc;
1359
+ bool result = doc.load_buffer_inplace(truncated_data, i);
1360
+
1361
+ // only eof is parseable
1362
+ CHECK((i == original_size) ? result : !result);
1363
+ }
1364
+
1365
+ // fragment mode
1366
+ {
1367
+ memcpy(truncated_data, original_data, i);
1368
+
1369
+ xml_document doc;
1370
+ bool result = doc.load_buffer_inplace(truncated_data, i, parse_default | parse_fragment);
1371
+
1372
+ // some truncate locations are parseable - those that come after declaration, declaration + doctype, declaration + doctype + comment and eof
1373
+ CHECK(((i >= 21 && i <= 23) || (i >= 66 && i <= 68) || (i >= 95 && i <= 97) || i == original_size) ? result : !result);
1374
+ }
1375
+ }
1376
+
1377
+ delete[] buffer;
1378
+ delete[] original_data;
1379
+ }
1380
+
1381
+ TEST(document_load_buffer_short)
1382
+ {
1383
+ char* data = new char[4];
1384
+ memcpy(data, "abcd", 4);
1385
+
1386
+ xml_document doc;
1387
+
1388
+ CHECK(doc.load_buffer(data, 4).status == status_no_document_element);
1389
+ CHECK(doc.load_buffer(data + 1, 3).status == status_no_document_element);
1390
+ CHECK(doc.load_buffer(data + 2, 2).status == status_no_document_element);
1391
+ CHECK(doc.load_buffer(data + 3, 1).status == status_no_document_element);
1392
+ CHECK(doc.load_buffer(data + 4, 0).status == status_no_document_element);
1393
+ CHECK(doc.load_buffer(0, 0).status == status_no_document_element);
1394
+
1395
+ delete[] data;
1396
+ }
1397
+
1398
+ TEST(document_load_buffer_short_fragment)
1399
+ {
1400
+ char* data = new char[4];
1401
+ memcpy(data, "abcd", 4);
1402
+
1403
+ xml_document doc;
1404
+
1405
+ CHECK(doc.load_buffer(data, 4, parse_fragment) && test_string_equal(doc.text().get(), STR("abcd")));
1406
+ CHECK(doc.load_buffer(data + 1, 3, parse_fragment) && test_string_equal(doc.text().get(), STR("bcd")));
1407
+ CHECK(doc.load_buffer(data + 2, 2, parse_fragment) && test_string_equal(doc.text().get(), STR("cd")));
1408
+ CHECK(doc.load_buffer(data + 3, 1, parse_fragment) && test_string_equal(doc.text().get(), STR("d")));
1409
+ CHECK(doc.load_buffer(data + 4, 0, parse_fragment) && !doc.first_child());
1410
+ CHECK(doc.load_buffer(0, 0, parse_fragment) && !doc.first_child());
1411
+
1412
+ delete[] data;
1413
+ }
1414
+
1415
+ TEST(document_load_buffer_inplace_short)
1416
+ {
1417
+ char* data = new char[4];
1418
+ memcpy(data, "abcd", 4);
1419
+
1420
+ xml_document doc;
1421
+
1422
+ CHECK(doc.load_buffer_inplace(data, 4).status == status_no_document_element);
1423
+ CHECK(doc.load_buffer_inplace(data + 1, 3).status == status_no_document_element);
1424
+ CHECK(doc.load_buffer_inplace(data + 2, 2).status == status_no_document_element);
1425
+ CHECK(doc.load_buffer_inplace(data + 3, 1).status == status_no_document_element);
1426
+ CHECK(doc.load_buffer_inplace(data + 4, 0).status == status_no_document_element);
1427
+ CHECK(doc.load_buffer_inplace(0, 0).status == status_no_document_element);
1428
+
1429
+ delete[] data;
1430
+ }
1431
+
1432
+ #ifndef PUGIXML_NO_EXCEPTIONS
1433
+ TEST(document_load_exceptions)
1434
+ {
1435
+ bool thrown = false;
1436
+
1437
+ try
1438
+ {
1439
+ xml_document doc;
1440
+ if (!doc.load_string(STR("<node attribute='value"))) throw std::bad_alloc();
1441
+
1442
+ CHECK_FORCE_FAIL("Expected parsing failure");
1443
+ }
1444
+ catch (const std::bad_alloc&)
1445
+ {
1446
+ thrown = true;
1447
+ }
1448
+
1449
+ CHECK(thrown);
1450
+ }
1451
+ #endif
1452
+
1453
+ TEST_XML_FLAGS(document_element, "<?xml version='1.0'?><node><child/></node><!---->", parse_default | parse_declaration | parse_comments)
1454
+ {
1455
+ CHECK(doc.document_element() == doc.child(STR("node")));
1456
+ }
1457
+
1458
+ TEST_XML_FLAGS(document_element_absent, "<!---->", parse_comments | parse_fragment)
1459
+ {
1460
+ CHECK(doc.document_element() == xml_node());
1461
+ }
1462
+
1463
+ TEST_XML(document_reset, "<node><child/></node>")
1464
+ {
1465
+ CHECK(doc.first_child());
1466
+
1467
+ doc.reset();
1468
+ CHECK(!doc.first_child());
1469
+ CHECK_NODE(doc, STR(""));
1470
+
1471
+ doc.reset();
1472
+ CHECK(!doc.first_child());
1473
+ CHECK_NODE(doc, STR(""));
1474
+
1475
+ CHECK(doc.load_string(STR("<node/>")));
1476
+ CHECK(doc.first_child());
1477
+ CHECK_NODE(doc, STR("<node/>"));
1478
+
1479
+ doc.reset();
1480
+ CHECK(!doc.first_child());
1481
+ CHECK_NODE(doc, STR(""));
1482
+ }
1483
+
1484
+ TEST(document_reset_empty)
1485
+ {
1486
+ xml_document doc;
1487
+
1488
+ doc.reset();
1489
+ CHECK(!doc.first_child());
1490
+ CHECK_NODE(doc, STR(""));
1491
+ }
1492
+
1493
+ TEST_XML(document_reset_copy, "<node><child/></node>")
1494
+ {
1495
+ xml_document doc2;
1496
+
1497
+ CHECK_NODE(doc2, STR(""));
1498
+
1499
+ doc2.reset(doc);
1500
+
1501
+ CHECK_NODE(doc2, STR("<node><child/></node>"));
1502
+ CHECK(doc.first_child() != doc2.first_child());
1503
+
1504
+ doc.reset(doc2);
1505
+
1506
+ CHECK_NODE(doc, STR("<node><child/></node>"));
1507
+ CHECK(doc.first_child() != doc2.first_child());
1508
+
1509
+ CHECK(doc.first_child().offset_debug() == -1);
1510
+ }
1511
+
1512
+ TEST_XML(document_reset_copy_self, "<node><child/></node>")
1513
+ {
1514
+ CHECK_NODE(doc, STR("<node><child/></node>"));
1515
+
1516
+ doc.reset(doc);
1517
+
1518
+ CHECK(!doc.first_child());
1519
+ CHECK_NODE(doc, STR(""));
1520
+ }
1521
+
1522
+ TEST(document_load_buffer_utf_truncated)
1523
+ {
1524
+ const unsigned char utf8[] = {'<', 0xe2, 0x82, 0xac, '/', '>'};
1525
+ const unsigned char utf16_be[] = {0, '<', 0x20, 0xac, 0, '/', 0, '>'};
1526
+ const unsigned char utf16_le[] = {'<', 0, 0xac, 0x20, '/', 0, '>', 0};
1527
+ const unsigned char utf32_be[] = {0, 0, 0, '<', 0, 0, 0x20, 0xac, 0, 0, 0, '/', 0, 0, 0, '>'};
1528
+ const unsigned char utf32_le[] = {'<', 0, 0, 0, 0xac, 0x20, 0, 0, '/', 0, 0, 0, '>', 0, 0, 0};
1529
+
1530
+ struct document_data_t
1531
+ {
1532
+ xml_encoding encoding;
1533
+
1534
+ const unsigned char* data;
1535
+ size_t size;
1536
+ };
1537
+
1538
+ const document_data_t data[] =
1539
+ {
1540
+ { encoding_utf8, utf8, sizeof(utf8) },
1541
+ { encoding_utf16_be, utf16_be, sizeof(utf16_be) },
1542
+ { encoding_utf16_le, utf16_le, sizeof(utf16_le) },
1543
+ { encoding_utf32_be, utf32_be, sizeof(utf32_be) },
1544
+ { encoding_utf32_le, utf32_le, sizeof(utf32_le) },
1545
+ };
1546
+
1547
+ for (size_t i = 0; i < sizeof(data) / sizeof(data[0]); ++i)
1548
+ {
1549
+ const document_data_t& d = data[i];
1550
+
1551
+ for (size_t j = 0; j <= d.size; ++j)
1552
+ {
1553
+ char* buffer = new char[j];
1554
+ memcpy(buffer, d.data, j);
1555
+
1556
+ xml_document doc;
1557
+ xml_parse_result res = doc.load_buffer(buffer, j, parse_default, d.encoding);
1558
+
1559
+ if (j == d.size)
1560
+ {
1561
+ CHECK(res);
1562
+
1563
+ const char_t* name = doc.first_child().name();
1564
+
1565
+ #ifdef PUGIXML_WCHAR_MODE
1566
+ CHECK(name[0] == 0x20ac && name[1] == 0);
1567
+ #else
1568
+ CHECK_STRING(name, "\xe2\x82\xac");
1569
+ #endif
1570
+ }
1571
+ else
1572
+ {
1573
+ CHECK(!res || !doc.first_child());
1574
+ }
1575
+
1576
+ delete[] buffer;
1577
+ }
1578
+ }
1579
+ }
1580
+
1581
+ #ifndef PUGIXML_NO_STL
1582
+ TEST(document_load_stream_truncated)
1583
+ {
1584
+ const unsigned char utf32_be[] = {0, 0, 0, '<', 0, 0, 0x20, 0xac, 0, 0, 0, '/', 0, 0, 0, '>'};
1585
+
1586
+ for (size_t i = 0; i <= sizeof(utf32_be); ++i)
1587
+ {
1588
+ std::string prefix(reinterpret_cast<const char*>(utf32_be), i);
1589
+ std::istringstream iss(prefix);
1590
+
1591
+ xml_document doc;
1592
+ xml_parse_result res = doc.load(iss);
1593
+
1594
+ if (i == sizeof(utf32_be))
1595
+ {
1596
+ CHECK(res);
1597
+ }
1598
+ else
1599
+ {
1600
+ CHECK(!res || !doc.first_child());
1601
+
1602
+ if (i < 8)
1603
+ {
1604
+ CHECK(!doc.first_child());
1605
+ }
1606
+ else
1607
+ {
1608
+ const char_t* name = doc.first_child().name();
1609
+
1610
+ #ifdef PUGIXML_WCHAR_MODE
1611
+ CHECK(name[0] == 0x20ac && name[1] == 0);
1612
+ #else
1613
+ CHECK_STRING(name, "\xe2\x82\xac");
1614
+ #endif
1615
+ }
1616
+ }
1617
+ }
1618
+ }
1619
+ #endif
1620
+
1621
+ TEST(document_alignment)
1622
+ {
1623
+ char buf[256 + sizeof(xml_document)];
1624
+
1625
+ for (size_t offset = 0; offset < 256; offset += sizeof(void*))
1626
+ {
1627
+ xml_document* doc = new (buf + offset) xml_document;
1628
+
1629
+ CHECK(doc->load_string(STR("<node />")));
1630
+ CHECK_NODE(*doc, STR("<node/>"));
1631
+
1632
+ doc->~xml_document();
1633
+ }
1634
+ }
1635
+
1636
+ TEST(document_convert_out_of_memory)
1637
+ {
1638
+ file_data_t files[] =
1639
+ {
1640
+ {"tests/data/utftest_utf16_be_clean.xml", encoding_utf16_be, 0, 0},
1641
+ {"tests/data/utftest_utf16_le_clean.xml", encoding_utf16_le, 0, 0},
1642
+ {"tests/data/utftest_utf32_be_clean.xml", encoding_utf32_be, 0, 0},
1643
+ {"tests/data/utftest_utf32_le_clean.xml", encoding_utf32_le, 0, 0},
1644
+ {"tests/data/utftest_utf8_clean.xml", encoding_utf8, 0, 0},
1645
+ {"tests/data/latintest_latin1.xml", encoding_latin1, 0, 0}
1646
+ };
1647
+
1648
+ // load files in memory
1649
+ for (unsigned int i = 0; i < sizeof(files) / sizeof(files[0]); ++i)
1650
+ {
1651
+ CHECK(load_file_in_memory(files[i].path, files[i].data, files[i].size));
1652
+ }
1653
+
1654
+ // disallow allocations
1655
+ test_runner::_memory_fail_threshold = 1;
1656
+
1657
+ for (unsigned int src = 0; src < sizeof(files) / sizeof(files[0]); ++src)
1658
+ {
1659
+ xml_document doc;
1660
+ CHECK_ALLOC_FAIL(CHECK(doc.load_buffer(files[src].data, files[src].size, parse_default, files[src].encoding).status == status_out_of_memory));
1661
+ }
1662
+
1663
+ // cleanup
1664
+ for (unsigned int j = 0; j < sizeof(files) / sizeof(files[0]); ++j)
1665
+ {
1666
+ delete[] files[j].data;
1667
+ }
1668
+ }
1669
+
1670
+ #ifdef PUGIXML_HAS_MOVE
1671
+ TEST_XML(document_move_ctor, "<node1/><node2/>")
1672
+ {
1673
+ xml_document other = std::move(doc);
1674
+
1675
+ CHECK(doc.first_child().empty());
1676
+
1677
+ CHECK_STRING(other.first_child().name(), STR("node1"));
1678
+ CHECK(other.first_child().parent() == other);
1679
+
1680
+ CHECK_STRING(other.last_child().name(), STR("node2"));
1681
+ CHECK(other.last_child().parent() == other);
1682
+ }
1683
+
1684
+ TEST_XML(document_move_assign, "<node1/><node2/>")
1685
+ {
1686
+ xml_document other;
1687
+ CHECK(other.load_string(STR("<node3/>")));
1688
+
1689
+ other = std::move(doc);
1690
+
1691
+ CHECK(doc.first_child().empty());
1692
+
1693
+ CHECK_STRING(other.first_child().name(), STR("node1"));
1694
+ CHECK(other.first_child().parent() == other);
1695
+
1696
+ CHECK_STRING(other.last_child().name(), STR("node2"));
1697
+ CHECK(other.last_child().parent() == other);
1698
+ }
1699
+
1700
+ TEST_XML(document_move_zero_alloc, "<node1/><node2/>")
1701
+ {
1702
+ test_runner::_memory_fail_threshold = 1;
1703
+
1704
+ xml_document other = std::move(doc);
1705
+
1706
+ CHECK(doc.first_child().empty());
1707
+
1708
+ CHECK_STRING(other.first_child().name(), STR("node1"));
1709
+ CHECK(other.first_child().parent() == other);
1710
+
1711
+ CHECK_STRING(other.last_child().name(), STR("node2"));
1712
+ CHECK(other.last_child().parent() == other);
1713
+ }
1714
+
1715
+ TEST(document_move_append_buffer)
1716
+ {
1717
+ xml_document* doc = new xml_document();
1718
+ CHECK(doc->load_string(STR("<node1 attr1='value1'><node2/></node1>")));
1719
+ CHECK(doc->child(STR("node1")).append_buffer("<node3/>", 8));
1720
+ CHECK(doc->child(STR("node1")).append_buffer("<node4/>", 8));
1721
+
1722
+ xml_document other = std::move(*doc);
1723
+ delete doc;
1724
+
1725
+ CHECK(other.child(STR("node1")).append_buffer("<node5/>", 8));
1726
+ CHECK(other.child(STR("node1")).append_buffer("<node6/>", 8));
1727
+
1728
+ CHECK_NODE(other, STR("<node1 attr1=\"value1\"><node2/><node3/><node4/><node5/><node6/></node1>"));
1729
+ }
1730
+
1731
+ TEST(document_move_append_child)
1732
+ {
1733
+ xml_document* doc = new xml_document();
1734
+ CHECK(doc->load_string(STR("<node1 attr1='value1'><node2/></node1>")));
1735
+
1736
+ xml_document other = std::move(*doc);
1737
+ delete doc;
1738
+
1739
+ for (int i = 0; i < 3000; ++i)
1740
+ other.child(STR("node1")).append_child(STR("node"));
1741
+
1742
+ for (int i = 0; i < 3000; ++i)
1743
+ other.child(STR("node1")).remove_child(other.child(STR("node1")).last_child());
1744
+
1745
+ CHECK_NODE(other, STR("<node1 attr1=\"value1\"><node2/></node1>"));
1746
+
1747
+ other.remove_child(other.first_child());
1748
+
1749
+ CHECK(!other.first_child());
1750
+ }
1751
+
1752
+ TEST(document_move_empty)
1753
+ {
1754
+ xml_document* doc = new xml_document();
1755
+ xml_document other = std::move(*doc);
1756
+ delete doc;
1757
+ }
1758
+
1759
+ TEST(document_move_large)
1760
+ {
1761
+ xml_document* doc = new xml_document();
1762
+
1763
+ xml_node dn = doc->append_child(STR("node"));
1764
+
1765
+ for (int i = 0; i < 3000; ++i)
1766
+ dn.append_child(STR("child"));
1767
+
1768
+ xml_document other = std::move(*doc);
1769
+ delete doc;
1770
+
1771
+ xml_node on = other.child(STR("node"));
1772
+
1773
+ for (int i = 0; i < 3000; ++i)
1774
+ CHECK(on.remove_child(on.first_child()));
1775
+
1776
+ CHECK(!on.first_child());
1777
+ }
1778
+
1779
+ TEST_XML(document_move_buffer, "<node1/><node2/>")
1780
+ {
1781
+ CHECK(doc.child(STR("node2")).offset_debug() == 9);
1782
+
1783
+ xml_document other = std::move(doc);
1784
+
1785
+ CHECK(other.child(STR("node2")).offset_debug() == 9);
1786
+ }
1787
+
1788
+ TEST_XML(document_move_append_child_zero_alloc, "<node1/><node2/>")
1789
+ {
1790
+ test_runner::_memory_fail_threshold = 1;
1791
+
1792
+ xml_document other = std::move(doc);
1793
+
1794
+ CHECK(other.append_child(STR("node3")));
1795
+
1796
+ CHECK_NODE(other, STR("<node1/><node2/><node3/>"));
1797
+ }
1798
+
1799
+ TEST(document_move_empty_zero_alloc)
1800
+ {
1801
+ xml_document* docs = new xml_document[32];
1802
+
1803
+ test_runner::_memory_fail_threshold = 1;
1804
+
1805
+ for (int i = 1; i < 32; ++i)
1806
+ docs[i] = std::move(docs[i-1]);
1807
+
1808
+ delete[] docs;
1809
+ }
1810
+
1811
+ #ifndef PUGIXML_COMPACT
1812
+ TEST(document_move_repeated_zero_alloc)
1813
+ {
1814
+ xml_document docs[32];
1815
+
1816
+ CHECK(docs[0].load_string(STR("<node><child/></node>")));
1817
+
1818
+ test_runner::_memory_fail_threshold = 1;
1819
+
1820
+ for (int i = 1; i < 32; ++i)
1821
+ docs[i] = std::move(docs[i-1]);
1822
+
1823
+ for (int i = 0; i < 31; ++i)
1824
+ CHECK(!docs[i].first_child());
1825
+
1826
+ CHECK_NODE(docs[31], STR("<node><child/></node>"));
1827
+ }
1828
+ #endif
1829
+
1830
+ #ifdef PUGIXML_COMPACT
1831
+ TEST(document_move_compact_fail)
1832
+ {
1833
+ xml_document docs[32];
1834
+
1835
+ CHECK(docs[0].load_string(STR("<node><child/></node>")));
1836
+
1837
+ test_runner::_memory_fail_threshold = 1;
1838
+
1839
+ int safe_count = 21;
1840
+
1841
+ for (int i = 1; i <= safe_count; ++i)
1842
+ docs[i] = std::move(docs[i-1]);
1843
+
1844
+ CHECK_ALLOC_FAIL(docs[safe_count+1] = std::move(docs[safe_count]));
1845
+
1846
+ for (int i = 0; i < safe_count; ++i)
1847
+ CHECK(!docs[i].first_child());
1848
+
1849
+ CHECK_NODE(docs[safe_count], STR("<node><child/></node>"));
1850
+ CHECK(!docs[safe_count+1].first_child());
1851
+ }
1852
+ #endif
1853
+
1854
+ TEST(document_move_assign_empty)
1855
+ {
1856
+ xml_document doc;
1857
+ doc.append_child(STR("node"));
1858
+
1859
+ doc = xml_document();
1860
+ doc.append_child(STR("node2"));
1861
+
1862
+ CHECK_NODE(doc, STR("<node2/>"));
1863
+ }
1864
+ #endif
1865
+
1866
+ TEST(document_load_buffer_convert_out_of_memory)
1867
+ {
1868
+ const char* source = "<node>\xe7</node>";
1869
+ size_t size = strlen(source);
1870
+
1871
+ test_runner::_memory_fail_threshold = 1;
1872
+
1873
+ xml_document doc;
1874
+
1875
+ xml_parse_result result;
1876
+ result.status = status_out_of_memory;
1877
+ CHECK_ALLOC_FAIL(result = doc.load_buffer(source, size, pugi::parse_default, pugi::encoding_latin1));
1878
+
1879
+ CHECK(result.status == status_out_of_memory);
1880
+ }
1881
+
1882
+ TEST(document_load_buffer_own_convert_out_of_memory)
1883
+ {
1884
+ const char* source = "<node>\xe7</node>";
1885
+ size_t size = strlen(source);
1886
+
1887
+ void* buffer = pugi::get_memory_allocation_function()(size);
1888
+ CHECK(buffer);
1889
+ memcpy(buffer, source, size);
1890
+
1891
+ test_runner::_memory_fail_threshold = 1;
1892
+
1893
+ xml_document doc;
1894
+
1895
+ xml_parse_result result;
1896
+ result.status = status_out_of_memory;
1897
+ CHECK_ALLOC_FAIL(result = doc.load_buffer_inplace_own(buffer, size, pugi::parse_default, pugi::encoding_latin1));
1898
+
1899
+ CHECK(result.status == status_out_of_memory);
1900
+ }
1901
+
1902
+ TEST(document_load_buffer_wide_truncated)
1903
+ {
1904
+ xml_document doc;
1905
+
1906
+ char buf[1] = {};
1907
+ CHECK(doc.load_buffer_inplace(buf, 1, parse_default, encoding_wchar).status == status_no_document_element);
1908
+ CHECK(doc.load_buffer_inplace(buf, 1, parse_fragment, encoding_wchar).status == status_ok);
1909
+ CHECK(!doc.first_child());
1910
+ }