@scriptc/runtime 0.0.0 → 0.0.2

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 (416) hide show
  1. package/LICENSE +202 -0
  2. package/package.json +16 -6
  3. package/src/scr_array.c +488 -0
  4. package/src/scr_assert.c +1393 -0
  5. package/src/scr_async.c +2593 -0
  6. package/src/scr_async_dyn.c +607 -0
  7. package/src/scr_bytes.c +1425 -0
  8. package/src/scr_bytes_io.c +161 -0
  9. package/src/scr_child.c +3587 -0
  10. package/src/scr_closure.c +214 -0
  11. package/src/scr_console.c +143 -0
  12. package/src/scr_cycle.c +218 -0
  13. package/src/scr_dc.c +805 -0
  14. package/src/scr_dgram.c +1007 -0
  15. package/src/scr_dyn_handle.c +154 -0
  16. package/src/scr_dyn_invoke.c +644 -0
  17. package/src/scr_error.c +332 -0
  18. package/src/scr_events.c +714 -0
  19. package/src/scr_events_emitter.c +699 -0
  20. package/src/scr_exception.c +242 -0
  21. package/src/scr_fetch.c +1130 -0
  22. package/src/scr_fetch_curl.c +654 -0
  23. package/src/scr_http.c +3482 -0
  24. package/src/scr_http2.c +3030 -0
  25. package/src/scr_inspect.c +803 -0
  26. package/src/scr_inspect_island.c +51 -0
  27. package/src/scr_island.c +9363 -0
  28. package/src/scr_json.c +2151 -0
  29. package/src/scr_lib.c +3612 -0
  30. package/src/scr_loop_epoll.c +241 -0
  31. package/src/scr_loop_kqueue.c +121 -0
  32. package/src/scr_loop_wsapoll.c +208 -0
  33. package/src/scr_map.c +591 -0
  34. package/src/scr_net.c +3017 -0
  35. package/src/scr_net_island.c +458 -0
  36. package/src/scr_number.c +115 -0
  37. package/src/scr_object.c +25 -0
  38. package/src/scr_path.c +1266 -0
  39. package/src/scr_platform.h +119 -0
  40. package/src/scr_readline.c +287 -0
  41. package/src/scr_regex.c +1080 -0
  42. package/src/scr_runtime.h +5046 -0
  43. package/src/scr_stream.c +2877 -0
  44. package/src/scr_string.c +1264 -0
  45. package/src/scr_symbol.c +132 -0
  46. package/src/scr_test.c +662 -0
  47. package/src/scr_tls.c +1520 -0
  48. package/src/scr_union.c +105 -0
  49. package/src/scr_url.c +911 -0
  50. package/src/scr_url_internal.h +29 -0
  51. package/src/scr_url_params.c +561 -0
  52. package/src/scr_watch.c +568 -0
  53. package/src/scr_web.c +1778 -0
  54. package/src/scr_win.c +76 -0
  55. package/src/scr_zlib.c +197 -0
  56. package/src/scr_zlib_island.c +15 -0
  57. package/vendor/README.md +52 -0
  58. package/vendor/curl/COPYRIGHT +534 -0
  59. package/vendor/curl/include/curl/curl.h +3214 -0
  60. package/vendor/curl/include/curl/curlver.h +79 -0
  61. package/vendor/curl/include/curl/easy.h +125 -0
  62. package/vendor/curl/include/curl/header.h +74 -0
  63. package/vendor/curl/include/curl/mprintf.h +52 -0
  64. package/vendor/curl/include/curl/multi.h +460 -0
  65. package/vendor/curl/include/curl/options.h +70 -0
  66. package/vendor/curl/include/curl/stdcheaders.h +35 -0
  67. package/vendor/curl/include/curl/system.h +508 -0
  68. package/vendor/curl/include/curl/typecheck-gcc.h +716 -0
  69. package/vendor/curl/include/curl/urlapi.h +149 -0
  70. package/vendor/curl/include/curl/websockets.h +84 -0
  71. package/vendor/mbedtls/LICENSE +553 -0
  72. package/vendor/mbedtls/include/CMakeLists.txt +22 -0
  73. package/vendor/mbedtls/include/mbedtls/aes.h +631 -0
  74. package/vendor/mbedtls/include/mbedtls/aria.h +343 -0
  75. package/vendor/mbedtls/include/mbedtls/asn1.h +642 -0
  76. package/vendor/mbedtls/include/mbedtls/asn1write.h +390 -0
  77. package/vendor/mbedtls/include/mbedtls/base64.h +82 -0
  78. package/vendor/mbedtls/include/mbedtls/bignum.h +1088 -0
  79. package/vendor/mbedtls/include/mbedtls/block_cipher.h +76 -0
  80. package/vendor/mbedtls/include/mbedtls/build_info.h +194 -0
  81. package/vendor/mbedtls/include/mbedtls/camellia.h +305 -0
  82. package/vendor/mbedtls/include/mbedtls/ccm.h +526 -0
  83. package/vendor/mbedtls/include/mbedtls/chacha20.h +209 -0
  84. package/vendor/mbedtls/include/mbedtls/chachapoly.h +351 -0
  85. package/vendor/mbedtls/include/mbedtls/check_config.h +1149 -0
  86. package/vendor/mbedtls/include/mbedtls/cipher.h +1250 -0
  87. package/vendor/mbedtls/include/mbedtls/cmac.h +246 -0
  88. package/vendor/mbedtls/include/mbedtls/compat-2.x.h +46 -0
  89. package/vendor/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h +578 -0
  90. package/vendor/mbedtls/include/mbedtls/config_adjust_legacy_from_psa.h +873 -0
  91. package/vendor/mbedtls/include/mbedtls/config_adjust_psa_from_legacy.h +359 -0
  92. package/vendor/mbedtls/include/mbedtls/config_adjust_psa_superset_legacy.h +145 -0
  93. package/vendor/mbedtls/include/mbedtls/config_adjust_ssl.h +91 -0
  94. package/vendor/mbedtls/include/mbedtls/config_adjust_x509.h +35 -0
  95. package/vendor/mbedtls/include/mbedtls/config_psa.h +61 -0
  96. package/vendor/mbedtls/include/mbedtls/constant_time.h +36 -0
  97. package/vendor/mbedtls/include/mbedtls/ctr_drbg.h +596 -0
  98. package/vendor/mbedtls/include/mbedtls/debug.h +156 -0
  99. package/vendor/mbedtls/include/mbedtls/des.h +385 -0
  100. package/vendor/mbedtls/include/mbedtls/dhm.h +972 -0
  101. package/vendor/mbedtls/include/mbedtls/ecdh.h +455 -0
  102. package/vendor/mbedtls/include/mbedtls/ecdsa.h +674 -0
  103. package/vendor/mbedtls/include/mbedtls/ecjpake.h +298 -0
  104. package/vendor/mbedtls/include/mbedtls/ecp.h +1517 -0
  105. package/vendor/mbedtls/include/mbedtls/entropy.h +274 -0
  106. package/vendor/mbedtls/include/mbedtls/error.h +201 -0
  107. package/vendor/mbedtls/include/mbedtls/gcm.h +387 -0
  108. package/vendor/mbedtls/include/mbedtls/hkdf.h +124 -0
  109. package/vendor/mbedtls/include/mbedtls/hmac_drbg.h +434 -0
  110. package/vendor/mbedtls/include/mbedtls/lms.h +440 -0
  111. package/vendor/mbedtls/include/mbedtls/mbedtls_config.h +4446 -0
  112. package/vendor/mbedtls/include/mbedtls/md.h +526 -0
  113. package/vendor/mbedtls/include/mbedtls/md5.h +190 -0
  114. package/vendor/mbedtls/include/mbedtls/memory_buffer_alloc.h +142 -0
  115. package/vendor/mbedtls/include/mbedtls/net_sockets.h +299 -0
  116. package/vendor/mbedtls/include/mbedtls/nist_kw.h +166 -0
  117. package/vendor/mbedtls/include/mbedtls/oid.h +727 -0
  118. package/vendor/mbedtls/include/mbedtls/pem.h +160 -0
  119. package/vendor/mbedtls/include/mbedtls/pk.h +1303 -0
  120. package/vendor/mbedtls/include/mbedtls/pkcs12.h +186 -0
  121. package/vendor/mbedtls/include/mbedtls/pkcs5.h +198 -0
  122. package/vendor/mbedtls/include/mbedtls/pkcs7.h +252 -0
  123. package/vendor/mbedtls/include/mbedtls/platform.h +516 -0
  124. package/vendor/mbedtls/include/mbedtls/platform_time.h +79 -0
  125. package/vendor/mbedtls/include/mbedtls/platform_util.h +247 -0
  126. package/vendor/mbedtls/include/mbedtls/poly1305.h +168 -0
  127. package/vendor/mbedtls/include/mbedtls/private_access.h +20 -0
  128. package/vendor/mbedtls/include/mbedtls/psa_util.h +207 -0
  129. package/vendor/mbedtls/include/mbedtls/ripemd160.h +136 -0
  130. package/vendor/mbedtls/include/mbedtls/rsa.h +1170 -0
  131. package/vendor/mbedtls/include/mbedtls/sha1.h +219 -0
  132. package/vendor/mbedtls/include/mbedtls/sha256.h +200 -0
  133. package/vendor/mbedtls/include/mbedtls/sha3.h +172 -0
  134. package/vendor/mbedtls/include/mbedtls/sha512.h +208 -0
  135. package/vendor/mbedtls/include/mbedtls/ssl.h +5887 -0
  136. package/vendor/mbedtls/include/mbedtls/ssl_cache.h +187 -0
  137. package/vendor/mbedtls/include/mbedtls/ssl_ciphersuites.h +482 -0
  138. package/vendor/mbedtls/include/mbedtls/ssl_cookie.h +106 -0
  139. package/vendor/mbedtls/include/mbedtls/ssl_ticket.h +199 -0
  140. package/vendor/mbedtls/include/mbedtls/threading.h +167 -0
  141. package/vendor/mbedtls/include/mbedtls/timing.h +94 -0
  142. package/vendor/mbedtls/include/mbedtls/version.h +78 -0
  143. package/vendor/mbedtls/include/mbedtls/x509.h +500 -0
  144. package/vendor/mbedtls/include/mbedtls/x509_crl.h +184 -0
  145. package/vendor/mbedtls/include/mbedtls/x509_crt.h +1208 -0
  146. package/vendor/mbedtls/include/mbedtls/x509_csr.h +382 -0
  147. package/vendor/mbedtls/include/psa/build_info.h +20 -0
  148. package/vendor/mbedtls/include/psa/crypto.h +4998 -0
  149. package/vendor/mbedtls/include/psa/crypto_adjust_auto_enabled.h +31 -0
  150. package/vendor/mbedtls/include/psa/crypto_adjust_config_dependencies.h +51 -0
  151. package/vendor/mbedtls/include/psa/crypto_adjust_config_key_pair_types.h +101 -0
  152. package/vendor/mbedtls/include/psa/crypto_adjust_config_synonyms.h +49 -0
  153. package/vendor/mbedtls/include/psa/crypto_builtin_composites.h +214 -0
  154. package/vendor/mbedtls/include/psa/crypto_builtin_key_derivation.h +118 -0
  155. package/vendor/mbedtls/include/psa/crypto_builtin_primitives.h +114 -0
  156. package/vendor/mbedtls/include/psa/crypto_compat.h +230 -0
  157. package/vendor/mbedtls/include/psa/crypto_config.h +145 -0
  158. package/vendor/mbedtls/include/psa/crypto_driver_common.h +44 -0
  159. package/vendor/mbedtls/include/psa/crypto_driver_contexts_composites.h +151 -0
  160. package/vendor/mbedtls/include/psa/crypto_driver_contexts_key_derivation.h +52 -0
  161. package/vendor/mbedtls/include/psa/crypto_driver_contexts_primitives.h +105 -0
  162. package/vendor/mbedtls/include/psa/crypto_extra.h +2145 -0
  163. package/vendor/mbedtls/include/psa/crypto_legacy.h +88 -0
  164. package/vendor/mbedtls/include/psa/crypto_platform.h +102 -0
  165. package/vendor/mbedtls/include/psa/crypto_se_driver.h +1383 -0
  166. package/vendor/mbedtls/include/psa/crypto_sizes.h +1319 -0
  167. package/vendor/mbedtls/include/psa/crypto_struct.h +527 -0
  168. package/vendor/mbedtls/include/psa/crypto_types.h +508 -0
  169. package/vendor/mbedtls/include/psa/crypto_values.h +2782 -0
  170. package/vendor/mbedtls/library/aes.c +2294 -0
  171. package/vendor/mbedtls/library/aesce.c +624 -0
  172. package/vendor/mbedtls/library/aesce.h +136 -0
  173. package/vendor/mbedtls/library/aesni.c +846 -0
  174. package/vendor/mbedtls/library/aesni.h +162 -0
  175. package/vendor/mbedtls/library/alignment.h +704 -0
  176. package/vendor/mbedtls/library/aria.c +969 -0
  177. package/vendor/mbedtls/library/asn1parse.c +468 -0
  178. package/vendor/mbedtls/library/asn1write.c +440 -0
  179. package/vendor/mbedtls/library/base64.c +322 -0
  180. package/vendor/mbedtls/library/base64_internal.h +45 -0
  181. package/vendor/mbedtls/library/bignum.c +2583 -0
  182. package/vendor/mbedtls/library/bignum_core.c +1240 -0
  183. package/vendor/mbedtls/library/bignum_core.h +872 -0
  184. package/vendor/mbedtls/library/bignum_core_invasive.h +38 -0
  185. package/vendor/mbedtls/library/bignum_internal.h +122 -0
  186. package/vendor/mbedtls/library/bignum_mod.c +394 -0
  187. package/vendor/mbedtls/library/bignum_mod.h +452 -0
  188. package/vendor/mbedtls/library/bignum_mod_raw.c +276 -0
  189. package/vendor/mbedtls/library/bignum_mod_raw.h +416 -0
  190. package/vendor/mbedtls/library/bignum_mod_raw_invasive.h +34 -0
  191. package/vendor/mbedtls/library/block_cipher.c +207 -0
  192. package/vendor/mbedtls/library/block_cipher_internal.h +99 -0
  193. package/vendor/mbedtls/library/bn_mul.h +1094 -0
  194. package/vendor/mbedtls/library/camellia.c +1058 -0
  195. package/vendor/mbedtls/library/ccm.c +777 -0
  196. package/vendor/mbedtls/library/chacha20.c +563 -0
  197. package/vendor/mbedtls/library/chacha20_internal.h +23 -0
  198. package/vendor/mbedtls/library/chachapoly.c +487 -0
  199. package/vendor/mbedtls/library/check_crypto_config.h +136 -0
  200. package/vendor/mbedtls/library/cipher.c +1712 -0
  201. package/vendor/mbedtls/library/cipher_invasive.h +28 -0
  202. package/vendor/mbedtls/library/cipher_wrap.c +2482 -0
  203. package/vendor/mbedtls/library/cipher_wrap.h +178 -0
  204. package/vendor/mbedtls/library/cmac.c +1067 -0
  205. package/vendor/mbedtls/library/common.h +487 -0
  206. package/vendor/mbedtls/library/constant_time.c +247 -0
  207. package/vendor/mbedtls/library/constant_time_impl.h +541 -0
  208. package/vendor/mbedtls/library/constant_time_internal.h +579 -0
  209. package/vendor/mbedtls/library/ctr.h +35 -0
  210. package/vendor/mbedtls/library/ctr_drbg.c +1016 -0
  211. package/vendor/mbedtls/library/debug.c +475 -0
  212. package/vendor/mbedtls/library/debug_internal.h +185 -0
  213. package/vendor/mbedtls/library/des.c +1042 -0
  214. package/vendor/mbedtls/library/dhm.c +700 -0
  215. package/vendor/mbedtls/library/ecdh.c +696 -0
  216. package/vendor/mbedtls/library/ecdsa.c +858 -0
  217. package/vendor/mbedtls/library/ecjpake.c +1216 -0
  218. package/vendor/mbedtls/library/ecp.c +3674 -0
  219. package/vendor/mbedtls/library/ecp_curves.c +6125 -0
  220. package/vendor/mbedtls/library/ecp_curves_new.c +9 -0
  221. package/vendor/mbedtls/library/ecp_internal_alt.h +287 -0
  222. package/vendor/mbedtls/library/ecp_invasive.h +305 -0
  223. package/vendor/mbedtls/library/entropy.c +680 -0
  224. package/vendor/mbedtls/library/entropy_poll.c +233 -0
  225. package/vendor/mbedtls/library/entropy_poll.h +64 -0
  226. package/vendor/mbedtls/library/error.c +878 -0
  227. package/vendor/mbedtls/library/gcm.c +1330 -0
  228. package/vendor/mbedtls/library/hkdf.c +161 -0
  229. package/vendor/mbedtls/library/hmac_drbg.c +633 -0
  230. package/vendor/mbedtls/library/lmots.c +789 -0
  231. package/vendor/mbedtls/library/lmots.h +288 -0
  232. package/vendor/mbedtls/library/lms.c +778 -0
  233. package/vendor/mbedtls/library/md.c +1108 -0
  234. package/vendor/mbedtls/library/md5.c +426 -0
  235. package/vendor/mbedtls/library/md_psa.h +26 -0
  236. package/vendor/mbedtls/library/md_wrap.h +46 -0
  237. package/vendor/mbedtls/library/memory_buffer_alloc.c +751 -0
  238. package/vendor/mbedtls/library/mps_common.h +181 -0
  239. package/vendor/mbedtls/library/mps_error.h +89 -0
  240. package/vendor/mbedtls/library/mps_reader.c +538 -0
  241. package/vendor/mbedtls/library/mps_reader.h +366 -0
  242. package/vendor/mbedtls/library/mps_trace.c +112 -0
  243. package/vendor/mbedtls/library/mps_trace.h +154 -0
  244. package/vendor/mbedtls/library/net_sockets.c +694 -0
  245. package/vendor/mbedtls/library/nist_kw.c +729 -0
  246. package/vendor/mbedtls/library/oid.c +1166 -0
  247. package/vendor/mbedtls/library/padlock.c +157 -0
  248. package/vendor/mbedtls/library/padlock.h +111 -0
  249. package/vendor/mbedtls/library/pem.c +554 -0
  250. package/vendor/mbedtls/library/pk.c +1602 -0
  251. package/vendor/mbedtls/library/pk_ecc.c +261 -0
  252. package/vendor/mbedtls/library/pk_internal.h +241 -0
  253. package/vendor/mbedtls/library/pk_wrap.c +1618 -0
  254. package/vendor/mbedtls/library/pk_wrap.h +138 -0
  255. package/vendor/mbedtls/library/pkcs12.c +437 -0
  256. package/vendor/mbedtls/library/pkcs5.c +500 -0
  257. package/vendor/mbedtls/library/pkcs7.c +787 -0
  258. package/vendor/mbedtls/library/pkparse.c +1392 -0
  259. package/vendor/mbedtls/library/pkwrite.c +631 -0
  260. package/vendor/mbedtls/library/pkwrite.h +121 -0
  261. package/vendor/mbedtls/library/platform.c +402 -0
  262. package/vendor/mbedtls/library/platform_util.c +258 -0
  263. package/vendor/mbedtls/library/poly1305.c +492 -0
  264. package/vendor/mbedtls/library/psa_crypto.c +9532 -0
  265. package/vendor/mbedtls/library/psa_crypto_aead.c +646 -0
  266. package/vendor/mbedtls/library/psa_crypto_aead.h +499 -0
  267. package/vendor/mbedtls/library/psa_crypto_cipher.c +747 -0
  268. package/vendor/mbedtls/library/psa_crypto_cipher.h +316 -0
  269. package/vendor/mbedtls/library/psa_crypto_client.c +22 -0
  270. package/vendor/mbedtls/library/psa_crypto_core.h +983 -0
  271. package/vendor/mbedtls/library/psa_crypto_core_common.h +52 -0
  272. package/vendor/mbedtls/library/psa_crypto_driver_wrappers.h +2896 -0
  273. package/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.c +256 -0
  274. package/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.h +31 -0
  275. package/vendor/mbedtls/library/psa_crypto_ecp.c +594 -0
  276. package/vendor/mbedtls/library/psa_crypto_ecp.h +267 -0
  277. package/vendor/mbedtls/library/psa_crypto_ffdh.c +361 -0
  278. package/vendor/mbedtls/library/psa_crypto_ffdh.h +131 -0
  279. package/vendor/mbedtls/library/psa_crypto_hash.c +470 -0
  280. package/vendor/mbedtls/library/psa_crypto_hash.h +211 -0
  281. package/vendor/mbedtls/library/psa_crypto_invasive.h +92 -0
  282. package/vendor/mbedtls/library/psa_crypto_its.h +131 -0
  283. package/vendor/mbedtls/library/psa_crypto_mac.c +505 -0
  284. package/vendor/mbedtls/library/psa_crypto_mac.h +264 -0
  285. package/vendor/mbedtls/library/psa_crypto_pake.c +571 -0
  286. package/vendor/mbedtls/library/psa_crypto_pake.h +159 -0
  287. package/vendor/mbedtls/library/psa_crypto_random.c +181 -0
  288. package/vendor/mbedtls/library/psa_crypto_random.h +72 -0
  289. package/vendor/mbedtls/library/psa_crypto_random_impl.h +200 -0
  290. package/vendor/mbedtls/library/psa_crypto_rsa.c +714 -0
  291. package/vendor/mbedtls/library/psa_crypto_rsa.h +321 -0
  292. package/vendor/mbedtls/library/psa_crypto_se.c +373 -0
  293. package/vendor/mbedtls/library/psa_crypto_se.h +192 -0
  294. package/vendor/mbedtls/library/psa_crypto_slot_management.c +1137 -0
  295. package/vendor/mbedtls/library/psa_crypto_slot_management.h +344 -0
  296. package/vendor/mbedtls/library/psa_crypto_storage.c +481 -0
  297. package/vendor/mbedtls/library/psa_crypto_storage.h +392 -0
  298. package/vendor/mbedtls/library/psa_its_file.c +254 -0
  299. package/vendor/mbedtls/library/psa_util.c +614 -0
  300. package/vendor/mbedtls/library/psa_util_internal.h +100 -0
  301. package/vendor/mbedtls/library/ripemd160.c +490 -0
  302. package/vendor/mbedtls/library/rsa.c +3121 -0
  303. package/vendor/mbedtls/library/rsa_alt_helpers.c +455 -0
  304. package/vendor/mbedtls/library/rsa_alt_helpers.h +209 -0
  305. package/vendor/mbedtls/library/rsa_internal.h +188 -0
  306. package/vendor/mbedtls/library/sha1.c +480 -0
  307. package/vendor/mbedtls/library/sha256.c +983 -0
  308. package/vendor/mbedtls/library/sha3.c +721 -0
  309. package/vendor/mbedtls/library/sha512.c +1115 -0
  310. package/vendor/mbedtls/library/ssl_cache.c +410 -0
  311. package/vendor/mbedtls/library/ssl_ciphersuites.c +2050 -0
  312. package/vendor/mbedtls/library/ssl_ciphersuites_internal.h +154 -0
  313. package/vendor/mbedtls/library/ssl_client.c +1023 -0
  314. package/vendor/mbedtls/library/ssl_client.h +22 -0
  315. package/vendor/mbedtls/library/ssl_cookie.c +384 -0
  316. package/vendor/mbedtls/library/ssl_debug_helpers.h +85 -0
  317. package/vendor/mbedtls/library/ssl_debug_helpers_generated.c +251 -0
  318. package/vendor/mbedtls/library/ssl_misc.h +3198 -0
  319. package/vendor/mbedtls/library/ssl_msg.c +6619 -0
  320. package/vendor/mbedtls/library/ssl_ticket.c +556 -0
  321. package/vendor/mbedtls/library/ssl_tls.c +10234 -0
  322. package/vendor/mbedtls/library/ssl_tls12_client.c +3688 -0
  323. package/vendor/mbedtls/library/ssl_tls12_server.c +4311 -0
  324. package/vendor/mbedtls/library/ssl_tls13_client.c +3208 -0
  325. package/vendor/mbedtls/library/ssl_tls13_generic.c +1793 -0
  326. package/vendor/mbedtls/library/ssl_tls13_invasive.h +23 -0
  327. package/vendor/mbedtls/library/ssl_tls13_keys.c +1918 -0
  328. package/vendor/mbedtls/library/ssl_tls13_keys.h +668 -0
  329. package/vendor/mbedtls/library/ssl_tls13_server.c +3624 -0
  330. package/vendor/mbedtls/library/threading.c +193 -0
  331. package/vendor/mbedtls/library/threading_internal.h +28 -0
  332. package/vendor/mbedtls/library/timing.c +152 -0
  333. package/vendor/mbedtls/library/version.c +32 -0
  334. package/vendor/mbedtls/library/version_features.c +856 -0
  335. package/vendor/mbedtls/library/x509.c +1776 -0
  336. package/vendor/mbedtls/library/x509_create.c +570 -0
  337. package/vendor/mbedtls/library/x509_crl.c +708 -0
  338. package/vendor/mbedtls/library/x509_crt.c +3311 -0
  339. package/vendor/mbedtls/library/x509_csr.c +648 -0
  340. package/vendor/mbedtls/library/x509_internal.h +101 -0
  341. package/vendor/mbedtls/library/x509write.c +174 -0
  342. package/vendor/mbedtls/library/x509write_crt.c +688 -0
  343. package/vendor/mbedtls/library/x509write_csr.c +336 -0
  344. package/vendor/quickjs-ng/CMakeLists.txt +566 -0
  345. package/vendor/quickjs-ng/LICENSE +24 -0
  346. package/vendor/quickjs-ng/README.md +24 -0
  347. package/vendor/quickjs-ng/api-test.c +1195 -0
  348. package/vendor/quickjs-ng/builtin-array-fromasync.h +119 -0
  349. package/vendor/quickjs-ng/builtin-iterator-zip-keyed.h +332 -0
  350. package/vendor/quickjs-ng/builtin-iterator-zip.h +337 -0
  351. package/vendor/quickjs-ng/cutils.h +1998 -0
  352. package/vendor/quickjs-ng/dtoa.c +1619 -0
  353. package/vendor/quickjs-ng/dtoa.h +87 -0
  354. package/vendor/quickjs-ng/gen/function_source.c +81 -0
  355. package/vendor/quickjs-ng/gen/hello.c +53 -0
  356. package/vendor/quickjs-ng/gen/hello_module.c +106 -0
  357. package/vendor/quickjs-ng/gen/repl.c +3036 -0
  358. package/vendor/quickjs-ng/gen/standalone.c +323 -0
  359. package/vendor/quickjs-ng/gen/test_fib.c +81 -0
  360. package/vendor/quickjs-ng/libregexp-opcode.h +73 -0
  361. package/vendor/quickjs-ng/libregexp.c +3474 -0
  362. package/vendor/quickjs-ng/libregexp.h +101 -0
  363. package/vendor/quickjs-ng/libunicode-table.h +5173 -0
  364. package/vendor/quickjs-ng/libunicode.c +2069 -0
  365. package/vendor/quickjs-ng/libunicode.h +172 -0
  366. package/vendor/quickjs-ng/list.h +107 -0
  367. package/vendor/quickjs-ng/lre-test.c +52 -0
  368. package/vendor/quickjs-ng/qjs.c +762 -0
  369. package/vendor/quickjs-ng/qjsc.c +673 -0
  370. package/vendor/quickjs-ng/quickjs-atom.h +280 -0
  371. package/vendor/quickjs-ng/quickjs-c-atomics.h +54 -0
  372. package/vendor/quickjs-ng/quickjs-libc.c +5037 -0
  373. package/vendor/quickjs-ng/quickjs-libc.h +87 -0
  374. package/vendor/quickjs-ng/quickjs-opcode.h +377 -0
  375. package/vendor/quickjs-ng/quickjs.c +64041 -0
  376. package/vendor/quickjs-ng/quickjs.h +1447 -0
  377. package/vendor/quickjs-ng/run-test262.c +2374 -0
  378. package/vendor/quickjs-ng/unicode_gen.c +3121 -0
  379. package/vendor/quickjs-ng/unicode_gen_def.h +310 -0
  380. package/vendor/ryu/LICENSE-Boost +23 -0
  381. package/vendor/ryu/common.h +114 -0
  382. package/vendor/ryu/d2s.c +509 -0
  383. package/vendor/ryu/d2s_full_table.h +367 -0
  384. package/vendor/ryu/d2s_intrinsics.h +357 -0
  385. package/vendor/ryu/d2s_small_table.h +186 -0
  386. package/vendor/ryu/digit_table.h +35 -0
  387. package/vendor/ryu/ryu.h +46 -0
  388. package/vendor/zlib/LICENSE +22 -0
  389. package/vendor/zlib/adler32.c +164 -0
  390. package/vendor/zlib/compress.c +75 -0
  391. package/vendor/zlib/crc32.c +1049 -0
  392. package/vendor/zlib/crc32.h +9446 -0
  393. package/vendor/zlib/deflate.c +2139 -0
  394. package/vendor/zlib/deflate.h +377 -0
  395. package/vendor/zlib/gzclose.c +23 -0
  396. package/vendor/zlib/gzguts.h +214 -0
  397. package/vendor/zlib/gzlib.c +582 -0
  398. package/vendor/zlib/gzread.c +602 -0
  399. package/vendor/zlib/gzwrite.c +631 -0
  400. package/vendor/zlib/infback.c +628 -0
  401. package/vendor/zlib/inffast.c +320 -0
  402. package/vendor/zlib/inffast.h +11 -0
  403. package/vendor/zlib/inffixed.h +94 -0
  404. package/vendor/zlib/inflate.c +1526 -0
  405. package/vendor/zlib/inflate.h +126 -0
  406. package/vendor/zlib/inftrees.c +299 -0
  407. package/vendor/zlib/inftrees.h +62 -0
  408. package/vendor/zlib/trees.c +1117 -0
  409. package/vendor/zlib/trees.h +128 -0
  410. package/vendor/zlib/uncompr.c +85 -0
  411. package/vendor/zlib/zconf.h +543 -0
  412. package/vendor/zlib/zlib.h +1938 -0
  413. package/vendor/zlib/zutil.c +299 -0
  414. package/vendor/zlib/zutil.h +254 -0
  415. package/README.md +0 -3
  416. package/index.js +0 -2
