react-native-quick-crypto 1.1.0 → 1.1.1

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 (687) hide show
  1. package/android/build.gradle +5 -1
  2. package/cpp/argon2/HybridArgon2.cpp +10 -3
  3. package/cpp/blake3/HybridBlake3.cpp +5 -3
  4. package/cpp/cipher/CCMCipher.cpp +29 -16
  5. package/cpp/cipher/CCMCipher.hpp +2 -4
  6. package/cpp/cipher/ChaCha20Cipher.cpp +14 -18
  7. package/cpp/cipher/ChaCha20Cipher.hpp +2 -4
  8. package/cpp/cipher/ChaCha20Poly1305Cipher.cpp +34 -23
  9. package/cpp/cipher/ChaCha20Poly1305Cipher.hpp +2 -4
  10. package/cpp/cipher/GCMCipher.cpp +14 -15
  11. package/cpp/cipher/HybridCipher.cpp +39 -36
  12. package/cpp/cipher/HybridCipher.hpp +17 -1
  13. package/cpp/cipher/HybridRsaCipher.cpp +74 -29
  14. package/cpp/cipher/OCBCipher.cpp +4 -3
  15. package/cpp/cipher/XChaCha20Poly1305Cipher.cpp +14 -13
  16. package/cpp/cipher/XSalsa20Cipher.cpp +72 -6
  17. package/cpp/cipher/XSalsa20Cipher.hpp +25 -3
  18. package/cpp/cipher/XSalsa20Poly1305Cipher.cpp +21 -25
  19. package/cpp/dh/HybridDiffieHellman.cpp +29 -0
  20. package/cpp/ec/HybridEcKeyPair.cpp +35 -33
  21. package/cpp/ec/HybridEcKeyPair.hpp +3 -7
  22. package/cpp/ecdh/HybridECDH.cpp +23 -0
  23. package/cpp/ed25519/HybridEdKeyPair.cpp +73 -117
  24. package/cpp/ed25519/HybridEdKeyPair.hpp +5 -9
  25. package/cpp/hash/HybridHash.cpp +5 -7
  26. package/cpp/hkdf/HybridHkdf.cpp +6 -4
  27. package/cpp/hmac/HybridHmac.cpp +4 -6
  28. package/cpp/kmac/HybridKmac.cpp +4 -4
  29. package/cpp/mldsa/HybridMlDsaKeyPair.cpp +37 -49
  30. package/cpp/mlkem/HybridMlKemKeyPair.cpp +39 -43
  31. package/cpp/pbkdf2/HybridPbkdf2.cpp +7 -8
  32. package/cpp/rsa/HybridRsaKeyPair.cpp +5 -8
  33. package/cpp/rsa/HybridRsaKeyPair.hpp +4 -7
  34. package/cpp/scrypt/HybridScrypt.cpp +6 -4
  35. package/cpp/sign/HybridSignHandle.cpp +25 -68
  36. package/cpp/sign/HybridVerifyHandle.cpp +23 -60
  37. package/cpp/utils/HybridUtils.cpp +183 -43
  38. package/cpp/utils/HybridUtils.hpp +9 -2
  39. package/cpp/utils/QuickCryptoUtils.hpp +72 -0
  40. package/lib/commonjs/argon2.js +51 -2
  41. package/lib/commonjs/argon2.js.map +1 -1
  42. package/lib/commonjs/cipher.js +109 -11
  43. package/lib/commonjs/cipher.js.map +1 -1
  44. package/lib/commonjs/dsa.js +8 -2
  45. package/lib/commonjs/dsa.js.map +1 -1
  46. package/lib/commonjs/hash.js +15 -5
  47. package/lib/commonjs/hash.js.map +1 -1
  48. package/lib/commonjs/hkdf.js +33 -6
  49. package/lib/commonjs/hkdf.js.map +1 -1
  50. package/lib/commonjs/hmac.js +15 -5
  51. package/lib/commonjs/hmac.js.map +1 -1
  52. package/lib/commonjs/keys/publicCipher.js +10 -4
  53. package/lib/commonjs/keys/publicCipher.js.map +1 -1
  54. package/lib/commonjs/random.js +11 -2
  55. package/lib/commonjs/random.js.map +1 -1
  56. package/lib/commonjs/rsa.js +12 -5
  57. package/lib/commonjs/rsa.js.map +1 -1
  58. package/lib/commonjs/scrypt.js +47 -6
  59. package/lib/commonjs/scrypt.js.map +1 -1
  60. package/lib/commonjs/subtle.js +76 -5
  61. package/lib/commonjs/subtle.js.map +1 -1
  62. package/lib/commonjs/utils/cipher.js +18 -7
  63. package/lib/commonjs/utils/cipher.js.map +1 -1
  64. package/lib/commonjs/utils/conversion.js +33 -9
  65. package/lib/commonjs/utils/conversion.js.map +1 -1
  66. package/lib/commonjs/utils/timingSafeEqual.js +7 -2
  67. package/lib/commonjs/utils/timingSafeEqual.js.map +1 -1
  68. package/lib/commonjs/x509certificate.js +6 -6
  69. package/lib/commonjs/x509certificate.js.map +1 -1
  70. package/lib/module/argon2.js +51 -2
  71. package/lib/module/argon2.js.map +1 -1
  72. package/lib/module/cipher.js +109 -11
  73. package/lib/module/cipher.js.map +1 -1
  74. package/lib/module/dsa.js +8 -2
  75. package/lib/module/dsa.js.map +1 -1
  76. package/lib/module/hash.js +15 -5
  77. package/lib/module/hash.js.map +1 -1
  78. package/lib/module/hkdf.js +33 -6
  79. package/lib/module/hkdf.js.map +1 -1
  80. package/lib/module/hmac.js +15 -5
  81. package/lib/module/hmac.js.map +1 -1
  82. package/lib/module/keys/publicCipher.js +10 -4
  83. package/lib/module/keys/publicCipher.js.map +1 -1
  84. package/lib/module/random.js +11 -2
  85. package/lib/module/random.js.map +1 -1
  86. package/lib/module/rsa.js +11 -4
  87. package/lib/module/rsa.js.map +1 -1
  88. package/lib/module/scrypt.js +47 -6
  89. package/lib/module/scrypt.js.map +1 -1
  90. package/lib/module/subtle.js +76 -5
  91. package/lib/module/subtle.js.map +1 -1
  92. package/lib/module/utils/cipher.js +18 -7
  93. package/lib/module/utils/cipher.js.map +1 -1
  94. package/lib/module/utils/conversion.js +33 -9
  95. package/lib/module/utils/conversion.js.map +1 -1
  96. package/lib/module/utils/timingSafeEqual.js +8 -3
  97. package/lib/module/utils/timingSafeEqual.js.map +1 -1
  98. package/lib/module/x509certificate.js +6 -6
  99. package/lib/module/x509certificate.js.map +1 -1
  100. package/lib/typescript/argon2.d.ts.map +1 -1
  101. package/lib/typescript/cipher.d.ts +2 -2
  102. package/lib/typescript/cipher.d.ts.map +1 -1
  103. package/lib/typescript/dsa.d.ts.map +1 -1
  104. package/lib/typescript/hash.d.ts +2 -2
  105. package/lib/typescript/hash.d.ts.map +1 -1
  106. package/lib/typescript/hkdf.d.ts.map +1 -1
  107. package/lib/typescript/hmac.d.ts +2 -2
  108. package/lib/typescript/hmac.d.ts.map +1 -1
  109. package/lib/typescript/index.d.ts +1 -1
  110. package/lib/typescript/index.d.ts.map +1 -1
  111. package/lib/typescript/keys/publicCipher.d.ts.map +1 -1
  112. package/lib/typescript/random.d.ts.map +1 -1
  113. package/lib/typescript/rsa.d.ts.map +1 -1
  114. package/lib/typescript/scrypt.d.ts.map +1 -1
  115. package/lib/typescript/specs/utils.nitro.d.ts +0 -2
  116. package/lib/typescript/specs/utils.nitro.d.ts.map +1 -1
  117. package/lib/typescript/subtle.d.ts.map +1 -1
  118. package/lib/typescript/utils/cipher.d.ts +13 -1
  119. package/lib/typescript/utils/cipher.d.ts.map +1 -1
  120. package/lib/typescript/utils/conversion.d.ts +9 -6
  121. package/lib/typescript/utils/conversion.d.ts.map +1 -1
  122. package/lib/typescript/utils/timingSafeEqual.d.ts.map +1 -1
  123. package/lib/typescript/x509certificate.d.ts.map +1 -1
  124. package/nitrogen/generated/shared/c++/HybridUtilsSpec.cpp +0 -2
  125. package/nitrogen/generated/shared/c++/HybridUtilsSpec.hpp +0 -3
  126. package/package.json +37 -5
  127. package/src/argon2.ts +80 -2
  128. package/src/cipher.ts +139 -15
  129. package/src/dsa.ts +11 -2
  130. package/src/hash.ts +17 -7
  131. package/src/hkdf.ts +44 -6
  132. package/src/hmac.ts +17 -7
  133. package/src/keys/publicCipher.ts +10 -4
  134. package/src/random.ts +11 -2
  135. package/src/rsa.ts +18 -4
  136. package/src/scrypt.ts +73 -6
  137. package/src/specs/utils.nitro.ts +0 -2
  138. package/src/subtle.ts +90 -8
  139. package/src/utils/cipher.ts +30 -8
  140. package/src/utils/conversion.ts +58 -20
  141. package/src/utils/timingSafeEqual.ts +8 -3
  142. package/src/x509certificate.ts +5 -6
  143. package/deps/blake3/.cargo/config.toml +0 -2
  144. package/deps/blake3/.git-blame-ignore-revs +0 -2
  145. package/deps/blake3/.github/workflows/build_b3sum.py +0 -38
  146. package/deps/blake3/.github/workflows/ci.yml +0 -491
  147. package/deps/blake3/.github/workflows/tag.yml +0 -43
  148. package/deps/blake3/.github/workflows/upload_github_release_asset.py +0 -73
  149. package/deps/blake3/CONTRIBUTING.md +0 -31
  150. package/deps/blake3/Cargo.toml +0 -135
  151. package/deps/blake3/b3sum/Cargo.lock +0 -513
  152. package/deps/blake3/b3sum/Cargo.toml +0 -26
  153. package/deps/blake3/b3sum/README.md +0 -72
  154. package/deps/blake3/b3sum/src/main.rs +0 -564
  155. package/deps/blake3/b3sum/src/unit_tests.rs +0 -235
  156. package/deps/blake3/b3sum/tests/cli_tests.rs +0 -680
  157. package/deps/blake3/b3sum/what_does_check_do.md +0 -176
  158. package/deps/blake3/benches/bench.rs +0 -623
  159. package/deps/blake3/build.rs +0 -389
  160. package/deps/blake3/c/CMakeLists.txt +0 -383
  161. package/deps/blake3/c/CMakePresets.json +0 -73
  162. package/deps/blake3/c/Makefile.testing +0 -82
  163. package/deps/blake3/c/blake3-config.cmake.in +0 -14
  164. package/deps/blake3/c/blake3_avx2.c +0 -326
  165. package/deps/blake3/c/blake3_avx2_x86-64_unix.S +0 -1815
  166. package/deps/blake3/c/blake3_avx2_x86-64_windows_gnu.S +0 -1817
  167. package/deps/blake3/c/blake3_avx2_x86-64_windows_msvc.asm +0 -1828
  168. package/deps/blake3/c/blake3_avx512.c +0 -1388
  169. package/deps/blake3/c/blake3_avx512_x86-64_unix.S +0 -4824
  170. package/deps/blake3/c/blake3_avx512_x86-64_windows_gnu.S +0 -2615
  171. package/deps/blake3/c/blake3_avx512_x86-64_windows_msvc.asm +0 -2634
  172. package/deps/blake3/c/blake3_c_rust_bindings/Cargo.toml +0 -32
  173. package/deps/blake3/c/blake3_c_rust_bindings/README.md +0 -4
  174. package/deps/blake3/c/blake3_c_rust_bindings/benches/bench.rs +0 -477
  175. package/deps/blake3/c/blake3_c_rust_bindings/build.rs +0 -253
  176. package/deps/blake3/c/blake3_c_rust_bindings/cross_test.sh +0 -31
  177. package/deps/blake3/c/blake3_c_rust_bindings/src/lib.rs +0 -333
  178. package/deps/blake3/c/blake3_c_rust_bindings/src/test.rs +0 -696
  179. package/deps/blake3/c/blake3_sse2.c +0 -566
  180. package/deps/blake3/c/blake3_sse2_x86-64_unix.S +0 -2291
  181. package/deps/blake3/c/blake3_sse2_x86-64_windows_gnu.S +0 -2332
  182. package/deps/blake3/c/blake3_sse2_x86-64_windows_msvc.asm +0 -2350
  183. package/deps/blake3/c/blake3_sse41.c +0 -560
  184. package/deps/blake3/c/blake3_sse41_x86-64_unix.S +0 -2028
  185. package/deps/blake3/c/blake3_sse41_x86-64_windows_gnu.S +0 -2069
  186. package/deps/blake3/c/blake3_sse41_x86-64_windows_msvc.asm +0 -2089
  187. package/deps/blake3/c/blake3_tbb.cpp +0 -37
  188. package/deps/blake3/c/dependencies/CMakeLists.txt +0 -3
  189. package/deps/blake3/c/dependencies/tbb/CMakeLists.txt +0 -28
  190. package/deps/blake3/c/example.c +0 -36
  191. package/deps/blake3/c/example_tbb.c +0 -57
  192. package/deps/blake3/c/libblake3.pc.in +0 -12
  193. package/deps/blake3/c/main.c +0 -166
  194. package/deps/blake3/c/test.py +0 -97
  195. package/deps/blake3/media/B3.svg +0 -70
  196. package/deps/blake3/media/BLAKE3.svg +0 -85
  197. package/deps/blake3/media/speed.svg +0 -1474
  198. package/deps/blake3/reference_impl/Cargo.toml +0 -8
  199. package/deps/blake3/reference_impl/README.md +0 -14
  200. package/deps/blake3/reference_impl/reference_impl.rs +0 -374
  201. package/deps/blake3/src/ffi_avx2.rs +0 -65
  202. package/deps/blake3/src/ffi_avx512.rs +0 -169
  203. package/deps/blake3/src/ffi_neon.rs +0 -82
  204. package/deps/blake3/src/ffi_sse2.rs +0 -126
  205. package/deps/blake3/src/ffi_sse41.rs +0 -126
  206. package/deps/blake3/src/guts.rs +0 -60
  207. package/deps/blake3/src/hazmat.rs +0 -704
  208. package/deps/blake3/src/io.rs +0 -64
  209. package/deps/blake3/src/join.rs +0 -92
  210. package/deps/blake3/src/lib.rs +0 -1835
  211. package/deps/blake3/src/platform.rs +0 -587
  212. package/deps/blake3/src/portable.rs +0 -198
  213. package/deps/blake3/src/rust_avx2.rs +0 -474
  214. package/deps/blake3/src/rust_sse2.rs +0 -775
  215. package/deps/blake3/src/rust_sse41.rs +0 -766
  216. package/deps/blake3/src/test.rs +0 -1049
  217. package/deps/blake3/src/traits.rs +0 -227
  218. package/deps/blake3/src/wasm32_simd.rs +0 -794
  219. package/deps/blake3/test_vectors/Cargo.toml +0 -19
  220. package/deps/blake3/test_vectors/cross_test.sh +0 -25
  221. package/deps/blake3/test_vectors/src/bin/generate.rs +0 -4
  222. package/deps/blake3/test_vectors/src/lib.rs +0 -350
  223. package/deps/blake3/test_vectors/test_vectors.json +0 -217
  224. package/deps/blake3/tools/compiler_version/Cargo.toml +0 -7
  225. package/deps/blake3/tools/compiler_version/build.rs +0 -6
  226. package/deps/blake3/tools/compiler_version/src/main.rs +0 -27
  227. package/deps/blake3/tools/instruction_set_support/Cargo.toml +0 -6
  228. package/deps/blake3/tools/instruction_set_support/src/main.rs +0 -10
  229. package/deps/blake3/tools/release.md +0 -16
  230. package/deps/ncrypto/.bazelignore +0 -4
  231. package/deps/ncrypto/.bazelrc +0 -1
  232. package/deps/ncrypto/.bazelversion +0 -1
  233. package/deps/ncrypto/.clang-format +0 -111
  234. package/deps/ncrypto/.github/workflows/bazel.yml +0 -58
  235. package/deps/ncrypto/.github/workflows/commitlint.yml +0 -16
  236. package/deps/ncrypto/.github/workflows/linter.yml +0 -38
  237. package/deps/ncrypto/.github/workflows/macos.yml +0 -43
  238. package/deps/ncrypto/.github/workflows/release-please.yml +0 -16
  239. package/deps/ncrypto/.github/workflows/ubuntu.yml +0 -128
  240. package/deps/ncrypto/.github/workflows/visual-studio.yml +0 -49
  241. package/deps/ncrypto/.python-version +0 -1
  242. package/deps/ncrypto/.release-please-manifest.json +0 -3
  243. package/deps/ncrypto/BUILD.bazel +0 -44
  244. package/deps/ncrypto/CHANGELOG.md +0 -37
  245. package/deps/ncrypto/CMakeLists.txt +0 -79
  246. package/deps/ncrypto/MODULE.bazel +0 -16
  247. package/deps/ncrypto/MODULE.bazel.lock +0 -461
  248. package/deps/ncrypto/cmake/CPM.cmake +0 -1225
  249. package/deps/ncrypto/cmake/ncrypto-flags.cmake +0 -17
  250. package/deps/ncrypto/ncrypto.pc.in +0 -10
  251. package/deps/ncrypto/patches/0001-Expose-libdecrepit-so-NodeJS-can-use-it-for-ncrypto.patch +0 -28
  252. package/deps/ncrypto/pyproject.toml +0 -38
  253. package/deps/ncrypto/release-please-config.json +0 -11
  254. package/deps/ncrypto/src/CMakeLists.txt +0 -40
  255. package/deps/ncrypto/tests/BUILD.bazel +0 -11
  256. package/deps/ncrypto/tests/CMakeLists.txt +0 -7
  257. package/deps/ncrypto/tests/basic.cpp +0 -856
  258. package/deps/ncrypto/tools/run-clang-format.sh +0 -42
  259. package/deps/simdutf/.clang-format +0 -4
  260. package/deps/simdutf/.github/ISSUE_TEMPLATE/bug_report.md +0 -62
  261. package/deps/simdutf/.github/ISSUE_TEMPLATE/config.yml +0 -1
  262. package/deps/simdutf/.github/ISSUE_TEMPLATE/feature_request.md +0 -35
  263. package/deps/simdutf/.github/ISSUE_TEMPLATE/standard-issue-template.md +0 -29
  264. package/deps/simdutf/.github/pull_request_template.md +0 -51
  265. package/deps/simdutf/.github/workflows/aarch64.yml +0 -39
  266. package/deps/simdutf/.github/workflows/alpine.yml +0 -27
  267. package/deps/simdutf/.github/workflows/amalgamation_demos.yml +0 -34
  268. package/deps/simdutf/.github/workflows/armv7.yml +0 -32
  269. package/deps/simdutf/.github/workflows/atomic_fuzz.yml +0 -25
  270. package/deps/simdutf/.github/workflows/cifuzz.yml +0 -37
  271. package/deps/simdutf/.github/workflows/clangformat.yml +0 -36
  272. package/deps/simdutf/.github/workflows/debian-latestcxxstandards.yml +0 -40
  273. package/deps/simdutf/.github/workflows/debian.yml +0 -33
  274. package/deps/simdutf/.github/workflows/documentation.yml +0 -36
  275. package/deps/simdutf/.github/workflows/emscripten.yml +0 -19
  276. package/deps/simdutf/.github/workflows/loongarch64-gcc-14.2.yml +0 -39
  277. package/deps/simdutf/.github/workflows/macos-latest.yml +0 -29
  278. package/deps/simdutf/.github/workflows/msys2-clang.yml +0 -48
  279. package/deps/simdutf/.github/workflows/msys2.yml +0 -50
  280. package/deps/simdutf/.github/workflows/ppc64le.yml +0 -29
  281. package/deps/simdutf/.github/workflows/rvv-1024-clang-18.yml +0 -35
  282. package/deps/simdutf/.github/workflows/rvv-128-clang-17.yml +0 -35
  283. package/deps/simdutf/.github/workflows/rvv-256-gcc-14.yml +0 -31
  284. package/deps/simdutf/.github/workflows/s390x.yml +0 -29
  285. package/deps/simdutf/.github/workflows/selective-amalgamation.yml +0 -29
  286. package/deps/simdutf/.github/workflows/typos.yml +0 -19
  287. package/deps/simdutf/.github/workflows/ubuntu22-cxx20.yml +0 -30
  288. package/deps/simdutf/.github/workflows/ubuntu22.yml +0 -32
  289. package/deps/simdutf/.github/workflows/ubuntu22_gcc12.yml +0 -27
  290. package/deps/simdutf/.github/workflows/ubuntu22sani.yml +0 -29
  291. package/deps/simdutf/.github/workflows/ubuntu24-cxxstandards.yml +0 -34
  292. package/deps/simdutf/.github/workflows/ubuntu24-unsignedchar.yml +0 -34
  293. package/deps/simdutf/.github/workflows/ubuntu24.yml +0 -32
  294. package/deps/simdutf/.github/workflows/ubuntu24sani.yml +0 -36
  295. package/deps/simdutf/.github/workflows/ubuntu24sani_clang.yml +0 -29
  296. package/deps/simdutf/.github/workflows/vs17-arm-ci.yml +0 -21
  297. package/deps/simdutf/.github/workflows/vs17-ci-cxx20.yml +0 -41
  298. package/deps/simdutf/.github/workflows/vs17-ci.yml +0 -41
  299. package/deps/simdutf/.github/workflows/vs17-clang-ci.yml +0 -41
  300. package/deps/simdutf/.github/workflows/vs17-cxxstandards.yml +0 -36
  301. package/deps/simdutf/AI_USAGE_POLICY.md +0 -56
  302. package/deps/simdutf/AUTHORS +0 -6
  303. package/deps/simdutf/CMakeLists.txt +0 -231
  304. package/deps/simdutf/CONTRIBUTING.md +0 -214
  305. package/deps/simdutf/CONTRIBUTORS +0 -1
  306. package/deps/simdutf/Doxyfile +0 -2584
  307. package/deps/simdutf/Makefile.crosscompile +0 -54
  308. package/deps/simdutf/README-RVV.md +0 -16
  309. package/deps/simdutf/SECURITY.md +0 -8
  310. package/deps/simdutf/benchmarks/CMakeLists.txt +0 -101
  311. package/deps/simdutf/benchmarks/alignment.cpp +0 -150
  312. package/deps/simdutf/benchmarks/base64/CMakeLists.txt +0 -30
  313. package/deps/simdutf/benchmarks/base64/benchmark_base64.cpp +0 -875
  314. package/deps/simdutf/benchmarks/base64/libbase64_spaces.h +0 -49
  315. package/deps/simdutf/benchmarks/base64/node_base64.h +0 -227
  316. package/deps/simdutf/benchmarks/base64/openssl3_base64.h +0 -334
  317. package/deps/simdutf/benchmarks/benchmark.cpp +0 -65
  318. package/deps/simdutf/benchmarks/benchmark_to_well_formed_utf16.cpp +0 -347
  319. package/deps/simdutf/benchmarks/competition/.clang-format-ignore +0 -5
  320. package/deps/simdutf/benchmarks/competition/CppCon2018/utf_utils.cpp +0 -1276
  321. package/deps/simdutf/benchmarks/competition/CppCon2018/utf_utils.h +0 -595
  322. package/deps/simdutf/benchmarks/competition/README.md +0 -7
  323. package/deps/simdutf/benchmarks/competition/hoehrmann/hoehrmann.h +0 -91
  324. package/deps/simdutf/benchmarks/competition/inoue2008/inoue_utf8_to_utf16.h +0 -444
  325. package/deps/simdutf/benchmarks/competition/inoue2008/inoue_utf8_to_utf16_tables.h +0 -13183
  326. package/deps/simdutf/benchmarks/competition/inoue2008/script.py +0 -73
  327. package/deps/simdutf/benchmarks/competition/llvm/ConvertUTF.cpp +0 -738
  328. package/deps/simdutf/benchmarks/competition/llvm/ConvertUTF.h +0 -293
  329. package/deps/simdutf/benchmarks/competition/u8u16/COPYRIGHT +0 -8
  330. package/deps/simdutf/benchmarks/competition/u8u16/Makefile +0 -44
  331. package/deps/simdutf/benchmarks/competition/u8u16/OSL3.0.txt +0 -169
  332. package/deps/simdutf/benchmarks/competition/u8u16/Profiling/BOM_Profiler.h +0 -148
  333. package/deps/simdutf/benchmarks/competition/u8u16/Profiling/i386_timer.h +0 -45
  334. package/deps/simdutf/benchmarks/competition/u8u16/Profiling/ppc_timer.c +0 -34
  335. package/deps/simdutf/benchmarks/competition/u8u16/README +0 -56
  336. package/deps/simdutf/benchmarks/competition/u8u16/config/config_defs.h +0 -43
  337. package/deps/simdutf/benchmarks/competition/u8u16/config/g4_config.h +0 -27
  338. package/deps/simdutf/benchmarks/competition/u8u16/config/mmx_config.h +0 -16
  339. package/deps/simdutf/benchmarks/competition/u8u16/config/p4_config.h +0 -18
  340. package/deps/simdutf/benchmarks/competition/u8u16/config/p4_ideal_config.h +0 -16
  341. package/deps/simdutf/benchmarks/competition/u8u16/config/spu_config.h +0 -28
  342. package/deps/simdutf/benchmarks/competition/u8u16/config/ssse3_config.h +0 -20
  343. package/deps/simdutf/benchmarks/competition/u8u16/iconv_u8u16.c +0 -2
  344. package/deps/simdutf/benchmarks/competition/u8u16/lib/altivec_simd.h +0 -440
  345. package/deps/simdutf/benchmarks/competition/u8u16/lib/libgen/make_basic_ops.py +0 -121
  346. package/deps/simdutf/benchmarks/competition/u8u16/lib/libgen/make_half_operand_versions.py +0 -158
  347. package/deps/simdutf/benchmarks/competition/u8u16/lib/libgen/make_test.py +0 -270
  348. package/deps/simdutf/benchmarks/competition/u8u16/lib/mmx_simd.h +0 -141
  349. package/deps/simdutf/benchmarks/competition/u8u16/lib/mmx_simd_basic.h +0 -216
  350. package/deps/simdutf/benchmarks/competition/u8u16/lib/mmx_simd_built_in.h +0 -119
  351. package/deps/simdutf/benchmarks/competition/u8u16/lib/mmx_simd_modified.h +0 -2430
  352. package/deps/simdutf/benchmarks/competition/u8u16/lib/outline.txt +0 -39
  353. package/deps/simdutf/benchmarks/competition/u8u16/lib/spu_simd.h +0 -421
  354. package/deps/simdutf/benchmarks/competition/u8u16/lib/sse_simd.h +0 -836
  355. package/deps/simdutf/benchmarks/competition/u8u16/lib/stdint.h +0 -222
  356. package/deps/simdutf/benchmarks/competition/u8u16/libu8u16_BE.c +0 -4
  357. package/deps/simdutf/benchmarks/competition/u8u16/libu8u16_LE.c +0 -5
  358. package/deps/simdutf/benchmarks/competition/u8u16/proto/u8u16.py +0 -390
  359. package/deps/simdutf/benchmarks/competition/u8u16/src/Makefile +0 -18
  360. package/deps/simdutf/benchmarks/competition/u8u16/src/bytelex.h +0 -448
  361. package/deps/simdutf/benchmarks/competition/u8u16/src/charsets/ASCII_EBCDIC.h +0 -284
  362. package/deps/simdutf/benchmarks/competition/u8u16/src/libu8u16.c +0 -1975
  363. package/deps/simdutf/benchmarks/competition/u8u16/src/libu8u16.pdf +0 -0
  364. package/deps/simdutf/benchmarks/competition/u8u16/src/libu8u16.w +0 -2263
  365. package/deps/simdutf/benchmarks/competition/u8u16/src/multiliteral.h +0 -239
  366. package/deps/simdutf/benchmarks/competition/u8u16/src/u8u16.c +0 -232
  367. package/deps/simdutf/benchmarks/competition/u8u16/src/x8x16.c +0 -194
  368. package/deps/simdutf/benchmarks/competition/u8u16/src/xml_error.c +0 -193
  369. package/deps/simdutf/benchmarks/competition/u8u16/src/xml_error.h +0 -167
  370. package/deps/simdutf/benchmarks/competition/u8u16/src/xmldecl.c +0 -288
  371. package/deps/simdutf/benchmarks/competition/u8u16/src/xmldecl.h +0 -117
  372. package/deps/simdutf/benchmarks/competition/u8u16/u8u16_g4.c +0 -2
  373. package/deps/simdutf/benchmarks/competition/u8u16/u8u16_mmx.c +0 -2
  374. package/deps/simdutf/benchmarks/competition/u8u16/u8u16_p4.c +0 -3
  375. package/deps/simdutf/benchmarks/competition/u8u16/u8u16_p4_ideal.c +0 -2
  376. package/deps/simdutf/benchmarks/competition/u8u16/u8u16_spu.c +0 -2
  377. package/deps/simdutf/benchmarks/competition/u8u16/u8u16_ssse3.c +0 -3
  378. package/deps/simdutf/benchmarks/competition/u8u16/x8x16_p4.c +0 -2
  379. package/deps/simdutf/benchmarks/competition/utf8lut/LICENSE +0 -23
  380. package/deps/simdutf/benchmarks/competition/utf8lut/data/test_minimal.txt +0 -44
  381. package/deps/simdutf/benchmarks/competition/utf8lut/readme.md +0 -106
  382. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_clang_corr_tests.cmd +0 -11
  383. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_clang_corr_tests.sh +0 -13
  384. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_gcc_corr_tests.sh +0 -13
  385. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_gcc_example.sh +0 -13
  386. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_gcc_file_conv.sh +0 -14
  387. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_gcc_iconv_lib.sh +0 -11
  388. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_gcc_iconv_sample.sh +0 -8
  389. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_mingw_corr_tests.cmd +0 -12
  390. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_mingw_example.cmd +0 -13
  391. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_mingw_file_conv.cmd +0 -14
  392. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_mingw_iconv_lib.cmd +0 -11
  393. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_mingw_iconv_sample.cmd +0 -8
  394. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_msvc_corr_tests.cmd +0 -11
  395. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_msvc_example.cmd +0 -12
  396. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_msvc_file_conv.cmd +0 -13
  397. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_msvc_iconv_lib.cmd +0 -10
  398. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/build_msvc_iconv_sample.cmd +0 -9
  399. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/html_table.py +0 -25
  400. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/measure.py +0 -94
  401. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/resize.py +0 -20
  402. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/wipe_all.cmd +0 -2
  403. package/deps/simdutf/benchmarks/competition/utf8lut/scripts/wipe_interm.cmd +0 -1
  404. package/deps/simdutf/benchmarks/competition/utf8lut/src/base/CustomMemcpy.h +0 -75
  405. package/deps/simdutf/benchmarks/competition/utf8lut/src/base/PerfDefs.h +0 -47
  406. package/deps/simdutf/benchmarks/competition/utf8lut/src/base/Timing.cpp +0 -17
  407. package/deps/simdutf/benchmarks/competition/utf8lut/src/base/Timing.h +0 -76
  408. package/deps/simdutf/benchmarks/competition/utf8lut/src/buffer/AllProcessors.cpp +0 -35
  409. package/deps/simdutf/benchmarks/competition/utf8lut/src/buffer/BaseBufferProcessor.cpp +0 -117
  410. package/deps/simdutf/benchmarks/competition/utf8lut/src/buffer/BaseBufferProcessor.h +0 -210
  411. package/deps/simdutf/benchmarks/competition/utf8lut/src/buffer/BufferDecoder.h +0 -158
  412. package/deps/simdutf/benchmarks/competition/utf8lut/src/buffer/BufferEncoder.h +0 -104
  413. package/deps/simdutf/benchmarks/competition/utf8lut/src/buffer/ProcessorPlugins.h +0 -334
  414. package/deps/simdutf/benchmarks/competition/utf8lut/src/buffer/ProcessorSelector.h +0 -186
  415. package/deps/simdutf/benchmarks/competition/utf8lut/src/core/DecoderLut.cpp +0 -140
  416. package/deps/simdutf/benchmarks/competition/utf8lut/src/core/DecoderLut.h +0 -42
  417. package/deps/simdutf/benchmarks/competition/utf8lut/src/core/DecoderProcess.h +0 -100
  418. package/deps/simdutf/benchmarks/competition/utf8lut/src/core/Dfa.h +0 -57
  419. package/deps/simdutf/benchmarks/competition/utf8lut/src/core/EncoderLut.cpp +0 -85
  420. package/deps/simdutf/benchmarks/competition/utf8lut/src/core/EncoderLut.h +0 -27
  421. package/deps/simdutf/benchmarks/competition/utf8lut/src/core/EncoderProcess.h +0 -126
  422. package/deps/simdutf/benchmarks/competition/utf8lut/src/core/ProcessTrivial.h +0 -108
  423. package/deps/simdutf/benchmarks/competition/utf8lut/src/iconv/iconv.cpp +0 -139
  424. package/deps/simdutf/benchmarks/competition/utf8lut/src/iconv/iconv.h +0 -74
  425. package/deps/simdutf/benchmarks/competition/utf8lut/src/message/MessageConverter.cpp +0 -65
  426. package/deps/simdutf/benchmarks/competition/utf8lut/src/message/MessageConverter.h +0 -91
  427. package/deps/simdutf/benchmarks/competition/utf8lut/src/tests/CorrectnessTests.cpp +0 -772
  428. package/deps/simdutf/benchmarks/competition/utf8lut/src/tests/Example.cpp +0 -12
  429. package/deps/simdutf/benchmarks/competition/utf8lut/src/tests/FileConverter.cpp +0 -486
  430. package/deps/simdutf/benchmarks/competition/utf8lut/src/tests/iconv_sample.c +0 -162
  431. package/deps/simdutf/benchmarks/competition/utf8lut/src/utf8lut.h +0 -15
  432. package/deps/simdutf/benchmarks/competition/utf8sse4/fromutf8-sse.cpp +0 -292
  433. package/deps/simdutf/benchmarks/competition/utfcpp/LICENSE +0 -23
  434. package/deps/simdutf/benchmarks/competition/utfcpp/README.md +0 -1503
  435. package/deps/simdutf/benchmarks/competition/utfcpp/source/utf8/checked.h +0 -335
  436. package/deps/simdutf/benchmarks/competition/utfcpp/source/utf8/core.h +0 -338
  437. package/deps/simdutf/benchmarks/competition/utfcpp/source/utf8/cpp11.h +0 -103
  438. package/deps/simdutf/benchmarks/competition/utfcpp/source/utf8/cpp17.h +0 -103
  439. package/deps/simdutf/benchmarks/competition/utfcpp/source/utf8/unchecked.h +0 -274
  440. package/deps/simdutf/benchmarks/competition/utfcpp/source/utf8.h +0 -34
  441. package/deps/simdutf/benchmarks/dataset/README.md +0 -155
  442. package/deps/simdutf/benchmarks/dataset/emoji.txt +0 -204
  443. package/deps/simdutf/benchmarks/dataset/scripts/utf8type.py +0 -40
  444. package/deps/simdutf/benchmarks/dataset/wikipedia_mars/Makefile +0 -80
  445. package/deps/simdutf/benchmarks/dataset/wikipedia_mars/convert_to_utf6.py +0 -20
  446. package/deps/simdutf/benchmarks/find/CMakeLists.txt +0 -6
  447. package/deps/simdutf/benchmarks/find/findbenchmark.cpp +0 -63
  448. package/deps/simdutf/benchmarks/find/findbenchmarker.h +0 -46
  449. package/deps/simdutf/benchmarks/shortbench.cpp +0 -555
  450. package/deps/simdutf/benchmarks/src/CMakeLists.txt +0 -52
  451. package/deps/simdutf/benchmarks/src/apple_arm_events.h +0 -1104
  452. package/deps/simdutf/benchmarks/src/benchmark.cpp +0 -3899
  453. package/deps/simdutf/benchmarks/src/benchmark.h +0 -317
  454. package/deps/simdutf/benchmarks/src/benchmark_base.cpp +0 -144
  455. package/deps/simdutf/benchmarks/src/benchmark_base.h +0 -98
  456. package/deps/simdutf/benchmarks/src/cmdline.cpp +0 -176
  457. package/deps/simdutf/benchmarks/src/cmdline.h +0 -35
  458. package/deps/simdutf/benchmarks/src/event_counter.h +0 -162
  459. package/deps/simdutf/benchmarks/src/linux-perf-events.h +0 -104
  460. package/deps/simdutf/benchmarks/stream.cpp +0 -209
  461. package/deps/simdutf/benchmarks/threaded.cpp +0 -123
  462. package/deps/simdutf/cmake/CPM.cmake +0 -1363
  463. package/deps/simdutf/cmake/JoinPaths.cmake +0 -23
  464. package/deps/simdutf/cmake/add_cpp_test.cmake +0 -68
  465. package/deps/simdutf/cmake/simdutf-config.cmake.in +0 -2
  466. package/deps/simdutf/cmake/simdutf-flags.cmake +0 -26
  467. package/deps/simdutf/cmake/toolchains-ci/riscv64-linux-gnu.cmake +0 -4
  468. package/deps/simdutf/cmake/toolchains-dev/README.md +0 -32
  469. package/deps/simdutf/cmake/toolchains-dev/aarch64.cmake +0 -14
  470. package/deps/simdutf/cmake/toolchains-dev/loongarch64.cmake +0 -22
  471. package/deps/simdutf/cmake/toolchains-dev/powerpc64.cmake +0 -16
  472. package/deps/simdutf/cmake/toolchains-dev/powerpc64le.cmake +0 -16
  473. package/deps/simdutf/cmake/toolchains-dev/riscv64.cmake +0 -16
  474. package/deps/simdutf/cmake/toolchains-dev/rvv-spike.cmake +0 -38
  475. package/deps/simdutf/doc/avx512.png +0 -0
  476. package/deps/simdutf/doc/logo.png +0 -0
  477. package/deps/simdutf/doc/logo.svg +0 -165
  478. package/deps/simdutf/doc/node2023.png +0 -0
  479. package/deps/simdutf/doc/shortinput.md +0 -78
  480. package/deps/simdutf/doc/utf16utf8.png +0 -0
  481. package/deps/simdutf/doc/utf8utf16.png +0 -0
  482. package/deps/simdutf/doc/widelogo.png +0 -0
  483. package/deps/simdutf/doxygen.py +0 -50
  484. package/deps/simdutf/fuzz/.clang-format +0 -9
  485. package/deps/simdutf/fuzz/CMakeLists.txt +0 -45
  486. package/deps/simdutf/fuzz/README.md +0 -168
  487. package/deps/simdutf/fuzz/atomic_base64.cpp +0 -448
  488. package/deps/simdutf/fuzz/base64.cpp +0 -278
  489. package/deps/simdutf/fuzz/build.sh +0 -83
  490. package/deps/simdutf/fuzz/conversion.cpp +0 -669
  491. package/deps/simdutf/fuzz/helpers/.clang-format-ignore +0 -1
  492. package/deps/simdutf/fuzz/helpers/common.h +0 -135
  493. package/deps/simdutf/fuzz/helpers/nameof.hpp +0 -1258
  494. package/deps/simdutf/fuzz/main.cpp +0 -72
  495. package/deps/simdutf/fuzz/minimize_and_cleanse.sh +0 -87
  496. package/deps/simdutf/fuzz/misc.cpp +0 -216
  497. package/deps/simdutf/fuzz/random_fuzz.sh +0 -154
  498. package/deps/simdutf/fuzz/roundtrip.cpp +0 -588
  499. package/deps/simdutf/fuzz/safe_conversion.cpp +0 -104
  500. package/deps/simdutf/riscv/Dockerfile +0 -16
  501. package/deps/simdutf/riscv/README.md +0 -24
  502. package/deps/simdutf/riscv/remove-docker-station +0 -8
  503. package/deps/simdutf/riscv/run-docker-station +0 -31
  504. package/deps/simdutf/scripts/.flake8 +0 -2
  505. package/deps/simdutf/scripts/Makefile +0 -2
  506. package/deps/simdutf/scripts/README_ADD_FUNCTION.md +0 -49
  507. package/deps/simdutf/scripts/add_function.py +0 -330
  508. package/deps/simdutf/scripts/amalgamation_tests.py +0 -156
  509. package/deps/simdutf/scripts/base64/Makefile +0 -2
  510. package/deps/simdutf/scripts/base64/README.md +0 -2
  511. package/deps/simdutf/scripts/base64/avx512.py +0 -76
  512. package/deps/simdutf/scripts/base64/neon_decode.py +0 -143
  513. package/deps/simdutf/scripts/base64/neon_generate_lut.py +0 -101
  514. package/deps/simdutf/scripts/base64/sse.py +0 -252
  515. package/deps/simdutf/scripts/base64/sseregular.py +0 -160
  516. package/deps/simdutf/scripts/base64/sseurl.py +0 -283
  517. package/deps/simdutf/scripts/base64/table.py +0 -59
  518. package/deps/simdutf/scripts/base64bench_print.py +0 -145
  519. package/deps/simdutf/scripts/benchmark-all.py +0 -119
  520. package/deps/simdutf/scripts/benchmark_print.py +0 -324
  521. package/deps/simdutf/scripts/check_feature_macros.py +0 -156
  522. package/deps/simdutf/scripts/check_typos.sh +0 -13
  523. package/deps/simdutf/scripts/clang_format.sh +0 -35
  524. package/deps/simdutf/scripts/clang_format_docker.sh +0 -38
  525. package/deps/simdutf/scripts/common.py +0 -24
  526. package/deps/simdutf/scripts/compilation_benchmark.py +0 -55
  527. package/deps/simdutf/scripts/compile_many_variations.sh +0 -64
  528. package/deps/simdutf/scripts/create_latex_table.py +0 -62
  529. package/deps/simdutf/scripts/docker/Dockerfile +0 -14
  530. package/deps/simdutf/scripts/docker/Makefile +0 -9
  531. package/deps/simdutf/scripts/docker/README.md +0 -30
  532. package/deps/simdutf/scripts/docker/llvm.gpg +0 -0
  533. package/deps/simdutf/scripts/ppc64_convert_utf16_to_utf8.py +0 -155
  534. package/deps/simdutf/scripts/prepare_doxygen.sh +0 -21
  535. package/deps/simdutf/scripts/release.py +0 -197
  536. package/deps/simdutf/scripts/shortinputplots.py +0 -97
  537. package/deps/simdutf/scripts/sse_convert_utf16_to_utf8.py +0 -422
  538. package/deps/simdutf/scripts/sse_convert_utf32_to_utf16.py +0 -105
  539. package/deps/simdutf/scripts/sse_utf8_utf16_decode.py +0 -186
  540. package/deps/simdutf/scripts/sse_validate_utf16le_proof.py +0 -137
  541. package/deps/simdutf/scripts/sse_validate_utf16le_testcases.py +0 -129
  542. package/deps/simdutf/scripts/table.py +0 -207
  543. package/deps/simdutf/scripts/tests/new.txt +0 -33
  544. package/deps/simdutf/scripts/tests/old.txt +0 -33
  545. package/deps/simdutf/scripts/tests/results.txt +0 -272
  546. package/deps/simdutf/simdutf.pc.in +0 -11
  547. package/deps/simdutf/singleheader/.flake8 +0 -2
  548. package/deps/simdutf/singleheader/CMakeLists.txt +0 -64
  549. package/deps/simdutf/singleheader/README-dev.md +0 -81
  550. package/deps/simdutf/singleheader/README.md +0 -19
  551. package/deps/simdutf/singleheader/amalgamate.py +0 -513
  552. package/deps/simdutf/singleheader/amalgamation_demo.c +0 -59
  553. package/deps/simdutf/singleheader/amalgamation_demo.cpp +0 -54
  554. package/deps/simdutf/singleheader/test-features.py +0 -262
  555. package/deps/simdutf/src/CMakeLists.txt +0 -78
  556. package/deps/simdutf/tests/CMakeLists.txt +0 -483
  557. package/deps/simdutf/tests/atomic_base64_tests.cpp +0 -2845
  558. package/deps/simdutf/tests/base64_tests.cpp +0 -3617
  559. package/deps/simdutf/tests/basic_fuzzer.cpp +0 -805
  560. package/deps/simdutf/tests/bele_tests.cpp +0 -182
  561. package/deps/simdutf/tests/constexpr_base64_tests.cpp +0 -387
  562. package/deps/simdutf/tests/convert_latin1_to_utf16be_tests.cpp +0 -52
  563. package/deps/simdutf/tests/convert_latin1_to_utf16le_tests.cpp +0 -80
  564. package/deps/simdutf/tests/convert_latin1_to_utf32_tests.cpp +0 -66
  565. package/deps/simdutf/tests/convert_latin1_to_utf8_tests.cpp +0 -120
  566. package/deps/simdutf/tests/convert_utf16_to_utf8_safe_tests.cpp +0 -203
  567. package/deps/simdutf/tests/convert_utf16_to_utf8_with_replacement_tests.cpp +0 -276
  568. package/deps/simdutf/tests/convert_utf16be_to_latin1_tests.cpp +0 -109
  569. package/deps/simdutf/tests/convert_utf16be_to_latin1_tests_with_errors.cpp +0 -136
  570. package/deps/simdutf/tests/convert_utf16be_to_utf32_tests.cpp +0 -193
  571. package/deps/simdutf/tests/convert_utf16be_to_utf32_with_errors_tests.cpp +0 -381
  572. package/deps/simdutf/tests/convert_utf16be_to_utf8_tests.cpp +0 -259
  573. package/deps/simdutf/tests/convert_utf16be_to_utf8_with_errors_tests.cpp +0 -266
  574. package/deps/simdutf/tests/convert_utf16le_to_latin1_tests.cpp +0 -148
  575. package/deps/simdutf/tests/convert_utf16le_to_latin1_tests_with_errors.cpp +0 -176
  576. package/deps/simdutf/tests/convert_utf16le_to_utf32_tests.cpp +0 -213
  577. package/deps/simdutf/tests/convert_utf16le_to_utf32_with_errors_tests.cpp +0 -318
  578. package/deps/simdutf/tests/convert_utf16le_to_utf8_tests.cpp +0 -343
  579. package/deps/simdutf/tests/convert_utf16le_to_utf8_with_errors_tests.cpp +0 -271
  580. package/deps/simdutf/tests/convert_utf32_to_latin1_tests.cpp +0 -111
  581. package/deps/simdutf/tests/convert_utf32_to_latin1_with_errors_tests.cpp +0 -96
  582. package/deps/simdutf/tests/convert_utf32_to_utf16be_tests.cpp +0 -148
  583. package/deps/simdutf/tests/convert_utf32_to_utf16be_with_errors_tests.cpp +0 -192
  584. package/deps/simdutf/tests/convert_utf32_to_utf16le_tests.cpp +0 -166
  585. package/deps/simdutf/tests/convert_utf32_to_utf16le_with_errors_tests.cpp +0 -215
  586. package/deps/simdutf/tests/convert_utf32_to_utf8_tests.cpp +0 -181
  587. package/deps/simdutf/tests/convert_utf32_to_utf8_with_errors_tests.cpp +0 -261
  588. package/deps/simdutf/tests/convert_utf8_to_latin1_tests.cpp +0 -516
  589. package/deps/simdutf/tests/convert_utf8_to_latin1_with_errors_tests.cpp +0 -579
  590. package/deps/simdutf/tests/convert_utf8_to_utf16be_tests.cpp +0 -412
  591. package/deps/simdutf/tests/convert_utf8_to_utf16be_with_errors_tests.cpp +0 -480
  592. package/deps/simdutf/tests/convert_utf8_to_utf16le_tests.cpp +0 -671
  593. package/deps/simdutf/tests/convert_utf8_to_utf16le_with_errors_tests.cpp +0 -455
  594. package/deps/simdutf/tests/convert_utf8_to_utf32_tests.cpp +0 -1204
  595. package/deps/simdutf/tests/convert_utf8_to_utf32_with_errors_tests.cpp +0 -337
  596. package/deps/simdutf/tests/convert_valid_utf16be_to_latin1_tests.cpp +0 -37
  597. package/deps/simdutf/tests/convert_valid_utf16be_to_utf32_tests.cpp +0 -97
  598. package/deps/simdutf/tests/convert_valid_utf16be_to_utf8_tests.cpp +0 -126
  599. package/deps/simdutf/tests/convert_valid_utf16le_to_latin1_tests.cpp +0 -71
  600. package/deps/simdutf/tests/convert_valid_utf16le_to_utf32_tests.cpp +0 -122
  601. package/deps/simdutf/tests/convert_valid_utf16le_to_utf8_tests.cpp +0 -244
  602. package/deps/simdutf/tests/convert_valid_utf32_to_latin1_tests.cpp +0 -49
  603. package/deps/simdutf/tests/convert_valid_utf32_to_utf16be_tests.cpp +0 -92
  604. package/deps/simdutf/tests/convert_valid_utf32_to_utf16le_tests.cpp +0 -114
  605. package/deps/simdutf/tests/convert_valid_utf32_to_utf8_tests.cpp +0 -109
  606. package/deps/simdutf/tests/convert_valid_utf8_to_latin1_tests.cpp +0 -84
  607. package/deps/simdutf/tests/convert_valid_utf8_to_utf16be_tests.cpp +0 -124
  608. package/deps/simdutf/tests/convert_valid_utf8_to_utf16le_tests.cpp +0 -221
  609. package/deps/simdutf/tests/convert_valid_utf8_to_utf32_tests.cpp +0 -155
  610. package/deps/simdutf/tests/count_utf16be.cpp +0 -64
  611. package/deps/simdutf/tests/count_utf16le.cpp +0 -61
  612. package/deps/simdutf/tests/count_utf8.cpp +0 -87
  613. package/deps/simdutf/tests/detect_encodings_tests.cpp +0 -312
  614. package/deps/simdutf/tests/embed/valid_utf8.txt +0 -1
  615. package/deps/simdutf/tests/embed_tests.cpp +0 -22
  616. package/deps/simdutf/tests/find_tests.cpp +0 -77
  617. package/deps/simdutf/tests/fixed_string_tests.cpp +0 -153
  618. package/deps/simdutf/tests/helpers/CMakeLists.txt +0 -25
  619. package/deps/simdutf/tests/helpers/compiletime_conversions.h +0 -222
  620. package/deps/simdutf/tests/helpers/fixed_string.h +0 -267
  621. package/deps/simdutf/tests/helpers/random_int.cpp +0 -30
  622. package/deps/simdutf/tests/helpers/random_int.h +0 -39
  623. package/deps/simdutf/tests/helpers/random_utf16.cpp +0 -123
  624. package/deps/simdutf/tests/helpers/random_utf16.h +0 -52
  625. package/deps/simdutf/tests/helpers/random_utf32.cpp +0 -41
  626. package/deps/simdutf/tests/helpers/random_utf32.h +0 -40
  627. package/deps/simdutf/tests/helpers/random_utf8.cpp +0 -93
  628. package/deps/simdutf/tests/helpers/random_utf8.h +0 -36
  629. package/deps/simdutf/tests/helpers/test.cpp +0 -231
  630. package/deps/simdutf/tests/helpers/test.h +0 -193
  631. package/deps/simdutf/tests/helpers/transcode_test_base.cpp +0 -1257
  632. package/deps/simdutf/tests/helpers/transcode_test_base.h +0 -683
  633. package/deps/simdutf/tests/helpers/utf16.h +0 -27
  634. package/deps/simdutf/tests/installation_tests/find/CMakeLists.txt +0 -43
  635. package/deps/simdutf/tests/installation_tests/from_fetch/CMakeLists.txt +0 -47
  636. package/deps/simdutf/tests/internal_tests.cpp +0 -27
  637. package/deps/simdutf/tests/null_safety_tests.cpp +0 -94
  638. package/deps/simdutf/tests/random_fuzzer.cpp +0 -779
  639. package/deps/simdutf/tests/readme_tests.cpp +0 -274
  640. package/deps/simdutf/tests/reference/CMakeLists.txt +0 -23
  641. package/deps/simdutf/tests/reference/decode_utf16.h +0 -81
  642. package/deps/simdutf/tests/reference/decode_utf32.h +0 -47
  643. package/deps/simdutf/tests/reference/encode_latin1.cpp +0 -1
  644. package/deps/simdutf/tests/reference/encode_latin1.h +0 -32
  645. package/deps/simdutf/tests/reference/encode_utf16.cpp +0 -49
  646. package/deps/simdutf/tests/reference/encode_utf16.h +0 -20
  647. package/deps/simdutf/tests/reference/encode_utf32.cpp +0 -1
  648. package/deps/simdutf/tests/reference/encode_utf32.h +0 -36
  649. package/deps/simdutf/tests/reference/encode_utf8.cpp +0 -1
  650. package/deps/simdutf/tests/reference/encode_utf8.h +0 -40
  651. package/deps/simdutf/tests/reference/validate_utf16.cpp +0 -60
  652. package/deps/simdutf/tests/reference/validate_utf16.h +0 -14
  653. package/deps/simdutf/tests/reference/validate_utf16_to_latin1.cpp +0 -35
  654. package/deps/simdutf/tests/reference/validate_utf16_to_latin1.h +0 -13
  655. package/deps/simdutf/tests/reference/validate_utf32.cpp +0 -27
  656. package/deps/simdutf/tests/reference/validate_utf32.h +0 -12
  657. package/deps/simdutf/tests/reference/validate_utf32_to_latin1.cpp +0 -27
  658. package/deps/simdutf/tests/reference/validate_utf32_to_latin1.h +0 -12
  659. package/deps/simdutf/tests/reference/validate_utf8.cpp +0 -82
  660. package/deps/simdutf/tests/reference/validate_utf8.h +0 -11
  661. package/deps/simdutf/tests/reference/validate_utf8_to_latin1.cpp +0 -43
  662. package/deps/simdutf/tests/reference/validate_utf8_to_latin1.h +0 -12
  663. package/deps/simdutf/tests/select_implementation.cpp +0 -43
  664. package/deps/simdutf/tests/simdutf_c_tests.cpp +0 -244
  665. package/deps/simdutf/tests/span_tests.cpp +0 -401
  666. package/deps/simdutf/tests/special_tests.cpp +0 -559
  667. package/deps/simdutf/tests/straight_c_test.c +0 -187
  668. package/deps/simdutf/tests/text_encoding_tests.cpp +0 -77
  669. package/deps/simdutf/tests/to_well_formed_utf16_tests.cpp +0 -377
  670. package/deps/simdutf/tests/utf8_length_from_utf16_tests.cpp +0 -202
  671. package/deps/simdutf/tests/validate_ascii_basic_tests.cpp +0 -165
  672. package/deps/simdutf/tests/validate_ascii_with_errors_tests.cpp +0 -77
  673. package/deps/simdutf/tests/validate_utf16be_basic_tests.cpp +0 -175
  674. package/deps/simdutf/tests/validate_utf16be_with_errors_tests.cpp +0 -188
  675. package/deps/simdutf/tests/validate_utf16le_basic_tests.cpp +0 -268
  676. package/deps/simdutf/tests/validate_utf16le_with_errors_tests.cpp +0 -274
  677. package/deps/simdutf/tests/validate_utf32_basic_tests.cpp +0 -92
  678. package/deps/simdutf/tests/validate_utf32_with_errors_tests.cpp +0 -114
  679. package/deps/simdutf/tests/validate_utf8_basic_tests.cpp +0 -178
  680. package/deps/simdutf/tests/validate_utf8_brute_force_tests.cpp +0 -88
  681. package/deps/simdutf/tests/validate_utf8_puzzler_tests.cpp +0 -33
  682. package/deps/simdutf/tests/validate_utf8_with_errors_tests.cpp +0 -228
  683. package/deps/simdutf/tools/CMakeLists.txt +0 -85
  684. package/deps/simdutf/tools/fastbase64.cpp +0 -250
  685. package/deps/simdutf/tools/sutf.cpp +0 -556
  686. package/deps/simdutf/tools/sutf.h +0 -40
  687. package/lib/tsconfig.tsbuildinfo +0 -1