@@ -0,0 +1,3474 @@
1
+ /*
2
+ * Regular Expression Engine
3
+ *
4
+ * Copyright (c) 2017-2018 Fabrice Bellard
5
+ *
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to deal
8
+ * in the Software without restriction, including without limitation the rights
9
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ * copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ * THE SOFTWARE.
23
+ */
24
+ #include <stdlib.h>
25
+ #include <stdio.h>
26
+ #include <stdarg.h>
27
+ #include <inttypes.h>
28
+ #include <string.h>
29
+ #include <assert.h>
30
+
31
+ #include "cutils.h"
32
+ #include "libregexp.h"
33
+ #include "libunicode.h"
34
+
35
+ /* ASCII identifier tables, used by lre_js_is_ident_first/next in libregexp.h
36
+ and by quickjs.c. */
37
+ uint32_t const lre_id_start_table_ascii[4] = {
38
+ /* $ A-Z _ a-z */
39
+ 0x00000000, 0x00000010, 0x87FFFFFE, 0x07FFFFFE
40
+ };
41
+
42
+ uint32_t const lre_id_continue_table_ascii[4] = {
43
+ /* $ 0-9 A-Z _ a-z */
44
+ 0x00000000, 0x03FF0010, 0x87FFFFFE, 0x07FFFFFE
45
+ };
46
+
47
+ /*
48
+ TODO:
49
+ - remove REOP_char_i and REOP_range_i by precomputing the case folding.
50
+ - add specific opcodes for simple unicode property tests so that the
51
+ generated bytecode is smaller.
52
+ - Add a lock step execution mode (=linear time execution guaranteed)
53
+ when the regular expression is "simple" i.e. no backreference nor
54
+ complicated lookahead. The opcodes are designed for this execution
55
+ model.
56
+ */
57
+
58
+ #if defined(TEST)
59
+ #define DUMP_REOP
60
+ #endif
61
+ //#define DUMP_REOP
62
+ //#define DUMP_EXEC
63
+
64
+ typedef enum {
65
+ #define DEF(id, size) REOP_ ## id,
66
+ #include "libregexp-opcode.h"
67
+ #undef DEF
68
+ REOP_COUNT,
69
+ } REOPCodeEnum;
70
+
71
+ #define CAPTURE_COUNT_MAX 255
72
+ #define REGISTER_COUNT_MAX 255
73
+ /* must be large enough to have a negligible runtime cost and small
74
+ enough to call the interrupt callback often. */
75
+ #define INTERRUPT_COUNTER_INIT 10000
76
+
77
+ /* unicode code points */
78
+ #define CP_LS 0x2028
79
+ #define CP_PS 0x2029
80
+
81
+ #define TMP_BUF_SIZE 128
82
+
83
+ typedef struct {
84
+ DynBuf byte_code;
85
+ const uint8_t *buf_ptr;
86
+ const uint8_t *buf_end;
87
+ const uint8_t *buf_start;
88
+ int re_flags;
89
+ bool is_unicode;
90
+ bool unicode_sets; /* if set, is_unicode is also set */
91
+ bool ignore_case;
92
+ bool multi_line;
93
+ bool dotall;
94
+ uint8_t group_name_scope;
95
+ int capture_count;
96
+ int total_capture_count; /* -1 = not computed yet */
97
+ int has_named_captures; /* -1 = don't know, 0 = no, 1 = yes */
98
+ void *opaque;
99
+ DynBuf group_names;
100
+ union {
101
+ char error_msg[TMP_BUF_SIZE];
102
+ char tmp_buf[TMP_BUF_SIZE];
103
+ } u;
104
+ } REParseState;
105
+
106
+ typedef struct {
107
+ #ifdef DUMP_REOP
108
+ const char *name;
109
+ #endif
110
+ uint8_t size;
111
+ } REOpCode;
112
+
113
+ static const REOpCode reopcode_info[REOP_COUNT] = {
114
+ #ifdef DUMP_REOP
115
+ #define DEF(id, size) { #id, size },
116
+ #else
117
+ #define DEF(id, size) { size },
118
+ #endif
119
+ #include "libregexp-opcode.h"
120
+ #undef DEF
121
+ };
122
+
123
+ #define RE_HEADER_FLAGS 0
124
+ #define RE_HEADER_CAPTURE_COUNT 2
125
+ #define RE_HEADER_REGISTER_COUNT 3
126
+ #define RE_HEADER_BYTECODE_LEN 4
127
+
128
+ #define RE_HEADER_LEN 8
129
+
130
+ static inline int lre_is_digit(int c) {
131
+ return c >= '0' && c <= '9';
132
+ }
133
+
134
+ /* insert 'len' bytes at position 'pos'. Return < 0 if error. */
135
+ static int dbuf_insert(DynBuf *s, int pos, int len)
136
+ {
137
+ if (dbuf_claim(s, len))
138
+ return -1;
139
+ memmove(s->buf + pos + len, s->buf + pos, s->size - pos);
140
+ s->size += len;
141
+ return 0;
142
+ }
143
+
144
+ typedef struct REString {
145
+ struct REString *next;
146
+ uint32_t hash;
147
+ uint32_t len;
148
+ uint32_t buf[];
149
+ } REString;
150
+
151
+ typedef struct {
152
+ /* the string list is the union of 'char_range' and of the strings
153
+ in hash_table[]. The strings in hash_table[] have a length !=
154
+ 1. */
155
+ CharRange cr;
156
+ uint32_t n_strings;
157
+ uint32_t hash_size;
158
+ int hash_bits;
159
+ REString **hash_table;
160
+ } REStringList;
161
+
162
+ static uint32_t re_string_hash(int len, const uint32_t *buf)
163
+ {
164
+ int i;
165
+ uint32_t h;
166
+ h = 1;
167
+ for(i = 0; i < len; i++)
168
+ h = h * 263 + buf[i];
169
+ return hash32(h);
170
+ }
171
+
172
+ static void re_string_list_init(REParseState *s1, REStringList *s)
173
+ {
174
+ cr_init(&s->cr, s1->opaque, lre_realloc);
175
+ s->n_strings = 0;
176
+ s->hash_size = 0;
177
+ s->hash_bits = 0;
178
+ s->hash_table = NULL;
179
+ }
180
+
181
+ static void re_string_list_free(REStringList *s)
182
+ {
183
+ REString *p, *p_next;
184
+ int i;
185
+ for(i = 0; i < s->hash_size; i++) {
186
+ for(p = s->hash_table[i]; p != NULL; p = p_next) {
187
+ p_next = p->next;
188
+ lre_realloc(s->cr.mem_opaque, p, 0);
189
+ }
190
+ }
191
+ lre_realloc(s->cr.mem_opaque, s->hash_table, 0);
192
+
193
+ cr_free(&s->cr);
194
+ }
195
+
196
+ #ifdef DUMP_REOP
197
+ static void lre_print_char(int c, bool is_range)
198
+ {
199
+ if (c == '\'' || c == '\\' ||
200
+ (is_range && (c == '-' || c == ']'))) {
201
+ printf("\\%c", c);
202
+ } else if (c >= ' ' && c <= 126) {
203
+ printf("%c", c);
204
+ } else {
205
+ printf("\\u{%04x}", c);
206
+ }
207
+ }
208
+
209
+ static __maybe_unused void re_string_list_dump(const char *str, const REStringList *s)
210
+ {
211
+ REString *p;
212
+ const CharRange *cr;
213
+ int i, j, k;
214
+
215
+ printf("%s:\n", str);
216
+ printf(" ranges: [");
217
+ cr = &s->cr;
218
+ for(i = 0; i < cr->len; i += 2) {
219
+ lre_print_char(cr->points[i], true);
220
+ if (cr->points[i] != cr->points[i + 1] - 1) {
221
+ printf("-");
222
+ lre_print_char(cr->points[i + 1] - 1, true);
223
+ }
224
+ }
225
+ printf("]\n");
226
+
227
+ j = 0;
228
+ for(i = 0; i < s->hash_size; i++) {
229
+ for(p = s->hash_table[i]; p != NULL; p = p->next) {
230
+ printf(" %d/%d: '", j, s->n_strings);
231
+ for(k = 0; k < p->len; k++) {
232
+ lre_print_char(p->buf[k], false);
233
+ }
234
+ printf("'\n");
235
+ j++;
236
+ }
237
+ }
238
+ }
239
+ #endif /* DUMP_REOP */
240
+
241
+ static int re_string_find2(REStringList *s, int len, const uint32_t *buf,
242
+ uint32_t h0, bool add_flag)
243
+ {
244
+ uint32_t h = 0; /* avoid warning */
245
+ REString *p;
246
+ if (s->n_strings != 0) {
247
+ h = h0 >> (32 - s->hash_bits);
248
+ for(p = s->hash_table[h]; p != NULL; p = p->next) {
249
+ if (p->hash == h0 && p->len == len &&
250
+ !memcmp(p->buf, buf, len * sizeof(buf[0]))) {
251
+ return 1;
252
+ }
253
+ }
254
+ }
255
+ /* not found */
256
+ if (!add_flag)
257
+ return 0;
258
+ /* increase the size of the hash table if needed */
259
+ if (unlikely((s->n_strings + 1) > s->hash_size)) {
260
+ REString **new_hash_table, *p_next;
261
+ int new_hash_bits, i;
262
+ uint32_t new_hash_size;
263
+ new_hash_bits = max_int(s->hash_bits + 1, 4);
264
+ new_hash_size = 1 << new_hash_bits;
265
+ new_hash_table = lre_realloc(s->cr.mem_opaque, NULL,
266
+ sizeof(new_hash_table[0]) * new_hash_size);
267
+ if (!new_hash_table)
268
+ return -1;
269
+ memset(new_hash_table, 0, sizeof(new_hash_table[0]) * new_hash_size);
270
+ for(i = 0; i < s->hash_size; i++) {
271
+ for(p = s->hash_table[i]; p != NULL; p = p_next) {
272
+ p_next = p->next;
273
+ h = p->hash >> (32 - new_hash_bits);
274
+ p->next = new_hash_table[h];
275
+ new_hash_table[h] = p;
276
+ }
277
+ }
278
+ lre_realloc(s->cr.mem_opaque, s->hash_table, 0);
279
+ s->hash_bits = new_hash_bits;
280
+ s->hash_size = new_hash_size;
281
+ s->hash_table = new_hash_table;
282
+ h = h0 >> (32 - s->hash_bits);
283
+ }
284
+
285
+ p = lre_realloc(s->cr.mem_opaque, NULL, sizeof(REString) + len * sizeof(buf[0]));
286
+ if (!p)
287
+ return -1;
288
+ p->next = s->hash_table[h];
289
+ s->hash_table[h] = p;
290
+ s->n_strings++;
291
+ p->hash = h0;
292
+ p->len = len;
293
+ memcpy(p->buf, buf, sizeof(buf[0]) * len);
294
+ return 1;
295
+ }
296
+
297
+ static int re_string_find(REStringList *s, int len, const uint32_t *buf,
298
+ bool add_flag)
299
+ {
300
+ uint32_t h0;
301
+ h0 = re_string_hash(len, buf);
302
+ return re_string_find2(s, len, buf, h0, add_flag);
303
+ }
304
+
305
+ /* return -1 if memory error, 0 if OK */
306
+ static int re_string_add(REStringList *s, int len, const uint32_t *buf)
307
+ {
308
+ if (len == 1) {
309
+ return cr_union_interval(&s->cr, buf[0], buf[0]);
310
+ }
311
+ if (re_string_find(s, len, buf, true) < 0)
312
+ return -1;
313
+ return 0;
314
+ }
315
+
316
+ /* a = a op b */
317
+ static int re_string_list_op(REStringList *a, REStringList *b, int op)
318
+ {
319
+ int i, ret;
320
+ REString *p, **pp;
321
+
322
+ if (cr_op1(&a->cr, b->cr.points, b->cr.len, op))
323
+ return -1;
324
+
325
+ switch(op) {
326
+ case CR_OP_UNION:
327
+ if (b->n_strings != 0) {
328
+ for(i = 0; i < b->hash_size; i++) {
329
+ for(p = b->hash_table[i]; p != NULL; p = p->next) {
330
+ if (re_string_find2(a, p->len, p->buf, p->hash, true) < 0)
331
+ return -1;
332
+ }
333
+ }
334
+ }
335
+ break;
336
+ case CR_OP_INTER:
337
+ case CR_OP_SUB:
338
+ for(i = 0; i < a->hash_size; i++) {
339
+ pp = &a->hash_table[i];
340
+ for(;;) {
341
+ p = *pp;
342
+ if (p == NULL)
343
+ break;
344
+ ret = re_string_find2(b, p->len, p->buf, p->hash, false);
345
+ if (op == CR_OP_SUB)
346
+ ret = !ret;
347
+ if (!ret) {
348
+ /* remove it */
349
+ *pp = p->next;
350
+ a->n_strings--;
351
+ lre_realloc(a->cr.mem_opaque, p, 0);
352
+ } else {
353
+ /* keep it */
354
+ pp = &p->next;
355
+ }
356
+ }
357
+ }
358
+ break;
359
+ default:
360
+ abort();
361
+ }
362
+ return 0;
363
+ }
364
+
365
+ static int re_string_list_canonicalize(REParseState *s1,
366
+ REStringList *s, bool is_unicode)
367
+ {
368
+ if (cr_regexp_canonicalize(&s->cr, is_unicode))
369
+ return -1;
370
+ if (s->n_strings != 0) {
371
+ REStringList a_s, *a = &a_s;
372
+ int i, j;
373
+ REString *p;
374
+
375
+ /* XXX: simplify */
376
+ re_string_list_init(s1, a);
377
+
378
+ a->n_strings = s->n_strings;
379
+ a->hash_size = s->hash_size;
380
+ a->hash_bits = s->hash_bits;
381
+ a->hash_table = s->hash_table;
382
+
383
+ s->n_strings = 0;
384
+ s->hash_size = 0;
385
+ s->hash_bits = 0;
386
+ s->hash_table = NULL;
387
+
388
+ for(i = 0; i < a->hash_size; i++) {
389
+ for(p = a->hash_table[i]; p != NULL; p = p->next) {
390
+ for(j = 0; j < p->len; j++) {
391
+ p->buf[j] = lre_canonicalize(p->buf[j], is_unicode);
392
+ }
393
+ if (re_string_add(s, p->len, p->buf)) {
394
+ re_string_list_free(a);
395
+ return -1;
396
+ }
397
+ }
398
+ }
399
+ re_string_list_free(a);
400
+ }
401
+ return 0;
402
+ }
403
+
404
+ static const uint16_t char_range_d[] = {
405
+ 1,
406
+ 0x0030, 0x0039 + 1,
407
+ };
408
+
409
+ /* code point ranges for Zs,Zl or Zp property */
410
+ static const uint16_t char_range_s[] = {
411
+ 10,
412
+ 0x0009, 0x000D + 1,
413
+ 0x0020, 0x0020 + 1,
414
+ 0x00A0, 0x00A0 + 1,
415
+ 0x1680, 0x1680 + 1,
416
+ 0x2000, 0x200A + 1,
417
+ /* 2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;; */
418
+ /* 2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;; */
419
+ 0x2028, 0x2029 + 1,
420
+ 0x202F, 0x202F + 1,
421
+ 0x205F, 0x205F + 1,
422
+ 0x3000, 0x3000 + 1,
423
+ /* FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; */
424
+ 0xFEFF, 0xFEFF + 1,
425
+ };
426
+
427
+ static const uint16_t char_range_w[] = {
428
+ 4,
429
+ 0x0030, 0x0039 + 1,
430
+ 0x0041, 0x005A + 1,
431
+ 0x005F, 0x005F + 1,
432
+ 0x0061, 0x007A + 1,
433
+ };
434
+
435
+ #define CLASS_RANGE_BASE 0x40000000
436
+
437
+ typedef enum {
438
+ CHAR_RANGE_d,
439
+ CHAR_RANGE_D,
440
+ CHAR_RANGE_s,
441
+ CHAR_RANGE_S,
442
+ CHAR_RANGE_w,
443
+ CHAR_RANGE_W,
444
+ } CharRangeEnum;
445
+
446
+ static const uint16_t * const char_range_table[] = {
447
+ char_range_d,
448
+ char_range_s,
449
+ char_range_w,
450
+ };
451
+
452
+ static int cr_init_char_range(REParseState *s, REStringList *cr, uint32_t c)
453
+ {
454
+ bool invert;
455
+ const uint16_t *c_pt;
456
+ int len, i;
457
+
458
+ invert = c & 1;
459
+ c_pt = char_range_table[c >> 1];
460
+ len = *c_pt++;
461
+ re_string_list_init(s, cr);
462
+ for(i = 0; i < len * 2; i++) {
463
+ if (cr_add_point(&cr->cr, c_pt[i]))
464
+ goto fail;
465
+ }
466
+ if (invert) {
467
+ if (cr_invert(&cr->cr))
468
+ goto fail;
469
+ }
470
+ return 0;
471
+ fail:
472
+ re_string_list_free(cr);
473
+ return -1;
474
+ }
475
+
476
+ #ifdef DUMP_REOP
477
+ static __maybe_unused void lre_dump_bytecode(const uint8_t *buf,
478
+ int buf_len)
479
+ {
480
+ int pos, len, opcode, bc_len, re_flags, i;
481
+ uint32_t val, val2;
482
+
483
+ assert(buf_len >= RE_HEADER_LEN);
484
+
485
+ re_flags = lre_get_flags(buf);
486
+ bc_len = get_u32(buf + RE_HEADER_BYTECODE_LEN);
487
+ assert(bc_len + RE_HEADER_LEN <= buf_len);
488
+ printf("flags: 0x%x capture_count=%d reg_count=%d\n",
489
+ re_flags, buf[RE_HEADER_CAPTURE_COUNT], buf[RE_HEADER_REGISTER_COUNT]);
490
+ if (re_flags & LRE_FLAG_NAMED_GROUPS) {
491
+ const char *p;
492
+ p = (char *)buf + RE_HEADER_LEN + bc_len;
493
+ printf("named groups: ");
494
+ for(i = 1; i < buf[RE_HEADER_CAPTURE_COUNT]; i++) {
495
+ if (i != 1)
496
+ printf(",");
497
+ printf("<%s>", p);
498
+ p += strlen(p) + LRE_GROUP_NAME_TRAILER_LEN;
499
+ }
500
+ printf("\n");
501
+ assert(p == (char *)(buf + buf_len));
502
+ }
503
+ printf("bytecode_len=%d\n", bc_len);
504
+
505
+ buf += RE_HEADER_LEN;
506
+ pos = 0;
507
+ while (pos < bc_len) {
508
+ printf("%5u: ", pos);
509
+ opcode = buf[pos];
510
+ len = reopcode_info[opcode].size;
511
+ if (opcode >= REOP_COUNT) {
512
+ printf(" invalid opcode=0x%02x\n", opcode);
513
+ break;
514
+ }
515
+ if ((pos + len) > bc_len) {
516
+ printf(" buffer overflow (opcode=0x%02x)\n", opcode);
517
+ break;
518
+ }
519
+ printf("%s", reopcode_info[opcode].name);
520
+ switch(opcode) {
521
+ case REOP_char:
522
+ case REOP_char_i:
523
+ val = get_u16(buf + pos + 1);
524
+ if (val >= ' ' && val <= 126)
525
+ printf(" '%c'", val);
526
+ else
527
+ printf(" 0x%04x", val);
528
+ break;
529
+ case REOP_char32:
530
+ case REOP_char32_i:
531
+ val = get_u32(buf + pos + 1);
532
+ if (val >= ' ' && val <= 126)
533
+ printf(" '%c'", val);
534
+ else
535
+ printf(" 0x%08x", val);
536
+ break;
537
+ case REOP_goto:
538
+ case REOP_split_goto_first:
539
+ case REOP_split_next_first:
540
+ case REOP_lookahead:
541
+ case REOP_negative_lookahead:
542
+ val = get_u32(buf + pos + 1);
543
+ val += (pos + 5);
544
+ printf(" %u", val);
545
+ break;
546
+ case REOP_loop:
547
+ val2 = buf[pos + 1];
548
+ val = get_u32(buf + pos + 2);
549
+ val += (pos + 6);
550
+ printf(" r%u, %u", val2, val);
551
+ break;
552
+ case REOP_loop_split_goto_first:
553
+ case REOP_loop_split_next_first:
554
+ case REOP_loop_check_adv_split_goto_first:
555
+ case REOP_loop_check_adv_split_next_first:
556
+ {
557
+ uint32_t limit;
558
+ val2 = buf[pos + 1];
559
+ limit = get_u32(buf + pos + 2);
560
+ val = get_u32(buf + pos + 6);
561
+ val += (pos + 10);
562
+ printf(" r%u, %u, %u", val2, limit, val);
563
+ }
564
+ break;
565
+ case REOP_save_start:
566
+ case REOP_save_end:
567
+ printf(" %u", buf[pos + 1]);
568
+ break;
569
+ case REOP_back_reference:
570
+ case REOP_back_reference_i:
571
+ case REOP_backward_back_reference:
572
+ case REOP_backward_back_reference_i:
573
+ {
574
+ int n, i;
575
+ n = buf[pos + 1];
576
+ len += n;
577
+ for(i = 0; i < n; i++) {
578
+ if (i != 0)
579
+ printf(",");
580
+ printf(" %u", buf[pos + 2 + i]);
581
+ }
582
+ }
583
+ break;
584
+ case REOP_save_reset:
585
+ printf(" %u %u", buf[pos + 1], buf[pos + 2]);
586
+ break;
587
+ case REOP_set_i32:
588
+ val = buf[pos + 1];
589
+ val2 = get_u32(buf + pos + 2);
590
+ printf(" r%u, %d", val, val2);
591
+ break;
592
+ case REOP_set_char_pos:
593
+ case REOP_check_advance:
594
+ val = buf[pos + 1];
595
+ printf(" r%u", val);
596
+ break;
597
+ case REOP_range:
598
+ case REOP_range_i:
599
+ {
600
+ int n, i;
601
+ n = get_u16(buf + pos + 1);
602
+ len += n * 4;
603
+ for(i = 0; i < n * 2; i++) {
604
+ val = get_u16(buf + pos + 3 + i * 2);
605
+ printf(" 0x%04x", val);
606
+ }
607
+ }
608
+ break;
609
+ case REOP_range32:
610
+ case REOP_range32_i:
611
+ {
612
+ int n, i;
613
+ n = get_u16(buf + pos + 1);
614
+ len += n * 8;
615
+ for(i = 0; i < n * 2; i++) {
616
+ val = get_u32(buf + pos + 3 + i * 4);
617
+ printf(" 0x%08x", val);
618
+ }
619
+ }
620
+ break;
621
+ default:
622
+ break;
623
+ }
624
+ printf("\n");
625
+ pos += len;
626
+ }
627
+ }
628
+ #endif
629
+
630
+ static void re_emit_op(REParseState *s, int op)
631
+ {
632
+ dbuf_putc(&s->byte_code, op);
633
+ }
634
+
635
+ /* return the offset of the u32 value */
636
+ static int re_emit_op_u32(REParseState *s, int op, uint32_t val)
637
+ {
638
+ int pos;
639
+ dbuf_putc(&s->byte_code, op);
640
+ pos = s->byte_code.size;
641
+ dbuf_put_u32(&s->byte_code, val);
642
+ return pos;
643
+ }
644
+
645
+ static int re_emit_goto(REParseState *s, int op, uint32_t val)
646
+ {
647
+ int pos;
648
+ dbuf_putc(&s->byte_code, op);
649
+ pos = s->byte_code.size;
650
+ dbuf_put_u32(&s->byte_code, val - (pos + 4));
651
+ return pos;
652
+ }
653
+
654
+ static int re_emit_goto_u8(REParseState *s, int op, uint32_t arg, uint32_t val)
655
+ {
656
+ int pos;
657
+ dbuf_putc(&s->byte_code, op);
658
+ dbuf_putc(&s->byte_code, arg);
659
+ pos = s->byte_code.size;
660
+ dbuf_put_u32(&s->byte_code, val - (pos + 4));
661
+ return pos;
662
+ }
663
+
664
+ static int re_emit_goto_u8_u32(REParseState *s, int op, uint32_t arg0, uint32_t arg1, uint32_t val)
665
+ {
666
+ int pos;
667
+ dbuf_putc(&s->byte_code, op);
668
+ dbuf_putc(&s->byte_code, arg0);
669
+ dbuf_put_u32(&s->byte_code, arg1);
670
+ pos = s->byte_code.size;
671
+ dbuf_put_u32(&s->byte_code, val - (pos + 4));
672
+ return pos;
673
+ }
674
+
675
+ static void re_emit_op_u8(REParseState *s, int op, uint32_t val)
676
+ {
677
+ dbuf_putc(&s->byte_code, op);
678
+ dbuf_putc(&s->byte_code, val);
679
+ }
680
+
681
+ static void re_emit_op_u16(REParseState *s, int op, uint32_t val)
682
+ {
683
+ dbuf_putc(&s->byte_code, op);
684
+ dbuf_put_u16(&s->byte_code, val);
685
+ }
686
+
687
+ static int JS_PRINTF_FORMAT_ATTR(2, 3) re_parse_error(REParseState *s, JS_PRINTF_FORMAT const char *fmt, ...)
688
+ {
689
+ va_list ap;
690
+ va_start(ap, fmt);
691
+ vsnprintf(s->u.error_msg, sizeof(s->u.error_msg), fmt, ap);
692
+ va_end(ap);
693
+ return -1;
694
+ }
695
+
696
+ static int re_parse_out_of_memory(REParseState *s)
697
+ {
698
+ return re_parse_error(s, "out of memory");
699
+ }
700
+
701
+ /* If allow_overflow is false, return -1 in case of
702
+ overflow. Otherwise return INT32_MAX. */
703
+ static int parse_digits(const uint8_t **pp, bool allow_overflow)
704
+ {
705
+ const uint8_t *p;
706
+ uint64_t v;
707
+ int c;
708
+
709
+ p = *pp;
710
+ v = 0;
711
+ for(;;) {
712
+ c = *p;
713
+ if (c < '0' || c > '9')
714
+ break;
715
+ v = v * 10 + c - '0';
716
+ if (v >= INT32_MAX) {
717
+ if (allow_overflow)
718
+ v = INT32_MAX;
719
+ else
720
+ return -1;
721
+ }
722
+ p++;
723
+ }
724
+ *pp = p;
725
+ return v;
726
+ }
727
+
728
+ static int re_parse_expect(REParseState *s, const uint8_t **pp, int c)
729
+ {
730
+ const uint8_t *p;
731
+ p = *pp;
732
+ if (*p != c)
733
+ return re_parse_error(s, "expecting '%c'", c);
734
+ p++;
735
+ *pp = p;
736
+ return 0;
737
+ }
738
+
739
+ /* Parse an escape sequence, *pp points after the '\':
740
+ allow_utf16 value:
741
+ 0 : no UTF-16 escapes allowed
742
+ 1 : UTF-16 escapes allowed
743
+ 2 : UTF-16 escapes allowed and escapes of surrogate pairs are
744
+ converted to a unicode character (unicode regexp case).
745
+
746
+ Return the unicode char and update *pp if recognized,
747
+ return -1 if malformed escape,
748
+ return -2 otherwise. */
749
+ int lre_parse_escape(const uint8_t **pp, int allow_utf16)
750
+ {
751
+ const uint8_t *p;
752
+ uint32_t c;
753
+
754
+ p = *pp;
755
+ c = *p++;
756
+ switch(c) {
757
+ case 'b':
758
+ c = '\b';
759
+ break;
760
+ case 'f':
761
+ c = '\f';
762
+ break;
763
+ case 'n':
764
+ c = '\n';
765
+ break;
766
+ case 'r':
767
+ c = '\r';
768
+ break;
769
+ case 't':
770
+ c = '\t';
771
+ break;
772
+ case 'v':
773
+ c = '\v';
774
+ break;
775
+ case 'x':
776
+ {
777
+ int h0, h1;
778
+
779
+ h0 = from_hex(*p++);
780
+ if (h0 < 0)
781
+ return -1;
782
+ h1 = from_hex(*p++);
783
+ if (h1 < 0)
784
+ return -1;
785
+ c = (h0 << 4) | h1;
786
+ }
787
+ break;
788
+ case 'u':
789
+ {
790
+ int h, i;
791
+ uint32_t c1;
792
+
793
+ if (*p == '{' && allow_utf16) {
794
+ p++;
795
+ c = 0;
796
+ for(;;) {
797
+ h = from_hex(*p++);
798
+ if (h < 0)
799
+ return -1;
800
+ c = (c << 4) | h;
801
+ if (c > 0x10FFFF)
802
+ return -1;
803
+ if (*p == '}')
804
+ break;
805
+ }
806
+ p++;
807
+ } else {
808
+ c = 0;
809
+ for(i = 0; i < 4; i++) {
810
+ h = from_hex(*p++);
811
+ if (h < 0) {
812
+ return -1;
813
+ }
814
+ c = (c << 4) | h;
815
+ }
816
+ if (is_hi_surrogate(c) &&
817
+ allow_utf16 == 2 && p[0] == '\\' && p[1] == 'u') {
818
+ /* convert an escaped surrogate pair into a
819
+ unicode char */
820
+ c1 = 0;
821
+ for(i = 0; i < 4; i++) {
822
+ h = from_hex(p[2 + i]);
823
+ if (h < 0)
824
+ break;
825
+ c1 = (c1 << 4) | h;
826
+ }
827
+ if (i == 4 && is_lo_surrogate(c1)) {
828
+ p += 6;
829
+ c = from_surrogate(c, c1);
830
+ }
831
+ }
832
+ }
833
+ }
834
+ break;
835
+ case '0': case '1': case '2': case '3':
836
+ case '4': case '5': case '6': case '7':
837
+ c -= '0';
838
+ if (allow_utf16 == 2) {
839
+ /* only accept \0 not followed by digit */
840
+ if (c != 0 || lre_is_digit(*p))
841
+ return -1;
842
+ } else {
843
+ /* parse a legacy octal sequence */
844
+ uint32_t v;
845
+ v = *p - '0';
846
+ if (v > 7)
847
+ break;
848
+ c = (c << 3) | v;
849
+ p++;
850
+ if (c >= 32)
851
+ break;
852
+ v = *p - '0';
853
+ if (v > 7)
854
+ break;
855
+ c = (c << 3) | v;
856
+ p++;
857
+ }
858
+ break;
859
+ default:
860
+ return -2;
861
+ }
862
+ *pp = p;
863
+ return c;
864
+ }
865
+
866
+ /* XXX: we use the same chars for name and value */
867
+ static bool is_unicode_char(int c)
868
+ {
869
+ return ((c >= '0' && c <= '9') ||
870
+ (c >= 'A' && c <= 'Z') ||
871
+ (c >= 'a' && c <= 'z') ||
872
+ (c == '_'));
873
+ }
874
+
875
+ /* XXX: memory error test */
876
+ static void seq_prop_cb(void *opaque, const uint32_t *seq, int seq_len)
877
+ {
878
+ REStringList *sl = opaque;
879
+ re_string_add(sl, seq_len, seq);
880
+ }
881
+
882
+ static int parse_unicode_property(REParseState *s, REStringList *cr,
883
+ const uint8_t **pp, bool is_inv,
884
+ bool allow_sequence_prop)
885
+ {
886
+ const uint8_t *p;
887
+ char name[64], value[64];
888
+ char *q;
889
+ bool script_ext;
890
+ int ret;
891
+
892
+ p = *pp;
893
+ if (*p != '{')
894
+ return re_parse_error(s, "expecting '{' after \\p");
895
+ p++;
896
+ q = name;
897
+ while (is_unicode_char(*p)) {
898
+ if ((q - name) >= sizeof(name) - 1)
899
+ goto unknown_property_name;
900
+ *q++ = *p++;
901
+ }
902
+ *q = '\0';
903
+ q = value;
904
+ if (*p == '=') {
905
+ p++;
906
+ while (is_unicode_char(*p)) {
907
+ if ((q - value) >= sizeof(value) - 1)
908
+ return re_parse_error(s, "unknown unicode property value");
909
+ *q++ = *p++;
910
+ }
911
+ }
912
+ *q = '\0';
913
+ if (*p != '}')
914
+ return re_parse_error(s, "expecting '}'");
915
+ p++;
916
+ // printf("name=%s value=%s\n", name, value);
917
+
918
+ if (!strcmp(name, "Script") || !strcmp(name, "sc")) {
919
+ script_ext = false;
920
+ goto do_script;
921
+ } else if (!strcmp(name, "Script_Extensions") || !strcmp(name, "scx")) {
922
+ script_ext = true;
923
+ do_script:
924
+ re_string_list_init(s, cr);
925
+ ret = unicode_script(&cr->cr, value, script_ext);
926
+ if (ret) {
927
+ re_string_list_free(cr);
928
+ if (ret == -2)
929
+ return re_parse_error(s, "unknown unicode script");
930
+ else
931
+ goto out_of_memory;
932
+ }
933
+ } else if (!strcmp(name, "General_Category") || !strcmp(name, "gc")) {
934
+ re_string_list_init(s, cr);
935
+ ret = unicode_general_category(&cr->cr, value);
936
+ if (ret) {
937
+ re_string_list_free(cr);
938
+ if (ret == -2)
939
+ return re_parse_error(s, "unknown unicode general category");
940
+ else
941
+ goto out_of_memory;
942
+ }
943
+ } else if (value[0] == '\0') {
944
+ re_string_list_init(s, cr);
945
+ ret = unicode_general_category(&cr->cr, name);
946
+ if (ret == -1) {
947
+ re_string_list_free(cr);
948
+ goto out_of_memory;
949
+ }
950
+ if (ret < 0) {
951
+ ret = unicode_prop(&cr->cr, name);
952
+ if (ret == -1) {
953
+ re_string_list_free(cr);
954
+ goto out_of_memory;
955
+ }
956
+ }
957
+ if (ret < 0 && !is_inv && allow_sequence_prop) {
958
+ CharRange cr_tmp;
959
+ cr_init(&cr_tmp, s->opaque, lre_realloc);
960
+ ret = unicode_sequence_prop(name, seq_prop_cb, cr, &cr_tmp);
961
+ cr_free(&cr_tmp);
962
+ if (ret == -1) {
963
+ re_string_list_free(cr);
964
+ goto out_of_memory;
965
+ }
966
+ }
967
+ if (ret < 0)
968
+ goto unknown_property_name;
969
+ } else {
970
+ unknown_property_name:
971
+ return re_parse_error(s, "unknown unicode property name");
972
+ }
973
+
974
+ /* the ordering of case folding and inversion differs with
975
+ unicode_sets. 'unicode_sets' ordering is more consistent */
976
+ /* XXX: the spec seems incorrect, we do it as the other engines
977
+ seem to do it. */
978
+ if (s->ignore_case && s->unicode_sets) {
979
+ if (re_string_list_canonicalize(s, cr, s->is_unicode)) {
980
+ re_string_list_free(cr);
981
+ goto out_of_memory;
982
+ }
983
+ }
984
+ if (is_inv) {
985
+ if (cr_invert(&cr->cr)) {
986
+ re_string_list_free(cr);
987
+ goto out_of_memory;
988
+ }
989
+ }
990
+ if (s->ignore_case && !s->unicode_sets) {
991
+ if (re_string_list_canonicalize(s, cr, s->is_unicode)) {
992
+ re_string_list_free(cr);
993
+ goto out_of_memory;
994
+ }
995
+ }
996
+ *pp = p;
997
+ return 0;
998
+ out_of_memory:
999
+ return re_parse_out_of_memory(s);
1000
+ }
1001
+
1002
+ static int get_class_atom(REParseState *s, REStringList *cr,
1003
+ const uint8_t **pp, bool inclass);
1004
+
1005
+ static int parse_class_string_disjunction(REParseState *s, REStringList *cr,
1006
+ const uint8_t **pp)
1007
+ {
1008
+ const uint8_t *p;
1009
+ DynBuf str;
1010
+ int c;
1011
+
1012
+ p = *pp;
1013
+ if (*p != '{')
1014
+ return re_parse_error(s, "expecting '{' after \\q");
1015
+
1016
+ dbuf_init2(&str, s->opaque, lre_realloc);
1017
+ re_string_list_init(s, cr);
1018
+
1019
+ p++;
1020
+ for(;;) {
1021
+ str.size = 0;
1022
+ while (*p != '}' && *p != '|') {
1023
+ c = get_class_atom(s, NULL, &p, false);
1024
+ if (c < 0)
1025
+ goto fail;
1026
+ if (dbuf_put_u32(&str, c)) {
1027
+ re_parse_out_of_memory(s);
1028
+ goto fail;
1029
+ }
1030
+ }
1031
+ if (re_string_add(cr, str.size / 4, (uint32_t *)str.buf)) {
1032
+ re_parse_out_of_memory(s);
1033
+ goto fail;
1034
+ }
1035
+ if (*p == '}')
1036
+ break;
1037
+ p++;
1038
+ }
1039
+ if (s->ignore_case) {
1040
+ if (re_string_list_canonicalize(s, cr, true))
1041
+ goto fail;
1042
+ }
1043
+ p++; /* skip the '}' */
1044
+ dbuf_free(&str);
1045
+ *pp = p;
1046
+ return 0;
1047
+ fail:
1048
+ dbuf_free(&str);
1049
+ re_string_list_free(cr);
1050
+ return -1;
1051
+ }
1052
+
1053
+ /* return -1 if error otherwise the character or a class range
1054
+ (CLASS_RANGE_BASE) if cr != NULL. In case of class range, 'cr' is
1055
+ initialized. Otherwise, it is ignored. */
1056
+ static int get_class_atom(REParseState *s, REStringList *cr,
1057
+ const uint8_t **pp, bool inclass)
1058
+ {
1059
+ const uint8_t *p;
1060
+ uint32_t c;
1061
+ int ret;
1062
+
1063
+ p = *pp;
1064
+
1065
+ c = *p;
1066
+ switch(c) {
1067
+ case '\\':
1068
+ p++;
1069
+ if (p >= s->buf_end)
1070
+ goto unexpected_end;
1071
+ c = *p++;
1072
+ switch(c) {
1073
+ case 'd':
1074
+ c = CHAR_RANGE_d;
1075
+ goto class_range;
1076
+ case 'D':
1077
+ c = CHAR_RANGE_D;
1078
+ goto class_range;
1079
+ case 's':
1080
+ c = CHAR_RANGE_s;
1081
+ goto class_range;
1082
+ case 'S':
1083
+ c = CHAR_RANGE_S;
1084
+ goto class_range;
1085
+ case 'w':
1086
+ c = CHAR_RANGE_w;
1087
+ goto class_range;
1088
+ case 'W':
1089
+ c = CHAR_RANGE_W;
1090
+ class_range:
1091
+ if (!cr)
1092
+ goto default_escape;
1093
+ if (cr_init_char_range(s, cr, c))
1094
+ return -1;
1095
+ c += CLASS_RANGE_BASE;
1096
+ break;
1097
+ case 'c':
1098
+ c = *p;
1099
+ if ((c >= 'a' && c <= 'z') ||
1100
+ (c >= 'A' && c <= 'Z') ||
1101
+ (((c >= '0' && c <= '9') || c == '_') &&
1102
+ inclass && !s->is_unicode)) { /* Annex B.1.4 */
1103
+ c &= 0x1f;
1104
+ p++;
1105
+ } else if (s->is_unicode) {
1106
+ goto invalid_escape;
1107
+ } else {
1108
+ /* otherwise return '\' and 'c' */
1109
+ p--;
1110
+ c = '\\';
1111
+ }
1112
+ break;
1113
+ case '-':
1114
+ if (!inclass && s->is_unicode)
1115
+ goto invalid_escape;
1116
+ break;
1117
+ case '^':
1118
+ case '$':
1119
+ case '\\':
1120
+ case '.':
1121
+ case '*':
1122
+ case '+':
1123
+ case '?':
1124
+ case '(':
1125
+ case ')':
1126
+ case '[':
1127
+ case ']':
1128
+ case '{':
1129
+ case '}':
1130
+ case '|':
1131
+ case '/':
1132
+ /* always valid to escape these characters */
1133
+ break;
1134
+ case 'p':
1135
+ case 'P':
1136
+ if (s->is_unicode && cr) {
1137
+ if (parse_unicode_property(s, cr, &p, (c == 'P'), s->unicode_sets))
1138
+ return -1;
1139
+ c = CLASS_RANGE_BASE;
1140
+ break;
1141
+ }
1142
+ goto default_escape;
1143
+ case 'q':
1144
+ if (s->unicode_sets && cr && inclass) {
1145
+ if (parse_class_string_disjunction(s, cr, &p))
1146
+ return -1;
1147
+ c = CLASS_RANGE_BASE;
1148
+ break;
1149
+ }
1150
+ goto default_escape;
1151
+ default:
1152
+ default_escape:
1153
+ p--;
1154
+ ret = lre_parse_escape(&p, s->is_unicode * 2);
1155
+ if (ret >= 0) {
1156
+ c = ret;
1157
+ } else {
1158
+ if (s->is_unicode) {
1159
+ invalid_escape:
1160
+ return re_parse_error(s, "invalid escape sequence in regular expression");
1161
+ } else {
1162
+ /* just ignore the '\' */
1163
+ goto normal_char;
1164
+ }
1165
+ }
1166
+ break;
1167
+ }
1168
+ break;
1169
+ case '\0':
1170
+ if (p >= s->buf_end) {
1171
+ unexpected_end:
1172
+ return re_parse_error(s, "unexpected end");
1173
+ }
1174
+ /* fall thru */
1175
+ goto normal_char;
1176
+
1177
+ case '&':
1178
+ case '!':
1179
+ case '#':
1180
+ case '$':
1181
+ case '%':
1182
+ case '*':
1183
+ case '+':
1184
+ case ',':
1185
+ case '.':
1186
+ case ':':
1187
+ case ';':
1188
+ case '<':
1189
+ case '=':
1190
+ case '>':
1191
+ case '?':
1192
+ case '@':
1193
+ case '^':
1194
+ case '`':
1195
+ case '~':
1196
+ if (s->unicode_sets && p[1] == c) {
1197
+ /* forbidden double characters */
1198
+ return re_parse_error(s, "invalid class set operation in regular expression");
1199
+ }
1200
+ goto normal_char;
1201
+
1202
+ case '(':
1203
+ case ')':
1204
+ case '[':
1205
+ case ']':
1206
+ case '{':
1207
+ case '}':
1208
+ case '/':
1209
+ case '-':
1210
+ case '|':
1211
+ if (s->unicode_sets) {
1212
+ /* invalid characters in unicode sets */
1213
+ return re_parse_error(s, "invalid character in class in regular expression");
1214
+ }
1215
+ goto normal_char;
1216
+
1217
+ default:
1218
+ normal_char:
1219
+ /* normal char */
1220
+ if (c >= 128) {
1221
+ c = utf8_decode_len(p, UTF8_CHAR_LEN_MAX, &p);
1222
+ if ((unsigned)c > 0xffff && !s->is_unicode) {
1223
+ /* XXX: should handle non BMP-1 code points */
1224
+ return re_parse_error(s, "malformed unicode char");
1225
+ }
1226
+ } else {
1227
+ p++;
1228
+ }
1229
+ break;
1230
+ }
1231
+ *pp = p;
1232
+ return c;
1233
+ }
1234
+
1235
+ static int re_emit_range(REParseState *s, const CharRange *cr)
1236
+ {
1237
+ int len, i;
1238
+ uint32_t high;
1239
+
1240
+ len = (unsigned)cr->len / 2;
1241
+ if (len >= 65535)
1242
+ return re_parse_error(s, "too many ranges");
1243
+ if (len == 0) {
1244
+ re_emit_op_u32(s, REOP_char32, -1);
1245
+ } else {
1246
+ high = cr->points[cr->len - 1];
1247
+ if (high == UINT32_MAX)
1248
+ high = cr->points[cr->len - 2];
1249
+ if (high <= 0xffff) {
1250
+ /* can use 16 bit ranges with the conversion that 0xffff =
1251
+ infinity */
1252
+ re_emit_op_u16(s, s->ignore_case ? REOP_range_i : REOP_range, len);
1253
+ for(i = 0; i < cr->len; i += 2) {
1254
+ dbuf_put_u16(&s->byte_code, cr->points[i]);
1255
+ high = cr->points[i + 1] - 1;
1256
+ if (high == UINT32_MAX - 1)
1257
+ high = 0xffff;
1258
+ dbuf_put_u16(&s->byte_code, high);
1259
+ }
1260
+ } else {
1261
+ re_emit_op_u16(s, s->ignore_case ? REOP_range32_i : REOP_range32, len);
1262
+ for(i = 0; i < cr->len; i += 2) {
1263
+ dbuf_put_u32(&s->byte_code, cr->points[i]);
1264
+ dbuf_put_u32(&s->byte_code, cr->points[i + 1] - 1);
1265
+ }
1266
+ }
1267
+ }
1268
+ return 0;
1269
+ }
1270
+
1271
+ static int re_string_cmp_len(const void *a, const void *b, void *arg)
1272
+ {
1273
+ REString *p1 = *(REString **)a;
1274
+ REString *p2 = *(REString **)b;
1275
+ return (p1->len < p2->len) - (p1->len > p2->len);
1276
+ }
1277
+
1278
+ static void re_emit_char(REParseState *s, int c)
1279
+ {
1280
+ if (c <= 0xffff)
1281
+ re_emit_op_u16(s, s->ignore_case ? REOP_char_i : REOP_char, c);
1282
+ else
1283
+ re_emit_op_u32(s, s->ignore_case ? REOP_char32_i : REOP_char32, c);
1284
+ }
1285
+
1286
+ static int re_emit_string_list(REParseState *s, const REStringList *sl)
1287
+ {
1288
+ REString **tab, *p;
1289
+ int i, j, split_pos, last_match_pos, n;
1290
+ bool has_empty_string, is_last;
1291
+
1292
+ // re_string_list_dump("sl", sl);
1293
+ if (sl->n_strings == 0) {
1294
+ /* simple case: only characters */
1295
+ if (re_emit_range(s, &sl->cr))
1296
+ return -1;
1297
+ } else {
1298
+ /* at least one string list is present : match the longest ones first */
1299
+ /* XXX: add a new op_switch opcode to compile as a trie */
1300
+ tab = lre_realloc(s->opaque, NULL, sizeof(tab[0]) * sl->n_strings);
1301
+ if (!tab) {
1302
+ re_parse_out_of_memory(s);
1303
+ return -1;
1304
+ }
1305
+ has_empty_string = false;
1306
+ n = 0;
1307
+ for(i = 0; i < sl->hash_size; i++) {
1308
+ for(p = sl->hash_table[i]; p != NULL; p = p->next) {
1309
+ if (p->len == 0) {
1310
+ has_empty_string = true;
1311
+ } else {
1312
+ tab[n++] = p;
1313
+ }
1314
+ }
1315
+ }
1316
+ assert(n <= sl->n_strings);
1317
+
1318
+ rqsort(tab, n, sizeof(tab[0]), re_string_cmp_len, NULL);
1319
+
1320
+ last_match_pos = -1;
1321
+ for(i = 0; i < n; i++) {
1322
+ p = tab[i];
1323
+ is_last = !has_empty_string && sl->cr.len == 0 && i == (n - 1);
1324
+ if (!is_last)
1325
+ split_pos = re_emit_op_u32(s, REOP_split_next_first, 0);
1326
+ else
1327
+ split_pos = 0;
1328
+ for(j = 0; j < p->len; j++) {
1329
+ re_emit_char(s, p->buf[j]);
1330
+ }
1331
+ if (!is_last) {
1332
+ last_match_pos = re_emit_op_u32(s, REOP_goto, last_match_pos);
1333
+ put_u32(s->byte_code.buf + split_pos, s->byte_code.size - (split_pos + 4));
1334
+ }
1335
+ }
1336
+
1337
+ if (sl->cr.len != 0) {
1338
+ /* char range */
1339
+ is_last = !has_empty_string;
1340
+ if (!is_last)
1341
+ split_pos = re_emit_op_u32(s, REOP_split_next_first, 0);
1342
+ else
1343
+ split_pos = 0; /* not used */
1344
+ if (re_emit_range(s, &sl->cr)) {
1345
+ lre_realloc(s->opaque, tab, 0);
1346
+ return -1;
1347
+ }
1348
+ if (!is_last)
1349
+ put_u32(s->byte_code.buf + split_pos, s->byte_code.size - (split_pos + 4));
1350
+ }
1351
+
1352
+ /* patch the 'goto match' */
1353
+ while (last_match_pos != -1) {
1354
+ int next_pos = get_u32(s->byte_code.buf + last_match_pos);
1355
+ put_u32(s->byte_code.buf + last_match_pos, s->byte_code.size - (last_match_pos + 4));
1356
+ last_match_pos = next_pos;
1357
+ }
1358
+
1359
+ lre_realloc(s->opaque, tab, 0);
1360
+ }
1361
+ return 0;
1362
+ }
1363
+
1364
+ static int re_parse_nested_class(REParseState *s, REStringList *cr, const uint8_t **pp);
1365
+
1366
+ static int re_parse_class_set_operand(REParseState *s, REStringList *cr, const uint8_t **pp)
1367
+ {
1368
+ int c1;
1369
+ const uint8_t *p = *pp;
1370
+
1371
+ if (*p == '[') {
1372
+ if (re_parse_nested_class(s, cr, pp))
1373
+ return -1;
1374
+ } else {
1375
+ c1 = get_class_atom(s, cr, pp, true);
1376
+ if (c1 < 0)
1377
+ return -1;
1378
+ if (c1 < CLASS_RANGE_BASE) {
1379
+ /* create a range with a single character */
1380
+ re_string_list_init(s, cr);
1381
+ if (s->ignore_case)
1382
+ c1 = lre_canonicalize(c1, s->is_unicode);
1383
+ if (cr_union_interval(&cr->cr, c1, c1)) {
1384
+ re_string_list_free(cr);
1385
+ return -1;
1386
+ }
1387
+ }
1388
+ }
1389
+ return 0;
1390
+ }
1391
+
1392
+ static int re_parse_nested_class(REParseState *s, REStringList *cr, const uint8_t **pp)
1393
+ {
1394
+ const uint8_t *p;
1395
+ uint32_t c1, c2;
1396
+ int ret;
1397
+ REStringList cr1_s, *cr1 = &cr1_s;
1398
+ bool invert, is_first;
1399
+
1400
+ if (lre_check_stack_overflow(s->opaque, 0))
1401
+ return re_parse_error(s, "stack overflow");
1402
+
1403
+ re_string_list_init(s, cr);
1404
+ p = *pp;
1405
+ p++; /* skip '[' */
1406
+
1407
+ invert = false;
1408
+ if (*p == '^') {
1409
+ p++;
1410
+ invert = true;
1411
+ }
1412
+
1413
+ /* handle unions */
1414
+ is_first = true;
1415
+ for(;;) {
1416
+ if (*p == ']')
1417
+ break;
1418
+ if (*p == '[' && s->unicode_sets) {
1419
+ if (re_parse_nested_class(s, cr1, &p))
1420
+ goto fail;
1421
+ goto class_union;
1422
+ } else {
1423
+ c1 = get_class_atom(s, cr1, &p, true);
1424
+ if ((int)c1 < 0)
1425
+ goto fail;
1426
+ if (*p == '-' && p[1] != ']') {
1427
+ const uint8_t *p0 = p + 1;
1428
+ if (p[1] == '-' && s->unicode_sets && is_first)
1429
+ goto class_atom; /* first character class followed by '--' */
1430
+ if (c1 >= CLASS_RANGE_BASE) {
1431
+ if (s->is_unicode) {
1432
+ re_string_list_free(cr1);
1433
+ goto invalid_class_range;
1434
+ }
1435
+ /* Annex B: match '-' character */
1436
+ goto class_atom;
1437
+ }
1438
+ c2 = get_class_atom(s, cr1, &p0, true);
1439
+ if ((int)c2 < 0)
1440
+ goto fail;
1441
+ if (c2 >= CLASS_RANGE_BASE) {
1442
+ re_string_list_free(cr1);
1443
+ if (s->is_unicode) {
1444
+ goto invalid_class_range;
1445
+ }
1446
+ /* Annex B: match '-' character */
1447
+ goto class_atom;
1448
+ }
1449
+ p = p0;
1450
+ if (c2 < c1) {
1451
+ invalid_class_range:
1452
+ re_parse_error(s, "invalid class range");
1453
+ goto fail;
1454
+ }
1455
+ if (s->ignore_case) {
1456
+ CharRange cr2_s, *cr2 = &cr2_s;
1457
+ cr_init(cr2, s->opaque, lre_realloc);
1458
+ if (cr_add_interval(cr2, c1, c2 + 1) ||
1459
+ cr_regexp_canonicalize(cr2, s->is_unicode) ||
1460
+ cr_op1(&cr->cr, cr2->points, cr2->len, CR_OP_UNION)) {
1461
+ cr_free(cr2);
1462
+ goto memory_error;
1463
+ }
1464
+ cr_free(cr2);
1465
+ } else {
1466
+ if (cr_union_interval(&cr->cr, c1, c2))
1467
+ goto memory_error;
1468
+ }
1469
+ is_first = false; /* union operation */
1470
+ } else {
1471
+ class_atom:
1472
+ if (c1 >= CLASS_RANGE_BASE) {
1473
+ class_union:
1474
+ ret = re_string_list_op(cr, cr1, CR_OP_UNION);
1475
+ re_string_list_free(cr1);
1476
+ if (ret)
1477
+ goto memory_error;
1478
+ } else {
1479
+ if (s->ignore_case)
1480
+ c1 = lre_canonicalize(c1, s->is_unicode);
1481
+ if (cr_union_interval(&cr->cr, c1, c1))
1482
+ goto memory_error;
1483
+ }
1484
+ }
1485
+ }
1486
+ if (s->unicode_sets && is_first) {
1487
+ if (*p == '&' && p[1] == '&' && p[2] != '&') {
1488
+ /* handle '&&' */
1489
+ for(;;) {
1490
+ if (*p == ']') {
1491
+ break;
1492
+ } else if (*p == '&' && p[1] == '&' && p[2] != '&') {
1493
+ p += 2;
1494
+ } else {
1495
+ goto invalid_operation;
1496
+ }
1497
+ if (re_parse_class_set_operand(s, cr1, &p))
1498
+ goto fail;
1499
+ ret = re_string_list_op(cr, cr1, CR_OP_INTER);
1500
+ re_string_list_free(cr1);
1501
+ if (ret)
1502
+ goto memory_error;
1503
+ }
1504
+ } else if (*p == '-' && p[1] == '-') {
1505
+ /* handle '--' */
1506
+ for(;;) {
1507
+ if (*p == ']') {
1508
+ break;
1509
+ } else if (*p == '-' && p[1] == '-') {
1510
+ p += 2;
1511
+ } else {
1512
+ invalid_operation:
1513
+ re_parse_error(s, "invalid operation in regular expression");
1514
+ goto fail;
1515
+ }
1516
+ if (re_parse_class_set_operand(s, cr1, &p))
1517
+ goto fail;
1518
+ ret = re_string_list_op(cr, cr1, CR_OP_SUB);
1519
+ re_string_list_free(cr1);
1520
+ if (ret)
1521
+ goto memory_error;
1522
+ }
1523
+ }
1524
+ }
1525
+ is_first = false;
1526
+ }
1527
+
1528
+ p++; /* skip ']' */
1529
+ *pp = p;
1530
+ if (invert) {
1531
+ /* XXX: add may_contain_string syntax check to be fully
1532
+ compliant. The test here accepts more input than the
1533
+ spec. */
1534
+ if (cr->n_strings != 0) {
1535
+ re_parse_error(s, "negated character class with strings in regular expression debugger eval code");
1536
+ goto fail;
1537
+ }
1538
+ if (cr_invert(&cr->cr))
1539
+ goto memory_error;
1540
+ }
1541
+ return 0;
1542
+ memory_error:
1543
+ re_parse_out_of_memory(s);
1544
+ fail:
1545
+ re_string_list_free(cr);
1546
+ return -1;
1547
+ }
1548
+
1549
+ static int re_parse_char_class(REParseState *s, const uint8_t **pp)
1550
+ {
1551
+ REStringList cr_s, *cr = &cr_s;
1552
+
1553
+ if (re_parse_nested_class(s, cr, pp))
1554
+ return -1;
1555
+ if (re_emit_string_list(s, cr))
1556
+ goto fail;
1557
+ re_string_list_free(cr);
1558
+ return 0;
1559
+ fail:
1560
+ re_string_list_free(cr);
1561
+ return -1;
1562
+ }
1563
+
1564
+ /* need_check_adv: false if the opcodes always advance the char pointer
1565
+ need_capture_init: true if all the captures in the atom are not set
1566
+ */
1567
+ static bool re_need_check_adv_and_capture_init(bool *pneed_capture_init,
1568
+ const uint8_t *bc_buf, int bc_buf_len)
1569
+ {
1570
+ int pos, opcode, len;
1571
+ uint32_t val;
1572
+ bool need_check_adv, need_capture_init;
1573
+
1574
+ need_check_adv = true;
1575
+ need_capture_init = false;
1576
+ pos = 0;
1577
+ while (pos < bc_buf_len) {
1578
+ opcode = bc_buf[pos];
1579
+ len = reopcode_info[opcode].size;
1580
+ switch(opcode) {
1581
+ case REOP_range:
1582
+ case REOP_range_i:
1583
+ val = get_u16(bc_buf + pos + 1);
1584
+ len += val * 4;
1585
+ need_check_adv = false;
1586
+ break;
1587
+ case REOP_range32:
1588
+ case REOP_range32_i:
1589
+ val = get_u16(bc_buf + pos + 1);
1590
+ len += val * 8;
1591
+ need_check_adv = false;
1592
+ break;
1593
+ case REOP_char:
1594
+ case REOP_char_i:
1595
+ case REOP_char32:
1596
+ case REOP_char32_i:
1597
+ case REOP_dot:
1598
+ case REOP_any:
1599
+ case REOP_space:
1600
+ case REOP_not_space:
1601
+ need_check_adv = false;
1602
+ break;
1603
+ case REOP_line_start:
1604
+ case REOP_line_start_m:
1605
+ case REOP_line_end:
1606
+ case REOP_line_end_m:
1607
+ case REOP_set_i32:
1608
+ case REOP_set_char_pos:
1609
+ case REOP_word_boundary:
1610
+ case REOP_word_boundary_i:
1611
+ case REOP_not_word_boundary:
1612
+ case REOP_not_word_boundary_i:
1613
+ case REOP_prev:
1614
+ /* no effect */
1615
+ break;
1616
+ case REOP_save_start:
1617
+ case REOP_save_end:
1618
+ case REOP_save_reset:
1619
+ break;
1620
+ case REOP_back_reference:
1621
+ case REOP_back_reference_i:
1622
+ case REOP_backward_back_reference:
1623
+ case REOP_backward_back_reference_i:
1624
+ val = bc_buf[pos + 1];
1625
+ len += val;
1626
+ need_capture_init = true;
1627
+ break;
1628
+ default:
1629
+ /* safe behavior: we cannot predict the outcome */
1630
+ need_capture_init = true;
1631
+ goto done;
1632
+ }
1633
+ pos += len;
1634
+ }
1635
+ done:
1636
+ *pneed_capture_init = need_capture_init;
1637
+ return need_check_adv;
1638
+ }
1639
+
1640
+ /* '*pp' is the first char after '<' */
1641
+ static int re_parse_group_name(char *buf, int buf_size, const uint8_t **pp)
1642
+ {
1643
+ const uint8_t *p, *p1;
1644
+ uint32_t c, d;
1645
+ char *q;
1646
+
1647
+ p = *pp;
1648
+ q = buf;
1649
+ for(;;) {
1650
+ c = *p;
1651
+ if (c == '\\') {
1652
+ p++;
1653
+ if (*p != 'u')
1654
+ return -1;
1655
+ c = lre_parse_escape(&p, 2); // accept surrogate pairs
1656
+ } else if (c == '>') {
1657
+ break;
1658
+ } else if (c >= 128) {
1659
+ c = utf8_decode_len(p, UTF8_CHAR_LEN_MAX, &p);
1660
+ if (is_hi_surrogate(c)) {
1661
+ d = utf8_decode_len(p, UTF8_CHAR_LEN_MAX, &p1);
1662
+ if (is_lo_surrogate(d)) {
1663
+ c = from_surrogate(c, d);
1664
+ p = p1;
1665
+ }
1666
+ }
1667
+ } else {
1668
+ p++;
1669
+ }
1670
+ if (c > 0x10FFFF)
1671
+ return -1;
1672
+ if (q == buf) {
1673
+ if (!lre_js_is_ident_first(c))
1674
+ return -1;
1675
+ } else {
1676
+ if (!lre_js_is_ident_next(c))
1677
+ return -1;
1678
+ }
1679
+ if ((q - buf + UTF8_CHAR_LEN_MAX + 1) > buf_size)
1680
+ return -1;
1681
+ if (c < 128) {
1682
+ *q++ = c;
1683
+ } else {
1684
+ q += utf8_encode((uint8_t*)q, c);
1685
+ }
1686
+ }
1687
+ if (q == buf)
1688
+ return -1;
1689
+ *q = '\0';
1690
+ p++;
1691
+ *pp = p;
1692
+ return 0;
1693
+ }
1694
+
1695
+ /* if capture_name = NULL: return the number of captures + 1.
1696
+ Otherwise, return the number of matching capture groups */
1697
+ static int re_parse_captures(REParseState *s, int *phas_named_captures,
1698
+ const char *capture_name, bool emit_group_index)
1699
+ {
1700
+ const uint8_t *p;
1701
+ int capture_index, n;
1702
+ char name[TMP_BUF_SIZE];
1703
+
1704
+ capture_index = 1;
1705
+ n = 0;
1706
+ *phas_named_captures = 0;
1707
+ for (p = s->buf_start; p < s->buf_end; p++) {
1708
+ switch (*p) {
1709
+ case '(':
1710
+ if (p[1] == '?') {
1711
+ if (p[2] == '<' && p[3] != '=' && p[3] != '!') {
1712
+ *phas_named_captures = 1;
1713
+ /* potential named capture */
1714
+ if (capture_name) {
1715
+ p += 3;
1716
+ if (re_parse_group_name(name, sizeof(name), &p) == 0) {
1717
+ if (!strcmp(name, capture_name)) {
1718
+ if (emit_group_index)
1719
+ dbuf_putc(&s->byte_code, capture_index);
1720
+ n++;
1721
+ }
1722
+ }
1723
+ }
1724
+ capture_index++;
1725
+ if (capture_index >= CAPTURE_COUNT_MAX)
1726
+ goto done;
1727
+ }
1728
+ } else {
1729
+ capture_index++;
1730
+ if (capture_index >= CAPTURE_COUNT_MAX)
1731
+ goto done;
1732
+ }
1733
+ break;
1734
+ case '\\':
1735
+ p++;
1736
+ break;
1737
+ case '[':
1738
+ for (p += 1 + (*p == ']'); p < s->buf_end && *p != ']'; p++) {
1739
+ if (*p == '\\')
1740
+ p++;
1741
+ }
1742
+ break;
1743
+ }
1744
+ }
1745
+ done:
1746
+ if (capture_name) {
1747
+ return n;
1748
+ } else {
1749
+ return capture_index;
1750
+ }
1751
+ }
1752
+
1753
+ static int re_count_captures(REParseState *s)
1754
+ {
1755
+ if (s->total_capture_count < 0) {
1756
+ s->total_capture_count = re_parse_captures(s, &s->has_named_captures,
1757
+ NULL, false);
1758
+ }
1759
+ return s->total_capture_count;
1760
+ }
1761
+
1762
+ static bool re_has_named_captures(REParseState *s)
1763
+ {
1764
+ if (s->has_named_captures < 0)
1765
+ re_count_captures(s);
1766
+ return s->has_named_captures;
1767
+ }
1768
+
1769
+ static int find_group_name(REParseState *s, const char *name, bool emit_group_index)
1770
+ {
1771
+ const char *p, *buf_end;
1772
+ size_t len, name_len;
1773
+ int capture_index, n;
1774
+
1775
+ p = (char *)s->group_names.buf;
1776
+ if (!p)
1777
+ return 0;
1778
+ buf_end = (char *)s->group_names.buf + s->group_names.size;
1779
+ name_len = strlen(name);
1780
+ capture_index = 1;
1781
+ n = 0;
1782
+ while (p < buf_end) {
1783
+ len = strlen(p);
1784
+ if (len == name_len && memcmp(name, p, name_len) == 0) {
1785
+ if (emit_group_index)
1786
+ dbuf_putc(&s->byte_code, capture_index);
1787
+ n++;
1788
+ }
1789
+ p += len + LRE_GROUP_NAME_TRAILER_LEN;
1790
+ capture_index++;
1791
+ }
1792
+ return n;
1793
+ }
1794
+
1795
+ static bool is_duplicate_group_name(REParseState *s, const char *name, int scope)
1796
+ {
1797
+ const char *p, *buf_end;
1798
+ size_t len, name_len;
1799
+ int scope1;
1800
+
1801
+ p = (char *)s->group_names.buf;
1802
+ if (!p)
1803
+ return 0;
1804
+ buf_end = (char *)s->group_names.buf + s->group_names.size;
1805
+ name_len = strlen(name);
1806
+ while (p < buf_end) {
1807
+ len = strlen(p);
1808
+ if (len == name_len && memcmp(name, p, name_len) == 0) {
1809
+ scope1 = (uint8_t)p[len + 1];
1810
+ if (scope == scope1)
1811
+ return true;
1812
+ }
1813
+ p += len + LRE_GROUP_NAME_TRAILER_LEN;
1814
+ }
1815
+ return false;
1816
+ }
1817
+
1818
+ static int re_parse_disjunction(REParseState *s, bool is_backward_dir);
1819
+
1820
+ static int re_parse_modifiers(REParseState *s, const uint8_t **pp)
1821
+ {
1822
+ const uint8_t *p = *pp;
1823
+ int mask = 0;
1824
+ int val;
1825
+
1826
+ for(;;) {
1827
+ if (*p == 'i') {
1828
+ val = LRE_FLAG_IGNORECASE;
1829
+ } else if (*p == 'm') {
1830
+ val = LRE_FLAG_MULTILINE;
1831
+ } else if (*p == 's') {
1832
+ val = LRE_FLAG_DOTALL;
1833
+ } else {
1834
+ break;
1835
+ }
1836
+ if (mask & val)
1837
+ return re_parse_error(s, "duplicate modifier: '%c'", *p);
1838
+ mask |= val;
1839
+ p++;
1840
+ }
1841
+ *pp = p;
1842
+ return mask;
1843
+ }
1844
+
1845
+ static bool update_modifier(bool val, int add_mask, int remove_mask,
1846
+ int mask)
1847
+ {
1848
+ if (add_mask & mask)
1849
+ val = true;
1850
+ if (remove_mask & mask)
1851
+ val = false;
1852
+ return val;
1853
+ }
1854
+
1855
+ static int re_parse_term(REParseState *s, bool is_backward_dir)
1856
+ {
1857
+ const uint8_t *p;
1858
+ int c, last_atom_start, quant_min, quant_max, last_capture_count;
1859
+ bool greedy, is_neg, is_backward_lookahead;
1860
+ REStringList cr_s, *cr = &cr_s;
1861
+
1862
+ last_atom_start = -1;
1863
+ last_capture_count = 0;
1864
+ p = s->buf_ptr;
1865
+ c = *p;
1866
+ switch(c) {
1867
+ case '^':
1868
+ p++;
1869
+ re_emit_op(s, s->multi_line ? REOP_line_start_m : REOP_line_start);
1870
+ break;
1871
+ case '$':
1872
+ p++;
1873
+ re_emit_op(s, s->multi_line ? REOP_line_end_m : REOP_line_end);
1874
+ break;
1875
+ case '.':
1876
+ p++;
1877
+ last_atom_start = s->byte_code.size;
1878
+ last_capture_count = s->capture_count;
1879
+ if (is_backward_dir)
1880
+ re_emit_op(s, REOP_prev);
1881
+ re_emit_op(s, s->dotall ? REOP_any : REOP_dot);
1882
+ if (is_backward_dir)
1883
+ re_emit_op(s, REOP_prev);
1884
+ break;
1885
+ case '{':
1886
+ if (s->is_unicode) {
1887
+ return re_parse_error(s, "syntax error");
1888
+ } else if (!lre_is_digit(p[1])) {
1889
+ /* Annex B: we accept '{' not followed by digits as a
1890
+ normal atom */
1891
+ goto parse_class_atom;
1892
+ } else {
1893
+ const uint8_t *p1 = p + 1;
1894
+ /* Annex B: error if it is like a repetition count */
1895
+ parse_digits(&p1, true);
1896
+ if (*p1 == ',') {
1897
+ p1++;
1898
+ if (lre_is_digit(*p1)) {
1899
+ parse_digits(&p1, true);
1900
+ }
1901
+ }
1902
+ if (*p1 != '}') {
1903
+ goto parse_class_atom;
1904
+ }
1905
+ }
1906
+ /* fall thru */
1907
+ case '*':
1908
+ case '+':
1909
+ case '?':
1910
+ return re_parse_error(s, "nothing to repeat");
1911
+ case '(':
1912
+ if (p[1] == '?') {
1913
+ if (p[2] == ':') {
1914
+ p += 3;
1915
+ last_atom_start = s->byte_code.size;
1916
+ last_capture_count = s->capture_count;
1917
+ s->buf_ptr = p;
1918
+ if (re_parse_disjunction(s, is_backward_dir))
1919
+ return -1;
1920
+ p = s->buf_ptr;
1921
+ if (re_parse_expect(s, &p, ')'))
1922
+ return -1;
1923
+ } else if (p[2] == 'i' || p[2] == 'm' || p[2] == 's' || p[2] == '-') {
1924
+ bool saved_ignore_case, saved_multi_line, saved_dotall;
1925
+ int add_mask, remove_mask;
1926
+ p += 2;
1927
+ remove_mask = 0;
1928
+ add_mask = re_parse_modifiers(s, &p);
1929
+ if (add_mask < 0)
1930
+ return -1;
1931
+ if (*p == '-') {
1932
+ p++;
1933
+ remove_mask = re_parse_modifiers(s, &p);
1934
+ if (remove_mask < 0)
1935
+ return -1;
1936
+ }
1937
+ if ((add_mask == 0 && remove_mask == 0) ||
1938
+ (add_mask & remove_mask) != 0) {
1939
+ return re_parse_error(s, "invalid modifiers");
1940
+ }
1941
+ if (re_parse_expect(s, &p, ':'))
1942
+ return -1;
1943
+ saved_ignore_case = s->ignore_case;
1944
+ saved_multi_line = s->multi_line;
1945
+ saved_dotall = s->dotall;
1946
+ s->ignore_case = update_modifier(s->ignore_case, add_mask, remove_mask, LRE_FLAG_IGNORECASE);
1947
+ s->multi_line = update_modifier(s->multi_line, add_mask, remove_mask, LRE_FLAG_MULTILINE);
1948
+ s->dotall = update_modifier(s->dotall, add_mask, remove_mask, LRE_FLAG_DOTALL);
1949
+
1950
+ last_atom_start = s->byte_code.size;
1951
+ last_capture_count = s->capture_count;
1952
+ s->buf_ptr = p;
1953
+ if (re_parse_disjunction(s, is_backward_dir))
1954
+ return -1;
1955
+ p = s->buf_ptr;
1956
+ if (re_parse_expect(s, &p, ')'))
1957
+ return -1;
1958
+ s->ignore_case = saved_ignore_case;
1959
+ s->multi_line = saved_multi_line;
1960
+ s->dotall = saved_dotall;
1961
+ } else if ((p[2] == '=' || p[2] == '!')) {
1962
+ is_neg = (p[2] == '!');
1963
+ is_backward_lookahead = false;
1964
+ p += 3;
1965
+ goto lookahead;
1966
+ } else if (p[2] == '<' &&
1967
+ (p[3] == '=' || p[3] == '!')) {
1968
+ int pos;
1969
+ is_neg = (p[3] == '!');
1970
+ is_backward_lookahead = true;
1971
+ p += 4;
1972
+ /* lookahead */
1973
+ lookahead:
1974
+ /* Annex B allows lookahead to be used as an atom for
1975
+ the quantifiers */
1976
+ if (!s->is_unicode && !is_backward_lookahead) {
1977
+ last_atom_start = s->byte_code.size;
1978
+ last_capture_count = s->capture_count;
1979
+ }
1980
+ pos = re_emit_op_u32(s, REOP_lookahead + is_neg, 0);
1981
+ s->buf_ptr = p;
1982
+ if (re_parse_disjunction(s, is_backward_lookahead))
1983
+ return -1;
1984
+ p = s->buf_ptr;
1985
+ if (re_parse_expect(s, &p, ')'))
1986
+ return -1;
1987
+ re_emit_op(s, REOP_lookahead_match + is_neg);
1988
+ /* jump after the 'match' after the lookahead is successful */
1989
+ if (dbuf_error(&s->byte_code))
1990
+ return -1;
1991
+ put_u32(s->byte_code.buf + pos, s->byte_code.size - (pos + 4));
1992
+ } else if (p[2] == '<') {
1993
+ p += 3;
1994
+ if (re_parse_group_name(s->u.tmp_buf, sizeof(s->u.tmp_buf),
1995
+ &p)) {
1996
+ return re_parse_error(s, "invalid group name");
1997
+ }
1998
+ /* poor's man method to test duplicate group
1999
+ names. */
2000
+ /* XXX: this method does not catch all the errors*/
2001
+ if (is_duplicate_group_name(s, s->u.tmp_buf, s->group_name_scope)) {
2002
+ return re_parse_error(s, "duplicate group name");
2003
+ }
2004
+ /* group name with a trailing zero */
2005
+ dbuf_put(&s->group_names, (uint8_t *)s->u.tmp_buf,
2006
+ strlen(s->u.tmp_buf) + 1);
2007
+ dbuf_putc(&s->group_names, s->group_name_scope);
2008
+ s->has_named_captures = 1;
2009
+ goto parse_capture;
2010
+ } else {
2011
+ return re_parse_error(s, "invalid group");
2012
+ }
2013
+ } else {
2014
+ int capture_index;
2015
+ p++;
2016
+ /* capture without group name */
2017
+ dbuf_putc(&s->group_names, 0);
2018
+ dbuf_putc(&s->group_names, 0);
2019
+ parse_capture:
2020
+ if (s->capture_count >= CAPTURE_COUNT_MAX)
2021
+ return re_parse_error(s, "too many captures");
2022
+ last_atom_start = s->byte_code.size;
2023
+ last_capture_count = s->capture_count;
2024
+ capture_index = s->capture_count++;
2025
+ re_emit_op_u8(s, REOP_save_start + is_backward_dir,
2026
+ capture_index);
2027
+
2028
+ s->buf_ptr = p;
2029
+ if (re_parse_disjunction(s, is_backward_dir))
2030
+ return -1;
2031
+ p = s->buf_ptr;
2032
+
2033
+ re_emit_op_u8(s, REOP_save_start + 1 - is_backward_dir,
2034
+ capture_index);
2035
+
2036
+ if (re_parse_expect(s, &p, ')'))
2037
+ return -1;
2038
+ }
2039
+ break;
2040
+ case '\\':
2041
+ switch(p[1]) {
2042
+ case 'b':
2043
+ case 'B':
2044
+ if (p[1] != 'b') {
2045
+ re_emit_op(s, s->ignore_case && s->is_unicode ? REOP_not_word_boundary_i : REOP_not_word_boundary);
2046
+ } else {
2047
+ re_emit_op(s, s->ignore_case && s->is_unicode ? REOP_word_boundary_i : REOP_word_boundary);
2048
+ }
2049
+ p += 2;
2050
+ break;
2051
+ case 'k':
2052
+ {
2053
+ const uint8_t *p1;
2054
+ int dummy_res, n;
2055
+ bool is_forward;
2056
+
2057
+ p1 = p;
2058
+ if (p1[2] != '<') {
2059
+ /* annex B: we tolerate invalid group names in non
2060
+ unicode mode if there is no named capture
2061
+ definition */
2062
+ if (s->is_unicode || re_has_named_captures(s))
2063
+ return re_parse_error(s, "expecting group name");
2064
+ else
2065
+ goto parse_class_atom;
2066
+ }
2067
+ p1 += 3;
2068
+ if (re_parse_group_name(s->u.tmp_buf, sizeof(s->u.tmp_buf),
2069
+ &p1)) {
2070
+ if (s->is_unicode || re_has_named_captures(s))
2071
+ return re_parse_error(s, "invalid group name");
2072
+ else
2073
+ goto parse_class_atom;
2074
+ }
2075
+ is_forward = false;
2076
+ n = find_group_name(s, s->u.tmp_buf, false);
2077
+ if (n == 0) {
2078
+ /* no capture name parsed before, try to look
2079
+ after (inefficient, but hopefully not common */
2080
+ n = re_parse_captures(s, &dummy_res, s->u.tmp_buf, false);
2081
+ if (n == 0) {
2082
+ if (s->is_unicode || re_has_named_captures(s))
2083
+ return re_parse_error(s, "group name not defined");
2084
+ else
2085
+ goto parse_class_atom;
2086
+ }
2087
+ is_forward = true;
2088
+ }
2089
+ last_atom_start = s->byte_code.size;
2090
+ last_capture_count = s->capture_count;
2091
+
2092
+ /* emit back references to all the captures indexes matching the group name */
2093
+ re_emit_op_u8(s, REOP_back_reference + 2 * is_backward_dir + s->ignore_case, n);
2094
+ if (is_forward) {
2095
+ re_parse_captures(s, &dummy_res, s->u.tmp_buf, true);
2096
+ } else {
2097
+ find_group_name(s, s->u.tmp_buf, true);
2098
+ }
2099
+ p = p1;
2100
+ }
2101
+ break;
2102
+ case '0':
2103
+ p += 2;
2104
+ c = 0;
2105
+ if (s->is_unicode) {
2106
+ if (lre_is_digit(*p)) {
2107
+ return re_parse_error(s, "invalid decimal escape in regular expression");
2108
+ }
2109
+ } else {
2110
+ /* Annex B.1.4: accept legacy octal */
2111
+ if (*p >= '0' && *p <= '7') {
2112
+ c = *p++ - '0';
2113
+ if (*p >= '0' && *p <= '7') {
2114
+ c = (c << 3) + *p++ - '0';
2115
+ }
2116
+ }
2117
+ }
2118
+ goto normal_char;
2119
+ case '1': case '2': case '3': case '4':
2120
+ case '5': case '6': case '7': case '8':
2121
+ case '9':
2122
+ {
2123
+ const uint8_t *q = ++p;
2124
+
2125
+ c = parse_digits(&p, false);
2126
+ if (c < 0 || (c >= s->capture_count && c >= re_count_captures(s))) {
2127
+ if (!s->is_unicode) {
2128
+ /* Annex B.1.4: accept legacy octal */
2129
+ p = q;
2130
+ if (*p <= '7') {
2131
+ c = 0;
2132
+ if (*p <= '3')
2133
+ c = *p++ - '0';
2134
+ if (*p >= '0' && *p <= '7') {
2135
+ c = (c << 3) + *p++ - '0';
2136
+ if (*p >= '0' && *p <= '7') {
2137
+ c = (c << 3) + *p++ - '0';
2138
+ }
2139
+ }
2140
+ } else {
2141
+ c = *p++;
2142
+ }
2143
+ goto normal_char;
2144
+ }
2145
+ return re_parse_error(s, "back reference out of range in regular expression");
2146
+ }
2147
+ last_atom_start = s->byte_code.size;
2148
+ last_capture_count = s->capture_count;
2149
+
2150
+ re_emit_op_u8(s, REOP_back_reference + 2 * is_backward_dir + s->ignore_case, 1);
2151
+ dbuf_putc(&s->byte_code, c);
2152
+ }
2153
+ break;
2154
+ default:
2155
+ goto parse_class_atom;
2156
+ }
2157
+ break;
2158
+ case '[':
2159
+ last_atom_start = s->byte_code.size;
2160
+ last_capture_count = s->capture_count;
2161
+ if (is_backward_dir)
2162
+ re_emit_op(s, REOP_prev);
2163
+ if (re_parse_char_class(s, &p))
2164
+ return -1;
2165
+ if (is_backward_dir)
2166
+ re_emit_op(s, REOP_prev);
2167
+ break;
2168
+ case ']':
2169
+ case '}':
2170
+ if (s->is_unicode)
2171
+ return re_parse_error(s, "syntax error");
2172
+ goto parse_class_atom;
2173
+ default:
2174
+ parse_class_atom:
2175
+ c = get_class_atom(s, cr, &p, false);
2176
+ if ((int)c < 0)
2177
+ return -1;
2178
+ normal_char:
2179
+ last_atom_start = s->byte_code.size;
2180
+ last_capture_count = s->capture_count;
2181
+ if (is_backward_dir)
2182
+ re_emit_op(s, REOP_prev);
2183
+ if (c >= CLASS_RANGE_BASE) {
2184
+ int ret = 0;
2185
+ /* optimize the common 'space' tests */
2186
+ if (c == (CLASS_RANGE_BASE + CHAR_RANGE_s)) {
2187
+ re_emit_op(s, REOP_space);
2188
+ } else if (c == (CLASS_RANGE_BASE + CHAR_RANGE_S)) {
2189
+ re_emit_op(s, REOP_not_space);
2190
+ } else {
2191
+ ret = re_emit_string_list(s, cr);
2192
+ }
2193
+ re_string_list_free(cr);
2194
+ if (ret)
2195
+ return -1;
2196
+ } else {
2197
+ if (s->ignore_case)
2198
+ c = lre_canonicalize(c, s->is_unicode);
2199
+ re_emit_char(s, c);
2200
+ }
2201
+ if (is_backward_dir)
2202
+ re_emit_op(s, REOP_prev);
2203
+ break;
2204
+ }
2205
+
2206
+ /* quantifier */
2207
+ if (last_atom_start >= 0) {
2208
+ c = *p;
2209
+ switch(c) {
2210
+ case '*':
2211
+ p++;
2212
+ quant_min = 0;
2213
+ quant_max = INT32_MAX;
2214
+ goto quantifier;
2215
+ case '+':
2216
+ p++;
2217
+ quant_min = 1;
2218
+ quant_max = INT32_MAX;
2219
+ goto quantifier;
2220
+ case '?':
2221
+ p++;
2222
+ quant_min = 0;
2223
+ quant_max = 1;
2224
+ goto quantifier;
2225
+ case '{':
2226
+ {
2227
+ const uint8_t *p1 = p;
2228
+ /* As an extension (see ES6 annex B), we accept '{' not
2229
+ followed by digits as a normal atom */
2230
+ if (!lre_is_digit(p[1])) {
2231
+ if (s->is_unicode)
2232
+ goto invalid_quant_count;
2233
+ break;
2234
+ }
2235
+ p++;
2236
+ quant_min = parse_digits(&p, true);
2237
+ quant_max = quant_min;
2238
+ if (*p == ',') {
2239
+ p++;
2240
+ if (lre_is_digit(*p)) {
2241
+ quant_max = parse_digits(&p, true);
2242
+ if (quant_max < quant_min) {
2243
+ invalid_quant_count:
2244
+ return re_parse_error(s, "invalid repetition count");
2245
+ }
2246
+ } else {
2247
+ quant_max = INT32_MAX; /* infinity */
2248
+ }
2249
+ }
2250
+ if (*p != '}' && !s->is_unicode) {
2251
+ /* Annex B: normal atom if invalid '{' syntax */
2252
+ p = p1;
2253
+ break;
2254
+ }
2255
+ if (re_parse_expect(s, &p, '}'))
2256
+ return -1;
2257
+ }
2258
+ quantifier:
2259
+ greedy = true;
2260
+ if (*p == '?') {
2261
+ p++;
2262
+ greedy = false;
2263
+ }
2264
+ if (last_atom_start < 0) {
2265
+ return re_parse_error(s, "nothing to repeat");
2266
+ }
2267
+ {
2268
+ bool need_capture_init, add_zero_advance_check;
2269
+ int len, pos;
2270
+
2271
+ /* the spec tells that if there is no advance when
2272
+ running the atom after the first quant_min times,
2273
+ then there is no match. We remove this test when we
2274
+ are sure the atom always advances the position. */
2275
+ add_zero_advance_check =
2276
+ re_need_check_adv_and_capture_init(&need_capture_init,
2277
+ s->byte_code.buf + last_atom_start,
2278
+ s->byte_code.size - last_atom_start);
2279
+
2280
+ /* general case: need to reset the capture at each
2281
+ iteration. We don't do it if there are no captures
2282
+ in the atom or if we are sure all captures are
2283
+ initialized in the atom. If quant_min = 0, we still
2284
+ need to reset once the captures in case the atom
2285
+ does not match. */
2286
+ if (need_capture_init && last_capture_count != s->capture_count) {
2287
+ if (dbuf_insert(&s->byte_code, last_atom_start, 3))
2288
+ goto out_of_memory;
2289
+ int pos = last_atom_start;
2290
+ s->byte_code.buf[pos++] = REOP_save_reset;
2291
+ s->byte_code.buf[pos++] = last_capture_count;
2292
+ s->byte_code.buf[pos++] = s->capture_count - 1;
2293
+ }
2294
+
2295
+ len = s->byte_code.size - last_atom_start;
2296
+ if (quant_min == 0) {
2297
+ /* need to reset the capture in case the atom is
2298
+ not executed */
2299
+ if (!need_capture_init && last_capture_count != s->capture_count) {
2300
+ if (dbuf_insert(&s->byte_code, last_atom_start, 3))
2301
+ goto out_of_memory;
2302
+ s->byte_code.buf[last_atom_start++] = REOP_save_reset;
2303
+ s->byte_code.buf[last_atom_start++] = last_capture_count;
2304
+ s->byte_code.buf[last_atom_start++] = s->capture_count - 1;
2305
+ }
2306
+ if (quant_max == 0) {
2307
+ s->byte_code.size = last_atom_start;
2308
+ } else if (quant_max == 1 || quant_max == INT32_MAX) {
2309
+ bool has_goto = (quant_max == INT32_MAX);
2310
+ if (dbuf_insert(&s->byte_code, last_atom_start, 5 + add_zero_advance_check * 2))
2311
+ goto out_of_memory;
2312
+ s->byte_code.buf[last_atom_start] = REOP_split_goto_first +
2313
+ greedy;
2314
+ put_u32(s->byte_code.buf + last_atom_start + 1,
2315
+ len + 5 * has_goto + add_zero_advance_check * 2 * 2);
2316
+ if (add_zero_advance_check) {
2317
+ s->byte_code.buf[last_atom_start + 1 + 4] = REOP_set_char_pos;
2318
+ s->byte_code.buf[last_atom_start + 1 + 4 + 1] = 0;
2319
+ re_emit_op_u8(s, REOP_check_advance, 0);
2320
+ }
2321
+ if (has_goto)
2322
+ re_emit_goto(s, REOP_goto, last_atom_start);
2323
+ } else {
2324
+ if (dbuf_insert(&s->byte_code, last_atom_start, 11 + add_zero_advance_check * 2))
2325
+ goto out_of_memory;
2326
+ pos = last_atom_start;
2327
+ s->byte_code.buf[pos++] = REOP_split_goto_first + greedy;
2328
+ put_u32(s->byte_code.buf + pos, 6 + add_zero_advance_check * 2 + len + 10);
2329
+ pos += 4;
2330
+
2331
+ s->byte_code.buf[pos++] = REOP_set_i32;
2332
+ s->byte_code.buf[pos++] = 0;
2333
+ put_u32(s->byte_code.buf + pos, quant_max);
2334
+ pos += 4;
2335
+ last_atom_start = pos;
2336
+ if (add_zero_advance_check) {
2337
+ s->byte_code.buf[pos++] = REOP_set_char_pos;
2338
+ s->byte_code.buf[pos++] = 0;
2339
+ }
2340
+ re_emit_goto_u8_u32(s, (add_zero_advance_check ? REOP_loop_check_adv_split_next_first : REOP_loop_split_next_first) - greedy, 0, quant_max, last_atom_start);
2341
+ }
2342
+ } else if (quant_min == 1 && quant_max == INT32_MAX &&
2343
+ !add_zero_advance_check) {
2344
+ re_emit_goto(s, REOP_split_next_first - greedy,
2345
+ last_atom_start);
2346
+ } else {
2347
+ if (quant_min == quant_max)
2348
+ add_zero_advance_check = false;
2349
+ if (dbuf_insert(&s->byte_code, last_atom_start, 6 + add_zero_advance_check * 2))
2350
+ goto out_of_memory;
2351
+ /* Note: we assume the string length is < INT32_MAX */
2352
+ pos = last_atom_start;
2353
+ s->byte_code.buf[pos++] = REOP_set_i32;
2354
+ s->byte_code.buf[pos++] = 0;
2355
+ put_u32(s->byte_code.buf + pos, quant_max);
2356
+ pos += 4;
2357
+ last_atom_start = pos;
2358
+ if (add_zero_advance_check) {
2359
+ s->byte_code.buf[pos++] = REOP_set_char_pos;
2360
+ s->byte_code.buf[pos++] = 0;
2361
+ }
2362
+ if (quant_min == quant_max) {
2363
+ /* a simple loop is enough */
2364
+ re_emit_goto_u8(s, REOP_loop, 0, last_atom_start);
2365
+ } else {
2366
+ re_emit_goto_u8_u32(s, (add_zero_advance_check ? REOP_loop_check_adv_split_next_first : REOP_loop_split_next_first) - greedy, 0, quant_max - quant_min, last_atom_start);
2367
+ }
2368
+ }
2369
+ last_atom_start = -1;
2370
+ }
2371
+ break;
2372
+ default:
2373
+ break;
2374
+ }
2375
+ }
2376
+ s->buf_ptr = p;
2377
+ return 0;
2378
+ out_of_memory:
2379
+ return re_parse_out_of_memory(s);
2380
+ }
2381
+
2382
+ static int re_parse_alternative(REParseState *s, bool is_backward_dir)
2383
+ {
2384
+ const uint8_t *p;
2385
+ int ret;
2386
+ size_t start, term_start, end, term_size;
2387
+
2388
+ start = s->byte_code.size;
2389
+ for(;;) {
2390
+ p = s->buf_ptr;
2391
+ if (p >= s->buf_end)
2392
+ break;
2393
+ if (*p == '|' || *p == ')')
2394
+ break;
2395
+ term_start = s->byte_code.size;
2396
+ ret = re_parse_term(s, is_backward_dir);
2397
+ if (ret)
2398
+ return ret;
2399
+ if (is_backward_dir) {
2400
+ /* reverse the order of the terms (XXX: inefficient, but
2401
+ speed is not really critical here) */
2402
+ end = s->byte_code.size;
2403
+ term_size = end - term_start;
2404
+ if (dbuf_claim(&s->byte_code, term_size))
2405
+ return -1;
2406
+ memmove(s->byte_code.buf + start + term_size,
2407
+ s->byte_code.buf + start,
2408
+ end - start);
2409
+ memcpy(s->byte_code.buf + start, s->byte_code.buf + end,
2410
+ term_size);
2411
+ }
2412
+ }
2413
+ return 0;
2414
+ }
2415
+
2416
+ static int re_parse_disjunction(REParseState *s, bool is_backward_dir)
2417
+ {
2418
+ int start, len, pos;
2419
+
2420
+ if (lre_check_stack_overflow(s->opaque, 0))
2421
+ return re_parse_error(s, "stack overflow");
2422
+
2423
+ start = s->byte_code.size;
2424
+ if (re_parse_alternative(s, is_backward_dir))
2425
+ return -1;
2426
+ while (*s->buf_ptr == '|') {
2427
+ s->buf_ptr++;
2428
+
2429
+ len = s->byte_code.size - start;
2430
+
2431
+ /* insert a split before the first alternative */
2432
+ if (dbuf_insert(&s->byte_code, start, 5)) {
2433
+ return re_parse_out_of_memory(s);
2434
+ }
2435
+ s->byte_code.buf[start] = REOP_split_next_first;
2436
+ put_u32(s->byte_code.buf + start + 1, len + 5);
2437
+
2438
+ pos = re_emit_op_u32(s, REOP_goto, 0);
2439
+
2440
+ s->group_name_scope++;
2441
+
2442
+ if (re_parse_alternative(s, is_backward_dir))
2443
+ return -1;
2444
+
2445
+ /* patch the goto */
2446
+ len = s->byte_code.size - (pos + 4);
2447
+ put_u32(s->byte_code.buf + pos, len);
2448
+ }
2449
+ return 0;
2450
+ }
2451
+
2452
+ /* Allocate the registers as a stack. The control flow is recursive so
2453
+ the analysis can be linear. */
2454
+ static int compute_register_count(uint8_t *bc_buf, int bc_buf_len)
2455
+ {
2456
+ int stack_size, stack_size_max, pos, opcode, len;
2457
+ uint32_t val;
2458
+
2459
+ stack_size = 0;
2460
+ stack_size_max = 0;
2461
+ bc_buf += RE_HEADER_LEN;
2462
+ bc_buf_len -= RE_HEADER_LEN;
2463
+ pos = 0;
2464
+ while (pos < bc_buf_len) {
2465
+ opcode = bc_buf[pos];
2466
+ len = reopcode_info[opcode].size;
2467
+ assert(opcode < REOP_COUNT);
2468
+ assert((pos + len) <= bc_buf_len);
2469
+ switch(opcode) {
2470
+ case REOP_set_i32:
2471
+ case REOP_set_char_pos:
2472
+ bc_buf[pos + 1] = stack_size;
2473
+ stack_size++;
2474
+ if (stack_size > stack_size_max) {
2475
+ if (stack_size > REGISTER_COUNT_MAX)
2476
+ return -1;
2477
+ stack_size_max = stack_size;
2478
+ }
2479
+ break;
2480
+ case REOP_check_advance:
2481
+ case REOP_loop:
2482
+ case REOP_loop_split_goto_first:
2483
+ case REOP_loop_split_next_first:
2484
+ assert(stack_size > 0);
2485
+ stack_size--;
2486
+ bc_buf[pos + 1] = stack_size;
2487
+ break;
2488
+ case REOP_loop_check_adv_split_goto_first:
2489
+ case REOP_loop_check_adv_split_next_first:
2490
+ assert(stack_size >= 2);
2491
+ stack_size -= 2;
2492
+ bc_buf[pos + 1] = stack_size;
2493
+ break;
2494
+ case REOP_range:
2495
+ case REOP_range_i:
2496
+ val = get_u16(bc_buf + pos + 1);
2497
+ len += val * 4;
2498
+ break;
2499
+ case REOP_range32:
2500
+ case REOP_range32_i:
2501
+ val = get_u16(bc_buf + pos + 1);
2502
+ len += val * 8;
2503
+ break;
2504
+ case REOP_back_reference:
2505
+ case REOP_back_reference_i:
2506
+ case REOP_backward_back_reference:
2507
+ case REOP_backward_back_reference_i:
2508
+ val = bc_buf[pos + 1];
2509
+ len += val;
2510
+ break;
2511
+ }
2512
+ pos += len;
2513
+ }
2514
+ return stack_size_max;
2515
+ }
2516
+
2517
+ static void *lre_bytecode_realloc(void *opaque, void *ptr, size_t size)
2518
+ {
2519
+ if (size > (INT32_MAX / 2)) {
2520
+ /* the bytecode cannot be larger than 2G. Leave some slack to
2521
+ avoid some overflows. */
2522
+ return NULL;
2523
+ } else {
2524
+ return lre_realloc(opaque, ptr, size);
2525
+ }
2526
+ }
2527
+
2528
+ /* 'buf' must be a zero terminated UTF-8 string of length buf_len.
2529
+ Return NULL if error and allocate an error message in *perror_msg,
2530
+ otherwise the compiled bytecode and its length in plen.
2531
+ */
2532
+ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
2533
+ const char *buf, size_t buf_len, int re_flags,
2534
+ void *opaque)
2535
+ {
2536
+ REParseState s_s, *s = &s_s;
2537
+ int register_count;
2538
+ bool is_sticky;
2539
+
2540
+ memset(s, 0, sizeof(*s));
2541
+ s->opaque = opaque;
2542
+ s->buf_ptr = (const uint8_t *)buf;
2543
+ s->buf_end = s->buf_ptr + buf_len;
2544
+ s->buf_start = s->buf_ptr;
2545
+ s->re_flags = re_flags;
2546
+ s->is_unicode = ((re_flags & (LRE_FLAG_UNICODE | LRE_FLAG_UNICODE_SETS)) != 0);
2547
+ is_sticky = ((re_flags & LRE_FLAG_STICKY) != 0);
2548
+ s->ignore_case = ((re_flags & LRE_FLAG_IGNORECASE) != 0);
2549
+ s->multi_line = ((re_flags & LRE_FLAG_MULTILINE) != 0);
2550
+ s->dotall = ((re_flags & LRE_FLAG_DOTALL) != 0);
2551
+ s->unicode_sets = ((re_flags & LRE_FLAG_UNICODE_SETS) != 0);
2552
+ s->capture_count = 1;
2553
+ s->total_capture_count = -1;
2554
+ s->has_named_captures = -1;
2555
+
2556
+ dbuf_init2(&s->byte_code, opaque, lre_bytecode_realloc);
2557
+ dbuf_init2(&s->group_names, opaque, lre_realloc);
2558
+
2559
+ dbuf_put_u16(&s->byte_code, re_flags); /* first element is the flags */
2560
+ dbuf_putc(&s->byte_code, 0); /* second element is the number of captures */
2561
+ dbuf_putc(&s->byte_code, 0); /* stack size */
2562
+ dbuf_put_u32(&s->byte_code, 0); /* bytecode length */
2563
+
2564
+ if (!is_sticky) {
2565
+ /* iterate thru all positions (about the same as .*?( ... ) )
2566
+ . We do it without an explicit loop so that lock step
2567
+ thread execution will be possible in an optimized
2568
+ implementation */
2569
+ re_emit_op_u32(s, REOP_split_goto_first, 1 + 5);
2570
+ re_emit_op(s, REOP_any);
2571
+ re_emit_op_u32(s, REOP_goto, -(5 + 1 + 5));
2572
+ }
2573
+ re_emit_op_u8(s, REOP_save_start, 0);
2574
+
2575
+ if (re_parse_disjunction(s, false)) {
2576
+ error:
2577
+ dbuf_free(&s->byte_code);
2578
+ dbuf_free(&s->group_names);
2579
+ js__pstrcpy(error_msg, error_msg_size, s->u.error_msg);
2580
+ *plen = 0;
2581
+ return NULL;
2582
+ }
2583
+
2584
+ re_emit_op_u8(s, REOP_save_end, 0);
2585
+
2586
+ re_emit_op(s, REOP_match);
2587
+
2588
+ if (*s->buf_ptr != '\0') {
2589
+ re_parse_error(s, "extraneous characters at the end");
2590
+ goto error;
2591
+ }
2592
+
2593
+ if (dbuf_error(&s->byte_code)) {
2594
+ re_parse_out_of_memory(s);
2595
+ goto error;
2596
+ }
2597
+
2598
+ register_count = compute_register_count(s->byte_code.buf, s->byte_code.size);
2599
+ if (register_count < 0) {
2600
+ re_parse_error(s, "too many imbricated quantifiers");
2601
+ goto error;
2602
+ }
2603
+
2604
+ s->byte_code.buf[RE_HEADER_CAPTURE_COUNT] = s->capture_count;
2605
+ s->byte_code.buf[RE_HEADER_REGISTER_COUNT] = register_count;
2606
+ put_u32(s->byte_code.buf + RE_HEADER_BYTECODE_LEN,
2607
+ s->byte_code.size - RE_HEADER_LEN);
2608
+
2609
+ /* add the named groups if needed */
2610
+ if (s->group_names.size > (s->capture_count - 1) * LRE_GROUP_NAME_TRAILER_LEN) {
2611
+ dbuf_put(&s->byte_code, s->group_names.buf, s->group_names.size);
2612
+ put_u16(s->byte_code.buf + RE_HEADER_FLAGS,
2613
+ lre_get_flags(s->byte_code.buf) | LRE_FLAG_NAMED_GROUPS);
2614
+ }
2615
+ dbuf_free(&s->group_names);
2616
+
2617
+ #ifdef DUMP_REOP
2618
+ lre_dump_bytecode(s->byte_code.buf, s->byte_code.size);
2619
+ #endif
2620
+
2621
+ error_msg[0] = '\0';
2622
+ *plen = s->byte_code.size;
2623
+ return s->byte_code.buf;
2624
+ }
2625
+
2626
+ static bool is_line_terminator(uint32_t c)
2627
+ {
2628
+ return (c == '\n' || c == '\r' || c == CP_LS || c == CP_PS);
2629
+ }
2630
+
2631
+ #define GET_CHAR(c, cptr, cbuf_end, cbuf_type) \
2632
+ do { \
2633
+ if (cbuf_type == 0) { \
2634
+ c = *cptr++; \
2635
+ } else { \
2636
+ const uint16_t *_p = (const uint16_t *)cptr; \
2637
+ const uint16_t *_end = (const uint16_t *)cbuf_end; \
2638
+ c = *_p++; \
2639
+ if (is_hi_surrogate(c) && cbuf_type == 2) { \
2640
+ if (_p < _end && is_lo_surrogate(*_p)) { \
2641
+ c = from_surrogate(c, *_p++); \
2642
+ } \
2643
+ } \
2644
+ cptr = (const void *)_p; \
2645
+ } \
2646
+ } while (0)
2647
+
2648
+ #define PEEK_CHAR(c, cptr, cbuf_end, cbuf_type) \
2649
+ do { \
2650
+ if (cbuf_type == 0) { \
2651
+ c = cptr[0]; \
2652
+ } else { \
2653
+ const uint16_t *_p = (const uint16_t *)cptr; \
2654
+ const uint16_t *_end = (const uint16_t *)cbuf_end; \
2655
+ c = *_p++; \
2656
+ if (is_hi_surrogate(c) && cbuf_type == 2) { \
2657
+ if (_p < _end && is_lo_surrogate(*_p)) { \
2658
+ c = from_surrogate(c, *_p); \
2659
+ } \
2660
+ } \
2661
+ } \
2662
+ } while (0)
2663
+
2664
+ #define PEEK_PREV_CHAR(c, cptr, cbuf_start, cbuf_type) \
2665
+ do { \
2666
+ if (cbuf_type == 0) { \
2667
+ c = cptr[-1]; \
2668
+ } else { \
2669
+ const uint16_t *_p = (const uint16_t *)cptr - 1; \
2670
+ const uint16_t *_start = (const uint16_t *)cbuf_start; \
2671
+ c = *_p; \
2672
+ if (is_lo_surrogate(c) && cbuf_type == 2) { \
2673
+ if (_p > _start && is_hi_surrogate(_p[-1])) { \
2674
+ c = from_surrogate(*--_p, c); \
2675
+ } \
2676
+ } \
2677
+ } \
2678
+ } while (0)
2679
+
2680
+ #define GET_PREV_CHAR(c, cptr, cbuf_start, cbuf_type) \
2681
+ do { \
2682
+ if (cbuf_type == 0) { \
2683
+ cptr--; \
2684
+ c = cptr[0]; \
2685
+ } else { \
2686
+ const uint16_t *_p = (const uint16_t *)cptr - 1; \
2687
+ const uint16_t *_start = (const uint16_t *)cbuf_start; \
2688
+ c = *_p; \
2689
+ if (is_lo_surrogate(c) && cbuf_type == 2) { \
2690
+ if (_p > _start && is_hi_surrogate(_p[-1])) { \
2691
+ c = from_surrogate(*--_p, c); \
2692
+ } \
2693
+ } \
2694
+ cptr = (const void *)_p; \
2695
+ } \
2696
+ } while (0)
2697
+
2698
+ #define PREV_CHAR(cptr, cbuf_start, cbuf_type) \
2699
+ do { \
2700
+ if (cbuf_type == 0) { \
2701
+ cptr--; \
2702
+ } else { \
2703
+ const uint16_t *_p = (const uint16_t *)cptr - 1; \
2704
+ const uint16_t *_start = (const uint16_t *)cbuf_start; \
2705
+ if (is_lo_surrogate(*_p) && cbuf_type == 2) { \
2706
+ if (_p > _start && is_hi_surrogate(_p[-1])) { \
2707
+ --_p; \
2708
+ } \
2709
+ } \
2710
+ cptr = (const void *)_p; \
2711
+ } \
2712
+ } while (0)
2713
+
2714
+ typedef enum {
2715
+ RE_EXEC_STATE_SPLIT,
2716
+ RE_EXEC_STATE_LOOKAHEAD,
2717
+ RE_EXEC_STATE_NEGATIVE_LOOKAHEAD,
2718
+ } REExecStateEnum;
2719
+
2720
+ #if INTPTR_MAX >= INT64_MAX
2721
+ #define BP_TYPE_BITS 3
2722
+ #else
2723
+ #define BP_TYPE_BITS 2
2724
+ #endif
2725
+
2726
+ typedef union {
2727
+ uint8_t *ptr;
2728
+ intptr_t val; /* for bp, the low BP_SHIFT bits store REExecStateEnum */
2729
+ struct {
2730
+ uintptr_t val : sizeof(uintptr_t) * 8 - BP_TYPE_BITS;
2731
+ uintptr_t type : BP_TYPE_BITS;
2732
+ } bp;
2733
+ } StackElem;
2734
+
2735
+ typedef struct {
2736
+ const uint8_t *cbuf;
2737
+ const uint8_t *cbuf_end;
2738
+ /* 0 = 8 bit chars, 1 = 16 bit chars, 2 = 16 bit chars, UTF-16 */
2739
+ int cbuf_type;
2740
+ int capture_count;
2741
+ bool is_unicode;
2742
+ int interrupt_counter;
2743
+ void *opaque; /* used for stack overflow check */
2744
+
2745
+ StackElem *stack_buf;
2746
+ size_t stack_size;
2747
+ StackElem static_stack_buf[32]; /* static stack to avoid allocation in most cases */
2748
+ } REExecContext;
2749
+
2750
+ static int lre_poll_timeout(REExecContext *s)
2751
+ {
2752
+ if (unlikely(--s->interrupt_counter <= 0)) {
2753
+ s->interrupt_counter = INTERRUPT_COUNTER_INIT;
2754
+ if (lre_check_timeout(s->opaque))
2755
+ return LRE_RET_TIMEOUT;
2756
+ }
2757
+ return 0;
2758
+ }
2759
+
2760
+ static no_inline int stack_realloc(REExecContext *s, size_t n)
2761
+ {
2762
+ StackElem *new_stack;
2763
+ size_t new_size;
2764
+ new_size = s->stack_size * 3 / 2;
2765
+ if (new_size < n)
2766
+ new_size = n;
2767
+ if (s->stack_buf == s->static_stack_buf) {
2768
+ new_stack = lre_realloc(s->opaque, NULL, new_size * sizeof(StackElem));
2769
+ if (!new_stack)
2770
+ return -1;
2771
+ /* XXX: could use correct size */
2772
+ memcpy(new_stack, s->stack_buf, s->stack_size * sizeof(StackElem));
2773
+ } else {
2774
+ new_stack = lre_realloc(s->opaque, s->stack_buf, new_size * sizeof(StackElem));
2775
+ if (!new_stack)
2776
+ return -1;
2777
+ }
2778
+ s->stack_size = new_size;
2779
+ s->stack_buf = new_stack;
2780
+ return 0;
2781
+ }
2782
+
2783
+ /* return 1 if match, 0 if not match or < 0 if error. */
2784
+ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
2785
+ const uint8_t *pc, const uint8_t *cptr)
2786
+ {
2787
+ int opcode;
2788
+ int cbuf_type;
2789
+ uint32_t val, c, idx;
2790
+ const uint8_t *cbuf_end;
2791
+ StackElem *sp, *bp, *stack_end;
2792
+ #ifdef DUMP_EXEC
2793
+ const uint8_t *pc_start = pc; /* TEST */
2794
+ #endif
2795
+ cbuf_type = s->cbuf_type;
2796
+ cbuf_end = s->cbuf_end;
2797
+
2798
+ sp = s->stack_buf;
2799
+ bp = s->stack_buf;
2800
+ stack_end = s->stack_buf + s->stack_size;
2801
+
2802
+ #define CHECK_STACK_SPACE(n) \
2803
+ if (unlikely((stack_end - sp) < (n))) { \
2804
+ size_t saved_sp = sp - s->stack_buf; \
2805
+ size_t saved_bp = bp - s->stack_buf; \
2806
+ if (stack_realloc(s, sp - s->stack_buf + (n))) \
2807
+ return LRE_RET_MEMORY_ERROR; \
2808
+ stack_end = s->stack_buf + s->stack_size; \
2809
+ sp = s->stack_buf + saved_sp; \
2810
+ bp = s->stack_buf + saved_bp; \
2811
+ }
2812
+
2813
+ /* XXX: could test if the value was saved to reduce the stack size
2814
+ but slower */
2815
+ #define SAVE_CAPTURE(idx, value) \
2816
+ { \
2817
+ CHECK_STACK_SPACE(2); \
2818
+ sp[0].val = idx; \
2819
+ sp[1].ptr = capture[idx]; \
2820
+ sp += 2; \
2821
+ capture[idx] = (value); \
2822
+ }
2823
+
2824
+ /* avoid saving the previous value if already saved */
2825
+ #define SAVE_CAPTURE_CHECK(idx, value) \
2826
+ { \
2827
+ StackElem *sp1; \
2828
+ sp1 = sp; \
2829
+ for(;;) { \
2830
+ if (sp1 > bp) { \
2831
+ if (sp1[-2].val == idx) \
2832
+ break; \
2833
+ sp1 -= 2; \
2834
+ } else { \
2835
+ CHECK_STACK_SPACE(2); \
2836
+ sp[0].val = idx; \
2837
+ sp[1].ptr = capture[idx]; \
2838
+ sp += 2; \
2839
+ break; \
2840
+ } \
2841
+ } \
2842
+ capture[idx] = (value); \
2843
+ }
2844
+
2845
+
2846
+ #ifdef DUMP_EXEC
2847
+ printf("%5s %5s %5s %5s %s\n", "PC", "CP", "BP", "SP", "OPCODE");
2848
+ #endif
2849
+ for(;;) {
2850
+ opcode = *pc++;
2851
+ #ifdef DUMP_EXEC
2852
+ printf("%5ld %5ld %5ld %5ld %s\n",
2853
+ pc - 1 - pc_start,
2854
+ cbuf_type == 0 ? cptr - s->cbuf : (cptr - s->cbuf) / 2,
2855
+ bp - s->stack_buf,
2856
+ sp - s->stack_buf,
2857
+ reopcode_info[opcode].name);
2858
+ #endif
2859
+ switch(opcode) {
2860
+ case REOP_match:
2861
+ return 1;
2862
+ no_match:
2863
+ for(;;) {
2864
+ REExecStateEnum type;
2865
+ if (bp == s->stack_buf)
2866
+ return 0;
2867
+ /* undo the modifications to capture[] */
2868
+ while (sp > bp) {
2869
+ capture[sp[-2].val] = sp[-1].ptr;
2870
+ sp -= 2;
2871
+ }
2872
+
2873
+ pc = sp[-3].ptr;
2874
+ cptr = sp[-2].ptr;
2875
+ type = sp[-1].bp.type;
2876
+ bp = s->stack_buf + sp[-1].bp.val;
2877
+ sp -= 3;
2878
+ if (type != RE_EXEC_STATE_LOOKAHEAD)
2879
+ break;
2880
+ }
2881
+ if (lre_poll_timeout(s))
2882
+ return LRE_RET_TIMEOUT;
2883
+ break;
2884
+ case REOP_lookahead_match:
2885
+ /* pop all the saved states until reaching the start of
2886
+ the lookahead and keep the updated captures and
2887
+ variables and the corresponding undo info. */
2888
+ {
2889
+ StackElem *sp1, *sp_top, *next_sp;
2890
+ REExecStateEnum type;
2891
+
2892
+ sp_top = sp;
2893
+ for(;;) {
2894
+ sp1 = sp;
2895
+ sp = bp;
2896
+ pc = sp[-3].ptr;
2897
+ cptr = sp[-2].ptr;
2898
+ type = sp[-1].bp.type;
2899
+ bp = s->stack_buf + sp[-1].bp.val;
2900
+ sp[-1].ptr = (void *)sp1; /* save the next value for the copy step */
2901
+ sp -= 3;
2902
+ if (type == RE_EXEC_STATE_LOOKAHEAD)
2903
+ break;
2904
+ }
2905
+ if (sp != s->stack_buf) {
2906
+ /* keep the undo info if there is a saved state */
2907
+ sp1 = sp;
2908
+ while (sp1 < sp_top) {
2909
+ next_sp = (void *)sp1[2].ptr;
2910
+ sp1 += 3;
2911
+ while (sp1 < next_sp)
2912
+ *sp++ = *sp1++;
2913
+ }
2914
+ }
2915
+ }
2916
+ break;
2917
+ case REOP_negative_lookahead_match:
2918
+ /* pop all the saved states until reaching start of the negative lookahead */
2919
+ for(;;) {
2920
+ REExecStateEnum type;
2921
+ type = bp[-1].bp.type;
2922
+ /* undo the modifications to capture[] */
2923
+ while (sp > bp) {
2924
+ capture[sp[-2].val] = sp[-1].ptr;
2925
+ sp -= 2;
2926
+ }
2927
+ pc = sp[-3].ptr;
2928
+ cptr = sp[-2].ptr;
2929
+ type = sp[-1].bp.type;
2930
+ bp = s->stack_buf + sp[-1].bp.val;
2931
+ sp -= 3;
2932
+ if (type == RE_EXEC_STATE_NEGATIVE_LOOKAHEAD)
2933
+ break;
2934
+ }
2935
+ goto no_match;
2936
+ case REOP_char32:
2937
+ case REOP_char32_i:
2938
+ val = get_u32(pc);
2939
+ pc += 4;
2940
+ goto test_char;
2941
+ case REOP_char:
2942
+ case REOP_char_i:
2943
+ val = get_u16(pc);
2944
+ pc += 2;
2945
+ test_char:
2946
+ if (cptr >= cbuf_end)
2947
+ goto no_match;
2948
+ GET_CHAR(c, cptr, cbuf_end, cbuf_type);
2949
+ if (opcode == REOP_char_i || opcode == REOP_char32_i) {
2950
+ c = lre_canonicalize(c, s->is_unicode);
2951
+ }
2952
+ if (val != c)
2953
+ goto no_match;
2954
+ break;
2955
+ case REOP_split_goto_first:
2956
+ case REOP_split_next_first:
2957
+ {
2958
+ const uint8_t *pc1;
2959
+
2960
+ val = get_u32(pc);
2961
+ pc += 4;
2962
+ if (opcode == REOP_split_next_first) {
2963
+ pc1 = pc + (int)val;
2964
+ } else {
2965
+ pc1 = pc;
2966
+ pc = pc + (int)val;
2967
+ }
2968
+ CHECK_STACK_SPACE(3);
2969
+ sp[0].ptr = (uint8_t *)pc1;
2970
+ sp[1].ptr = (uint8_t *)cptr;
2971
+ sp[2].bp.val = bp - s->stack_buf;
2972
+ sp[2].bp.type = RE_EXEC_STATE_SPLIT;
2973
+ sp += 3;
2974
+ bp = sp;
2975
+ }
2976
+ break;
2977
+ case REOP_lookahead:
2978
+ case REOP_negative_lookahead:
2979
+ val = get_u32(pc);
2980
+ pc += 4;
2981
+ CHECK_STACK_SPACE(3);
2982
+ sp[0].ptr = (uint8_t *)(pc + (int)val);
2983
+ sp[1].ptr = (uint8_t *)cptr;
2984
+ sp[2].bp.val = bp - s->stack_buf;
2985
+ sp[2].bp.type = RE_EXEC_STATE_LOOKAHEAD + opcode - REOP_lookahead;
2986
+ sp += 3;
2987
+ bp = sp;
2988
+ break;
2989
+ case REOP_goto:
2990
+ val = get_u32(pc);
2991
+ pc += 4 + (int)val;
2992
+ if (lre_poll_timeout(s))
2993
+ return LRE_RET_TIMEOUT;
2994
+ break;
2995
+ case REOP_line_start:
2996
+ case REOP_line_start_m:
2997
+ if (cptr == s->cbuf)
2998
+ break;
2999
+ if (opcode == REOP_line_start)
3000
+ goto no_match;
3001
+ PEEK_PREV_CHAR(c, cptr, s->cbuf, cbuf_type);
3002
+ if (!is_line_terminator(c))
3003
+ goto no_match;
3004
+ break;
3005
+ case REOP_line_end:
3006
+ case REOP_line_end_m:
3007
+ if (cptr == cbuf_end)
3008
+ break;
3009
+ if (opcode == REOP_line_end)
3010
+ goto no_match;
3011
+ PEEK_CHAR(c, cptr, cbuf_end, cbuf_type);
3012
+ if (!is_line_terminator(c))
3013
+ goto no_match;
3014
+ break;
3015
+ case REOP_dot:
3016
+ if (cptr == cbuf_end)
3017
+ goto no_match;
3018
+ GET_CHAR(c, cptr, cbuf_end, cbuf_type);
3019
+ if (is_line_terminator(c))
3020
+ goto no_match;
3021
+ break;
3022
+ case REOP_any:
3023
+ if (cptr == cbuf_end)
3024
+ goto no_match;
3025
+ GET_CHAR(c, cptr, cbuf_end, cbuf_type);
3026
+ break;
3027
+ case REOP_space:
3028
+ if (cptr == cbuf_end)
3029
+ goto no_match;
3030
+ GET_CHAR(c, cptr, cbuf_end, cbuf_type);
3031
+ if (!lre_is_space(c))
3032
+ goto no_match;
3033
+ break;
3034
+ case REOP_not_space:
3035
+ if (cptr == cbuf_end)
3036
+ goto no_match;
3037
+ GET_CHAR(c, cptr, cbuf_end, cbuf_type);
3038
+ if (lre_is_space(c))
3039
+ goto no_match;
3040
+ break;
3041
+ case REOP_save_start:
3042
+ case REOP_save_end:
3043
+ val = *pc++;
3044
+ if (val >= (uint32_t)s->capture_count)
3045
+ return LRE_RET_BYTECODE_ERROR;
3046
+ idx = 2 * val + opcode - REOP_save_start;
3047
+ SAVE_CAPTURE(idx, (uint8_t *)cptr);
3048
+ break;
3049
+ case REOP_save_reset:
3050
+ {
3051
+ uint32_t val2;
3052
+ val = pc[0];
3053
+ val2 = pc[1];
3054
+ pc += 2;
3055
+ if (val2 >= (uint32_t)s->capture_count)
3056
+ return LRE_RET_BYTECODE_ERROR;
3057
+ CHECK_STACK_SPACE(2 * (val2 - val + 1));
3058
+ while (val <= val2) {
3059
+ idx = 2 * val;
3060
+ SAVE_CAPTURE(idx, NULL);
3061
+ idx = 2 * val + 1;
3062
+ SAVE_CAPTURE(idx, NULL);
3063
+ val++;
3064
+ }
3065
+ }
3066
+ break;
3067
+ case REOP_set_i32:
3068
+ idx = 2 * s->capture_count + pc[0];
3069
+ val = get_u32(pc + 1);
3070
+ pc += 5;
3071
+ SAVE_CAPTURE_CHECK(idx, (void *)(uintptr_t)val);
3072
+ break;
3073
+ case REOP_loop:
3074
+ {
3075
+ uint32_t val2;
3076
+ idx = 2 * s->capture_count + pc[0];
3077
+ val = get_u32(pc + 1);
3078
+ pc += 5;
3079
+
3080
+ val2 = (uintptr_t)capture[idx] - 1;
3081
+ SAVE_CAPTURE_CHECK(idx, (void *)(uintptr_t)val2);
3082
+ if (val2 != 0) {
3083
+ pc += (int)val;
3084
+ if (lre_poll_timeout(s))
3085
+ return LRE_RET_TIMEOUT;
3086
+ }
3087
+ }
3088
+ break;
3089
+ case REOP_loop_split_goto_first:
3090
+ case REOP_loop_split_next_first:
3091
+ case REOP_loop_check_adv_split_goto_first:
3092
+ case REOP_loop_check_adv_split_next_first:
3093
+ {
3094
+ const uint8_t *pc1;
3095
+ uint32_t val2, limit;
3096
+ idx = 2 * s->capture_count + pc[0];
3097
+ limit = get_u32(pc + 1);
3098
+ val = get_u32(pc + 5);
3099
+ pc += 9;
3100
+
3101
+ /* decrement the counter */
3102
+ val2 = (uintptr_t)capture[idx] - 1;
3103
+ SAVE_CAPTURE_CHECK(idx, (void *)(uintptr_t)val2);
3104
+
3105
+ if (val2 > limit) {
3106
+ /* normal loop if counter > limit */
3107
+ pc += (int)val;
3108
+ if (lre_poll_timeout(s))
3109
+ return LRE_RET_TIMEOUT;
3110
+ } else {
3111
+ /* check advance */
3112
+ if ((opcode == REOP_loop_check_adv_split_goto_first ||
3113
+ opcode == REOP_loop_check_adv_split_next_first) &&
3114
+ capture[idx + 1] == cptr &&
3115
+ val2 != limit) {
3116
+ goto no_match;
3117
+ }
3118
+
3119
+ /* otherwise conditional split */
3120
+ if (val2 != 0) {
3121
+ if (opcode == REOP_loop_split_next_first ||
3122
+ opcode == REOP_loop_check_adv_split_next_first) {
3123
+ pc1 = pc + (int)val;
3124
+ } else {
3125
+ pc1 = pc;
3126
+ pc = pc + (int)val;
3127
+ }
3128
+ CHECK_STACK_SPACE(3);
3129
+ sp[0].ptr = (uint8_t *)pc1;
3130
+ sp[1].ptr = (uint8_t *)cptr;
3131
+ sp[2].bp.val = bp - s->stack_buf;
3132
+ sp[2].bp.type = RE_EXEC_STATE_SPLIT;
3133
+ sp += 3;
3134
+ bp = sp;
3135
+ }
3136
+ }
3137
+ }
3138
+ break;
3139
+ case REOP_set_char_pos:
3140
+ idx = 2 * s->capture_count + pc[0];
3141
+ pc++;
3142
+ SAVE_CAPTURE_CHECK(idx, (uint8_t *)cptr);
3143
+ break;
3144
+ case REOP_check_advance:
3145
+ idx = 2 * s->capture_count + pc[0];
3146
+ pc++;
3147
+ if (capture[idx] == cptr)
3148
+ goto no_match;
3149
+ break;
3150
+ case REOP_word_boundary:
3151
+ case REOP_word_boundary_i:
3152
+ case REOP_not_word_boundary:
3153
+ case REOP_not_word_boundary_i:
3154
+ {
3155
+ bool v1, v2;
3156
+ int ignore_case = (opcode == REOP_word_boundary_i || opcode == REOP_not_word_boundary_i);
3157
+ bool is_boundary = (opcode == REOP_word_boundary || opcode == REOP_word_boundary_i);
3158
+ /* char before */
3159
+ if (cptr == s->cbuf) {
3160
+ v1 = false;
3161
+ } else {
3162
+ PEEK_PREV_CHAR(c, cptr, s->cbuf, cbuf_type);
3163
+ if (c < 256) {
3164
+ v1 = (lre_is_word_byte(c) != 0);
3165
+ } else {
3166
+ v1 = ignore_case && (c == 0x017f || c == 0x212a);
3167
+ }
3168
+ }
3169
+ /* current char */
3170
+ if (cptr >= cbuf_end) {
3171
+ v2 = false;
3172
+ } else {
3173
+ PEEK_CHAR(c, cptr, cbuf_end, cbuf_type);
3174
+ if (c < 256) {
3175
+ v2 = (lre_is_word_byte(c) != 0);
3176
+ } else {
3177
+ v2 = ignore_case && (c == 0x017f || c == 0x212a);
3178
+ }
3179
+ }
3180
+ if (v1 ^ v2 ^ is_boundary)
3181
+ goto no_match;
3182
+ }
3183
+ break;
3184
+ case REOP_back_reference:
3185
+ case REOP_back_reference_i:
3186
+ case REOP_backward_back_reference:
3187
+ case REOP_backward_back_reference_i:
3188
+ {
3189
+ const uint8_t *cptr1, *cptr1_end, *cptr1_start;
3190
+ const uint8_t *pc1;
3191
+ uint32_t c1, c2;
3192
+ int i, n;
3193
+
3194
+ n = *pc++;
3195
+ pc1 = pc;
3196
+ pc += n;
3197
+
3198
+ for(i = 0; i < n; i++) {
3199
+ val = pc1[i];
3200
+ if (val >= s->capture_count)
3201
+ goto no_match;
3202
+ cptr1_start = capture[2 * val];
3203
+ cptr1_end = capture[2 * val + 1];
3204
+ /* test the first not empty capture */
3205
+ if (cptr1_start && cptr1_end) {
3206
+ if (opcode == REOP_back_reference ||
3207
+ opcode == REOP_back_reference_i) {
3208
+ cptr1 = cptr1_start;
3209
+ while (cptr1 < cptr1_end) {
3210
+ if (cptr >= cbuf_end)
3211
+ goto no_match;
3212
+ GET_CHAR(c1, cptr1, cptr1_end, cbuf_type);
3213
+ GET_CHAR(c2, cptr, cbuf_end, cbuf_type);
3214
+ if (opcode == REOP_back_reference_i) {
3215
+ c1 = lre_canonicalize(c1, s->is_unicode);
3216
+ c2 = lre_canonicalize(c2, s->is_unicode);
3217
+ }
3218
+ if (c1 != c2)
3219
+ goto no_match;
3220
+ }
3221
+ } else {
3222
+ cptr1 = cptr1_end;
3223
+ while (cptr1 > cptr1_start) {
3224
+ if (cptr == s->cbuf)
3225
+ goto no_match;
3226
+ GET_PREV_CHAR(c1, cptr1, cptr1_start, cbuf_type);
3227
+ GET_PREV_CHAR(c2, cptr, s->cbuf, cbuf_type);
3228
+ if (opcode == REOP_backward_back_reference_i) {
3229
+ c1 = lre_canonicalize(c1, s->is_unicode);
3230
+ c2 = lre_canonicalize(c2, s->is_unicode);
3231
+ }
3232
+ if (c1 != c2)
3233
+ goto no_match;
3234
+ }
3235
+ }
3236
+ break;
3237
+ }
3238
+ }
3239
+ }
3240
+ break;
3241
+ case REOP_range:
3242
+ case REOP_range_i:
3243
+ {
3244
+ int n;
3245
+ uint32_t low, high, idx_min, idx_max, idx;
3246
+
3247
+ n = get_u16(pc); /* n must be >= 1 */
3248
+ pc += 2;
3249
+ if (cptr >= cbuf_end)
3250
+ goto no_match;
3251
+ GET_CHAR(c, cptr, cbuf_end, cbuf_type);
3252
+ if (opcode == REOP_range_i) {
3253
+ c = lre_canonicalize(c, s->is_unicode);
3254
+ }
3255
+ idx_min = 0;
3256
+ low = get_u16(pc + 0 * 4);
3257
+ if (c < low)
3258
+ goto no_match;
3259
+ idx_max = n - 1;
3260
+ high = get_u16(pc + idx_max * 4 + 2);
3261
+ /* 0xffff in for last value means +infinity */
3262
+ if (unlikely(c >= 0xffff) && high == 0xffff)
3263
+ goto range_match;
3264
+ if (c > high)
3265
+ goto no_match;
3266
+ while (idx_min <= idx_max) {
3267
+ idx = (idx_min + idx_max) / 2;
3268
+ low = get_u16(pc + idx * 4);
3269
+ high = get_u16(pc + idx * 4 + 2);
3270
+ if (c < low)
3271
+ idx_max = idx - 1;
3272
+ else if (c > high)
3273
+ idx_min = idx + 1;
3274
+ else
3275
+ goto range_match;
3276
+ }
3277
+ goto no_match;
3278
+ range_match:
3279
+ pc += 4 * n;
3280
+ }
3281
+ break;
3282
+ case REOP_range32:
3283
+ case REOP_range32_i:
3284
+ {
3285
+ int n;
3286
+ uint32_t low, high, idx_min, idx_max, idx;
3287
+
3288
+ n = get_u16(pc); /* n must be >= 1 */
3289
+ pc += 2;
3290
+ if (cptr >= cbuf_end)
3291
+ goto no_match;
3292
+ GET_CHAR(c, cptr, cbuf_end, cbuf_type);
3293
+ if (opcode == REOP_range32_i) {
3294
+ c = lre_canonicalize(c, s->is_unicode);
3295
+ }
3296
+ idx_min = 0;
3297
+ low = get_u32(pc + 0 * 8);
3298
+ if (c < low)
3299
+ goto no_match;
3300
+ idx_max = n - 1;
3301
+ high = get_u32(pc + idx_max * 8 + 4);
3302
+ if (c > high)
3303
+ goto no_match;
3304
+ while (idx_min <= idx_max) {
3305
+ idx = (idx_min + idx_max) / 2;
3306
+ low = get_u32(pc + idx * 8);
3307
+ high = get_u32(pc + idx * 8 + 4);
3308
+ if (c < low)
3309
+ idx_max = idx - 1;
3310
+ else if (c > high)
3311
+ idx_min = idx + 1;
3312
+ else
3313
+ goto range32_match;
3314
+ }
3315
+ goto no_match;
3316
+ range32_match:
3317
+ pc += 8 * n;
3318
+ }
3319
+ break;
3320
+ case REOP_prev:
3321
+ /* go to the previous char */
3322
+ if (cptr == s->cbuf)
3323
+ goto no_match;
3324
+ PREV_CHAR(cptr, s->cbuf, cbuf_type);
3325
+ break;
3326
+ default:
3327
+ #ifdef DUMP_EXEC
3328
+ printf("unknown opcode pc=%ld\n", pc - 1 - pc_start);
3329
+ #endif
3330
+ abort();
3331
+ }
3332
+ }
3333
+ }
3334
+
3335
+ /* Return 1 if match, 0 if not match or < 0 if error (see LRE_RET_x). cindex is the
3336
+ starting position of the match and must be such as 0 <= cindex <=
3337
+ clen. */
3338
+ int lre_exec(uint8_t **capture,
3339
+ const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen,
3340
+ int cbuf_type, void *opaque)
3341
+ {
3342
+ REExecContext s_s, *s = &s_s;
3343
+ int re_flags, i, ret;
3344
+ const uint8_t *cptr;
3345
+
3346
+ re_flags = lre_get_flags(bc_buf);
3347
+ s->is_unicode = (re_flags & (LRE_FLAG_UNICODE | LRE_FLAG_UNICODE_SETS)) != 0;
3348
+ s->capture_count = bc_buf[RE_HEADER_CAPTURE_COUNT];
3349
+ s->cbuf = cbuf;
3350
+ s->cbuf_end = cbuf + (clen << cbuf_type);
3351
+ s->cbuf_type = cbuf_type;
3352
+ if (s->cbuf_type == 1 && s->is_unicode)
3353
+ s->cbuf_type = 2;
3354
+ s->interrupt_counter = INTERRUPT_COUNTER_INIT;
3355
+ s->opaque = opaque;
3356
+
3357
+ s->stack_buf = s->static_stack_buf;
3358
+ s->stack_size = countof(s->static_stack_buf);
3359
+
3360
+ for(i = 0; i < s->capture_count * 2; i++)
3361
+ capture[i] = NULL;
3362
+
3363
+ cptr = cbuf + (cindex << cbuf_type);
3364
+ if (0 < cindex && cindex < clen && s->cbuf_type == 2) {
3365
+ const uint16_t *p = (const uint16_t *)cptr;
3366
+ if (is_lo_surrogate(*p) && is_hi_surrogate(p[-1])) {
3367
+ cptr = (const uint8_t *)(p - 1);
3368
+ }
3369
+ }
3370
+
3371
+ ret = lre_exec_backtrack(s, capture, bc_buf + RE_HEADER_LEN, cptr);
3372
+
3373
+ if (s->stack_buf != s->static_stack_buf)
3374
+ lre_realloc(s->opaque, s->stack_buf, 0);
3375
+ return ret;
3376
+ }
3377
+
3378
+ int lre_get_alloc_count(const uint8_t *bc_buf)
3379
+ {
3380
+ return bc_buf[RE_HEADER_CAPTURE_COUNT] * 2 +
3381
+ bc_buf[RE_HEADER_REGISTER_COUNT];
3382
+ }
3383
+
3384
+ /* Structurally validate serialized regexp bytecode (e.g. from JS_ReadObject)
3385
+ before it is executed: a present header and a body length that fits within
3386
+ the buffer. Returns 0 on success, -1 if the bytecode is malformed. */
3387
+ int lre_check_bytecode(const uint8_t *bc_buf, int bc_buf_len)
3388
+ {
3389
+ uint32_t re_bytecode_len;
3390
+ if (bc_buf_len < RE_HEADER_LEN)
3391
+ return -1;
3392
+ re_bytecode_len = get_u32(bc_buf + RE_HEADER_BYTECODE_LEN);
3393
+ if (re_bytecode_len > (uint32_t)(bc_buf_len - RE_HEADER_LEN))
3394
+ return -1;
3395
+ return 0;
3396
+ }
3397
+
3398
+ int lre_get_capture_count(const uint8_t *bc_buf)
3399
+ {
3400
+ return bc_buf[RE_HEADER_CAPTURE_COUNT];
3401
+ }
3402
+
3403
+ int lre_get_flags(const uint8_t *bc_buf)
3404
+ {
3405
+ return get_u16(bc_buf + RE_HEADER_FLAGS);
3406
+ }
3407
+
3408
+ /* Return NULL if no group names. Otherwise, return a pointer to
3409
+ 'capture_count - 1' zero terminated UTF-8 strings. */
3410
+ const char *lre_get_groupnames(const uint8_t *bc_buf)
3411
+ {
3412
+ uint32_t re_bytecode_len;
3413
+ if ((lre_get_flags(bc_buf) & LRE_FLAG_NAMED_GROUPS) == 0)
3414
+ return NULL;
3415
+ re_bytecode_len = get_u32(bc_buf + RE_HEADER_BYTECODE_LEN);
3416
+ return (const char *)(bc_buf + RE_HEADER_LEN + re_bytecode_len);
3417
+ }
3418
+
3419
+ #ifdef TEST
3420
+
3421
+ bool lre_check_stack_overflow(void *opaque, size_t alloca_size)
3422
+ {
3423
+ return false;
3424
+ }
3425
+
3426
+ void *lre_realloc(void *opaque, void *ptr, size_t size)
3427
+ {
3428
+ return realloc(ptr, size);
3429
+ }
3430
+
3431
+ int main(int argc, char **argv)
3432
+ {
3433
+ int len, flags, ret, i;
3434
+ uint8_t *bc;
3435
+ char error_msg[64];
3436
+ uint8_t *capture;
3437
+ const char *input;
3438
+ int input_len, capture_count;
3439
+
3440
+ if (argc < 4) {
3441
+ printf("usage: %s regexp flags input\n", argv[0]);
3442
+ return 1;
3443
+ }
3444
+ flags = atoi(argv[2]);
3445
+ bc = lre_compile(&len, error_msg, sizeof(error_msg), argv[1],
3446
+ strlen(argv[1]), flags, NULL);
3447
+ if (!bc) {
3448
+ fprintf(stderr, "error: %s\n", error_msg);
3449
+ exit(1);
3450
+ }
3451
+
3452
+ input = argv[3];
3453
+ input_len = strlen(input);
3454
+
3455
+ capture = malloc(sizeof(capture[0]) * lre_get_alloc_count(bc));
3456
+ ret = lre_exec(capture, bc, (uint8_t *)input, 0, input_len, 0, NULL);
3457
+ printf("ret=%d\n", ret);
3458
+ if (ret == 1) {
3459
+ capture_count = lre_get_capture_count(bc);
3460
+ for(i = 0; i < 2 * capture_count; i++) {
3461
+ uint8_t *ptr;
3462
+ ptr = capture[i];
3463
+ printf("%d: ", i);
3464
+ if (!ptr)
3465
+ printf("<nil>");
3466
+ else
3467
+ printf("%u", (int)(ptr - (uint8_t *)input));
3468
+ printf("\n");
3469
+ }
3470
+ }
3471
+ free(capture);
3472
+ return 0;
3473
+ }
3474
+ #endif