@@ -1,3617 +0,0 @@
1
- #include "simdutf.h"
2
-
3
- #include <algorithm>
4
- #include <array>
5
- #include <cmath>
6
- #include <cstddef>
7
- #include <iostream>
8
- #include <tuple>
9
- #include <vector>
10
-
11
- #include <tests/helpers/random_int.h>
12
- #include <tests/helpers/test.h>
13
-
14
- // to limit the runtime of this test
15
- #ifndef SIMDUTF_BASE64_TEST_MAXLEN
16
- #error "SIMDUTF_BASE64_TEST_MAXLEN not set."
17
- #endif
18
- constexpr std::size_t max_len = SIMDUTF_BASE64_TEST_MAXLEN;
19
-
20
- // Return the length of the prefix that contains count base64 characters.
21
- // Thus, if count is 3, the function returns the length of the prefix
22
- // that contains 3 base64 characters. Padding characters are counted.
23
- size_t prefix_length_base64_index(size_t count, simdutf::base64_options options,
24
- const char *input, size_t length) {
25
- size_t i = 0;
26
- while (i < length && simdutf::base64_ignorable(input[i], options)) {
27
- i++;
28
- }
29
- if (count == 0) {
30
- return i; // duh!
31
- }
32
- for (; i < length; i++) {
33
- if (simdutf::base64_ignorable(input[i], options)) {
34
- continue;
35
- }
36
- // We have a base64 character or a padding character.
37
- count--;
38
- if (count == 0) {
39
- return i + 1;
40
- }
41
- }
42
- return -1; // should never happen
43
- }
44
-
45
- template <typename char_type>
46
- size_t length_without_empty_tail(
47
- const std::vector<char_type> &input,
48
- simdutf::base64_options options = simdutf::base64_options::base64_default) {
49
- if (input.size() == 0) {
50
- return 0;
51
- }
52
- size_t i = input.size();
53
- while (i > 0 && simdutf::base64_ignorable(input[i - 1], options)) {
54
- i--;
55
- }
56
- return i;
57
- }
58
-
59
- // We may disable base64url tests by commenting out this next line.
60
- #define SIMDUTF_BASE64URL_TESTS 1
61
-
62
- using random_generator = std::mt19937;
63
- static random_generator::result_type seed = 42;
64
-
65
- constexpr uint8_t to_base64_value[] = {
66
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 64, 64, 255, 64, 64, 255,
67
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
68
- 255, 255, 64, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255,
69
- 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
70
- 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
71
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
72
- 25, 255, 255, 255, 255, 255, 255, 26, 27, 28, 29, 30, 31, 32, 33,
73
- 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
74
- 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
75
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
76
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
77
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
78
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
79
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
80
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
81
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
82
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
83
- 255};
84
-
85
- constexpr uint8_t to_base64url_value[] = {
86
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 64, 64, 255, 64, 64, 255,
87
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
88
- 255, 255, 64, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
89
- 62, 255, 255, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255,
90
- 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
91
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
92
- 25, 255, 255, 255, 255, 63, 255, 26, 27, 28, 29, 30, 31, 32, 33,
93
- 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
94
- 49, 50, 51, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
95
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
96
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
97
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
98
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
99
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
100
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
101
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
102
- 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
103
- 255};
104
-
105
- template <typename char_type> bool is_space(char_type c) {
106
- const static std::array<char_type, 5> space = {' ', '\t', '\n', '\r', '\f'};
107
- return std::find(space.begin(), space.end(), c) != space.end();
108
- }
109
-
110
- template <typename char_type> bool is_non_base64_space(char_type c) {
111
- return uint8_t(c) >= 128 || to_base64_value[uint8_t(c)] == 255;
112
- }
113
-
114
- template <typename char_type> bool is_non_base64_url_space(char_type c) {
115
- return uint8_t(c) >= 128 || to_base64url_value[uint8_t(c)] == 255;
116
- }
117
-
118
- template <typename char_type>
119
- size_t add_space(std::vector<char_type> &v, std::mt19937 &gen) {
120
- const static std::array<char_type, 5> space = {' ', '\t', '\n', '\r', '\f'};
121
- std::uniform_int_distribution<int> index_dist(0, v.size());
122
- size_t i = index_dist(gen);
123
- std::uniform_int_distribution<int> char_dist(0, space.size() - 1);
124
- v.insert(v.begin() + i, space[char_dist(gen)]);
125
- return i;
126
- }
127
-
128
- // consider using add_simple_spaces for better performance.
129
- template <typename char_type>
130
- size_t add_simple_space(std::vector<char_type> &v, std::mt19937 &gen) {
131
- std::uniform_int_distribution<int> index_dist(0, v.size());
132
- size_t i = index_dist(gen);
133
- v.insert(v.begin() + i, ' ');
134
- return i;
135
- }
136
-
137
- template <typename char_type>
138
- std::vector<char_type> add_simple_spaces(std::vector<char_type> &v,
139
- std::mt19937 &gen,
140
- size_t number_of_spaces) {
141
- // If there are no spaces to add or the vector is empty, return
142
- if (number_of_spaces == 0) {
143
- return v;
144
- }
145
-
146
- // Generate unique random positions
147
- std::vector<bool> positions(v.size() + number_of_spaces, false);
148
- std::uniform_int_distribution<size_t> dist(0, positions.size() - 1);
149
- for (size_t i = 0; i < number_of_spaces; ++i) {
150
- size_t pos = dist(gen);
151
- while (positions[pos]) {
152
- pos = dist(gen);
153
- }
154
- positions[pos] = true;
155
- }
156
- std::vector<char_type> result;
157
- result.resize(v.size() + number_of_spaces);
158
- int pos = 0;
159
- for (size_t i = 0; i < v.size() + number_of_spaces; ++i) {
160
- if (positions[i]) {
161
- result[i] = ' ';
162
- } else {
163
- result[i] = v[pos++];
164
- }
165
- }
166
- return result;
167
- }
168
-
169
- std::string add_simple_spaces(const std::string &v, std::mt19937 &gen,
170
- size_t number_of_spaces) {
171
- // If there are no spaces to add or the vector is empty, return
172
- if (number_of_spaces == 0) {
173
- return v;
174
- }
175
-
176
- // Generate unique random positions
177
- std::vector<bool> positions(v.size() + number_of_spaces, false);
178
- std::uniform_int_distribution<size_t> dist(0, positions.size() - 1);
179
- for (size_t i = 0; i < number_of_spaces; ++i) {
180
- size_t pos = dist(gen);
181
- while (positions[pos]) {
182
- pos = dist(gen);
183
- }
184
- positions[pos] = true;
185
- }
186
- std::string result;
187
- result.resize(v.size() + number_of_spaces);
188
- int pos = 0;
189
- for (size_t i = 0; i < v.size() + number_of_spaces; ++i) {
190
- if (positions[i]) {
191
- result[i] = ' ';
192
- } else {
193
- result[i] = v[pos++];
194
- }
195
- }
196
- return result;
197
- }
198
-
199
- template <typename char_type>
200
- size_t add_garbage(std::vector<char_type> &v, std::mt19937 &gen,
201
- const uint8_t *table) {
202
- auto equal_sign = std::find(v.begin(), v.end(), '=');
203
- size_t len = v.size();
204
- if (equal_sign != v.end()) {
205
- len = std::distance(v.begin(), equal_sign);
206
- }
207
- std::uniform_int_distribution<int> index_dist(0, len);
208
- size_t i = index_dist(gen);
209
- std::uniform_int_distribution<int> char_dist(
210
- 0, (1 << (sizeof(char_type) * 8)) - 1);
211
- char_type c = char_dist(gen);
212
- while ((uint8_t(c) == c && table[uint8_t(c)] != 255) || c == '=') {
213
- c = char_dist(gen);
214
- }
215
- v.insert(v.begin() + i, c);
216
- return i;
217
- }
218
-
219
- // https://github.com/tc39/test262/blob/f0dc15c6c7ec095ba3caf3acc0f8665394665841/test/built-ins/Uint8Array/fromBase64/last-chunk-invalid.js
220
- TEST(tc39_illegal_padded_chunks) {
221
- std::string test_cases[] = {
222
- "=", "==", "===", "====", "=====", "A=",
223
- "A==", "A===", "A====", "A=====", "AA====", "AA=====",
224
- "AAA==", "AAA===", "AAA====", "AAA=====", "AAAA=", "AAAA==",
225
- "AAAA===", "AAAA====", "AAAA=====", "AAAAA=", "AAAAA==", "AAAAA===",
226
- "AAAAA====", "AAAAA====="};
227
- std::mt19937 gen((std::mt19937::result_type)(seed));
228
- for (const std::string &input : test_cases) {
229
- std::vector<uint8_t> back(255);
230
- size_t len = back.size();
231
- for (auto option :
232
- {simdutf::last_chunk_handling_options::strict,
233
- simdutf::last_chunk_handling_options::loose,
234
- simdutf::last_chunk_handling_options::stop_before_partial}) {
235
- auto r = simdutf::base64_to_binary_safe(
236
- input.data(), input.size(), reinterpret_cast<char *>(back.data()),
237
- len, simdutf::base64_default, option, true);
238
- ASSERT_FALSE(r.error == simdutf::error_code::SUCCESS);
239
- ASSERT_FALSE(r.error == simdutf::error_code::OUTPUT_BUFFER_TOO_SMALL);
240
- }
241
- }
242
- }
243
-
244
- // From Node.js tests:
245
- TEST(issue_node_anything_goes) {
246
-
247
- auto test =
248
- [](const std::string &input, const std::string &expected,
249
- simdutf::base64_options options =
250
- simdutf::base64_options::base64_default_or_url_accept_garbage) {
251
- size_t buflen = simdutf::maximal_binary_length_from_base64(
252
- input.data(), input.size());
253
- std::vector<char> back(buflen);
254
- size_t written_len = buflen;
255
- auto result = simdutf::base64_to_binary_safe(
256
- input.data(), input.length(), back.data(), written_len,
257
- simdutf::base64_default_or_url_accept_garbage);
258
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
259
- ASSERT_EQUAL(written_len, expected.size());
260
- ASSERT_TRUE(std::equal(back.begin(), back.begin() + written_len,
261
- expected.begin()));
262
- };
263
- test("YQ", "a");
264
- test("Y Q", "a");
265
- test("Y Q ", "a");
266
- test(" Y Q", "a");
267
- test("Y Q==", "a");
268
- test("YQ ==", "a");
269
- test("YQ == junk", "a");
270
- test("YWI", "ab");
271
- test("YWI=", "ab");
272
- test("YWJj", "abc");
273
- test("YWJjZA", "abcd");
274
- test("YWJjZA==", "abcd");
275
- test("YW Jj ZA ==", "abcd");
276
- test("YWJjZGU=", "abcde");
277
- test("YWJjZGVm", "abcdef");
278
- test("Y WJjZGVm", "abcdef");
279
- test("YW JjZGVm", "abcdef");
280
- test("YWJ jZGVm", "abcdef");
281
- test("YWJj ZGVm", "abcdef");
282
- test("Y W J j Z G V m", "abcdef");
283
- test("Y W\n JjZ \nG Vm", "abcdef");
284
- test("rMeTqoNvw-M_dQ", "\xac\xc7\x93\xaa\x83\x6f\xc3\xe3\x3f\x75");
285
-
286
- const char *text =
287
- "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do "
288
- "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut "
289
- "enim ad minim veniam, quis nostrud exercitation ullamco laboris "
290
- "nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in "
291
- "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla "
292
- "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in "
293
- "culpa qui officia deserunt mollit anim id est laborum.";
294
-
295
- test("TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Npbmcg"
296
- "ZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0"
297
- "IGRvbG9yZSBtYWduYSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVuaWFtLCBxdWlz"
298
- "IG5vc3RydWQgZXhlcmNpdGF0aW9uIHVsbGFtY28gbGFib3JpcyBuaXNpIHV0IGFsaXF1"
299
- "aXAgZXggZWEgY29tbW9kbyBjb25zZXF1YXQuIER1aXMgYXV0ZSBpcnVyZSBkb2xvciBp"
300
- "biByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZSB2ZWxpdCBlc3NlIGNpbGx1bSBkb2xv"
301
- "cmUgZXUgZnVnaWF0IG51bGxhIHBhcmlhdHVyLiBFeGNlcHRldXIgc2ludCBvY2NhZWNh"
302
- "dCBjdXBpZGF0YXQgbm9uIHByb2lkZW50LCBzdW50IGluIGN1bHBhIHF1aSBvZmZpY2lh"
303
- "IGRlc2VydW50IG1vbGxpdCBhbmltIGlkIGVzdCBsYWJvcnVtLg==",
304
- text);
305
-
306
- test("TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Npbmcg"
307
- "ZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0"
308
- "IGRvbG9yZSBtYWduYSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVuaWFtLCBxdWlz"
309
- "IG5vc3RydWQgZXhlcmNpdGF0aW9uIHVsbGFtY28gbGFib3JpcyBuaXNpIHV0IGFsaXF1"
310
- "aXAgZXggZWEgY29tbW9kbyBjb25zZXF1YXQuIER1aXMgYXV0ZSBpcnVyZSBkb2xvciBp"
311
- "biByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZSB2ZWxpdCBlc3NlIGNpbGx1bSBkb2xv"
312
- "cmUgZXUgZnVnaWF0IG51bGxhIHBhcmlhdHVyLiBFeGNlcHRldXIgc2ludCBvY2NhZWNh"
313
- "dCBjdXBpZGF0YXQgbm9uIHByb2lkZW50LCBzdW50IGluIGN1bHBhIHF1aSBvZmZpY2lh"
314
- "IGRlc2VydW50IG1vbGxpdCBhbmltIGlkIGVzdCBsYWJvcnVtLg",
315
- text);
316
-
317
- test("TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Npbmcg\n"
318
- "ZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0\n"
319
- "IGRvbG9yZSBtYWduYSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVuaWFtLCBxdWlz\n"
320
- "IG5vc3RydWQgZXhlcmNpdGF0aW9uIHVsbGFtY28gbGFib3JpcyBuaXNpIHV0IGFsaXF1\n"
321
- "aXAgZXggZWEgY29tbW9kbyBjb25zZXF1YXQuIER1aXMgYXV0ZSBpcnVyZSBkb2xvciBp\n"
322
- "biByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZSB2ZWxpdCBlc3NlIGNpbGx1bSBkb2xv\n"
323
- "cmUgZXUgZnVnaWF0IG51bGxhIHBhcmlhdHVyLiBFeGNlcHRldXIgc2ludCBvY2NhZWNh\n"
324
- "dCBjdXBpZGF0YXQgbm9uIHByb2lkZW50LCBzdW50IGluIGN1bHBhIHF1aSBvZmZpY2lh\n"
325
- "IGRlc2VydW50IG1vbGxpdCBhbmltIGlkIGVzdCBsYWJvcnVtLg==",
326
- text);
327
-
328
- test("TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Npbmcg\n"
329
- "ZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlIGV0\n"
330
- "IGRvbG9yZSBtYWduYSBhbGlxdWEuIFV0IGVuaW0gYWQgbWluaW0gdmVuaWFtLCBxdWlz\n"
331
- "IG5vc3RydWQgZXhlcmNpdGF0aW9uIHVsbGFtY28gbGFib3JpcyBuaXNpIHV0IGFsaXF1\n"
332
- "aXAgZXggZWEgY29tbW9kbyBjb25zZXF1YXQuIER1aXMgYXV0ZSBpcnVyZSBkb2xvciBp\n"
333
- "biByZXByZWhlbmRlcml0IGluIHZvbHVwdGF0ZSB2ZWxpdCBlc3NlIGNpbGx1bSBkb2xv\n"
334
- "cmUgZXUgZnVnaWF0IG51bGxhIHBhcmlhdHVyLiBFeGNlcHRldXIgc2ludCBvY2NhZWNh\n"
335
- "dCBjdXBpZGF0YXQgbm9uIHByb2lkZW50LCBzdW50IGluIGN1bHBhIHF1aSBvZmZpY2lh\n"
336
- "IGRlc2VydW50IG1vbGxpdCBhbmltIGlkIGVzdCBsYWJvcnVtLg",
337
- text);
338
- }
339
-
340
- TEST(issue_dash) {
341
- const std::string input = "Iw==";
342
- std::vector<char> back(1);
343
- size_t len = back.size();
344
- auto r = simdutf::base64_to_binary_safe(input.data(), input.size(),
345
- back.data(), len);
346
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
347
- ASSERT_EQUAL(r.count, 4);
348
- ASSERT_EQUAL(len, 1);
349
- ASSERT_EQUAL(back[0], '#');
350
- }
351
-
352
- TEST(issue_dash_partial) {
353
- const std::string input = "Iw==";
354
- std::vector<char> back(1);
355
- size_t len = back.size();
356
- auto r = simdutf::base64_to_binary_safe(
357
- input.data(), input.size(), back.data(), len, simdutf::base64_default,
358
- simdutf::last_chunk_handling_options::stop_before_partial);
359
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
360
- ASSERT_EQUAL(r.count, 4);
361
- ASSERT_EQUAL(len, 1);
362
- ASSERT_EQUAL(back[0], '#');
363
- }
364
-
365
- // https://github.com/tc39/test262
366
- TEST(tc39_4a) {
367
- std::pair<std::string, std::vector<uint8_t>> test_cases[] = {
368
- {"ZXhhZg==", {101, 120, 97, 102}},
369
- {"ZXhhZg", {101, 120, 97}},
370
- {"ZXhhZh==", {101, 120, 97, 102}},
371
- {"ZXhhZh", {101, 120, 97}},
372
- {"ZXhhZg=", {101, 120, 97}}};
373
- for (const auto tc : test_cases) {
374
- const std::string &input = tc.first;
375
- const std::vector<uint8_t> &expected = tc.second;
376
- std::vector<uint8_t> back(expected.size(), 255);
377
- size_t len = back.size();
378
- auto r = simdutf::base64_to_binary_safe(
379
- input.data(), input.size(), reinterpret_cast<char *>(back.data()), len,
380
- simdutf::base64_default,
381
- simdutf::last_chunk_handling_options::stop_before_partial, true);
382
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
383
- ASSERT_EQUAL(len, expected.size());
384
- ASSERT_EQUAL(back, expected);
385
- }
386
- }
387
-
388
- // https://github.com/tc39/test262
389
- TEST(tc39_4b) {
390
- std::pair<std::string, std::vector<uint8_t>> test_cases[] = {
391
- {"ZXhhZg==", {101, 120, 97, 102}},
392
- {"ZXhhZg", {101, 120, 97}},
393
- {"ZXhhZh==", {101, 120, 97, 102}},
394
- {"ZXhhZh", {101, 120, 97}},
395
- {"ZXhhZg=", {101, 120, 97}}};
396
- for (const auto tc : test_cases) {
397
- const std::string &input = tc.first;
398
- const std::vector<uint8_t> &expected = tc.second;
399
- std::vector<uint8_t> back(expected.size(), 255);
400
- size_t len = back.size();
401
- auto r = simdutf::base64_to_binary_safe(
402
- input.data(), input.size(), reinterpret_cast<char *>(back.data()), len,
403
- simdutf::base64_default,
404
- simdutf::last_chunk_handling_options::stop_before_partial, true);
405
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
406
- ASSERT_EQUAL(len, expected.size());
407
- ASSERT_EQUAL(back, expected);
408
- }
409
- }
410
-
411
- // https://github.com/tc39/test262
412
- TEST(tc39_3a) {
413
- const std::string input = "ZXhhZg===";
414
- std::vector<uint8_t> back = {255, 255, 255, 255, 255};
415
-
416
- size_t len = back.size();
417
- auto r = simdutf::base64_to_binary_safe(
418
- input.data(), input.size(), reinterpret_cast<char *>(back.data()), len,
419
- simdutf::base64_default,
420
- simdutf::last_chunk_handling_options::stop_before_partial, true);
421
- ASSERT_TRUE(r.error != simdutf::error_code::SUCCESS);
422
- }
423
-
424
- // https://github.com/tc39/test262
425
- TEST(tc39_3b) {
426
- const std::string input = "ZXhhZg===";
427
- std::vector<uint8_t> back = {255, 255, 255, 255, 255};
428
-
429
- size_t len = back.size();
430
- auto r = implementation.base64_to_binary(
431
- input.data(), input.size(), reinterpret_cast<char *>(back.data()),
432
- simdutf::base64_default,
433
- simdutf::last_chunk_handling_options::stop_before_partial);
434
- ASSERT_TRUE(r.error != simdutf::error_code::SUCCESS);
435
- }
436
-
437
- // https://github.com/tc39/test262
438
- TEST(tc39_1a) {
439
- const std::string input = "Zm9vYmE=";
440
- std::vector<uint8_t> back = {255, 255, 255, 255, 255};
441
- std::vector<uint8_t> expected = {102, 111, 111, 98, 97};
442
-
443
- size_t len = back.size();
444
- auto r = simdutf::base64_to_binary_safe(
445
- input.data(), input.size(), reinterpret_cast<char *>(back.data()), len,
446
- simdutf::base64_default,
447
- simdutf::last_chunk_handling_options::stop_before_partial, true);
448
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
449
- ASSERT_EQUAL(r.count, 8);
450
- ASSERT_EQUAL(len, 5);
451
- ASSERT_EQUAL(back, expected);
452
- }
453
-
454
- // https://github.com/tc39/test262
455
- TEST(tc39_1b) {
456
- const std::string input = "Zm9vYmE=";
457
- std::vector<uint8_t> back = {255, 255, 255, 255, 255};
458
- std::vector<uint8_t> expected = {102, 111, 111, 98, 97};
459
-
460
- size_t len = back.size();
461
- auto r = simdutf::base64_to_binary_safe(
462
- input.data(), input.size(), reinterpret_cast<char *>(back.data()), len,
463
- simdutf::base64_default,
464
- simdutf::last_chunk_handling_options::stop_before_partial, true);
465
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
466
- ASSERT_EQUAL(r.count, 8);
467
- ASSERT_EQUAL(len, 5);
468
- ASSERT_EQUAL(back, expected);
469
- }
470
-
471
- // https://github.com/tc39/test262
472
- TEST(tc39_2) {
473
- const std::string input = "Zm9vYmE";
474
- std::vector<uint8_t> back = {255, 255, 255, 255, 255};
475
- std::vector<uint8_t> expected = {102, 111, 111, 255, 255};
476
-
477
- size_t len = back.size();
478
- auto r = simdutf::base64_to_binary_safe(
479
- input.data(), input.size(), reinterpret_cast<char *>(back.data()), len,
480
- simdutf::base64_default,
481
- simdutf::last_chunk_handling_options::stop_before_partial, true);
482
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
483
- ASSERT_EQUAL(r.count, 4);
484
- ASSERT_EQUAL(len, 3);
485
- ASSERT_EQUAL(back, expected);
486
- }
487
-
488
- // https://github.com/tc39/test262/blob/f0dc15c6c7ec095ba3caf3acc0f8665394665841/test/built-ins/Uint8Array/fromBase64/last-chunk-invalid.js
489
- TEST(tc39_illegal_padded_chunks_unsafe) {
490
- std::string test_cases[] = {
491
- "=", "==", "===", "====", "=====", "A=",
492
- "A==", "A===", "A====", "A=====", "AA====", "AA=====",
493
- "AAA==", "AAA===", "AAA====", "AAA=====", "AAAA=", "AAAA==",
494
- "AAAA===", "AAAA====", "AAAA=====", "AAAAA=", "AAAAA==", "AAAAA===",
495
- "AAAAA====", "AAAAA====="};
496
- std::mt19937 gen((std::mt19937::result_type)(seed));
497
- for (const std::string &input : test_cases) {
498
- std::vector<uint8_t> back(255);
499
- size_t len = back.size();
500
- for (auto option :
501
- {simdutf::last_chunk_handling_options::strict,
502
- simdutf::last_chunk_handling_options::loose,
503
- simdutf::last_chunk_handling_options::stop_before_partial}) {
504
- auto r = simdutf::base64_to_binary(input.data(), input.size(),
505
- reinterpret_cast<char *>(back.data()),
506
- simdutf::base64_default, option);
507
- ASSERT_FALSE(r.error == simdutf::error_code::SUCCESS);
508
- }
509
- }
510
- std::string base(128, 'A');
511
- for (const std::string &input_orig : test_cases) {
512
- std::string input = base + input_orig;
513
-
514
- std::vector<uint8_t> back(255);
515
- size_t len = back.size();
516
- for (auto option :
517
- {simdutf::last_chunk_handling_options::strict,
518
- simdutf::last_chunk_handling_options::loose,
519
- simdutf::last_chunk_handling_options::stop_before_partial}) {
520
- auto r = simdutf::base64_to_binary(input.data(), input.size(),
521
- reinterpret_cast<char *>(back.data()),
522
- simdutf::base64_default, option);
523
- ASSERT_FALSE(r.error == simdutf::error_code::SUCCESS);
524
- }
525
- }
526
- for (const std::string &input_orig : test_cases) {
527
- std::string input = base + input_orig;
528
- input = add_simple_spaces(input, gen, 5 + 2 * input.size());
529
- std::vector<uint8_t> back(255);
530
- size_t len = back.size();
531
- for (auto option :
532
- {simdutf::last_chunk_handling_options::strict,
533
- simdutf::last_chunk_handling_options::loose,
534
- simdutf::last_chunk_handling_options::stop_before_partial}) {
535
- auto r = simdutf::base64_to_binary(input.data(), input.size(),
536
- reinterpret_cast<char *>(back.data()),
537
- simdutf::base64_default, option);
538
- ASSERT_FALSE(r.error == simdutf::error_code::SUCCESS);
539
- }
540
- }
541
- }
542
-
543
- auto verify_lines = [](const char *c, int N, int line_length) {
544
- int current_line_length = 0; // Track the length of the current line
545
- // Iterate through the string
546
- for (int i = 0; i < N; ++i) {
547
- if (c[i] == '\n') {
548
- // Check if a non-final line has incorrect length
549
- if (current_line_length != line_length) {
550
- std::cerr << "A non-final line has incorrect length "
551
- << current_line_length << " != " << line_length << "\n";
552
- std::cerr << std::string(c, N) << "\n";
553
- return false;
554
- }
555
- current_line_length = 0; // Reset for the next line
556
- continue;
557
- }
558
-
559
- current_line_length++;
560
- // Check if the current line exceeds the allowed length
561
- if (current_line_length > line_length) {
562
- std::cerr << "A line exceeds the allowed length " << current_line_length
563
- << " > " << line_length << "\n";
564
- std::cerr << std::string(c, N) << "\n";
565
- return false;
566
- }
567
- }
568
- return true;
569
- };
570
-
571
- TEST(with_lines_pauldreik) {
572
- size_t line_length = 5;
573
- size_t max_length = 2048;
574
- std::vector<char> source(max_length, 'f');
575
- std::vector<char> back(max_length);
576
- std::vector<char> buffer;
577
- for (auto selected_option : {simdutf::base64_options::base64_url,
578
- simdutf::base64_options::base64_default}) {
579
- for (size_t line_length = 5; line_length < 128; line_length += 7) {
580
- for (size_t length = 1; length < 2048; length += 17) {
581
- buffer.resize(simdutf::base64_length_from_binary_with_lines(
582
- length, selected_option, line_length));
583
- size_t size = implementation.binary_to_base64_with_lines(
584
- source.data(), length, buffer.data(), line_length, selected_option);
585
- auto r = implementation.base64_to_binary(buffer.data(), buffer.size(),
586
- back.data(), selected_option);
587
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
588
- ASSERT_TRUE(
589
- std::equal(back.begin(), back.begin() + length, source.begin()));
590
- ASSERT_EQUAL(size, buffer.size());
591
- ASSERT_TRUE(verify_lines(buffer.data(), buffer.size(), line_length));
592
- }
593
- }
594
- }
595
- }
596
-
597
- TEST(with_lines) {
598
-
599
- for (size_t line_length : {4, 64, 76, 80, 128}) {
600
- for (size_t len = 0; len < max_len; len += 17) {
601
- std::vector<char> source(len, 0);
602
- std::vector<char> buffer;
603
- buffer.resize(simdutf::base64_length_from_binary_with_lines(
604
- len, simdutf::base64_default, line_length));
605
- std::mt19937 gen((std::mt19937::result_type)(seed));
606
- std::uniform_int_distribution<int> byte_generator{0, 255};
607
- for (size_t trial = 0; trial < 2; trial++) {
608
- for (size_t i = 0; i < len; i++) {
609
- source[i] = byte_generator(gen);
610
- }
611
- size_t size = implementation.binary_to_base64_with_lines(
612
- source.data(), source.size(), buffer.data(), line_length);
613
- ASSERT_EQUAL(size, buffer.size());
614
- buffer.resize(size); // unnecessary
615
- ASSERT_TRUE(verify_lines(buffer.data(), buffer.size(), line_length));
616
- std::vector<char> back(simdutf::maximal_binary_length_from_base64(
617
- buffer.data(), buffer.size()));
618
- auto option = simdutf::last_chunk_handling_options::stop_before_partial;
619
-
620
- simdutf::full_result r = implementation.base64_to_binary_details(
621
- buffer.data(), buffer.size(), back.data(), simdutf::base64_default,
622
- option);
623
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
624
- const size_t expected_output_length = len;
625
- const size_t expected_input_length = prefix_length_base64_index(
626
- (expected_output_length + 2) / 3 * 4, simdutf::base64_default,
627
- buffer.data(), buffer.size());
628
- ASSERT_EQUAL(r.output_count, expected_output_length);
629
- ASSERT_TRUE(std::equal(back.begin(),
630
- back.begin() + expected_output_length,
631
- source.begin()));
632
- ASSERT_EQUAL(r.input_count, expected_input_length);
633
- }
634
- }
635
- }
636
- }
637
-
638
- // stop-before-partial should behave like so:
639
- // 1. if the last chunk is not a multiple of 4, we should stop before the last
640
- // chunk
641
- // 2. if the last chunk is a multiple of 4 (counting padding), we should
642
- // decode it
643
- // 3. If there is a padding character appearing in the last chunk where we have
644
- // fewer than 2 base64 characters, we should return an error.
645
- //
646
- // https://tc39.es/proposal-arraybuffer-base64/spec/#sec-frombase64
647
- //
648
- TEST(partial_should_decode_up_to_last_chunk) {
649
- for (size_t len = 0; len < max_len; len++) {
650
- std::vector<char> source(len, 0);
651
- std::vector<char> buffer;
652
- buffer.resize(simdutf::base64_length_from_binary(len));
653
- std::mt19937 gen((std::mt19937::result_type)(seed));
654
- std::uniform_int_distribution<int> byte_generator{0, 255};
655
- for (size_t trial = 0; trial < 10; trial++) {
656
- for (size_t i = 0; i < len; i++) {
657
- source[i] = byte_generator(gen);
658
- }
659
- buffer.resize(simdutf::base64_length_from_binary(len));
660
- size_t size = implementation.binary_to_base64(
661
- source.data(), source.size(), buffer.data());
662
- ASSERT_EQUAL(size, buffer.size());
663
- buffer.resize(size); // unnecessary
664
- add_simple_spaces(buffer, gen, 5 + 2 * len);
665
- std::vector<char> back(simdutf::maximal_binary_length_from_base64(
666
- buffer.data(), buffer.size()));
667
- auto option = simdutf::last_chunk_handling_options::stop_before_partial;
668
-
669
- simdutf::full_result r = implementation.base64_to_binary_details(
670
- buffer.data(), buffer.size(), back.data(), simdutf::base64_default,
671
- option);
672
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
673
- const size_t expected_output_length = len;
674
- const size_t expected_input_length = prefix_length_base64_index(
675
- (expected_output_length + 2) / 3 * 4, simdutf::base64_default,
676
- buffer.data(), buffer.size());
677
- ASSERT_EQUAL(r.output_count, expected_output_length);
678
- ASSERT_TRUE(std::equal(
679
- back.begin(), back.begin() + expected_output_length, source.begin()));
680
- // If there is just zero one character in the last chunk, and there is a
681
- // padding character, we should return an error.
682
- if (buffer.size() > 0 && len > 0 && len % 3 != 0) {
683
- // We have a last chunk that is not a multiple of 4.
684
- // So there are padding characters.
685
- size_t to_remove = 0;
686
- // We want to leave just one character in the last chunk
687
- // This should cause an error.
688
- if (len % 3 == 1) {
689
- // last chunk is 2
690
- to_remove = 1;
691
- } else if (len % 3 == 2) {
692
- // last chunk is 3
693
- to_remove = 2;
694
- }
695
- for (size_t i = buffer.size() - 1;; i--) {
696
- if (simdutf::base64_valid(buffer[i], simdutf::base64_default)) {
697
- buffer[i] = ' ';
698
- to_remove--;
699
- if (to_remove == 0) {
700
- break;
701
- }
702
- }
703
- }
704
- r = implementation.base64_to_binary_details(
705
- buffer.data(), buffer.size(), back.data(), simdutf::base64_default,
706
- option);
707
- ASSERT_EQUAL(r.error, simdutf::error_code::BASE64_INPUT_REMAINDER);
708
- // Next, we empty the last chunk
709
- for (size_t i = buffer.size() - 1;; i--) {
710
- if (simdutf::base64_valid(buffer[i], simdutf::base64_default)) {
711
- buffer[i] = ' ';
712
- break;
713
- }
714
- }
715
- r = implementation.base64_to_binary_details(
716
- buffer.data(), buffer.size(), back.data(), simdutf::base64_default,
717
- option);
718
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
719
- }
720
- }
721
- }
722
- }
723
-
724
- TEST(partial_should_decode_four_wise_chunks) {
725
- // 37 bytes = 4 * 3 + 1
726
- const std::string input = "X8vzLrvHmZgncicZDnXdVZkktaYFDvi41fA2A";
727
- std::vector<char> buffer;
728
- buffer.resize(input.size() / 4 * 3);
729
- auto option = simdutf::last_chunk_handling_options::stop_before_partial;
730
- auto r = implementation.base64_to_binary_details(
731
- input.data(), input.size(), buffer.data(), simdutf::base64_default,
732
- option);
733
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
734
- ASSERT_TRUE(r.input_count == 36);
735
- ASSERT_TRUE(r.output_count == 27);
736
- }
737
-
738
- TEST(stop_before_partial_one_char) {
739
- std::vector<char> base64(5463, 0x20);
740
- base64.back() = 0x38; // this is the number 8 (a valid base64 character)
741
- std::vector<char> back(0);
742
- // with stop_before_partial, we should stop before the last character
743
- // and not decode it. There should be no error.
744
- // https://tc39.es/proposal-arraybuffer-base64/spec/#sec-frombase64
745
- simdutf::result r = implementation.base64_to_binary(
746
- base64.data(), base64.size(), back.data(), simdutf::base64_default,
747
- simdutf::last_chunk_handling_options::stop_before_partial);
748
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
749
- ASSERT_EQUAL(r.count, 0);
750
- size_t buflen = back.size();
751
- ASSERT_EQUAL(buflen, 0);
752
- r = simdutf::base64_to_binary_safe(
753
- base64.data(), base64.size(), back.data(), buflen,
754
- simdutf::base64_default,
755
- simdutf::last_chunk_handling_options::stop_before_partial);
756
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
757
- ASSERT_EQUAL(buflen, 0);
758
- back.resize(base64.size());
759
- buflen = back.size();
760
- r = simdutf::base64_to_binary_safe(
761
- base64.data(), base64.size(), back.data(), buflen,
762
- simdutf::base64_default,
763
- simdutf::last_chunk_handling_options::stop_before_partial);
764
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
765
- ASSERT_EQUAL(buflen, 0);
766
- }
767
-
768
- TEST(hybrid_decoding) {
769
- std::vector<std::pair<std::string, std::vector<uint8_t>>> test_data = {
770
- {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA__--_"
771
- "--"
772
- "_--__"
773
- "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
774
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
775
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
776
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
777
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
778
- 0xff, 0xff, 0xbe, 0xff, 0xef, 0xbf, 0xfb, 0xef, 0xff, 0x00, 0x00, 0x00,
779
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
780
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
781
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
782
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
783
- {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA__-+_"
784
- "--"
785
- "_--/"
786
- "_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
787
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
788
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
789
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
790
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
791
- 0xff, 0xff, 0xbe, 0xff, 0xef, 0xbf, 0xfb, 0xef, 0xff, 0x00, 0x00, 0x00,
792
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
793
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
794
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
795
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
796
- {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA__-+_"
797
- "--"
798
- " / "
799
- "--/_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
800
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
801
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
802
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
803
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
804
- 0xff, 0xff, 0xbe, 0xff, 0xef, 0xbf, 0xfb, 0xef, 0xff, 0x00, 0x00, 0x00,
805
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
806
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
807
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
808
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
809
- {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//-+/"
810
- "--/--/"
811
- "_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
812
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
813
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
814
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
815
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
816
- 0xff, 0xff, 0xbe, 0xff, 0xef, 0xbf, 0xfb, 0xef, 0xff, 0x00, 0x00, 0x00,
817
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
818
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
819
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
820
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
821
-
822
- };
823
- for (const auto &test : test_data) {
824
- const std::string &base64 = test.first;
825
- const std::vector<uint8_t> &expected = test.second;
826
- std::vector<uint8_t> decoded(simdutf::maximal_binary_length_from_base64(
827
- base64.data(), base64.size()));
828
- auto r = implementation.base64_to_binary(
829
- base64.data(), base64.size(), reinterpret_cast<char *>(decoded.data()),
830
- simdutf::base64_default_or_url);
831
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
832
- ASSERT_EQUAL(r.count, expected.size());
833
- decoded.resize(r.count);
834
- ASSERT_EQUAL(decoded, expected);
835
- }
836
- }
837
-
838
- TEST(roundtrip_base64_with_spaces) {
839
- for (size_t len = 0; len < max_len; len++) {
840
- std::vector<char> source(len, 0);
841
- std::vector<char> buffer;
842
- buffer.resize(simdutf::base64_length_from_binary(len));
843
- std::mt19937 gen((std::mt19937::result_type)(seed));
844
- std::uniform_int_distribution<int> byte_generator{0, 255};
845
- for (size_t trial = 0; trial < 10; trial++) {
846
- for (size_t i = 0; i < len; i++) {
847
- source[i] = 'a' + i % ('z' - 'a'); // byte_generator(gen);
848
- }
849
- size_t size = implementation.binary_to_base64(
850
- source.data(), source.size(), buffer.data());
851
- buffer.resize(size);
852
- for (size_t i = 0; i < 5; i++) {
853
- add_space(buffer, gen);
854
- }
855
- std::vector<char> back(simdutf::maximal_binary_length_from_base64(
856
- buffer.data(), buffer.size()));
857
- for (auto option :
858
- {simdutf::last_chunk_handling_options::strict,
859
- simdutf::last_chunk_handling_options::loose,
860
- simdutf::last_chunk_handling_options::stop_before_partial}) {
861
- if (option ==
862
- simdutf::last_chunk_handling_options::stop_before_partial &&
863
- len % 3 != 0) {
864
- continue;
865
- }
866
- simdutf::result r = implementation.base64_to_binary(
867
- buffer.data(), buffer.size(), back.data(), simdutf::base64_default,
868
- option);
869
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
870
- ASSERT_EQUAL(r.count, len);
871
- ASSERT_BYTES_EQUAL(source, back, len);
872
- }
873
- for (auto option :
874
- {simdutf::last_chunk_handling_options::strict,
875
- simdutf::last_chunk_handling_options::loose,
876
- simdutf::last_chunk_handling_options::stop_before_partial}) {
877
- if (option ==
878
- simdutf::last_chunk_handling_options::stop_before_partial &&
879
- len % 3 != 0) {
880
- continue;
881
- }
882
- size_t back_length = back.size();
883
- auto r = simdutf::base64_to_binary_safe(
884
- buffer.data(), buffer.size(), back.data(), back_length,
885
- simdutf::base64_default, option);
886
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
887
- ASSERT_EQUAL(back_length, len);
888
-
889
- for (size_t i = r.count; i < buffer.size(); i++) {
890
- ASSERT_TRUE(is_space(buffer[i]));
891
- }
892
- ASSERT_TRUE(std::equal(back.begin(), back.begin() + back_length,
893
- source.begin()));
894
- }
895
- }
896
- }
897
- }
898
-
899
- TEST(roundtrip_base64_with_garbage) {
900
- for (size_t len = 0; len < max_len; len++) {
901
- std::vector<char> source(len, 0);
902
- std::vector<char> buffer;
903
- buffer.resize(simdutf::base64_length_from_binary(len));
904
- std::mt19937 gen((std::mt19937::result_type)(seed));
905
- std::uniform_int_distribution<int> byte_generator{0, 255};
906
- for (size_t trial = 0; trial < 10; trial++) {
907
- for (size_t i = 0; i < len; i++) {
908
- source[i] = byte_generator(gen);
909
- }
910
- size_t size = implementation.binary_to_base64(
911
- source.data(), source.size(), buffer.data());
912
- buffer.resize(size);
913
- for (size_t i = 0; i < 5; i++) {
914
- add_garbage(buffer, gen, to_base64_value);
915
- }
916
- std::vector<char> back(simdutf::maximal_binary_length_from_base64(
917
- buffer.data(), buffer.size()));
918
- for (auto option : {simdutf::last_chunk_handling_options::strict,
919
- simdutf::last_chunk_handling_options::loose}) {
920
- simdutf::result r = implementation.base64_to_binary(
921
- buffer.data(), buffer.size(), back.data(),
922
- simdutf::base64_default_accept_garbage, option);
923
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
924
- ASSERT_EQUAL(r.count, len);
925
- ASSERT_TRUE(
926
- std::equal(back.begin(), back.begin() + len, source.begin()));
927
- }
928
- for (auto option :
929
- {simdutf::last_chunk_handling_options::strict,
930
- simdutf::last_chunk_handling_options::loose,
931
- simdutf::last_chunk_handling_options::stop_before_partial}) {
932
- if (option ==
933
- simdutf::last_chunk_handling_options::stop_before_partial &&
934
- len % 3 != 0) {
935
- continue;
936
- }
937
- size_t back_length = back.size();
938
- auto r = simdutf::base64_to_binary_safe(
939
- buffer.data(), buffer.size(), back.data(), back_length,
940
- simdutf::base64_default_accept_garbage, option);
941
-
942
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
943
- ASSERT_EQUAL(back_length, len);
944
- for (size_t i = r.count; i < buffer.size(); i++) {
945
- ASSERT_TRUE(!simdutf::base64_valid(
946
- buffer[i], simdutf::base64_default_accept_garbage));
947
- }
948
- ASSERT_TRUE(std::equal(back.begin(), back.begin() + back_length,
949
- source.begin()));
950
- }
951
- }
952
- }
953
- }
954
-
955
- TEST(roundtrip_base64_url_with_garbage) {
956
- for (size_t len = 0; len < max_len; len++) {
957
- std::vector<char> source(len, 0);
958
- std::vector<char> buffer;
959
- buffer.resize(simdutf::base64_length_from_binary(len));
960
- std::mt19937 gen((std::mt19937::result_type)(seed));
961
- std::uniform_int_distribution<int> byte_generator{0, 255};
962
- for (size_t trial = 0; trial < 10; trial++) {
963
- for (size_t i = 0; i < len; i++) {
964
- source[i] = byte_generator(gen);
965
- }
966
- size_t size = implementation.binary_to_base64(
967
- source.data(), source.size(), buffer.data(), simdutf::base64_url);
968
- buffer.resize(size);
969
- for (size_t i = 0; i < 5; i++) {
970
- add_garbage(buffer, gen, to_base64url_value);
971
- }
972
- std::vector<char> back(simdutf::maximal_binary_length_from_base64(
973
- buffer.data(), buffer.size()));
974
- for (auto option :
975
- {simdutf::last_chunk_handling_options::strict,
976
- simdutf::last_chunk_handling_options::loose,
977
- simdutf::last_chunk_handling_options::stop_before_partial}) {
978
- if (option ==
979
- simdutf::last_chunk_handling_options::stop_before_partial &&
980
- len % 3 != 0) {
981
- continue;
982
- }
983
- simdutf::result r = implementation.base64_to_binary(
984
- buffer.data(), buffer.size(), back.data(),
985
- simdutf::base64_url_accept_garbage, option);
986
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
987
- ASSERT_EQUAL(r.count, len);
988
- ASSERT_TRUE(
989
- std::equal(back.begin(), back.begin() + len, source.begin()));
990
- }
991
- for (auto option :
992
- {simdutf::last_chunk_handling_options::strict,
993
- simdutf::last_chunk_handling_options::loose,
994
- simdutf::last_chunk_handling_options::stop_before_partial}) {
995
- if (option ==
996
- simdutf::last_chunk_handling_options::stop_before_partial &&
997
- len % 3 != 0) {
998
- continue;
999
- }
1000
- size_t back_length = back.size();
1001
- auto r = simdutf::base64_to_binary_safe(
1002
- buffer.data(), buffer.size(), back.data(), back_length,
1003
- simdutf::base64_url_accept_garbage, option);
1004
-
1005
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
1006
- ASSERT_EQUAL(back_length, len);
1007
-
1008
- if (option ==
1009
- simdutf::last_chunk_handling_options::stop_before_partial) {
1010
- for (size_t i = r.count; i < buffer.size(); i++) {
1011
- ASSERT_TRUE(is_non_base64_url_space(buffer[i]));
1012
- }
1013
- } else {
1014
- ASSERT_EQUAL(r.count, buffer.size());
1015
- }
1016
- ASSERT_TRUE(std::equal(back.begin(), back.begin() + back_length,
1017
- source.begin()));
1018
- }
1019
- }
1020
- }
1021
- }
1022
-
1023
- TEST(roundtrip_base64_with_lots_of_spaces) {
1024
- for (size_t len = 0; len < max_len; len++) {
1025
- std::vector<char> source(len, 0);
1026
- std::vector<char> buffer;
1027
- buffer.resize(simdutf::base64_length_from_binary(len));
1028
- std::mt19937 gen((std::mt19937::result_type)(seed));
1029
- std::uniform_int_distribution<int> byte_generator{0, 255};
1030
- for (size_t trial = 0; trial < 10; trial++) {
1031
- for (size_t i = 0; i < len; i++) {
1032
- source[i] = byte_generator(gen);
1033
- }
1034
- size_t size = implementation.binary_to_base64(
1035
- source.data(), source.size(), buffer.data());
1036
- buffer.resize(size);
1037
- add_simple_spaces(buffer, gen, 5 + 2 * len);
1038
- std::vector<char> back(simdutf::maximal_binary_length_from_base64(
1039
- buffer.data(), buffer.size()));
1040
- for (auto option :
1041
- {simdutf::last_chunk_handling_options::strict,
1042
- simdutf::last_chunk_handling_options::loose,
1043
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1044
- if (option ==
1045
- simdutf::last_chunk_handling_options::stop_before_partial &&
1046
- len % 3 != 0) {
1047
- continue;
1048
- }
1049
- simdutf::result r = implementation.base64_to_binary(
1050
- buffer.data(), buffer.size(), back.data(), simdutf::base64_default,
1051
- option);
1052
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
1053
- ASSERT_EQUAL(r.count, len);
1054
- ASSERT_TRUE(
1055
- std::equal(back.begin(), back.begin() + len, source.begin()));
1056
- }
1057
- for (auto option :
1058
- {simdutf::last_chunk_handling_options::strict,
1059
- simdutf::last_chunk_handling_options::loose,
1060
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1061
- if (option ==
1062
- simdutf::last_chunk_handling_options::stop_before_partial &&
1063
- len % 3 != 0) {
1064
- continue;
1065
- }
1066
- size_t back_length = back.size();
1067
- auto r = simdutf::base64_to_binary_safe(
1068
- buffer.data(), buffer.size(), back.data(), back_length,
1069
- simdutf::base64_default, option);
1070
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
1071
- ASSERT_EQUAL(back_length, len);
1072
-
1073
- if (option ==
1074
- simdutf::last_chunk_handling_options::stop_before_partial) {
1075
- for (size_t i = r.count; i < buffer.size(); i++) {
1076
- ASSERT_TRUE(is_space(buffer[i]));
1077
- }
1078
- if (r.count > 0) {
1079
- ASSERT_TRUE(!is_space(buffer[r.count - 1]));
1080
- }
1081
- } else {
1082
- ASSERT_EQUAL(r.count, buffer.size());
1083
- }
1084
- ASSERT_TRUE(std::equal(back.begin(), back.begin() + back_length,
1085
- source.begin()));
1086
- }
1087
- }
1088
- }
1089
- }
1090
-
1091
- TEST(roundtrip_base64_with_lots_of_spaces_at_the_end) {
1092
- std::vector<char> buffer;
1093
- for (size_t len = 0; len < max_len; len += 10) {
1094
- std::vector<char> source(len, 0);
1095
- buffer.clear();
1096
- buffer.resize(simdutf::base64_length_from_binary(len), '\0');
1097
- std::mt19937 gen((std::mt19937::result_type)(seed));
1098
- std::uniform_int_distribution<int> byte_generator{0, 255};
1099
- for (size_t trial = 0; trial < 10; trial++) {
1100
- for (size_t i = 0; i < len; i++) {
1101
- source[i] = byte_generator(gen);
1102
- }
1103
- size_t size = implementation.binary_to_base64(
1104
- source.data(), source.size(), buffer.data());
1105
- buffer.resize(size);
1106
- add_simple_spaces(buffer, gen, 5 + 2 * len);
1107
- std::vector<char> back(simdutf::maximal_binary_length_from_base64(
1108
- buffer.data(), buffer.size()));
1109
- buffer.resize(buffer.size() + 65536, ' ');
1110
- for (auto option :
1111
- {simdutf::last_chunk_handling_options::strict,
1112
- simdutf::last_chunk_handling_options::loose,
1113
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1114
- if (option ==
1115
- simdutf::last_chunk_handling_options::stop_before_partial &&
1116
- len % 3 != 0) {
1117
- continue;
1118
- }
1119
- size_t back_length = back.size();
1120
- auto r = simdutf::base64_to_binary_safe(
1121
- buffer.data(), buffer.size(), back.data(), back_length,
1122
- simdutf::base64_default, option);
1123
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
1124
- ASSERT_EQUAL(back_length, len);
1125
- for (size_t i = r.count; i < buffer.size(); i++) {
1126
- ASSERT_TRUE(is_space(buffer[i]));
1127
- }
1128
- ASSERT_TRUE(std::equal(back.begin(), back.begin() + back_length,
1129
- source.begin()));
1130
- }
1131
- }
1132
- }
1133
- }
1134
-
1135
- TEST(roundtrip_base64_with_lots_of_spaces_at_the_beginning) {
1136
- std::vector<char> buffer;
1137
- for (size_t len = 0; len < max_len; len += 10) {
1138
- std::vector<char> source(len, 0);
1139
- buffer.clear();
1140
- buffer.resize(simdutf::base64_length_from_binary(len), '\0');
1141
- std::mt19937 gen((std::mt19937::result_type)(seed));
1142
- std::uniform_int_distribution<int> byte_generator{0, 255};
1143
- for (size_t trial = 0; trial < 10; trial++) {
1144
- for (size_t i = 0; i < len; i++) {
1145
- source[i] = byte_generator(gen);
1146
- }
1147
- size_t size = implementation.binary_to_base64(
1148
- source.data(), source.size(), buffer.data());
1149
- buffer.resize(size);
1150
- add_simple_spaces(buffer, gen, 5 + 2 * len);
1151
- std::vector<char> back(simdutf::maximal_binary_length_from_base64(
1152
- buffer.data(), buffer.size()));
1153
- buffer.insert(buffer.begin(), 65536, ' ');
1154
- for (auto option :
1155
- {simdutf::last_chunk_handling_options::strict,
1156
- simdutf::last_chunk_handling_options::loose,
1157
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1158
- if (option ==
1159
- simdutf::last_chunk_handling_options::stop_before_partial &&
1160
- len % 3 != 0) {
1161
- continue;
1162
- }
1163
- size_t back_length = back.size();
1164
- auto r = simdutf::base64_to_binary_safe(
1165
- buffer.data(), buffer.size(), back.data(), back_length,
1166
- simdutf::base64_default, option);
1167
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
1168
- ASSERT_EQUAL(back_length, len);
1169
- for (size_t i = r.count; i < buffer.size(); i++) {
1170
- ASSERT_TRUE(is_space(buffer[i]));
1171
- }
1172
-
1173
- ASSERT_TRUE(std::equal(back.begin(), back.begin() + back_length,
1174
- source.begin()));
1175
- }
1176
- }
1177
- }
1178
- }
1179
-
1180
- TEST(base64_decode_just_one_padding_partial_safe) {
1181
- std::vector<std::tuple<std::string, simdutf::result, size_t>> test_cases = {
1182
- {"uuuu uu=", {simdutf::error_code::SUCCESS, 4}, 3},
1183
- // 5. If char is "=", then If chunkLength < 2, then Let error be a new
1184
- // SyntaxError exception.
1185
- {"uuuu u==",
1186
- {simdutf::error_code::BASE64_INPUT_REMAINDER, 18},
1187
- 3}, // error
1188
- {"uuuu u=",
1189
- {simdutf::error_code::BASE64_INPUT_REMAINDER, 18},
1190
- 3}, // error
1191
- {"uuuu ==",
1192
- {simdutf::error_code::INVALID_BASE64_CHARACTER, 17},
1193
- 3}, // error
1194
- {"uuuu =",
1195
- {simdutf::error_code::INVALID_BASE64_CHARACTER, 17},
1196
- 3}, // error
1197
- };
1198
- std::vector<char> buffer(128);
1199
- printf("\n");
1200
- for (auto &p : test_cases) {
1201
- auto input = std::get<0>(p);
1202
- auto expected_result = std::get<1>(p);
1203
- size_t expected_output = std::get<2>(p);
1204
- printf("input: %s\n", input.c_str());
1205
- for (auto option : {simdutf::base64_options::base64_default,
1206
- simdutf::base64_options::base64_url}) {
1207
- for (auto chunk_option :
1208
- {simdutf::last_chunk_handling_options::stop_before_partial}) {
1209
- for (size_t output = 3; output < buffer.size(); output++) {
1210
- size_t written = output;
1211
- auto result = simdutf::base64_to_binary_safe(
1212
- input.data(), input.size(), buffer.data(), written, option,
1213
- chunk_option);
1214
- ASSERT_EQUAL(result.error, expected_result.error);
1215
- ASSERT_EQUAL(written, expected_output);
1216
- ASSERT_EQUAL(result.count, expected_result.count);
1217
- }
1218
- }
1219
- }
1220
- }
1221
- }
1222
-
1223
- // partial decoding will succeed and just decode the first 3 bytes, even if we
1224
- // have ample output memory.
1225
- TEST(base64_decode_just_one_padding_partial_generous) {
1226
- std::vector<std::pair<std::string, simdutf::result>> test_cases = {
1227
- {"uuuu uu=", {simdutf::error_code::SUCCESS, 3}},
1228
- // 5. If char is "=", then If chunkLength < 2, then Let error be a new
1229
- // SyntaxError exception.
1230
- {"uuuu u==",
1231
- {simdutf::error_code::BASE64_INPUT_REMAINDER, 18}}, // error
1232
- {"uuuu u=",
1233
- {simdutf::error_code::BASE64_INPUT_REMAINDER, 18}}, // error
1234
- {"uuuu ==",
1235
- {simdutf::error_code::INVALID_BASE64_CHARACTER, 17}}, // error
1236
- {"uuuu =",
1237
- {simdutf::error_code::INVALID_BASE64_CHARACTER, 17}}, // error
1238
- };
1239
- std::vector<char> buffer(6);
1240
- for (auto &p : test_cases) {
1241
- auto input = p.first;
1242
- auto expected_result = p.second;
1243
- for (auto option : {simdutf::base64_options::base64_default,
1244
- simdutf::base64_options::base64_url}) {
1245
- for (auto chunk_option :
1246
- {simdutf::last_chunk_handling_options::stop_before_partial}) {
1247
- auto result = implementation.base64_to_binary(
1248
- input.data(), input.size(), buffer.data(), option, chunk_option);
1249
- ASSERT_EQUAL(result.error, expected_result.error);
1250
- ASSERT_EQUAL(result.count, expected_result.count);
1251
- }
1252
- }
1253
- }
1254
- }
1255
-
1256
- // loose decoding will fail when there is a single leftover padding character.
1257
- TEST(base64_decode_just_one_padding_loose) {
1258
- std::vector<std::pair<std::string, simdutf::result>> test_cases = {
1259
- {"uuuu =",
1260
- {simdutf::error_code::INVALID_BASE64_CHARACTER, 17}}};
1261
- std::vector<char> buffer(3);
1262
- for (auto &p : test_cases) {
1263
- auto input = p.first;
1264
- auto expected_result = p.second;
1265
- for (auto option : {simdutf::base64_options::base64_default,
1266
- simdutf::base64_options::base64_url}) {
1267
- for (auto chunk_option : {simdutf::last_chunk_handling_options::loose}) {
1268
- auto result = implementation.base64_to_binary(
1269
- input.data(), input.size(), buffer.data(), option, chunk_option);
1270
- ASSERT_EQUAL(result.error, expected_result.error);
1271
- ASSERT_EQUAL(result.count, expected_result.count);
1272
- }
1273
- }
1274
- }
1275
- }
1276
-
1277
- // strict decoding will fail with a pointer to the last valid character.
1278
- TEST(base64_decode_just_one_padding_strict) {
1279
- std::vector<std::pair<std::string, simdutf::result>> test_cases = {
1280
- {"uuuu =",
1281
- {simdutf::error_code::INVALID_BASE64_CHARACTER, 17}}};
1282
- std::vector<char> buffer(3);
1283
- for (auto &p : test_cases) {
1284
- auto input = p.first;
1285
- auto expected_result = p.second;
1286
- for (auto option : {simdutf::base64_options::base64_default,
1287
- simdutf::base64_options::base64_url}) {
1288
- for (auto chunk_option : {simdutf::last_chunk_handling_options::strict}) {
1289
- auto result = implementation.base64_to_binary(
1290
- input.data(), input.size(), buffer.data(), option, chunk_option);
1291
- ASSERT_EQUAL(result.error, expected_result.error);
1292
- ASSERT_EQUAL(result.count, expected_result.count);
1293
- }
1294
- }
1295
- }
1296
- }
1297
-
1298
- // partial decoding will succeed and just decode the first 3 bytes.
1299
- // https://tc39.es/proposal-arraybuffer-base64/spec/#sec-frombase64
1300
- TEST(base64_decode_just_one_padding_partial) {
1301
- std::vector<std::pair<std::string, simdutf::result>> test_cases = {
1302
- {"uuuu uu=", {simdutf::error_code::SUCCESS, 3}},
1303
- // 5. If char is "=", then If chunkLength < 2, then Let error be a new
1304
- // SyntaxError exception.
1305
- {"uuuu u==",
1306
- {simdutf::error_code::BASE64_INPUT_REMAINDER, 18}}, // error
1307
- {"uuuu u=",
1308
- {simdutf::error_code::BASE64_INPUT_REMAINDER, 18}}, // error
1309
- {"uuuu ==",
1310
- {simdutf::error_code::INVALID_BASE64_CHARACTER, 17}}, // error
1311
- {"uuuu =",
1312
- {simdutf::error_code::INVALID_BASE64_CHARACTER, 17}}, // error
1313
- };
1314
- std::vector<char> buffer(3);
1315
- for (auto &p : test_cases) {
1316
- auto input = p.first;
1317
- auto expected_result = p.second;
1318
- for (auto option : {simdutf::base64_options::base64_default,
1319
- simdutf::base64_options::base64_url}) {
1320
- for (auto chunk_option :
1321
- {simdutf::last_chunk_handling_options::stop_before_partial}) {
1322
- auto result = implementation.base64_to_binary(
1323
- input.data(), input.size(), buffer.data(), option, chunk_option);
1324
-
1325
- ASSERT_EQUAL(result.error, expected_result.error);
1326
- ASSERT_EQUAL(result.count, expected_result.count);
1327
- }
1328
- }
1329
- }
1330
- }
1331
-
1332
- TEST(base64_decode_partial_cases) {
1333
- std::vector<std::pair<std::string, simdutf::result>> test_cases = {
1334
- {"ZXhhZg", {simdutf::error_code::SUCCESS, 4}},
1335
- {"ZXhhZg "
1336
- " ",
1337
- {simdutf::error_code::SUCCESS, 4}},
1338
- {" "
1339
- "ZXhhZg",
1340
- {simdutf::error_code::SUCCESS, 68}},
1341
- };
1342
- std::vector<char> buffer(3);
1343
- for (auto &p : test_cases) {
1344
- auto input = p.first;
1345
- auto expected_result = p.second;
1346
- size_t written = buffer.size();
1347
- auto result = simdutf::base64_to_binary_safe(
1348
- input.data(), input.size(), buffer.data(), written,
1349
- simdutf::base64_default,
1350
- simdutf::last_chunk_handling_options::stop_before_partial);
1351
- ASSERT_EQUAL(result.error, expected_result.error);
1352
- ASSERT_EQUAL(result.count, expected_result.count);
1353
- }
1354
- }
1355
-
1356
- TEST(base64_decode_strict_cases) {
1357
- std::vector<std::pair<std::string, uint64_t>> test_cases = {
1358
- {"ZXhhZg==", simdutf::error_code::SUCCESS},
1359
- {"YWE=", simdutf::error_code::SUCCESS},
1360
- {"YWF=", simdutf::error_code::BASE64_EXTRA_BITS},
1361
- {"ZXhhZh==", simdutf::error_code::BASE64_EXTRA_BITS},
1362
- // {"ZXhhZg", simdutf::error_code::BASE64_INPUT_REMAINDER},
1363
- // {"ZXhhZh", simdutf::error_code::BASE64_INPUT_REMAINDER},
1364
- {"Z X h h Z h = =", simdutf::error_code::BASE64_EXTRA_BITS},
1365
- //{"ZX h hZg", simdutf::error_code::BASE64_INPUT_REMAINDER},
1366
- //{"ZXh hZ h", simdutf::error_code::BASE64_INPUT_REMAINDER},
1367
- };
1368
- std::vector<char> buffer(1024);
1369
- for (auto &p : test_cases) {
1370
- auto input = p.first;
1371
- auto expected_error = p.second;
1372
- simdutf::result result = implementation.base64_to_binary(
1373
- input.data(), input.size(), buffer.data(), simdutf::base64_default,
1374
- simdutf::last_chunk_handling_options::strict);
1375
- ASSERT_EQUAL(result.error, expected_error);
1376
- size_t written = buffer.size();
1377
- result = simdutf::base64_to_binary_safe(
1378
- input.data(), input.size(), buffer.data(), written,
1379
- simdutf::base64_default, simdutf::last_chunk_handling_options::strict);
1380
- ASSERT_EQUAL(result.error, expected_error);
1381
- }
1382
- }
1383
-
1384
- TEST(base64_decode_strict_cases_length) {
1385
- std::vector<std::pair<std::string, simdutf::result>> test_cases = {
1386
- {"ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
1387
- "dd"
1388
- "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddzzz=",
1389
- {simdutf::error_code::BASE64_EXTRA_BITS, 131}},
1390
- };
1391
- std::vector<char> buffer(1024);
1392
- for (auto &p : test_cases) {
1393
- auto input = p.first;
1394
- auto expected_result = p.second;
1395
- simdutf::result result = implementation.base64_to_binary(
1396
- input.data(), input.size(), buffer.data(), simdutf::base64_default,
1397
- simdutf::last_chunk_handling_options::strict);
1398
- ASSERT_EQUAL(result.error, expected_result.error);
1399
- ASSERT_EQUAL(result.count, expected_result.count);
1400
- size_t written = buffer.size();
1401
- result = simdutf::base64_to_binary_safe(
1402
- input.data(), input.size(), buffer.data(), written,
1403
- simdutf::base64_default, simdutf::last_chunk_handling_options::strict);
1404
- ASSERT_EQUAL(result.error, expected_result.error);
1405
- ASSERT_EQUAL(result.count, expected_result.count);
1406
- }
1407
- }
1408
-
1409
- // https://bugs.webkit.org/show_bug.cgi?id=290829
1410
- TEST(issue_webkit_290829) {
1411
- std::string data = "MjYyZg===";
1412
- std::vector<char> output(5); // 5 is part of the issue
1413
- std::vector<uint8_t> expected = {0x32, 0x36, 0x32};
1414
-
1415
- for (auto option :
1416
- {simdutf::last_chunk_handling_options::strict,
1417
- simdutf::last_chunk_handling_options::loose,
1418
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1419
- std::fill(output.begin(), output.end(), 0);
1420
- const auto r1 =
1421
- implementation.base64_to_binary(data.data(), data.size(), output.data(),
1422
- simdutf::base64_default, option);
1423
- ASSERT_EQUAL(r1.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
1424
- ASSERT_EQUAL(r1.count, 6);
1425
- }
1426
-
1427
- for (auto option :
1428
- {simdutf::last_chunk_handling_options::strict,
1429
- simdutf::last_chunk_handling_options::loose,
1430
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1431
- std::fill(output.begin(), output.end(), 0);
1432
- size_t back_length = output.size();
1433
- constexpr bool decode_up_to_bad_char = true;
1434
- auto r = simdutf::base64_to_binary_safe(
1435
- data.data(), data.size(), output.data(), back_length,
1436
- simdutf::base64_default, option, decode_up_to_bad_char);
1437
-
1438
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
1439
- ASSERT_EQUAL(r.count, 6);
1440
- ASSERT_EQUAL(back_length, 3);
1441
- ASSERT_BYTES_EQUAL(output, expected, 3);
1442
- }
1443
- }
1444
-
1445
- // https://bugs.webkit.org/show_bug.cgi?id=290829
1446
- TEST(issue_webkit_utf16_290829) {
1447
- std::string data = "MjYyZg===";
1448
- std::vector<char> output(5); // 5 is part of the issue
1449
- std::vector<uint16_t> expected = {0x32, 0x36, 0x32};
1450
-
1451
- for (auto option :
1452
- {simdutf::last_chunk_handling_options::strict,
1453
- simdutf::last_chunk_handling_options::loose,
1454
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1455
- std::fill(output.begin(), output.end(), 0);
1456
- const auto r1 =
1457
- implementation.base64_to_binary(data.data(), data.size(), output.data(),
1458
- simdutf::base64_default, option);
1459
- ASSERT_EQUAL(r1.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
1460
- ASSERT_EQUAL(r1.count, 6);
1461
- }
1462
-
1463
- for (auto option :
1464
- {simdutf::last_chunk_handling_options::strict,
1465
- simdutf::last_chunk_handling_options::loose,
1466
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1467
- std::fill(output.begin(), output.end(), 0);
1468
- size_t back_length = output.size();
1469
- constexpr bool decode_up_to_bad_char = true;
1470
- auto r = simdutf::base64_to_binary_safe(
1471
- data.data(), data.size(), output.data(), back_length,
1472
- simdutf::base64_default, option, decode_up_to_bad_char);
1473
-
1474
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
1475
- ASSERT_EQUAL(r.count, 6);
1476
- ASSERT_EQUAL(back_length, 3);
1477
- ASSERT_BYTES_EQUAL(output, expected, 3);
1478
- }
1479
- }
1480
-
1481
- // https://bugs.webkit.org/show_bug.cgi?id=290829
1482
- TEST(issue_webkit_utf16_290829_bad_char) {
1483
- std::string data(1024, 'A');
1484
- std::vector<char> expected(1024 / 4 * 3, 0);
1485
- std::vector<char> output(1024 / 4 * 3);
1486
- for (size_t invalid = 0; invalid < data.size(); invalid++) {
1487
- data[invalid] = '?'; // invalid
1488
- for (auto option :
1489
- {simdutf::last_chunk_handling_options::strict,
1490
- simdutf::last_chunk_handling_options::loose,
1491
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1492
- std::fill(output.begin(), output.end(), 255);
1493
- size_t back_length = output.size();
1494
- constexpr bool decode_up_to_bad_char = true;
1495
- auto r = simdutf::base64_to_binary_safe(
1496
- data.data(), data.size(), output.data(), back_length,
1497
- simdutf::base64_default, option, decode_up_to_bad_char);
1498
-
1499
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
1500
- ASSERT_EQUAL(r.count, invalid);
1501
- size_t expected_length = invalid / 4 * 3;
1502
- ASSERT_EQUAL(back_length, expected_length);
1503
- ASSERT_BYTES_EQUAL(output, expected, expected_length);
1504
- }
1505
- data[invalid] = 'A'; // valid
1506
- }
1507
- }
1508
-
1509
- TEST(issue_webkit_utf16_290829_example) {
1510
- std::string data(1024, 'A');
1511
- std::vector<char> expected(1024 / 4 * 3, 0);
1512
- std::vector<char> output(1024 / 4 * 3);
1513
- for (size_t invalid = 0; invalid < data.size(); invalid++) {
1514
- data[invalid] = '?'; // invalid
1515
- for (auto option :
1516
- {simdutf::last_chunk_handling_options::strict,
1517
- simdutf::last_chunk_handling_options::loose,
1518
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1519
- std::fill(output.begin(), output.end(), 255);
1520
- size_t back_length = output.size();
1521
- constexpr bool decode_up_to_bad_char = true;
1522
- auto r = simdutf::base64_to_binary_safe(
1523
- data.data(), data.size(), output.data(), back_length,
1524
- simdutf::base64_default, option, decode_up_to_bad_char);
1525
-
1526
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
1527
- ASSERT_EQUAL(r.count, invalid);
1528
- size_t expected_length = invalid / 4 * 3;
1529
- ASSERT_EQUAL(back_length, expected_length);
1530
- ASSERT_BYTES_EQUAL(output, expected, expected_length);
1531
- }
1532
- data[invalid] = 'A'; // valid
1533
- }
1534
- }
1535
-
1536
- TEST(issue_single_bad16) {
1537
- std::vector<char16_t> data = {0x3f};
1538
- ASSERT_EQUAL(data.size(), 1);
1539
- size_t outlen = implementation.maximal_binary_length_from_base64(data.data(),
1540
- data.size());
1541
- std::vector<char> out(outlen);
1542
- const auto r = implementation.base64_to_binary(
1543
- (const char *)data.data(), data.size(), out.data(),
1544
- simdutf::base64_url_with_padding,
1545
- simdutf::last_chunk_handling_options::strict);
1546
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
1547
- ASSERT_EQUAL(r.count, 0);
1548
- }
1549
-
1550
- TEST(issue_615) {
1551
- const std::vector<char> data{' ', '=', '='};
1552
- std::vector<char> output(100);
1553
- const auto r1 =
1554
- implementation.base64_to_binary(data.data(), data.size(), output.data(),
1555
- simdutf::base64_default, simdutf::strict);
1556
- ASSERT_EQUAL(r1.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
1557
- ASSERT_EQUAL(r1.count, 1);
1558
- const auto r2 = implementation.base64_to_binary(
1559
- data.data() + 1, data.size() - 1, output.data(), simdutf::base64_default,
1560
- simdutf::strict);
1561
- ASSERT_EQUAL(r2.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
1562
- ASSERT_EQUAL(r2.count, 0);
1563
- const auto r3 = implementation.base64_to_binary(
1564
- data.data(), data.size(), output.data(), simdutf::base64_default,
1565
- simdutf::stop_before_partial);
1566
- ASSERT_EQUAL(r3.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
1567
- ASSERT_EQUAL(r3.count, 1);
1568
- const auto r4 = implementation.base64_to_binary(
1569
- data.data() + 1, data.size() - 1, output.data(), simdutf::base64_default,
1570
- simdutf::stop_before_partial);
1571
- ASSERT_EQUAL(r4.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
1572
- ASSERT_EQUAL(r4.count, 0);
1573
- }
1574
-
1575
- TEST(issue_kkk) {
1576
- std::vector<char> data = {
1577
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
1578
- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
1579
- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
1580
- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
1581
- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
1582
- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
1583
- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
1584
- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x20, 0x20, 0x20, 0x20, 0x20,
1585
- 0x20, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
1586
- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
1587
- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
1588
- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
1589
- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
1590
- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
1591
- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
1592
- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x20, 0x20, 0x20,
1593
- 0x63};
1594
- ASSERT_EQUAL(data.size(), 193);
1595
- size_t outlen = implementation.maximal_binary_length_from_base64(data.data(),
1596
- data.size());
1597
- std::vector<char> out(outlen);
1598
- const auto r = implementation.base64_to_binary(
1599
- (const char *)data.data(), data.size(), out.data(),
1600
- simdutf::base64_url_with_padding,
1601
- simdutf::last_chunk_handling_options::strict);
1602
- ASSERT_EQUAL(r.error, simdutf::error_code::BASE64_INPUT_REMAINDER);
1603
- ASSERT_EQUAL(r.count, 193);
1604
- }
1605
-
1606
- TEST(issue_520) {
1607
- std::vector<unsigned char> data{
1608
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 12, 32,
1609
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1610
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
1611
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 82,
1612
- };
1613
- std::vector<char> out(48);
1614
-
1615
- const auto r =
1616
- implementation.base64_to_binary((const char *)data.data(), data.size(),
1617
- out.data(), simdutf::base64_default);
1618
- ASSERT_EQUAL(r.error, simdutf::error_code::BASE64_INPUT_REMAINDER);
1619
- ASSERT_EQUAL(r.count, 64);
1620
- }
1621
-
1622
- TEST(base64_decode_complete_input) {
1623
- std::vector<unsigned char> input_data = {0x54, 0x57, 0x46,
1624
- 0x75}; // "TWFu" Base64 for "Man"
1625
- std::vector<char> expected_output = {'M', 'a', 'n'};
1626
- std::vector<char> output_buffer(expected_output.size());
1627
-
1628
- // Test with all last_chunk_handling_options
1629
- for (auto option :
1630
- {simdutf::last_chunk_handling_options::strict,
1631
- simdutf::last_chunk_handling_options::loose,
1632
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1633
- auto result = implementation.base64_to_binary(
1634
- reinterpret_cast<const char *>(input_data.data()), input_data.size(),
1635
- output_buffer.data(), simdutf::base64_default, option);
1636
-
1637
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
1638
- ASSERT_EQUAL(result.count, expected_output.size());
1639
- ASSERT_TRUE(
1640
- (std::equal(output_buffer.begin(), output_buffer.begin() + result.count,
1641
- expected_output.begin())));
1642
- }
1643
- }
1644
-
1645
- // https://github.com/simdutf/simdutf/issues/824
1646
- /*
1647
- The TC39 base64 proposal step 10.a and 10.b together means that, when using
1648
- stop-before-partial:
1649
-
1650
- If in the middle of decoding a chunk, return the ending position of the previous
1651
- chunk before skipping whitespace. If not in the middle of decoding a chunk,
1652
- return the entire input length, including trailing whitespace.
1653
- */
1654
- TEST(issue_824) {
1655
- struct read_write {
1656
- size_t read;
1657
- size_t written;
1658
- };
1659
- std::vector<std::tuple<std::string, read_write, std::vector<uint8_t>>>
1660
- test_cases = {
1661
- {" ", {2, 0}, {}}, // return the entire input length, including
1662
- // trailing whitespace.
1663
- {" A A G A / v 8 ",
1664
- {8, 3},
1665
- {0, 1, 128}} // return the ending position of the previous chunk
1666
- // before skipping whitespace.
1667
- };
1668
-
1669
- std::vector<unsigned char> case1(5463, 0x20);
1670
- case1.back() = 0x38;
1671
- test_cases.emplace_back(std::string(case1.begin(), case1.end()),
1672
- read_write{0, 0}, std::vector<uint8_t>{});
1673
-
1674
- std::string long_input(1000, ' ');
1675
- test_cases.emplace_back(long_input, read_write{1000, 0},
1676
- std::vector<uint8_t>{});
1677
- test_cases.emplace_back(long_input + " A A G A / v 8 ",
1678
- read_write{1000 + 8, 3},
1679
- std::vector<uint8_t>{0, 1, 128});
1680
- // In https://tc39.es/proposal-arraybuffer-base64/spec/#sec-frombase64
1681
- // the 'read' variable is only ever incremented when a full chunk is
1682
- // successfully decoded. And we always return the 'read' variable,
1683
- // except when we reach the end of the input with a chunkLength of zero.
1684
- test_cases.emplace_back(long_input + "A", read_write{0, 0},
1685
- std::vector<uint8_t>{});
1686
- test_cases.emplace_back("AAAA" + long_input + "A", read_write{4, 3},
1687
- std::vector<uint8_t>{0, 0, 0});
1688
-
1689
- for (const std::tuple<std::string, read_write, std::vector<uint8_t>> &t :
1690
- test_cases) {
1691
- auto input_data = std::get<0>(t);
1692
- auto read_write_info = std::get<1>(t);
1693
- auto expected_output = std::get<2>(t);
1694
- std::vector<uint8_t> output_buffer(
1695
- implementation.maximal_binary_length_from_base64(input_data.data(),
1696
- input_data.size()));
1697
- size_t written = output_buffer.size();
1698
- auto result = simdutf::base64_to_binary_safe(
1699
- input_data.data(), input_data.size(),
1700
- reinterpret_cast<char *>(output_buffer.data()), written,
1701
- simdutf::base64_default,
1702
- simdutf::last_chunk_handling_options::stop_before_partial, true);
1703
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
1704
- ASSERT_EQUAL(result.count, read_write_info.read);
1705
- ASSERT_EQUAL(written, expected_output.size());
1706
- output_buffer.resize(written);
1707
- ASSERT_TRUE(output_buffer == expected_output);
1708
- }
1709
- for (const std::tuple<std::string, read_write, std::vector<uint8_t>> &t :
1710
- test_cases) {
1711
- auto input_data = std::get<0>(t);
1712
- auto read_write_info = std::get<1>(t);
1713
- auto expected_output = std::get<2>(t);
1714
- std::vector<uint8_t> output_buffer(expected_output.size());
1715
- size_t written = output_buffer.size();
1716
- auto result = simdutf::base64_to_binary_safe(
1717
- input_data.data(), input_data.size(),
1718
- reinterpret_cast<char *>(output_buffer.data()), written,
1719
- simdutf::base64_default,
1720
- simdutf::last_chunk_handling_options::stop_before_partial, true);
1721
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
1722
- ASSERT_EQUAL(result.count, read_write_info.read);
1723
- ASSERT_EQUAL(written, expected_output.size());
1724
- output_buffer.resize(written);
1725
- ASSERT_TRUE(output_buffer == expected_output);
1726
- }
1727
- }
1728
-
1729
- TEST(issue_824_a) {
1730
- std::vector<unsigned char> base64(5463, 0x20);
1731
- base64.back() = 0x38;
1732
- std::vector<char> outbuf(8224);
1733
- std::size_t outlen = outbuf.size();
1734
- const auto result = simdutf::base64_to_binary_safe(
1735
- (const char *)base64.data(), base64.size(), outbuf.data(), outlen,
1736
- simdutf::base64_default,
1737
- simdutf::last_chunk_handling_options::stop_before_partial, false);
1738
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
1739
- ASSERT_EQUAL(result.count, 0);
1740
- ASSERT_EQUAL(outlen, 0);
1741
- }
1742
-
1743
- TEST(issue_06_05_2025_001) {
1744
- const std::vector<unsigned char> base64{
1745
- 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
1746
- 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
1747
- 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
1748
- 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
1749
- 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
1750
- 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
1751
- 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
1752
- 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
1753
- 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x0a, 0x0a,
1754
- 0x0a, 0x6f, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
1755
- 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71, 0x71,
1756
- 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x0a,
1757
- 0x0a, 0x0a, 0x0a, 0x0a, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x0a,
1758
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x4b, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
1759
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
1760
- };
1761
- std::vector<char> outbuf(28426);
1762
- std::size_t outlen = outbuf.size();
1763
- const auto result = simdutf::base64_to_binary_safe(
1764
- (const char *)base64.data(), base64.size(), outbuf.data(), outlen,
1765
- simdutf::base64_default,
1766
- simdutf::last_chunk_handling_options::stop_before_partial, true);
1767
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
1768
- ASSERT_EQUAL(result.count, base64.size());
1769
- ASSERT_EQUAL(outlen, 111);
1770
- };
1771
-
1772
- // https://github.com/WebKit/WebKit/blob/18fad22e2078542316a576989676d31cfd08d777/JSTests/stress/uint8array-fromBase64.js#L135
1773
- TEST(base64_decode_webkit_cases) {
1774
-
1775
- struct read_write {
1776
- size_t read;
1777
- size_t written;
1778
- };
1779
- std::vector<std::tuple<std::string, read_write, std::vector<uint8_t>>>
1780
- test_cases = {
1781
- {"", {0, 0}, {}},
1782
- {"AA==", {4, 1}, {0}},
1783
- {"AQ==", {4, 1}, {1}},
1784
- {"gA==", {4, 1}, {128}},
1785
- {"/g==", {4, 1}, {254}},
1786
- {"/w==", {4, 1}, {255}},
1787
- {"AAE=", {4, 2}, {0, 1}},
1788
- {"/v8=", {4, 2}, {254, 255}},
1789
- {"AAGA/v8=", {8, 5}, {0, 1, 128, 254, 255}},
1790
- {" ", {2, 0}, {}},
1791
- {" A A = = ", {14, 1}, {0}},
1792
- {" A Q = = ", {14, 1}, {1}},
1793
- {" g A = = ", {14, 1}, {128}},
1794
- {" / g = = ", {14, 1}, {254}},
1795
- {" / w = = ", {14, 1}, {255}},
1796
- {" A A E = ", {14, 2}, {0, 1}},
1797
- {" / v 8 = ", {14, 2}, {254, 255}},
1798
- {" A A G A / v 8 = ", {26, 5}, {0, 1, 128, 254, 255}}};
1799
-
1800
- // Test with all last_chunk_handling_options
1801
- for (auto option :
1802
- {simdutf::last_chunk_handling_options::strict,
1803
- simdutf::last_chunk_handling_options::loose,
1804
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1805
- for (const std::tuple<std::string, read_write, std::vector<uint8_t>> &t :
1806
- test_cases) {
1807
- auto input_data = std::get<0>(t);
1808
- auto expected_output = std::get<2>(t);
1809
- std::vector<uint8_t> output_buffer(
1810
- implementation.maximal_binary_length_from_base64(input_data.data(),
1811
- input_data.size()));
1812
- auto result = implementation.base64_to_binary(
1813
- input_data.data(), input_data.size(),
1814
- reinterpret_cast<char *>(output_buffer.data()),
1815
- simdutf::base64_default, option);
1816
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
1817
- ASSERT_EQUAL(result.count, expected_output.size());
1818
- output_buffer.resize(result.count);
1819
- ASSERT_TRUE(output_buffer == expected_output);
1820
- }
1821
- }
1822
-
1823
- for (auto option :
1824
- {simdutf::last_chunk_handling_options::strict,
1825
- simdutf::last_chunk_handling_options::loose,
1826
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1827
- for (const std::tuple<std::string, read_write, std::vector<uint8_t>> &t :
1828
- test_cases) {
1829
- auto input_data = std::get<0>(t);
1830
- auto read_write_info = std::get<1>(t);
1831
- auto expected_output = std::get<2>(t);
1832
- std::vector<uint8_t> output_buffer(
1833
- implementation.maximal_binary_length_from_base64(input_data.data(),
1834
- input_data.size()));
1835
- auto result = implementation.base64_to_binary_details(
1836
- input_data.data(), input_data.size(),
1837
- reinterpret_cast<char *>(output_buffer.data()),
1838
- simdutf::base64_default, option);
1839
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
1840
- ASSERT_EQUAL(result.output_count, expected_output.size());
1841
- ASSERT_EQUAL(result.output_count, read_write_info.written);
1842
- ASSERT_EQUAL(result.input_count, read_write_info.read);
1843
- output_buffer.resize(result.output_count);
1844
- ASSERT_TRUE(output_buffer == expected_output);
1845
- }
1846
- }
1847
- // Test with all last_chunk_handling_options
1848
- for (auto option : {simdutf::last_chunk_handling_options::strict,
1849
- simdutf::last_chunk_handling_options::loose}) {
1850
- for (const std::tuple<std::string, read_write, std::vector<uint8_t>> &t :
1851
- test_cases) {
1852
- auto input_data = std::get<0>(t);
1853
- auto read_write_info = std::get<1>(t);
1854
- auto expected_output = std::get<2>(t);
1855
- std::vector<uint8_t> output_buffer(
1856
- implementation.maximal_binary_length_from_base64(input_data.data(),
1857
- input_data.size()));
1858
- size_t written = output_buffer.size();
1859
- auto result = simdutf::base64_to_binary_safe(
1860
- input_data.data(), input_data.size(),
1861
- reinterpret_cast<char *>(output_buffer.data()), written,
1862
- simdutf::base64_default, option);
1863
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
1864
- ASSERT_EQUAL(result.count, read_write_info.read);
1865
- ASSERT_EQUAL(written, expected_output.size());
1866
- output_buffer.resize(written);
1867
- ASSERT_TRUE(output_buffer == expected_output);
1868
- }
1869
- }
1870
- }
1871
-
1872
- // https://github.com/WebKit/WebKit/blob/18fad22e2078542316a576989676d31cfd08d777/JSTests/stress/uint8array-fromBase64.js#L206
1873
- TEST(base64_decode_webkit_more_cases) {
1874
- std::vector<std::string> test_cases = {
1875
- "AA", " A A ", "AQ", " A Q ", "gA",
1876
- " g A ", "/g", " / g ", "/w", " / w ",
1877
- "AAE", " A A E ", "/v8", " / v 8 "};
1878
- for (auto option :
1879
- {simdutf::last_chunk_handling_options::strict,
1880
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1881
- for (const std::string &input_data : test_cases) {
1882
- std::vector<uint8_t> output_buffer(
1883
- implementation.maximal_binary_length_from_base64(input_data.data(),
1884
- input_data.size()));
1885
- auto result = implementation.base64_to_binary(
1886
- input_data.data(), input_data.size(),
1887
- reinterpret_cast<char *>(output_buffer.data()),
1888
- simdutf::base64_default, option);
1889
- if (option == simdutf::last_chunk_handling_options::strict) {
1890
- ASSERT_EQUAL(result.error, simdutf::error_code::BASE64_INPUT_REMAINDER);
1891
- } else {
1892
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
1893
- ASSERT_EQUAL(result.count, 0);
1894
- }
1895
- }
1896
- }
1897
- for (auto option :
1898
- {simdutf::last_chunk_handling_options::strict,
1899
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1900
- for (const std::string &input_data : test_cases) {
1901
- std::vector<uint8_t> output_buffer(
1902
- implementation.maximal_binary_length_from_base64(input_data.data(),
1903
- input_data.size()));
1904
- size_t written = output_buffer.size();
1905
- auto result = simdutf::base64_to_binary_safe(
1906
- input_data.data(), input_data.size(),
1907
- reinterpret_cast<char *>(output_buffer.data()), written,
1908
- simdutf::base64_default, option);
1909
- if (option == simdutf::last_chunk_handling_options::strict) {
1910
- ASSERT_EQUAL(result.error, simdutf::error_code::BASE64_INPUT_REMAINDER);
1911
- } else {
1912
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
1913
- ASSERT_EQUAL(written, 0);
1914
- }
1915
- }
1916
- }
1917
- }
1918
-
1919
- TEST(base64_decode_webkit_like_but_random_more_cases) {
1920
- for (size_t len = 1; len <= max_len; len++) {
1921
- for (size_t trial = 0; trial < 10; trial++) {
1922
- std::vector<char> source(len, 0);
1923
- std::vector<char> buffer;
1924
- buffer.resize(simdutf::base64_length_from_binary(len));
1925
- std::mt19937 gen((std::mt19937::result_type)(seed));
1926
- std::uniform_int_distribution<int> byte_generator{0, 255};
1927
- for (size_t i = 0; i < len; i++) {
1928
- source[i] = byte_generator(gen);
1929
- }
1930
- simdutf_maybe_unused const size_t size = implementation.binary_to_base64(
1931
- source.data(), source.size(), buffer.data());
1932
- for (size_t removed = 1; !buffer.empty() && removed <= 2; removed++) {
1933
- buffer.pop_back();
1934
- for (auto option :
1935
- {simdutf::last_chunk_handling_options::strict,
1936
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1937
- std::vector<uint8_t> output_buffer(
1938
- implementation.maximal_binary_length_from_base64(buffer.data(),
1939
- buffer.size()));
1940
- auto result = implementation.base64_to_binary(
1941
- buffer.data(), buffer.size(),
1942
- reinterpret_cast<char *>(output_buffer.data()),
1943
- simdutf::base64_default, option);
1944
- if (option == simdutf::last_chunk_handling_options::strict) {
1945
- ASSERT_EQUAL(result.error,
1946
- simdutf::error_code::BASE64_INPUT_REMAINDER);
1947
- } else {
1948
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
1949
- ASSERT_EQUAL(result.count, (len - 1) / 3 * 3);
1950
- }
1951
- }
1952
- for (auto option :
1953
- {simdutf::last_chunk_handling_options::strict,
1954
- simdutf::last_chunk_handling_options::stop_before_partial}) {
1955
- std::vector<uint8_t> output_buffer(
1956
- implementation.maximal_binary_length_from_base64(buffer.data(),
1957
- buffer.size()));
1958
- size_t written = output_buffer.size();
1959
- auto result = simdutf::base64_to_binary_safe(
1960
- buffer.data(), buffer.size(),
1961
- reinterpret_cast<char *>(output_buffer.data()), written,
1962
- simdutf::base64_default, option);
1963
- if (option == simdutf::last_chunk_handling_options::strict) {
1964
- ASSERT_EQUAL(result.error,
1965
- simdutf::error_code::BASE64_INPUT_REMAINDER);
1966
- } else {
1967
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
1968
- ASSERT_EQUAL(written, (len - 1) / 3 * 3);
1969
- }
1970
- }
1971
- }
1972
- }
1973
- }
1974
- }
1975
-
1976
- TEST(base64_decode_webkit_like_but_random_with_spaces_more_cases) {
1977
- for (size_t len = 1; len <= max_len; len++) {
1978
- for (size_t trial = 0; trial < 20; trial++) {
1979
- std::vector<char> source(len, 0);
1980
- std::vector<char> buffer;
1981
- buffer.resize(simdutf::base64_length_from_binary(len));
1982
- std::mt19937 gen((std::mt19937::result_type)(seed));
1983
- std::uniform_int_distribution<int> byte_generator{0, 255};
1984
- for (size_t i = 0; i < len; i++) {
1985
- source[i] = byte_generator(gen);
1986
- }
1987
- simdutf_maybe_unused const size_t size = implementation.binary_to_base64(
1988
- source.data(), source.size(), buffer.data());
1989
- buffer = add_simple_spaces(buffer, gen, 5 + len / 4);
1990
- auto is_space = [](char c) {
1991
- return c == ' ' || c == '\t' || c == '\n' || c == '\r';
1992
- };
1993
- for (size_t removed = 1; !buffer.empty() && removed <= 2; removed++) {
1994
- while (is_space(buffer.back())) {
1995
- buffer.pop_back();
1996
- }
1997
- buffer.pop_back();
1998
- for (auto option :
1999
- {simdutf::last_chunk_handling_options::strict,
2000
- simdutf::last_chunk_handling_options::stop_before_partial}) {
2001
- std::vector<uint8_t> output_buffer(
2002
- implementation.maximal_binary_length_from_base64(buffer.data(),
2003
- buffer.size()));
2004
- auto result = implementation.base64_to_binary(
2005
- buffer.data(), buffer.size(),
2006
- reinterpret_cast<char *>(output_buffer.data()),
2007
- simdutf::base64_default, option);
2008
- if (option == simdutf::last_chunk_handling_options::strict) {
2009
- ASSERT_EQUAL(result.error,
2010
- simdutf::error_code::BASE64_INPUT_REMAINDER);
2011
- } else {
2012
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
2013
- ASSERT_EQUAL(result.count, (len - 1) / 3 * 3);
2014
- }
2015
- }
2016
- for (auto option :
2017
- {simdutf::last_chunk_handling_options::strict,
2018
- simdutf::last_chunk_handling_options::stop_before_partial}) {
2019
- std::vector<uint8_t> output_buffer(
2020
- simdutf::maximal_binary_length_from_base64(buffer.data(),
2021
- buffer.size()));
2022
- size_t written = output_buffer.size();
2023
- auto result = simdutf::base64_to_binary_safe(
2024
- buffer.data(), buffer.size(),
2025
- reinterpret_cast<char *>(output_buffer.data()), written,
2026
- simdutf::base64_default, option);
2027
- if (option == simdutf::last_chunk_handling_options::strict) {
2028
- ASSERT_EQUAL(result.error,
2029
- simdutf::error_code::BASE64_INPUT_REMAINDER);
2030
- } else {
2031
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
2032
- ASSERT_EQUAL(written, (len - 1) / 3 * 3);
2033
- }
2034
- }
2035
- }
2036
- }
2037
- }
2038
- }
2039
-
2040
- TEST(base64_decode_strict_mode) {
2041
- std::vector<std::pair<std::string, std::string>> test_cases = {
2042
- {"TQ", "M"}, // Length 2 (not multiple of 4)
2043
- {"TWE", "Ma"}, // Length 3 (not multiple of 4)
2044
- {"TWFu", "Man"}, // Length 4 (multiple of 4)
2045
- {"TWF1", "Mau"}, // Length 4 (multiple of 4)
2046
- {"TWFubWFu", "Manman"}, // Length 8 (multiple of 4)
2047
- };
2048
- for (const std::pair<std::string, std::string> &t : test_cases) {
2049
- auto input_data = t.first;
2050
- auto expected_output = t.second;
2051
- std::vector<uint8_t> output_buffer(expected_output.size() +
2052
- 3); // Add extra space for safety
2053
-
2054
- auto result = implementation.base64_to_binary(
2055
- input_data.data(), input_data.size(),
2056
- reinterpret_cast<char *>(output_buffer.data()), simdutf::base64_default,
2057
- simdutf::last_chunk_handling_options::strict);
2058
-
2059
- if (input_data.size() % 4 == 0) {
2060
- // Input length is a multiple of 4, expect success
2061
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
2062
- ASSERT_EQUAL(result.count, expected_output.size());
2063
- ASSERT_TRUE((std::equal(output_buffer.begin(),
2064
- output_buffer.begin() + result.count,
2065
- expected_output.begin())));
2066
- } else {
2067
- // Input length is not a multiple of 4, expect failure in strict mode
2068
- ASSERT_EQUAL(result.error, simdutf::error_code::BASE64_INPUT_REMAINDER);
2069
- }
2070
- }
2071
- }
2072
-
2073
- TEST(base64_decode_stop_before_partial) {
2074
- std::vector<std::pair<std::string, std::string>> test_cases = {
2075
- {"TQ", ""}, // Length 2 (no complete blocks)
2076
- {"TWE", ""}, // Length 3 (no complete blocks)
2077
- {"TWFu", "Man"}, // Length 4 (1 complete block)
2078
- {"TWFuTQ", "Man"}, // Length 6 (1 complete block)
2079
- {"TWFuTW", "Man"}, // Length 7 (1 complete block)
2080
- {"TWFuTWFu", "ManMan"}, // Length 8 (2 complete blocks)
2081
- };
2082
-
2083
- for (const std::pair<std::string, std::string> &t : test_cases) {
2084
- auto input_data = t.first;
2085
- auto expected_output = t.second;
2086
- std::vector<char> output_buffer(expected_output.size() + 3); // Extra space
2087
-
2088
- auto result = implementation.base64_to_binary(
2089
- input_data.data(), input_data.size(), output_buffer.data(),
2090
- simdutf::base64_default,
2091
- simdutf::last_chunk_handling_options::stop_before_partial);
2092
-
2093
- ASSERT_EQUAL(result.error, simdutf::error_code::SUCCESS);
2094
- ASSERT_EQUAL(result.count, expected_output.size());
2095
- ASSERT_TRUE(
2096
- (std::equal(output_buffer.begin(), output_buffer.begin() + result.count,
2097
- expected_output.begin())));
2098
- }
2099
- }
2100
-
2101
- TEST(issue_520_url) {
2102
- // output differs between implementations for decode
2103
- // impl arm64 got maxbinarylength=48 convertresult=[count=64,
2104
- // error=INVALID_BASE64_CHARACTER] impl fallback got maxbinarylength=48
2105
- // convertresult=[count=0, error=BASE64_INPUT_REMAINDER]
2106
-
2107
- std::vector<unsigned char> data{
2108
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 12, 32,
2109
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
2110
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
2111
- 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 82,
2112
- };
2113
- std::vector<char> out(48);
2114
-
2115
- const auto r = implementation.base64_to_binary(
2116
- (const char *)data.data(), data.size(), out.data(), simdutf::base64_url);
2117
- ASSERT_EQUAL(r.error, simdutf::error_code::BASE64_INPUT_REMAINDER);
2118
- ASSERT_EQUAL(r.count, 64);
2119
- }
2120
-
2121
- TEST(issue_511) {
2122
- // 0x7f is not a valid base64 character.
2123
- std::vector<unsigned char> data{
2124
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
2125
- 0x20, 0x7f, 0x57, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
2126
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
2127
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
2128
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
2129
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x5a};
2130
- std::vector<char> out(48);
2131
- const auto r = implementation.base64_to_binary(
2132
- (const char *)data.data(), data.size(), out.data(), simdutf::base64_url);
2133
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
2134
- ASSERT_EQUAL(r.count, 12);
2135
- }
2136
-
2137
- TEST(issue_509) {
2138
- std::vector<char> data{' ', '='};
2139
- std::vector<char> out(1);
2140
- const auto r = implementation.base64_to_binary(
2141
- data.data(), data.size(), out.data(), simdutf::base64_default);
2142
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
2143
- ASSERT_EQUAL(r.count, 1);
2144
- }
2145
-
2146
- TEST(issue_502_alt) {
2147
- for (std::size_t nof_equals = 1; nof_equals < 100; ++nof_equals) {
2148
- std::vector<char> data(nof_equals, '=');
2149
- std::vector<char> out(1);
2150
- const auto r = implementation.base64_to_binary(
2151
- data.data(), data.size(), out.data(), simdutf::base64_default);
2152
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
2153
- ASSERT_EQUAL(r.count, 0);
2154
- }
2155
- }
2156
-
2157
- TEST(issue_504) {
2158
- std::array<char16_t, 1> data{61}; // 61 is the ASCII code for '='
2159
- std::vector<char> out(1);
2160
- const auto r = implementation.base64_to_binary(
2161
- data.data(), data.size(), out.data(), simdutf::base64_default);
2162
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
2163
- ASSERT_EQUAL(r.count, 0);
2164
- }
2165
-
2166
- TEST(issue_504_8bit) {
2167
- std::array<char, 1> data{61}; // 61 is the ASCII code for '='
2168
- std::vector<char> out(1);
2169
- const auto r = implementation.base64_to_binary(
2170
- data.data(), data.size(), out.data(), simdutf::base64_default);
2171
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
2172
- ASSERT_EQUAL(r.count, 0);
2173
- }
2174
-
2175
- TEST(issue_502) {
2176
- std::array<char, 1> data{'='};
2177
- std::vector<char> out(1);
2178
- const auto r = implementation.base64_to_binary(
2179
- data.data(), data.size(), out.data(), simdutf::base64_default);
2180
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
2181
- ASSERT_EQUAL(r.count, 0);
2182
- }
2183
-
2184
- TEST(issue_503) {
2185
- std::array<char16_t, 1> data{15626}; // 0x3D0A
2186
- std::vector<char> out(1);
2187
- const auto r = implementation.base64_to_binary(
2188
- data.data(), data.size(), out.data(), simdutf::base64_default);
2189
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
2190
- ASSERT_EQUAL(r.count, 0);
2191
- }
2192
-
2193
- TEST(decode_non_ascii_utf16) {
2194
- std::vector<std::u16string> cases = {u"Zg\u2009=="};
2195
- std::vector<simdutf::error_code> codes = {
2196
- simdutf::error_code::INVALID_BASE64_CHARACTER};
2197
- std::vector<size_t> counts = {2};
2198
-
2199
- for (size_t i = 0; i < cases.size(); i++) {
2200
- std::vector<char> buffer(implementation.maximal_binary_length_from_base64(
2201
- cases[i].data(), cases[i].size()));
2202
- simdutf::result r = implementation.base64_to_binary(
2203
- cases[i].data(), cases[i].size(), buffer.data());
2204
- ASSERT_EQUAL(r.error, codes[i]);
2205
- ASSERT_EQUAL(r.count, counts[i]);
2206
- size_t len = buffer.size();
2207
- r = simdutf::base64_to_binary_safe(cases[i].data(), cases[i].size(),
2208
- buffer.data(), len);
2209
- ASSERT_EQUAL(r.error, codes[i]);
2210
- ASSERT_EQUAL(r.count, counts[i]);
2211
- }
2212
- }
2213
-
2214
- TEST(decode_non_ascii) {
2215
- std::vector<std::string> cases = {"Zg\u2009=="};
2216
- std::vector<simdutf::error_code> codes = {
2217
- simdutf::error_code::INVALID_BASE64_CHARACTER};
2218
- std::vector<size_t> counts = {2};
2219
-
2220
- for (size_t i = 0; i < cases.size(); i++) {
2221
- std::vector<char> buffer(implementation.maximal_binary_length_from_base64(
2222
- cases[i].data(), cases[i].size()));
2223
- simdutf::result r = implementation.base64_to_binary(
2224
- cases[i].data(), cases[i].size(), buffer.data());
2225
- ASSERT_EQUAL(r.error, codes[i]);
2226
- ASSERT_EQUAL(r.count, counts[i]);
2227
- size_t len = buffer.size();
2228
- r = simdutf::base64_to_binary_safe(cases[i].data(), cases[i].size(),
2229
- buffer.data(), len);
2230
- ASSERT_EQUAL(r.error, codes[i]);
2231
- ASSERT_EQUAL(r.count, counts[i]);
2232
- }
2233
- }
2234
-
2235
- TEST(decode_base64_cases) {
2236
- std::vector<std::vector<char>> cases = {{0x53, 0x53}};
2237
- std::vector<simdutf::error_code> codes = {simdutf::error_code::SUCCESS};
2238
- std::vector<size_t> counts = {1};
2239
-
2240
- for (size_t i = 0; i < cases.size(); i++) {
2241
- std::vector<char> buffer(implementation.maximal_binary_length_from_base64(
2242
- cases[i].data(), cases[i].size()));
2243
- simdutf::result r = implementation.base64_to_binary(
2244
- cases[i].data(), cases[i].size(), buffer.data());
2245
- ASSERT_EQUAL(r.error, codes[i]);
2246
- ASSERT_EQUAL(r.count, counts[i]);
2247
- }
2248
- }
2249
-
2250
- namespace cases {
2251
- const std::vector<std::pair<std::string, std::string>> whitespaces = {
2252
- {"abcd", " Y\fW\tJ\njZ A=\r= "},
2253
- };
2254
-
2255
- const std::vector<std::pair<std::string, std::string>> simple = {
2256
- {"Hello, World!", "SGVsbG8sIFdvcmxkIQ=="},
2257
- {"GeeksforGeeks", "R2Vla3Nmb3JHZWVrcw=="},
2258
- {"123456", "MTIzNDU2"},
2259
- {"Base64 Encoding", "QmFzZTY0IEVuY29kaW5n"},
2260
- {"!R~J2jL&mI]O)3=c:G3Mo)oqmJdxoprTZDyxEvU0MI.'Ww5H{G>}y;;+B8E_Ah,Ed[ "
2261
- "PdBqY'^N>O$4:7LK1<:|7)btV@|{YWR$$Er59-XjVrFl4L}~yzTEd4'E[@k",
2262
- "IVJ+SjJqTCZtSV1PKTM9YzpHM01vKW9xbUpkeG9wclRaRHl4RXZVME1JLidXdzVIe0c+"
2263
- "fXk7OytCOEVfQWgsRWRbIFBkQnFZJ15OPk8kNDo3TEsxPDp8NylidFZAfHtZV1IkJEVyNTk"
2264
- "tWGpWckZsNEx9fnl6VEVkNCdFW0Br"}};
2265
-
2266
- const std::vector<std::pair<std::string, std::string>> no_padding = {
2267
- {"Hello, World!", "SGVsbG8sIFdvcmxkIQ"},
2268
- {"GeeksforGeeks", "R2Vla3Nmb3JHZWVrcw"},
2269
- {"123456", "MTIzNDU2"},
2270
- {"Base64 Encoding", "QmFzZTY0IEVuY29kaW5n"},
2271
- {"!R~J2jL&mI]O)3=c:G3Mo)oqmJdxoprTZDyxEvU0MI.'Ww5H{G>}y;;+B8E_Ah,Ed[ "
2272
- "PdBqY'^N>O$4:7LK1<:|7)btV@|{YWR$$Er59-XjVrFl4L}~yzTEd4'E[@k",
2273
- "IVJ+SjJqTCZtSV1PKTM9YzpHM01vKW9xbUpkeG9wclRaRHl4RXZVME1JLidXdzVIe0c+"
2274
- "fXk7OytCOEVfQWgsRWRbIFBkQnFZJ15OPk8kNDo3TEsxPDp8NylidFZAfHtZV1IkJEVyNTk"
2275
- "tWGpWckZsNEx9fnl6VEVkNCdFW0Br"}};
2276
-
2277
- const std::vector<std::pair<std::string, std::string>> simple_url = {
2278
- {"Hello, World!", "SGVsbG8sIFdvcmxkIQ"},
2279
- {"GeeksforGeeks", "R2Vla3Nmb3JHZWVrcw"},
2280
- {"123456", "MTIzNDU2"},
2281
- {"Base64 Encoding", "QmFzZTY0IEVuY29kaW5n"},
2282
- {"!R~J2jL&mI]O)3=c:G3Mo)oqmJdxoprTZDyxEvU0MI.'Ww5H{G>}y;;+B8E_Ah,Ed[ "
2283
- "PdBqY'^N>O$4:7LK1<:|7)btV@|{YWR$$Er59-XjVrFl4L}~yzTEd4'E[@k",
2284
- "IVJ-SjJqTCZtSV1PKTM9YzpHM01vKW9xbUpkeG9wclRaRHl4RXZVME1JLidXdzVIe0c-"
2285
- "fXk7OytCOEVfQWgsRWRbIFBkQnFZJ15OPk8kNDo3TEsxPDp8NylidFZAfHtZV1IkJEVyNTk"
2286
- "tWGpWckZsNEx9fnl6VEVkNCdFW0Br"}};
2287
-
2288
- const std::vector<std::pair<std::string, std::string>> simple_url_with_padding =
2289
- {{"Hello, World!", "SGVsbG8sIFdvcmxkIQ=="},
2290
- {"GeeksforGeeks", "R2Vla3Nmb3JHZWVrcw=="},
2291
- {"123456", "MTIzNDU2"},
2292
- {"Base64 Encoding", "QmFzZTY0IEVuY29kaW5n"},
2293
- {"!R~J2jL&mI]O)3=c:G3Mo)oqmJdxoprTZDyxEvU0MI.'Ww5H{G>}y;;+B8E_Ah,Ed[ "
2294
- "PdBqY'^N>O$4:7LK1<:|7)btV@|{YWR$$Er59-XjVrFl4L}~yzTEd4'E[@k",
2295
- "IVJ-"
2296
- "SjJqTCZtSV1PKTM9YzpHM01vKW9xbUpkeG9wclRaRHl4RXZVME1JLidXdzVIe0c-"
2297
- "fXk7OytCOEVfQWgsRWRbIFBkQnFZJ15OPk8kNDo3TEsxPDp8NylidFZAfHtZV1IkJEV"
2298
- "yNTk"
2299
- "tWGpWckZsNEx9fnl6VEVkNCdFW0Br"}};
2300
- } // namespace cases
2301
-
2302
- namespace cases16 {
2303
- const std::vector<std::pair<std::string, std::u16string>> simple_with_padding =
2304
- {{"Hello, World!", u"SGVsbG8sIFdvcmxkIQ=="},
2305
- {"GeeksforGeeks", u"R2Vla3Nmb3JHZWVrcw=="},
2306
- {"123456", u"MTIzNDU2"},
2307
- {"Base64 Encoding", u"QmFzZTY0IEVuY29kaW5n"},
2308
- {"!R~J2jL&mI]O)3=c:G3Mo)oqmJdxoprTZDyxEvU0MI.'Ww5H{G>}y;;+B8E_Ah,Ed[ "
2309
- "PdBqY'^N>O$4:7LK1<:|7)btV@|{YWR$$Er59-XjVrFl4L}~yzTEd4'E[@k",
2310
- u"IVJ+"
2311
- u"SjJqTCZtSV1PKTM9YzpHM01vKW9xbUpkeG9wclRaRHl4RXZVME1JLidXdzVIe0c+"
2312
- u"fXk7OytCOEVfQWgsRWRbIFBkQnFZJ15OPk8kNDo3TEsxPDp8NylidFZAfHtZV1IkJE"
2313
- u"VyNT"
2314
- u"ktWGpWckZsNEx9fnl6VEVkNCdFW0Br"}};
2315
-
2316
- const std::vector<std::pair<std::string, std::u16string>>
2317
- simple_url_without_padding = {
2318
- {"Hello, World!", u"SGVsbG8sIFdvcmxkIQ"},
2319
- {"GeeksforGeeks", u"R2Vla3Nmb3JHZWVrcw"},
2320
- {"123456", u"MTIzNDU2"},
2321
- {"Base64 Encoding", u"QmFzZTY0IEVuY29kaW5n"},
2322
- {"!R~J2jL&mI]O)3=c:G3Mo)oqmJdxoprTZDyxEvU0MI.'Ww5H{G>}y;;+B8E_Ah,Ed[ "
2323
- "PdBqY'^N>O$4:7LK1<:|7)btV@|{YWR$$Er59-XjVrFl4L}~yzTEd4'E[@k",
2324
- u"IVJ-"
2325
- u"SjJqTCZtSV1PKTM9YzpHM01vKW9xbUpkeG9wclRaRHl4RXZVME1JLidXdzVIe0c-"
2326
- u"fXk7OytCOEVfQWgsRWRbIFBkQnFZJ15OPk8kNDo3TEsxPDp8NylidFZAfHtZV1IkJE"
2327
- u"Vy"
2328
- u"NT"
2329
- u"ktWGpWckZsNEx9fnl6VEVkNCdFW0Br"}};
2330
- } // namespace cases16
2331
-
2332
- TEST(complete_decode_base64_cases) {
2333
- for (const auto &p : cases::whitespaces) {
2334
- std::vector<char> buffer(implementation.maximal_binary_length_from_base64(
2335
- p.second.data(), p.second.size()));
2336
- simdutf::result r = implementation.base64_to_binary(
2337
- p.second.data(), p.second.size(), buffer.data());
2338
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2339
- ASSERT_EQUAL(r.count, p.first.size());
2340
- for (size_t i = 0; i < r.count; i++) {
2341
- ASSERT_EQUAL(buffer[i], p.first[i]);
2342
- }
2343
- }
2344
- }
2345
-
2346
- TEST(complete_safe_decode_base64_cases) {
2347
- for (const auto &p : cases::whitespaces) {
2348
- std::vector<char> buffer(implementation.maximal_binary_length_from_base64(
2349
- p.second.data(), p.second.size()));
2350
- size_t bufsize = buffer.size();
2351
- simdutf::result r = simdutf::base64_to_binary_safe(
2352
- p.second.data(), p.second.size(), buffer.data(), bufsize);
2353
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2354
- ASSERT_EQUAL(bufsize, p.first.size());
2355
- for (size_t i = 0; i < bufsize; i++) {
2356
- ASSERT_EQUAL(buffer[i], p.first[i]);
2357
- }
2358
- #if SIMDUTF_ATOMIC_REF
2359
- bufsize = buffer.size();
2360
- r = simdutf::atomic_base64_to_binary_safe(p.second.data(), p.second.size(),
2361
- buffer.data(), bufsize);
2362
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2363
- ASSERT_EQUAL(bufsize, p.first.size());
2364
- for (size_t i = 0; i < bufsize; i++) {
2365
- ASSERT_EQUAL(buffer[i], p.first[i]);
2366
- }
2367
- #endif
2368
- }
2369
- }
2370
-
2371
- TEST(complete_safe_decode_base64url_cases) {
2372
- for (const auto &p : cases::whitespaces) {
2373
- std::vector<char> buffer(implementation.maximal_binary_length_from_base64(
2374
- p.second.data(), p.second.size()));
2375
- size_t bufsize = buffer.size();
2376
- simdutf::result r = simdutf::base64_to_binary_safe(
2377
- p.second.data(), p.second.size(), buffer.data(), bufsize,
2378
- simdutf::base64_url);
2379
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2380
- ASSERT_EQUAL(bufsize, p.first.size());
2381
- for (size_t i = 0; i < bufsize; i++) {
2382
- ASSERT_EQUAL(buffer[i], p.first[i]);
2383
- }
2384
- #if SIMDUTF_ATOMIC_REF
2385
- bufsize = buffer.size();
2386
- r = simdutf::base64_to_binary_safe(p.second.data(), p.second.size(),
2387
- buffer.data(), bufsize,
2388
- simdutf::base64_url);
2389
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2390
- ASSERT_EQUAL(bufsize, p.first.size());
2391
- for (size_t i = 0; i < bufsize; i++) {
2392
- ASSERT_EQUAL(buffer[i], p.first[i]);
2393
- }
2394
- #endif
2395
- }
2396
- }
2397
-
2398
- TEST(encode_base64_cases) {
2399
- for (const auto &p : cases::simple) {
2400
- std::vector<char> buffer(
2401
- simdutf::base64_length_from_binary(p.first.size()));
2402
- ASSERT_EQUAL(buffer.size(), p.second.size());
2403
- size_t s = implementation.binary_to_base64(p.first.data(), p.first.size(),
2404
- buffer.data());
2405
- ASSERT_EQUAL(s, p.second.size());
2406
- ASSERT_EQUAL(std::string(buffer.data(), buffer.size()), p.second);
2407
- }
2408
- }
2409
-
2410
- TEST(decode_base64_simple) {
2411
- for (const auto &p : cases::simple) {
2412
- std::vector<char> buffer(implementation.maximal_binary_length_from_base64(
2413
- p.second.data(), p.second.size()));
2414
- ASSERT_EQUAL(buffer.size(), p.first.size());
2415
- simdutf::result r = implementation.base64_to_binary(
2416
- p.second.data(), p.second.size(), buffer.data());
2417
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2418
- ASSERT_EQUAL(r.count, p.first.size());
2419
- for (size_t i = 0; i < buffer.size(); i++) {
2420
- ASSERT_EQUAL(buffer[i], p.first[i]);
2421
- }
2422
- }
2423
- }
2424
-
2425
- TEST(safe_decode_base64_simple) {
2426
- for (const auto &p : cases::simple) {
2427
- std::vector<char> buffer(implementation.maximal_binary_length_from_base64(
2428
- p.second.data(), p.second.size()));
2429
- ASSERT_EQUAL(buffer.size(), p.first.size());
2430
- size_t length = buffer.size();
2431
- simdutf::result r = simdutf::base64_to_binary_safe(
2432
- p.second.data(), p.second.size(), buffer.data(), length);
2433
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2434
- ASSERT_EQUAL(r.count, p.second.size());
2435
- ASSERT_EQUAL(length, p.first.size());
2436
- for (size_t i = 0; i < buffer.size(); i++) {
2437
- ASSERT_EQUAL(buffer[i], p.first[i]);
2438
- }
2439
- }
2440
- }
2441
-
2442
- TEST(encode_base64_cases_no_padding) {
2443
- for (const auto &p : cases::no_padding) {
2444
- std::vector<char> buffer(simdutf::base64_length_from_binary(
2445
- p.first.size(), simdutf::base64_default_no_padding));
2446
- ASSERT_EQUAL(buffer.size(), p.second.size());
2447
- size_t s = implementation.binary_to_base64(
2448
- p.first.data(), p.first.size(), buffer.data(),
2449
- simdutf::base64_default_no_padding);
2450
- ASSERT_EQUAL(s, p.second.size());
2451
- ASSERT_EQUAL(std::string(buffer.data(), buffer.size()), p.second);
2452
- }
2453
- }
2454
-
2455
- #if SIMDUTF_BASE64URL_TESTS
2456
-
2457
- TEST(encode_base64url_simple) {
2458
- for (const auto &p : cases::simple_url) {
2459
- std::vector<char> buffer(simdutf::base64_length_from_binary(
2460
- p.first.size(), simdutf::base64_url));
2461
- ASSERT_EQUAL(buffer.size(), p.second.size());
2462
- size_t s = implementation.binary_to_base64(
2463
- p.first.data(), p.first.size(), buffer.data(), simdutf::base64_url);
2464
- ASSERT_EQUAL(s, p.second.size());
2465
- if (std::string(buffer.data(), buffer.size()) != p.second) {
2466
- printf("difference:\n");
2467
- printf(" %.*s\n", (int)s, buffer.data());
2468
- printf(" %.*s\n", (int)s, p.second.data());
2469
- }
2470
- ASSERT_EQUAL(std::string(buffer.data(), buffer.size()), p.second);
2471
- }
2472
- }
2473
-
2474
- TEST(decode_base64url) {
2475
- for (const auto &p : cases::simple_url) {
2476
- std::vector<char> buffer(implementation.maximal_binary_length_from_base64(
2477
- p.second.data(), p.second.size()));
2478
- ASSERT_EQUAL(buffer.size(), p.first.size());
2479
- simdutf::result r = implementation.base64_to_binary(
2480
- p.second.data(), p.second.size(), buffer.data(), simdutf::base64_url);
2481
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2482
- ASSERT_EQUAL(r.count, p.first.size());
2483
- for (size_t i = 0; i < buffer.size(); i++) {
2484
- ASSERT_EQUAL(buffer[i], p.first[i]);
2485
- }
2486
- }
2487
- }
2488
-
2489
- TEST(safe_decode_base64url) {
2490
- for (const auto &p : cases::simple_url) {
2491
- std::vector<char> buffer(implementation.maximal_binary_length_from_base64(
2492
- p.second.data(), p.second.size()));
2493
- ASSERT_EQUAL(buffer.size(), p.first.size());
2494
- size_t length = buffer.size();
2495
- simdutf::result r = simdutf::base64_to_binary_safe(
2496
- p.second.data(), p.second.size(), buffer.data(), length,
2497
- simdutf::base64_url);
2498
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2499
- ASSERT_EQUAL(r.count, p.second.size());
2500
- ASSERT_EQUAL(length, p.first.size());
2501
- for (size_t i = 0; i < buffer.size(); i++) {
2502
- ASSERT_EQUAL(buffer[i], p.first[i]);
2503
- }
2504
- }
2505
- }
2506
-
2507
- TEST(encode_base64url_with_padding_cases) {
2508
- for (const auto &p : cases::simple_url_with_padding) {
2509
- std::vector<char> buffer(simdutf::base64_length_from_binary(
2510
- p.first.size(), simdutf::base64_url_with_padding));
2511
- ASSERT_EQUAL(buffer.size(), p.second.size());
2512
- size_t s = implementation.binary_to_base64(
2513
- p.first.data(), p.first.size(), buffer.data(),
2514
- simdutf::base64_url_with_padding);
2515
- ASSERT_EQUAL(s, p.second.size());
2516
- if (std::string(buffer.data(), buffer.size()) != p.second) {
2517
- printf("difference:\n");
2518
- printf(" %.*s\n", (int)s, buffer.data());
2519
- printf(" %.*s\n", (int)s, p.second.data());
2520
- }
2521
- ASSERT_EQUAL(std::string(buffer.data(), buffer.size()), p.second);
2522
- }
2523
- }
2524
-
2525
- #endif
2526
-
2527
- TEST(decode_base64_cases_16) {
2528
- for (const auto &p : cases16::simple_with_padding) {
2529
- std::vector<char> buffer(implementation.maximal_binary_length_from_base64(
2530
- p.second.data(), p.second.size()));
2531
- ASSERT_EQUAL(buffer.size(), p.first.size());
2532
- simdutf::result r = implementation.base64_to_binary(
2533
- p.second.data(), p.second.size(), buffer.data());
2534
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2535
- ASSERT_EQUAL(r.count, p.first.size());
2536
- ASSERT_BYTES_EQUAL(buffer, p.first, r.count);
2537
- }
2538
- }
2539
-
2540
- TEST(safe_decode_base64_cases_16) {
2541
- for (const auto &p : cases16::simple_with_padding) {
2542
- std::vector<char> buffer(implementation.maximal_binary_length_from_base64(
2543
- p.second.data(), p.second.size()));
2544
- ASSERT_EQUAL(buffer.size(), p.first.size());
2545
- size_t length = buffer.size();
2546
- simdutf::result r = simdutf::base64_to_binary_safe(
2547
- p.second.data(), p.second.size(), buffer.data(), length);
2548
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2549
- ASSERT_EQUAL(r.count, p.second.size());
2550
- ASSERT_EQUAL(length, p.first.size());
2551
- for (size_t i = 0; i < buffer.size(); i++) {
2552
- ASSERT_EQUAL(buffer[i], p.first[i]);
2553
- }
2554
- }
2555
- }
2556
-
2557
- #if SIMDUTF_BASE64URL_TESTS
2558
-
2559
- TEST(decode_base64url_cases_16) {
2560
- for (const auto &p : cases16::simple_url_without_padding) {
2561
- std::vector<char> buffer(implementation.maximal_binary_length_from_base64(
2562
- p.second.data(), p.second.size()));
2563
- ASSERT_EQUAL(buffer.size(), p.first.size());
2564
- simdutf::result r = implementation.base64_to_binary(
2565
- p.second.data(), p.second.size(), buffer.data(), simdutf::base64_url);
2566
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2567
- ASSERT_EQUAL(r.count, p.first.size());
2568
- for (size_t i = 0; i < buffer.size(); i++) {
2569
- ASSERT_EQUAL(buffer[i], p.first[i]);
2570
- }
2571
- }
2572
- }
2573
-
2574
- TEST(safe_decode_base64url_cases_16) {
2575
- for (const auto &p : cases16::simple_url_without_padding) {
2576
- std::vector<char> buffer(implementation.maximal_binary_length_from_base64(
2577
- p.second.data(), p.second.size()));
2578
- ASSERT_EQUAL(buffer.size(), p.first.size());
2579
- size_t length = buffer.size();
2580
- simdutf::result r = simdutf::base64_to_binary_safe(
2581
- p.second.data(), p.second.size(), buffer.data(), length,
2582
- simdutf::base64_url);
2583
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2584
- ASSERT_EQUAL(r.count, p.second.size());
2585
- ASSERT_EQUAL(length, p.first.size());
2586
- for (size_t i = 0; i < buffer.size(); i++) {
2587
- ASSERT_EQUAL(buffer[i], p.first[i]);
2588
- }
2589
- }
2590
- }
2591
-
2592
- #endif
2593
-
2594
- TEST(roundtrip_base64) {
2595
- for (size_t len = 0; len < max_len; len++) {
2596
- std::vector<char> source(len, 0);
2597
- std::vector<char> buffer;
2598
- buffer.resize(simdutf::base64_length_from_binary(len));
2599
- std::vector<char> back(len);
2600
- std::mt19937 gen((std::mt19937::result_type)(seed));
2601
- std::uniform_int_distribution<int> byte_generator{0, 255};
2602
- for (size_t trial = 0; trial < 10; trial++) {
2603
- for (size_t i = 0; i < len; i++) {
2604
- source[i] = byte_generator(gen);
2605
- }
2606
- size_t size = implementation.binary_to_base64(
2607
- source.data(), source.size(), buffer.data());
2608
- ASSERT_EQUAL(size, simdutf::base64_length_from_binary(len));
2609
- simdutf::result r =
2610
- implementation.base64_to_binary(buffer.data(), size, back.data());
2611
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2612
- ASSERT_EQUAL(r.count, len);
2613
- if (back != source) {
2614
- printf("=====input size %zu\n", len);
2615
- for (size_t i = 0; i < len; i++) {
2616
- if (back[i] != source[i]) {
2617
- printf("Mismatch at position %zu trial %zu\n", i, trial);
2618
- }
2619
- printf("%zu: %02x %02x\n", i, uint8_t(back[i]), uint8_t(source[i]));
2620
- }
2621
- printf("=====base64 size %zu\n", size);
2622
- for (size_t i = 0; i < size; i++) {
2623
- printf("%zu: %02x %c\n", i, uint8_t(buffer[i]), buffer[i]);
2624
- }
2625
- }
2626
- ASSERT_TRUE(back == source);
2627
-
2628
- // Test with all last_chunk_handling_options
2629
- for (auto option : {simdutf::last_chunk_handling_options::strict,
2630
- simdutf::last_chunk_handling_options::loose}) {
2631
- r = implementation.base64_to_binary(buffer.data(), size, back.data(),
2632
- simdutf::base64_default, option);
2633
- ASSERT_TRUE((size % 4) == 0);
2634
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2635
- ASSERT_EQUAL(r.count, len);
2636
- ASSERT_TRUE(back == source);
2637
- }
2638
- }
2639
- }
2640
- }
2641
-
2642
- TEST(roundtrip_base64_16) {
2643
- for (size_t len = 0; len < max_len; len++) {
2644
- std::vector<char> source(len, 0);
2645
- std::vector<char> buffer;
2646
- std::vector<char16_t> buffer16;
2647
-
2648
- buffer.resize(simdutf::base64_length_from_binary(len));
2649
- std::vector<char> back(len);
2650
- std::mt19937 gen((std::mt19937::result_type)(seed));
2651
- std::uniform_int_distribution<int> byte_generator{0, 255};
2652
- for (size_t trial = 0; trial < 10; trial++) {
2653
- for (size_t i = 0; i < len; i++) {
2654
- source[i] = byte_generator(gen);
2655
- }
2656
- size_t size = implementation.binary_to_base64(
2657
- source.data(), source.size(), buffer.data());
2658
- buffer.resize(size);
2659
- buffer16.resize(buffer.size());
2660
- for (size_t i = 0; i < buffer.size(); i++) {
2661
- buffer16[i] = buffer[i];
2662
- }
2663
- ASSERT_EQUAL(size, simdutf::base64_length_from_binary(len));
2664
- simdutf::result r =
2665
- implementation.base64_to_binary(buffer16.data(), size, back.data());
2666
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2667
- ASSERT_EQUAL(r.count, len);
2668
- if (back != source) {
2669
- printf("=====input size %zu\n", len);
2670
- for (size_t i = 0; i < len; i++) {
2671
- if (back[i] != source[i]) {
2672
- printf("Mismatch at position %zu trial %zu\n", i, trial);
2673
- }
2674
- printf("%zu: %02x %02x\n", i, uint8_t(back[i]), uint8_t(source[i]));
2675
- }
2676
- printf("=====base64 size %zu\n", size);
2677
- for (size_t i = 0; i < size; i++) {
2678
- printf("%zu: %02x %c\n", i, uint8_t(buffer[i]), buffer[i]);
2679
- }
2680
- }
2681
- ASSERT_TRUE(back == source);
2682
-
2683
- // Test with all last_chunk_handling_options
2684
- for (auto option : {simdutf::last_chunk_handling_options::strict,
2685
- simdutf::last_chunk_handling_options::loose}) {
2686
- r = implementation.base64_to_binary(buffer.data(), size, back.data(),
2687
- simdutf::base64_default, option);
2688
- ASSERT_TRUE((size % 4) == 0);
2689
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2690
- ASSERT_EQUAL(r.count, len);
2691
- ASSERT_TRUE(back == source);
2692
- }
2693
- }
2694
- }
2695
- }
2696
-
2697
- #if SIMDUTF_BASE64URL_TESTS
2698
-
2699
- TEST(roundtrip_base64url) {
2700
- for (size_t len = 0; len < max_len; len++) {
2701
- std::vector<char> source(len, 0);
2702
- std::vector<char> buffer;
2703
- buffer.resize(simdutf::base64_length_from_binary(len, simdutf::base64_url));
2704
- std::vector<char> back(len);
2705
- std::mt19937 gen((std::mt19937::result_type)(seed));
2706
- std::uniform_int_distribution<int> byte_generator{0, 255};
2707
- for (size_t trial = 0; trial < 10; trial++) {
2708
- for (size_t i = 0; i < len; i++) {
2709
- source[i] = byte_generator(gen);
2710
- }
2711
- size_t size = implementation.binary_to_base64(
2712
- source.data(), source.size(), buffer.data(), simdutf::base64_url);
2713
- ASSERT_EQUAL(
2714
- size, simdutf::base64_length_from_binary(len, simdutf::base64_url));
2715
- simdutf::result r = implementation.base64_to_binary(
2716
- buffer.data(), size, back.data(), simdutf::base64_url);
2717
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2718
- ASSERT_EQUAL(r.count, len);
2719
- if (back != source) {
2720
- printf("=====input size %zu\n", len);
2721
- for (size_t i = 0; i < len; i++) {
2722
- if (back[i] != source[i]) {
2723
- printf("Mismatch at position %zu trial %zu\n", i, trial);
2724
- }
2725
- printf("%zu: %02x %02x\n", i, uint8_t(back[i]), uint8_t(source[i]));
2726
- }
2727
- printf("=====base64 size %zu\n", size);
2728
- for (size_t i = 0; i < size; i++) {
2729
- printf("%zu: %02x %c\n", i, uint8_t(buffer[i]), buffer[i]);
2730
- }
2731
- }
2732
- ASSERT_TRUE(back == source);
2733
-
2734
- // Test with all last_chunk_handling_options
2735
- for (auto option :
2736
- {simdutf::last_chunk_handling_options::strict,
2737
- simdutf::last_chunk_handling_options::loose,
2738
- simdutf::last_chunk_handling_options::stop_before_partial}) {
2739
- r = implementation.base64_to_binary(buffer.data(), size, back.data(),
2740
- simdutf::base64_url, option);
2741
- if ((size % 4) == 0) {
2742
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2743
- ASSERT_EQUAL(r.count, len);
2744
- ASSERT_TRUE(back == source);
2745
- } else {
2746
- if (option == simdutf::last_chunk_handling_options::strict) {
2747
- ASSERT_EQUAL(r.error, simdutf::error_code::BASE64_INPUT_REMAINDER);
2748
- } else if (option == simdutf::last_chunk_handling_options::loose) {
2749
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2750
- ASSERT_EQUAL(r.count, len);
2751
- ASSERT_TRUE(back == source);
2752
- } else if (option == simdutf::last_chunk_handling_options::
2753
- stop_before_partial) {
2754
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2755
- ASSERT_EQUAL(r.count, len / 3 * 3);
2756
- ASSERT_TRUE(std::equal(back.begin(), back.begin() + len / 3 * 3,
2757
- source.begin()));
2758
- }
2759
- }
2760
- }
2761
- }
2762
- }
2763
- }
2764
-
2765
- TEST(roundtrip_base64url_16) {
2766
- for (size_t len = 0; len < max_len; len++) {
2767
- std::vector<char> source(len, 0);
2768
- std::vector<char> buffer;
2769
- std::vector<char16_t> buffer16;
2770
-
2771
- buffer.resize(simdutf::base64_length_from_binary(len, simdutf::base64_url));
2772
- std::vector<char> back(len);
2773
- std::mt19937 gen((std::mt19937::result_type)(seed));
2774
- std::uniform_int_distribution<int> byte_generator{0, 255};
2775
- for (size_t trial = 0; trial < 10; trial++) {
2776
- for (size_t i = 0; i < len; i++) {
2777
- source[i] = byte_generator(gen);
2778
- }
2779
- size_t size = implementation.binary_to_base64(
2780
- source.data(), source.size(), buffer.data(), simdutf::base64_url);
2781
- buffer.resize(size);
2782
- buffer16.resize(buffer.size());
2783
- for (size_t i = 0; i < buffer.size(); i++) {
2784
- buffer16[i] = buffer[i];
2785
- }
2786
- ASSERT_EQUAL(
2787
- size, simdutf::base64_length_from_binary(len, simdutf::base64_url));
2788
- simdutf::result r = implementation.base64_to_binary(
2789
- buffer16.data(), size, back.data(), simdutf::base64_url);
2790
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2791
- ASSERT_EQUAL(r.count, len);
2792
- if (back != source) {
2793
- printf("=====input size %zu\n", len);
2794
- for (size_t i = 0; i < len; i++) {
2795
- if (back[i] != source[i]) {
2796
- printf("Mismatch at position %zu trial %zu\n", i, trial);
2797
- }
2798
- printf("%zu: %02x %02x\n", i, uint8_t(back[i]), uint8_t(source[i]));
2799
- }
2800
- printf("=====base64 size %zu\n", size);
2801
- for (size_t i = 0; i < size; i++) {
2802
- printf("%zu: %02x %c\n", i, uint8_t(buffer[i]), buffer[i]);
2803
- }
2804
- }
2805
- ASSERT_TRUE(back == source);
2806
- for (auto option :
2807
- {simdutf::last_chunk_handling_options::strict,
2808
- simdutf::last_chunk_handling_options::loose,
2809
- simdutf::last_chunk_handling_options::stop_before_partial}) {
2810
- r = implementation.base64_to_binary(buffer.data(), size, back.data(),
2811
- simdutf::base64_url, option);
2812
- if ((size % 4) == 0) {
2813
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2814
- ASSERT_EQUAL(r.count, len);
2815
- ASSERT_TRUE(back == source);
2816
- } else {
2817
- if (option == simdutf::last_chunk_handling_options::strict) {
2818
- ASSERT_EQUAL(r.error, simdutf::error_code::BASE64_INPUT_REMAINDER);
2819
- } else if (option == simdutf::last_chunk_handling_options::loose) {
2820
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2821
- ASSERT_EQUAL(r.count, len);
2822
- ASSERT_TRUE(back == source);
2823
- } else if (option == simdutf::last_chunk_handling_options::
2824
- stop_before_partial) {
2825
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
2826
- ASSERT_EQUAL(r.count, len / 3 * 3);
2827
- ASSERT_TRUE(std::equal(back.begin(), back.begin() + len / 3 * 3,
2828
- source.begin()));
2829
- }
2830
- }
2831
- }
2832
- }
2833
- }
2834
- }
2835
- #endif
2836
-
2837
- TEST(bad_padding_base64) {
2838
- for (size_t len = 0; len < max_len; len++) {
2839
- std::vector<char> source(len, 0);
2840
- std::vector<char> buffer;
2841
- buffer.resize(simdutf::base64_length_from_binary(len) + 1);
2842
- std::mt19937 gen((std::mt19937::result_type)(seed));
2843
- std::uniform_int_distribution<int> byte_generator{0, 255};
2844
- for (size_t trial = 0; trial < 10; trial++) {
2845
- for (size_t i = 0; i < len; i++) {
2846
- source[i] = byte_generator(gen);
2847
- }
2848
- size_t size = implementation.binary_to_base64(
2849
- source.data(), source.size(), buffer.data());
2850
- size_t padding = 0;
2851
- if (size > 0 && buffer[size - 1] == '=') {
2852
- padding++;
2853
- if (size > 1 && buffer[size - 2] == '=') {
2854
- padding++;
2855
- }
2856
- }
2857
- buffer.resize(size);
2858
- ; // in case we need
2859
- std::vector<char> back(simdutf::maximal_binary_length_from_base64(
2860
- buffer.data(), buffer.size()));
2861
- if (padding == 1) {
2862
- // adding padding should break
2863
- buffer.push_back('=');
2864
- for (size_t i = 0; i < 5; i++) {
2865
- add_space(buffer, gen);
2866
- }
2867
- simdutf::result r = simdutf::base64_to_binary(
2868
- buffer.data(), buffer.size(), back.data());
2869
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
2870
- } else if (padding == 2) {
2871
- // adding padding should break
2872
- {
2873
- auto copy = buffer;
2874
- copy.push_back('=');
2875
- for (size_t i = 0; i < 5; i++) {
2876
- add_space(copy, gen);
2877
- }
2878
- simdutf::result r =
2879
- simdutf::base64_to_binary(copy.data(), copy.size(), back.data());
2880
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
2881
- }
2882
- // removing padding should break
2883
- {
2884
- auto copy = buffer;
2885
- copy.resize(copy.size() - 1);
2886
- for (size_t i = 0; i < 5; i++) {
2887
- add_space(copy, gen);
2888
- }
2889
- simdutf::result r =
2890
- simdutf::base64_to_binary(copy.data(), copy.size(), back.data());
2891
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
2892
- }
2893
-
2894
- } else {
2895
- {
2896
- auto copy = buffer;
2897
- copy.push_back('=');
2898
- for (size_t i = 0; i < 5; i++) {
2899
- add_space(copy, gen);
2900
- }
2901
- simdutf::result r =
2902
- simdutf::base64_to_binary(copy.data(), copy.size(), back.data());
2903
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
2904
- }
2905
- }
2906
- }
2907
- }
2908
- }
2909
- TEST(doomed_base64_roundtrip) {
2910
- for (size_t len = 0; len < max_len; len++) {
2911
- std::vector<char> source(len, 0);
2912
- std::vector<char> buffer;
2913
- buffer.resize(simdutf::base64_length_from_binary(len));
2914
- std::mt19937 gen((std::mt19937::result_type)(seed));
2915
- std::uniform_int_distribution<int> byte_generator{0, 255};
2916
- for (size_t trial = 0; trial < 10; trial++) {
2917
- for (size_t i = 0; i < len; i++) {
2918
- source[i] = byte_generator(gen);
2919
- }
2920
- size_t size = implementation.binary_to_base64(
2921
- source.data(), source.size(), buffer.data());
2922
- buffer.resize(size);
2923
- size_t location = add_garbage(buffer, gen, to_base64_value);
2924
- std::vector<char> back(simdutf::maximal_binary_length_from_base64(
2925
- buffer.data(), buffer.size()));
2926
- simdutf::result r =
2927
- simdutf::base64_to_binary(buffer.data(), buffer.size(), back.data());
2928
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
2929
- ASSERT_EQUAL(r.count, location);
2930
- for (auto option :
2931
- {simdutf::last_chunk_handling_options::strict,
2932
- simdutf::last_chunk_handling_options::loose,
2933
- simdutf::last_chunk_handling_options::stop_before_partial}) {
2934
- size_t back_length = back.size();
2935
- r = simdutf::base64_to_binary_safe(buffer.data(), buffer.size(),
2936
- back.data(), back_length,
2937
- simdutf::base64_default, option);
2938
- ASSERT_EQUAL(r.error, simdutf::error_code::INVALID_BASE64_CHARACTER);
2939
- ASSERT_EQUAL(r.count, location);
2940
- }
2941
- }
2942
- }
2943
- }
2944
-
2945
- TEST(doomed_truncated_base64_roundtrip) {
2946
- for (size_t len = 1; len < max_len; len++) {
2947
- std::vector<char> source(len, 0);
2948
- std::vector<char> buffer;
2949
- std::mt19937 gen((std::mt19937::result_type)(seed));
2950
- std::uniform_int_distribution<int> byte_generator{0, 255};
2951
- for (size_t trial = 0; trial < 10; trial++) {
2952
- for (size_t i = 0; i < len; i++) {
2953
- source[i] = byte_generator(gen);
2954
- }
2955
- buffer.resize(simdutf::base64_length_from_binary(len));
2956
- size_t size = implementation.binary_to_base64(
2957
- source.data(), source.size(), buffer.data());
2958
- buffer.resize(size - 3);
2959
- std::vector<char> back(simdutf::maximal_binary_length_from_base64(
2960
- buffer.data(), buffer.size()));
2961
- for (auto option : {simdutf::last_chunk_handling_options::loose,
2962
- simdutf::last_chunk_handling_options::strict}) {
2963
- simdutf::result r = implementation.base64_to_binary(
2964
- buffer.data(), buffer.size(), back.data(), simdutf::base64_default,
2965
- option);
2966
- ASSERT_EQUAL(r.error, simdutf::error_code::BASE64_INPUT_REMAINDER);
2967
- size_t back_length = back.size();
2968
- r = simdutf::base64_to_binary_safe(buffer.data(), buffer.size(),
2969
- back.data(), back_length);
2970
- ASSERT_EQUAL(r.error, simdutf::error_code::BASE64_INPUT_REMAINDER);
2971
- }
2972
- }
2973
- }
2974
- }
2975
-
2976
- TEST(doomed_truncated_base64_roundtrip_16) {
2977
- for (size_t len = 1; len < max_len; len++) {
2978
- std::vector<char> source(len, 0);
2979
- std::vector<char> buffer;
2980
- std::vector<char16_t> buffer16;
2981
- std::mt19937 gen((std::mt19937::result_type)(seed));
2982
- std::uniform_int_distribution<int> byte_generator{0, 255};
2983
- for (size_t trial = 0; trial < 10; trial++) {
2984
- for (size_t i = 0; i < len; i++) {
2985
- source[i] = byte_generator(gen);
2986
- }
2987
- buffer.resize(simdutf::base64_length_from_binary(len));
2988
- size_t size = implementation.binary_to_base64(
2989
- source.data(), source.size(), buffer.data());
2990
- buffer.resize(size - 3);
2991
- buffer16.resize(buffer.size());
2992
- for (size_t i = 0; i < buffer.size(); i++) {
2993
- buffer16[i] = buffer[i];
2994
- }
2995
- std::vector<char> back(implementation.maximal_binary_length_from_base64(
2996
- buffer16.data(), buffer16.size()));
2997
- simdutf::result r = implementation.base64_to_binary(
2998
- buffer16.data(), buffer16.size(), back.data());
2999
- ASSERT_EQUAL(r.error, simdutf::error_code::BASE64_INPUT_REMAINDER);
3000
- size_t back_length = back.size();
3001
- r = simdutf::base64_to_binary_safe(buffer16.data(), buffer16.size(),
3002
- back.data(), back_length);
3003
- ASSERT_EQUAL(r.error, simdutf::error_code::BASE64_INPUT_REMAINDER);
3004
- }
3005
- }
3006
- }
3007
-
3008
- TEST(roundtrip_base64_16_with_spaces) {
3009
- for (size_t len = 0; len < max_len; len++) {
3010
- std::vector<char> source(len, 0);
3011
- std::vector<char> buffer;
3012
- std::vector<char16_t> buffer16;
3013
-
3014
- buffer.resize(simdutf::base64_length_from_binary(len));
3015
- std::vector<char> back(len);
3016
- std::mt19937 gen((std::mt19937::result_type)(seed));
3017
- std::uniform_int_distribution<int> byte_generator{0, 255};
3018
- for (size_t trial = 0; trial < 10; trial++) {
3019
- for (size_t i = 0; i < len; i++) {
3020
- source[i] = byte_generator(gen);
3021
- }
3022
- size_t size = implementation.binary_to_base64(
3023
- source.data(), source.size(), buffer.data());
3024
- buffer.resize(size);
3025
- for (size_t i = 0; i < 5; i++) {
3026
- add_space(buffer, gen);
3027
- }
3028
- buffer16.resize(buffer.size());
3029
- for (size_t i = 0; i < buffer.size(); i++) {
3030
- buffer16[i] = buffer[i];
3031
- }
3032
- ASSERT_EQUAL(size, simdutf::base64_length_from_binary(len));
3033
- simdutf::result r = implementation.base64_to_binary(
3034
- buffer16.data(), buffer16.size(), back.data());
3035
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
3036
- ASSERT_EQUAL(r.count, len);
3037
- if (back != source) {
3038
- printf("=====input size %zu\n", len);
3039
- for (size_t i = 0; i < len; i++) {
3040
- if (back[i] != source[i]) {
3041
- printf("Mismatch at position %zu trial %zu\n", i, trial);
3042
- }
3043
- printf("%zu: %02x %02x\n", i, uint8_t(back[i]), uint8_t(source[i]));
3044
- }
3045
- printf("=====base64 size %zu\n", size);
3046
- for (size_t i = 0; i < size; i++) {
3047
- printf("%zu: %02x %c\n", i, uint8_t(buffer[i]), buffer[i]);
3048
- }
3049
- }
3050
- ASSERT_TRUE(back == source);
3051
- }
3052
- }
3053
- }
3054
-
3055
- TEST(roundtrip_base64_16_with_garbage) {
3056
- for (size_t len = 0; len < max_len; len++) {
3057
- std::vector<char> source(len, 0);
3058
- std::vector<char> buffer;
3059
- std::vector<char16_t> buffer16;
3060
-
3061
- buffer.resize(simdutf::base64_length_from_binary(len));
3062
- std::vector<char> back(len);
3063
- std::mt19937 gen((std::mt19937::result_type)(seed));
3064
- std::uniform_int_distribution<int> byte_generator{0, 255};
3065
- for (size_t trial = 0; trial < 10; trial++) {
3066
- for (size_t i = 0; i < len; i++) {
3067
- source[i] = byte_generator(gen);
3068
- }
3069
- size_t size = implementation.binary_to_base64(
3070
- source.data(), source.size(), buffer.data());
3071
- buffer.resize(size);
3072
- for (size_t i = 0; i < 5; i++) {
3073
- add_garbage(buffer, gen, to_base64_value);
3074
- }
3075
- buffer16.resize(buffer.size());
3076
- for (size_t i = 0; i < buffer.size(); i++) {
3077
- buffer16[i] = buffer[i];
3078
- }
3079
- ASSERT_EQUAL(size, simdutf::base64_length_from_binary(len));
3080
- simdutf::result r = implementation.base64_to_binary(
3081
- buffer16.data(), buffer16.size(), back.data(),
3082
- simdutf::base64_default_accept_garbage);
3083
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
3084
- ASSERT_EQUAL(r.count, len);
3085
- if (back != source) {
3086
- printf("=====input size %zu\n", len);
3087
- for (size_t i = 0; i < len; i++) {
3088
- if (back[i] != source[i]) {
3089
- printf("Mismatch at position %zu trial %zu\n", i, trial);
3090
- }
3091
- printf("%zu: %02x %02x\n", i, uint8_t(back[i]), uint8_t(source[i]));
3092
- }
3093
- printf("=====base64 size %zu\n", size);
3094
- for (size_t i = 0; i < size; i++) {
3095
- printf("%zu: %02x %c\n", i, uint8_t(buffer[i]), buffer[i]);
3096
- }
3097
- }
3098
- ASSERT_TRUE(back == source);
3099
- }
3100
- }
3101
- }
3102
-
3103
- TEST(roundtrip_base64_url_16_with_garbage) {
3104
- for (size_t len = 0; len < max_len; len++) {
3105
- std::vector<char> source(len, 0);
3106
- std::vector<char> buffer;
3107
- std::vector<char16_t> buffer16;
3108
-
3109
- buffer.resize(simdutf::base64_length_from_binary(len));
3110
- std::vector<char> back(len);
3111
- std::mt19937 gen((std::mt19937::result_type)(seed));
3112
- std::uniform_int_distribution<int> byte_generator{0, 255};
3113
- for (size_t trial = 0; trial < 10; trial++) {
3114
- for (size_t i = 0; i < len; i++) {
3115
- source[i] = byte_generator(gen);
3116
- }
3117
- size_t size = implementation.binary_to_base64(
3118
- source.data(), source.size(), buffer.data(), simdutf::base64_url);
3119
- buffer.resize(size);
3120
- for (size_t i = 0; i < 5; i++) {
3121
- add_garbage(buffer, gen, to_base64url_value);
3122
- }
3123
- buffer16.resize(buffer.size());
3124
- for (size_t i = 0; i < buffer.size(); i++) {
3125
- buffer16[i] = buffer[i];
3126
- }
3127
- ASSERT_EQUAL(
3128
- size, simdutf::base64_length_from_binary(len, simdutf::base64_url));
3129
- simdutf::result r = implementation.base64_to_binary(
3130
- buffer16.data(), buffer16.size(), back.data(),
3131
- simdutf::base64_url_accept_garbage);
3132
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
3133
- ASSERT_EQUAL(r.count, len);
3134
- if (back != source) {
3135
- printf("=====input size %zu\n", len);
3136
- for (size_t i = 0; i < len; i++) {
3137
- if (back[i] != source[i]) {
3138
- printf("Mismatch at position %zu trial %zu\n", i, trial);
3139
- }
3140
- printf("%zu: %02x %02x\n", i, uint8_t(back[i]), uint8_t(source[i]));
3141
- }
3142
- printf("=====base64 size %zu\n", size);
3143
- for (size_t i = 0; i < size; i++) {
3144
- printf("%zu: %02x %c\n", i, uint8_t(buffer[i]), buffer[i]);
3145
- }
3146
- }
3147
- ASSERT_TRUE(back == source);
3148
- }
3149
- }
3150
- }
3151
-
3152
- TEST(aborted_safe_roundtrip_base64) {
3153
- for (size_t offset = 1; offset <= 16; offset += 3) {
3154
- for (size_t len = offset; len < (max_len / 2); len++) {
3155
- std::vector<char> source(len, 0);
3156
- std::vector<char> buffer;
3157
- buffer.resize(simdutf::base64_length_from_binary(len));
3158
- std::mt19937 gen((std::mt19937::result_type)(seed));
3159
- std::uniform_int_distribution<int> byte_generator{0, 255};
3160
- for (size_t trial = 0; trial < 10; trial++) {
3161
- for (size_t i = 0; i < len; i++) {
3162
- source[i] = byte_generator(gen);
3163
- }
3164
- size_t size = implementation.binary_to_base64(
3165
- source.data(), source.size(), buffer.data());
3166
- buffer.resize(size);
3167
- std::vector<char> back(simdutf::maximal_binary_length_from_base64(
3168
- buffer.data(), buffer.size()));
3169
- size_t limited_length = len - offset; // intentionally too little
3170
- back.resize(limited_length);
3171
- back.shrink_to_fit();
3172
- simdutf::result r = simdutf::base64_to_binary_safe(
3173
- buffer.data(), buffer.size(), back.data(), limited_length);
3174
- ASSERT_EQUAL(r.error, simdutf::error_code::OUTPUT_BUFFER_TOO_SMALL);
3175
- for (size_t i = 0; i < limited_length; i++) {
3176
- ASSERT_EQUAL(source[i], back[i]);
3177
- }
3178
- // Now let us decode the rest !!!
3179
- size_t input_index = r.count;
3180
- back.resize(simdutf::maximal_binary_length_from_base64(
3181
- buffer.data() + input_index, buffer.size() - input_index));
3182
- size_t second_length = back.size();
3183
- r = simdutf::base64_to_binary_safe(buffer.data() + input_index,
3184
- buffer.size() - input_index,
3185
- back.data(), second_length);
3186
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
3187
- back.resize(second_length);
3188
- ASSERT_EQUAL(second_length + limited_length, len);
3189
-
3190
- for (size_t i = 0; i < second_length; i++) {
3191
- ASSERT_EQUAL(source[i + limited_length], back[i]);
3192
- }
3193
- }
3194
- }
3195
- }
3196
- }
3197
-
3198
- TEST(aborted_safe_roundtrip_base64_16) {
3199
- for (size_t offset = 1; offset <= 16; offset += 3) {
3200
- for (size_t len = offset; len < (max_len / 2); len++) {
3201
- std::vector<char> source(len, 0);
3202
- std::vector<char> buffer;
3203
- std::vector<char16_t> buffer16;
3204
-
3205
- buffer.resize(simdutf::base64_length_from_binary(len));
3206
- std::vector<char> back(len);
3207
- std::mt19937 gen((std::mt19937::result_type)(seed));
3208
- std::uniform_int_distribution<int> byte_generator{0, 255};
3209
- for (size_t trial = 0; trial < 10; trial++) {
3210
- for (size_t i = 0; i < len; i++) {
3211
- source[i] = byte_generator(gen);
3212
- }
3213
- size_t size = implementation.binary_to_base64(
3214
- source.data(), source.size(), buffer.data());
3215
- buffer.resize(size);
3216
- buffer16.resize(buffer.size());
3217
- for (size_t i = 0; i < buffer.size(); i++) {
3218
- buffer16[i] = buffer[i];
3219
- }
3220
- ASSERT_EQUAL(size, simdutf::base64_length_from_binary(len));
3221
- size_t limited_length = len - offset; // intentionally too little
3222
- back.resize(limited_length);
3223
- back.shrink_to_fit();
3224
- simdutf::result r = simdutf::base64_to_binary_safe(
3225
- buffer.data(), buffer.size(), back.data(), limited_length);
3226
- ASSERT_EQUAL(r.error, simdutf::error_code::OUTPUT_BUFFER_TOO_SMALL);
3227
- for (size_t i = 0; i < limited_length; i++) {
3228
- ASSERT_EQUAL(source[i], back[i]);
3229
- }
3230
- // Now let us decode the rest !!!
3231
- size_t input_index = r.count;
3232
- back.resize(simdutf::maximal_binary_length_from_base64(
3233
- buffer.data() + input_index, buffer.size() - input_index));
3234
- size_t second_length = back.size();
3235
- r = simdutf::base64_to_binary_safe(buffer.data() + input_index,
3236
- buffer.size() - input_index,
3237
- back.data(), second_length);
3238
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
3239
- back.resize(second_length);
3240
- ASSERT_EQUAL(second_length + limited_length, len);
3241
- for (size_t i = 0; i < second_length; i++) {
3242
- ASSERT_EQUAL(source[i + limited_length], back[i]);
3243
- }
3244
- }
3245
- }
3246
- }
3247
- }
3248
-
3249
- TEST(aborted_safe_roundtrip_base64_with_spaces) {
3250
- for (size_t offset = 1; offset <= 16; offset += 3) {
3251
- for (size_t len = offset; len < (max_len / 2); len++) {
3252
- std::vector<char> source(len, 0);
3253
- std::vector<char> buffer;
3254
- buffer.resize(simdutf::base64_length_from_binary(len));
3255
- std::mt19937 gen((std::mt19937::result_type)(seed));
3256
- std::uniform_int_distribution<int> byte_generator{0, 255};
3257
- for (size_t trial = 0; trial < 10; trial++) {
3258
- for (size_t i = 0; i < len; i++) {
3259
- source[i] = byte_generator(gen);
3260
- }
3261
- size_t size = implementation.binary_to_base64(
3262
- source.data(), source.size(), buffer.data());
3263
- buffer.resize(size);
3264
- for (size_t i = 0; i < 5; i++) {
3265
- add_space(buffer, gen);
3266
- }
3267
- std::vector<char> back(simdutf::maximal_binary_length_from_base64(
3268
- buffer.data(), buffer.size()));
3269
- size_t limited_length = len - offset; // intentionally too little
3270
- back.resize(limited_length);
3271
- back.shrink_to_fit();
3272
- simdutf::result r = simdutf::base64_to_binary_safe(
3273
- buffer.data(), buffer.size(), back.data(), limited_length);
3274
- ASSERT_EQUAL(r.error, simdutf::error_code::OUTPUT_BUFFER_TOO_SMALL);
3275
- for (size_t i = 0; i < limited_length; i++) {
3276
- ASSERT_EQUAL(source[i], back[i]);
3277
- }
3278
- // Now let us decode the rest !!!
3279
- size_t input_index = r.count;
3280
- back.resize(simdutf::maximal_binary_length_from_base64(
3281
- buffer.data() + input_index, buffer.size() - input_index));
3282
- size_t second_length = back.size();
3283
- r = simdutf::base64_to_binary_safe(buffer.data() + input_index,
3284
- buffer.size() - input_index,
3285
- back.data(), second_length);
3286
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
3287
- back.resize(second_length);
3288
- ASSERT_EQUAL(second_length + limited_length, len);
3289
- for (size_t i = 0; i < second_length; i++) {
3290
- ASSERT_EQUAL(source[i + limited_length], back[i]);
3291
- }
3292
- }
3293
- }
3294
- }
3295
- }
3296
-
3297
- TEST(aborted_safe_roundtrip_base64_16_with_spaces) {
3298
- for (size_t offset = 1; offset <= 16; offset += 3) {
3299
- for (size_t len = offset; len < (max_len / 2); len++) {
3300
- std::vector<char> source(len, 0);
3301
- std::vector<char> buffer;
3302
- std::vector<char16_t> buffer16;
3303
-
3304
- buffer.resize(simdutf::base64_length_from_binary(len));
3305
- std::vector<char> back(len);
3306
- std::mt19937 gen((std::mt19937::result_type)(seed));
3307
- std::uniform_int_distribution<int> byte_generator{0, 255};
3308
- for (size_t trial = 0; trial < 10; trial++) {
3309
- for (size_t i = 0; i < len; i++) {
3310
- source[i] = byte_generator(gen);
3311
- }
3312
- size_t size = implementation.binary_to_base64(
3313
- source.data(), source.size(), buffer.data());
3314
- buffer.resize(size);
3315
- for (size_t i = 0; i < 5; i++) {
3316
- add_space(buffer, gen);
3317
- }
3318
- buffer16.resize(buffer.size());
3319
- for (size_t i = 0; i < buffer.size(); i++) {
3320
- buffer16[i] = buffer[i];
3321
- }
3322
- ASSERT_EQUAL(size, simdutf::base64_length_from_binary(len));
3323
- size_t limited_length = len - offset; // intentionally too little
3324
- back.resize(limited_length);
3325
- back.shrink_to_fit();
3326
- simdutf::result r = simdutf::base64_to_binary_safe(
3327
- buffer.data(), buffer.size(), back.data(), limited_length);
3328
- ASSERT_EQUAL(r.error, simdutf::error_code::OUTPUT_BUFFER_TOO_SMALL);
3329
- for (size_t i = 0; i < limited_length; i++) {
3330
- ASSERT_EQUAL(source[i], back[i]);
3331
- }
3332
- // Now let us decode the rest !!!
3333
- size_t input_index = r.count;
3334
- back.resize(simdutf::maximal_binary_length_from_base64(
3335
- buffer.data() + input_index, buffer.size() - input_index));
3336
- size_t second_length = back.size();
3337
- r = simdutf::base64_to_binary_safe(buffer.data() + input_index,
3338
- buffer.size() - input_index,
3339
- back.data(), second_length);
3340
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
3341
- back.resize(second_length);
3342
- ASSERT_EQUAL(second_length + limited_length, len);
3343
- for (size_t i = 0; i < second_length; i++) {
3344
- ASSERT_EQUAL(source[i + limited_length], back[i]);
3345
- }
3346
- }
3347
- }
3348
- }
3349
- }
3350
-
3351
- TEST(streaming_base64_roundtrip) {
3352
- size_t len = 2048;
3353
- std::vector<char> source(len, 0);
3354
- std::vector<char> buffer;
3355
- buffer.resize(simdutf::base64_length_from_binary(len));
3356
- std::mt19937 gen((std::mt19937::result_type)(seed));
3357
- std::uniform_int_distribution<int> byte_generator{0, 255};
3358
- for (size_t i = 0; i < len; i++) {
3359
- source[i] = byte_generator(gen);
3360
- }
3361
- size_t size = implementation.binary_to_base64(source.data(), source.size(),
3362
- buffer.data());
3363
- for (size_t window = 16; window <= 2048; window += 7) {
3364
- buffer.resize(size);
3365
- // build a buffer with enough space to receive the decoded base64
3366
- std::vector<char> back(len);
3367
- size_t outpos = 0;
3368
- size_t pos = 0;
3369
- for (; pos < buffer.size();) {
3370
- size_t count = std::min(window, buffer.size() - pos);
3371
-
3372
- simdutf::full_result r = implementation.base64_to_binary_details(
3373
- buffer.data() + pos, count, back.data() + outpos,
3374
- simdutf::base64_default,
3375
- simdutf::last_chunk_handling_options::only_full_chunks);
3376
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
3377
- ASSERT_TRUE(r.input_count <= count);
3378
- ASSERT_TRUE(r.output_count <= back.size() - outpos);
3379
- ASSERT_TRUE(r.output_count % 3 == 0);
3380
- ASSERT_TRUE(r.input_count % 4 == 0);
3381
-
3382
- outpos += r.output_count;
3383
- pos += r.input_count;
3384
- if (r.input_count == 0) {
3385
- break; // no more input
3386
- }
3387
- }
3388
- if (pos < buffer.size()) {
3389
- // we have a remainder
3390
-
3391
- simdutf::full_result r = implementation.base64_to_binary_details(
3392
- buffer.data() + pos, buffer.size() - pos, back.data() + outpos,
3393
- simdutf::base64_default,
3394
- simdutf::last_chunk_handling_options::strict);
3395
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
3396
- outpos += r.output_count;
3397
- pos += r.input_count;
3398
- }
3399
- back.resize(outpos);
3400
- ASSERT_TRUE(back == source);
3401
- }
3402
- }
3403
-
3404
- TEST(readme_test) {
3405
- size_t len = 2048;
3406
- std::vector<char> base64(len, 'a');
3407
- std::vector<char> back((len + 3) / 4 * 3);
3408
- size_t outpos = 0;
3409
- size_t window = 512;
3410
- for (size_t pos = 0; pos < base64.size(); pos += window) {
3411
- // how many base64 characters we can process in this iteration
3412
- size_t count = std::min(window, base64.size() - pos);
3413
- simdutf::result r = simdutf::base64_to_binary(base64.data() + pos, count,
3414
- back.data() + outpos);
3415
- if (r.error == simdutf::error_code::INVALID_BASE64_CHARACTER) {
3416
- printf("Invalid base64 character at position %zu\n", pos + r.count);
3417
- return;
3418
- }
3419
- // If we arrived at the end of the base64 input, we must check that the
3420
- // number of characters processed is a multiple of 4, or that we have a
3421
- // remainder of 0, 2 or 3.
3422
- if (count + pos == base64.size() &&
3423
- r.error == simdutf::error_code::BASE64_INPUT_REMAINDER) {
3424
- puts("The base64 input contained an invalid number of characters");
3425
- }
3426
- // If we are not at then end, we may have to reprocess either 1, 2 or 3
3427
- // bytes, and to drop the last 0, 2 or 3 bytes decoded.
3428
- size_t tail_bytes_to_reprocess = 0;
3429
- if (r.error == simdutf::error_code::BASE64_INPUT_REMAINDER) {
3430
- tail_bytes_to_reprocess = 1;
3431
- } else {
3432
- tail_bytes_to_reprocess = (r.count % 3) == 0 ? 0 : (r.count % 3) + 1;
3433
- }
3434
- pos -= tail_bytes_to_reprocess;
3435
- r.count -= (r.count % 3);
3436
- outpos += r.count;
3437
- }
3438
- // At then end, we resize the buffer to the actual number of bytes decoded.
3439
- back.resize(outpos);
3440
- }
3441
-
3442
- TEST(readme_safe) {
3443
- size_t len = 72;
3444
- std::vector<char> base64(len, 'a');
3445
- std::vector<char> back((len + 3) / 4 * 3);
3446
- size_t limited_length = back.size() / 2; // Intentionally too small
3447
- simdutf::result r = simdutf::base64_to_binary_safe(
3448
- base64.data(), base64.size(), back.data(), limited_length);
3449
- ASSERT_EQUAL(r.error, simdutf::error_code::OUTPUT_BUFFER_TOO_SMALL);
3450
-
3451
- // We decoded 'limited_length' bytes to back.
3452
- // Now let us decode the rest !!!
3453
- size_t input_index = r.count;
3454
- size_t limited_length2 = back.size();
3455
- r = simdutf::base64_to_binary_safe(base64.data() + input_index,
3456
- base64.size() - input_index, back.data(),
3457
- limited_length2);
3458
- ASSERT_EQUAL(r.error, simdutf::error_code::SUCCESS);
3459
- back.resize(limited_length2);
3460
- ASSERT_EQUAL(limited_length2 + limited_length, (len + 3) / 4 * 3);
3461
- }
3462
-
3463
- #if SIMDUTF_SPAN
3464
- TEST(base64_to_binary_safe_span_api_char) {
3465
- const std::string input{"QWJyYWNhZGFicmEh"};
3466
- const std::string expected_output{"Abracadabra!"};
3467
- std::string output(expected_output.size() + 4, '\0');
3468
- const auto [ret, outlen] = simdutf::base64_to_binary_safe(input, output);
3469
- ASSERT_EQUAL(ret.error, simdutf::SUCCESS);
3470
- ASSERT_EQUAL(ret.count, 16); // amount of consumed input
3471
- ASSERT_EQUAL(outlen, 12); // how much was written to output
3472
- }
3473
-
3474
- TEST(base64_to_binary_safe_span_api_char16) {
3475
- const std::u16string input{u"QWJyYWNhZGFicmEh"};
3476
- const std::string expected_output{"Abracadabra!"};
3477
- std::string output(expected_output.size() + 4, '\0');
3478
- const auto [ret, outlen] = simdutf::base64_to_binary_safe(input, output);
3479
- ASSERT_EQUAL(ret.error, simdutf::SUCCESS);
3480
- ASSERT_EQUAL(ret.count, 16); // amount of consumed input
3481
- ASSERT_EQUAL(outlen, 12); // how much was written to output
3482
- }
3483
-
3484
- TEST(binary_to_base64_with_lines_span_api_char) {
3485
- const std::string input{"Abracadabra!"};
3486
- const std::string expected_output{"QWJyY\nWNhZG\nFicmE\nh"};
3487
- std::string output(expected_output.size() + 4, '\0');
3488
- const auto outlen = simdutf::binary_to_base64_with_lines(input, output, 5);
3489
- ASSERT_EQUAL(outlen,
3490
- expected_output.size()); // how much was written to output
3491
- output.resize(outlen);
3492
- ASSERT_EQUAL(expected_output, output);
3493
- }
3494
-
3495
- #endif
3496
-
3497
- // Tests for binary_length_from_base64
3498
- TEST(binary_length_from_base64_basic) {
3499
- // Test basic strings without spaces
3500
- // "YQ==" decodes to "a" (1 byte)
3501
- ASSERT_EQUAL(simdutf::binary_length_from_base64("YQ==", 4), 1);
3502
- // "YWI=" decodes to "ab" (2 bytes)
3503
- ASSERT_EQUAL(simdutf::binary_length_from_base64("YWI=", 4), 2);
3504
- // "YWJj" decodes to "abc" (3 bytes)
3505
- ASSERT_EQUAL(simdutf::binary_length_from_base64("YWJj", 4), 3);
3506
- // "YWJjZA==" decodes to "abcd" (4 bytes)
3507
- ASSERT_EQUAL(simdutf::binary_length_from_base64("YWJjZA==", 8), 4);
3508
- // Empty string
3509
- ASSERT_EQUAL(simdutf::binary_length_from_base64("", 0), 0);
3510
- }
3511
-
3512
- TEST(binary_length_from_base64_with_spaces) {
3513
- // Test strings with spaces - binary_length_from_base64 should return exact
3514
- // length "Y Q = =" with spaces, should decode to "a" (1 byte)
3515
- ASSERT_EQUAL(simdutf::binary_length_from_base64("Y Q = =", 7), 1);
3516
- // " Y Q = = " with lots of spaces
3517
- ASSERT_EQUAL(simdutf::binary_length_from_base64(" Y Q = = ", 14), 1);
3518
- // " A A " should decode to 1 byte (2 base64 chars = 1 byte)
3519
- ASSERT_EQUAL(simdutf::binary_length_from_base64(" A A ", 8), 1);
3520
- // " A A G A / v 8 " should decode to 5 bytes (7 base64 chars)
3521
- ASSERT_EQUAL(
3522
- simdutf::binary_length_from_base64(" A A G A / v 8 ", 23), 5);
3523
- }
3524
-
3525
- TEST(binary_length_from_base64_matches_decode_result) {
3526
- // Verify that binary_length_from_base64 matches the actual decode result
3527
- std::vector<std::string> test_inputs = {
3528
- "YQ==",
3529
- "YWI=",
3530
- "YWJj",
3531
- "YWJjZA==",
3532
- " Y Q = = ",
3533
- " A A ",
3534
- " A A G A / v 8 ",
3535
- "SGVsbG8gV29ybGQh", // "Hello World!"
3536
- "SGVs bG8g V29y bGQh",
3537
- "dGVzdA==", // "test"
3538
- "dGVzdA", // "test" without padding
3539
- "dGVzdGluZw==" // "testing"
3540
- };
3541
-
3542
- for (const auto &input : test_inputs) {
3543
- size_t exact_len =
3544
- simdutf::binary_length_from_base64(input.data(), input.size());
3545
- size_t max_len =
3546
- simdutf::maximal_binary_length_from_base64(input.data(), input.size());
3547
- // exact length should be <= maximal length
3548
- ASSERT_TRUE(exact_len <= max_len);
3549
-
3550
- // Now decode and verify the exact length matches
3551
- std::vector<char> buffer(max_len);
3552
- auto result =
3553
- simdutf::base64_to_binary(input.data(), input.size(), buffer.data());
3554
- if (result.error == simdutf::error_code::SUCCESS) {
3555
- ASSERT_EQUAL(exact_len, result.count);
3556
- }
3557
- }
3558
- }
3559
-
3560
- TEST(binary_length_from_base64_char16) {
3561
- // Test with char16_t input
3562
- std::u16string input16 = u"YWJj"; // "abc"
3563
- ASSERT_EQUAL(
3564
- simdutf::binary_length_from_base64(input16.data(), input16.size()), 3);
3565
-
3566
- std::u16string input16_spaces = u" Y Q = = ";
3567
- ASSERT_EQUAL(simdutf::binary_length_from_base64(input16_spaces.data(),
3568
- input16_spaces.size()),
3569
- 1);
3570
- }
3571
-
3572
- TEST(binary_length_from_base64_url_variant) {
3573
- // Test with URL-safe base64 input
3574
- // The function counts non-whitespace characters regardless of variant
3575
- std::string url_input = "YWJj"; // Same as standard for this input
3576
- ASSERT_EQUAL(
3577
- simdutf::binary_length_from_base64(url_input.data(), url_input.size()),
3578
- 3);
3579
-
3580
- // Test with actual URL-safe characters
3581
- // "abc?" in URL-safe base64 is "YWJjPw" (no special chars needed here)
3582
- std::string url_input2 = "YWJjPw";
3583
- ASSERT_EQUAL(
3584
- simdutf::binary_length_from_base64(url_input2.data(), url_input2.size()),
3585
- 4);
3586
- }
3587
-
3588
- TEST(binary_length_from_base64_various_remainders) {
3589
- // Test various remainder cases
3590
- // 0 base64 chars = 0 bytes
3591
- ASSERT_EQUAL(simdutf::binary_length_from_base64("", 0), 0);
3592
- // 1 base64 char (invalid, but function still computes) = 0 bytes
3593
- ASSERT_EQUAL(simdutf::binary_length_from_base64("A", 1), 0);
3594
- // 2 base64 chars = 1 byte
3595
- ASSERT_EQUAL(simdutf::binary_length_from_base64("AA", 2), 1);
3596
- // 3 base64 chars = 2 bytes
3597
- ASSERT_EQUAL(simdutf::binary_length_from_base64("AAA", 3), 2);
3598
- // 4 base64 chars = 3 bytes
3599
- ASSERT_EQUAL(simdutf::binary_length_from_base64("AAAA", 4), 3);
3600
- // 5 base64 chars = 3 bytes (remainder 1 contributes 0)
3601
- ASSERT_EQUAL(simdutf::binary_length_from_base64("AAAAA", 5), 3);
3602
- // 6 base64 chars = 4 bytes
3603
- ASSERT_EQUAL(simdutf::binary_length_from_base64("AAAAAA", 6), 4);
3604
- // 7 base64 chars = 5 bytes
3605
- ASSERT_EQUAL(simdutf::binary_length_from_base64("AAAAAAA", 7), 5);
3606
- // 8 base64 chars = 6 bytes
3607
- ASSERT_EQUAL(simdutf::binary_length_from_base64("AAAAAAAA", 8), 6);
3608
- }
3609
-
3610
- int main(int argc, char *argv[]) {
3611
- const auto cmdline = simdutf::test::CommandLine::parse(argc, argv);
3612
- seed = cmdline.seed;
3613
-
3614
- simdutf::test::run(cmdline);
3615
-
3616
- return 0;
3617
- }