@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.
- package/LICENSE +202 -0
- package/package.json +16 -6
- package/src/scr_array.c +488 -0
- package/src/scr_assert.c +1393 -0
- package/src/scr_async.c +2593 -0
- package/src/scr_async_dyn.c +607 -0
- package/src/scr_bytes.c +1425 -0
- package/src/scr_bytes_io.c +161 -0
- package/src/scr_child.c +3587 -0
- package/src/scr_closure.c +214 -0
- package/src/scr_console.c +143 -0
- package/src/scr_cycle.c +218 -0
- package/src/scr_dc.c +805 -0
- package/src/scr_dgram.c +1007 -0
- package/src/scr_dyn_handle.c +154 -0
- package/src/scr_dyn_invoke.c +644 -0
- package/src/scr_error.c +332 -0
- package/src/scr_events.c +714 -0
- package/src/scr_events_emitter.c +699 -0
- package/src/scr_exception.c +242 -0
- package/src/scr_fetch.c +1130 -0
- package/src/scr_fetch_curl.c +654 -0
- package/src/scr_http.c +3482 -0
- package/src/scr_http2.c +3030 -0
- package/src/scr_inspect.c +803 -0
- package/src/scr_inspect_island.c +51 -0
- package/src/scr_island.c +9363 -0
- package/src/scr_json.c +2151 -0
- package/src/scr_lib.c +3612 -0
- package/src/scr_loop_epoll.c +241 -0
- package/src/scr_loop_kqueue.c +121 -0
- package/src/scr_loop_wsapoll.c +208 -0
- package/src/scr_map.c +591 -0
- package/src/scr_net.c +3017 -0
- package/src/scr_net_island.c +458 -0
- package/src/scr_number.c +115 -0
- package/src/scr_object.c +25 -0
- package/src/scr_path.c +1266 -0
- package/src/scr_platform.h +119 -0
- package/src/scr_readline.c +287 -0
- package/src/scr_regex.c +1080 -0
- package/src/scr_runtime.h +5046 -0
- package/src/scr_stream.c +2877 -0
- package/src/scr_string.c +1264 -0
- package/src/scr_symbol.c +132 -0
- package/src/scr_test.c +662 -0
- package/src/scr_tls.c +1520 -0
- package/src/scr_union.c +105 -0
- package/src/scr_url.c +911 -0
- package/src/scr_url_internal.h +29 -0
- package/src/scr_url_params.c +561 -0
- package/src/scr_watch.c +568 -0
- package/src/scr_web.c +1778 -0
- package/src/scr_win.c +76 -0
- package/src/scr_zlib.c +197 -0
- package/src/scr_zlib_island.c +15 -0
- package/vendor/README.md +52 -0
- package/vendor/curl/COPYRIGHT +534 -0
- package/vendor/curl/include/curl/curl.h +3214 -0
- package/vendor/curl/include/curl/curlver.h +79 -0
- package/vendor/curl/include/curl/easy.h +125 -0
- package/vendor/curl/include/curl/header.h +74 -0
- package/vendor/curl/include/curl/mprintf.h +52 -0
- package/vendor/curl/include/curl/multi.h +460 -0
- package/vendor/curl/include/curl/options.h +70 -0
- package/vendor/curl/include/curl/stdcheaders.h +35 -0
- package/vendor/curl/include/curl/system.h +508 -0
- package/vendor/curl/include/curl/typecheck-gcc.h +716 -0
- package/vendor/curl/include/curl/urlapi.h +149 -0
- package/vendor/curl/include/curl/websockets.h +84 -0
- package/vendor/mbedtls/LICENSE +553 -0
- package/vendor/mbedtls/include/CMakeLists.txt +22 -0
- package/vendor/mbedtls/include/mbedtls/aes.h +631 -0
- package/vendor/mbedtls/include/mbedtls/aria.h +343 -0
- package/vendor/mbedtls/include/mbedtls/asn1.h +642 -0
- package/vendor/mbedtls/include/mbedtls/asn1write.h +390 -0
- package/vendor/mbedtls/include/mbedtls/base64.h +82 -0
- package/vendor/mbedtls/include/mbedtls/bignum.h +1088 -0
- package/vendor/mbedtls/include/mbedtls/block_cipher.h +76 -0
- package/vendor/mbedtls/include/mbedtls/build_info.h +194 -0
- package/vendor/mbedtls/include/mbedtls/camellia.h +305 -0
- package/vendor/mbedtls/include/mbedtls/ccm.h +526 -0
- package/vendor/mbedtls/include/mbedtls/chacha20.h +209 -0
- package/vendor/mbedtls/include/mbedtls/chachapoly.h +351 -0
- package/vendor/mbedtls/include/mbedtls/check_config.h +1149 -0
- package/vendor/mbedtls/include/mbedtls/cipher.h +1250 -0
- package/vendor/mbedtls/include/mbedtls/cmac.h +246 -0
- package/vendor/mbedtls/include/mbedtls/compat-2.x.h +46 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h +578 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_legacy_from_psa.h +873 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_psa_from_legacy.h +359 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_psa_superset_legacy.h +145 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_ssl.h +91 -0
- package/vendor/mbedtls/include/mbedtls/config_adjust_x509.h +35 -0
- package/vendor/mbedtls/include/mbedtls/config_psa.h +61 -0
- package/vendor/mbedtls/include/mbedtls/constant_time.h +36 -0
- package/vendor/mbedtls/include/mbedtls/ctr_drbg.h +596 -0
- package/vendor/mbedtls/include/mbedtls/debug.h +156 -0
- package/vendor/mbedtls/include/mbedtls/des.h +385 -0
- package/vendor/mbedtls/include/mbedtls/dhm.h +972 -0
- package/vendor/mbedtls/include/mbedtls/ecdh.h +455 -0
- package/vendor/mbedtls/include/mbedtls/ecdsa.h +674 -0
- package/vendor/mbedtls/include/mbedtls/ecjpake.h +298 -0
- package/vendor/mbedtls/include/mbedtls/ecp.h +1517 -0
- package/vendor/mbedtls/include/mbedtls/entropy.h +274 -0
- package/vendor/mbedtls/include/mbedtls/error.h +201 -0
- package/vendor/mbedtls/include/mbedtls/gcm.h +387 -0
- package/vendor/mbedtls/include/mbedtls/hkdf.h +124 -0
- package/vendor/mbedtls/include/mbedtls/hmac_drbg.h +434 -0
- package/vendor/mbedtls/include/mbedtls/lms.h +440 -0
- package/vendor/mbedtls/include/mbedtls/mbedtls_config.h +4446 -0
- package/vendor/mbedtls/include/mbedtls/md.h +526 -0
- package/vendor/mbedtls/include/mbedtls/md5.h +190 -0
- package/vendor/mbedtls/include/mbedtls/memory_buffer_alloc.h +142 -0
- package/vendor/mbedtls/include/mbedtls/net_sockets.h +299 -0
- package/vendor/mbedtls/include/mbedtls/nist_kw.h +166 -0
- package/vendor/mbedtls/include/mbedtls/oid.h +727 -0
- package/vendor/mbedtls/include/mbedtls/pem.h +160 -0
- package/vendor/mbedtls/include/mbedtls/pk.h +1303 -0
- package/vendor/mbedtls/include/mbedtls/pkcs12.h +186 -0
- package/vendor/mbedtls/include/mbedtls/pkcs5.h +198 -0
- package/vendor/mbedtls/include/mbedtls/pkcs7.h +252 -0
- package/vendor/mbedtls/include/mbedtls/platform.h +516 -0
- package/vendor/mbedtls/include/mbedtls/platform_time.h +79 -0
- package/vendor/mbedtls/include/mbedtls/platform_util.h +247 -0
- package/vendor/mbedtls/include/mbedtls/poly1305.h +168 -0
- package/vendor/mbedtls/include/mbedtls/private_access.h +20 -0
- package/vendor/mbedtls/include/mbedtls/psa_util.h +207 -0
- package/vendor/mbedtls/include/mbedtls/ripemd160.h +136 -0
- package/vendor/mbedtls/include/mbedtls/rsa.h +1170 -0
- package/vendor/mbedtls/include/mbedtls/sha1.h +219 -0
- package/vendor/mbedtls/include/mbedtls/sha256.h +200 -0
- package/vendor/mbedtls/include/mbedtls/sha3.h +172 -0
- package/vendor/mbedtls/include/mbedtls/sha512.h +208 -0
- package/vendor/mbedtls/include/mbedtls/ssl.h +5887 -0
- package/vendor/mbedtls/include/mbedtls/ssl_cache.h +187 -0
- package/vendor/mbedtls/include/mbedtls/ssl_ciphersuites.h +482 -0
- package/vendor/mbedtls/include/mbedtls/ssl_cookie.h +106 -0
- package/vendor/mbedtls/include/mbedtls/ssl_ticket.h +199 -0
- package/vendor/mbedtls/include/mbedtls/threading.h +167 -0
- package/vendor/mbedtls/include/mbedtls/timing.h +94 -0
- package/vendor/mbedtls/include/mbedtls/version.h +78 -0
- package/vendor/mbedtls/include/mbedtls/x509.h +500 -0
- package/vendor/mbedtls/include/mbedtls/x509_crl.h +184 -0
- package/vendor/mbedtls/include/mbedtls/x509_crt.h +1208 -0
- package/vendor/mbedtls/include/mbedtls/x509_csr.h +382 -0
- package/vendor/mbedtls/include/psa/build_info.h +20 -0
- package/vendor/mbedtls/include/psa/crypto.h +4998 -0
- package/vendor/mbedtls/include/psa/crypto_adjust_auto_enabled.h +31 -0
- package/vendor/mbedtls/include/psa/crypto_adjust_config_dependencies.h +51 -0
- package/vendor/mbedtls/include/psa/crypto_adjust_config_key_pair_types.h +101 -0
- package/vendor/mbedtls/include/psa/crypto_adjust_config_synonyms.h +49 -0
- package/vendor/mbedtls/include/psa/crypto_builtin_composites.h +214 -0
- package/vendor/mbedtls/include/psa/crypto_builtin_key_derivation.h +118 -0
- package/vendor/mbedtls/include/psa/crypto_builtin_primitives.h +114 -0
- package/vendor/mbedtls/include/psa/crypto_compat.h +230 -0
- package/vendor/mbedtls/include/psa/crypto_config.h +145 -0
- package/vendor/mbedtls/include/psa/crypto_driver_common.h +44 -0
- package/vendor/mbedtls/include/psa/crypto_driver_contexts_composites.h +151 -0
- package/vendor/mbedtls/include/psa/crypto_driver_contexts_key_derivation.h +52 -0
- package/vendor/mbedtls/include/psa/crypto_driver_contexts_primitives.h +105 -0
- package/vendor/mbedtls/include/psa/crypto_extra.h +2145 -0
- package/vendor/mbedtls/include/psa/crypto_legacy.h +88 -0
- package/vendor/mbedtls/include/psa/crypto_platform.h +102 -0
- package/vendor/mbedtls/include/psa/crypto_se_driver.h +1383 -0
- package/vendor/mbedtls/include/psa/crypto_sizes.h +1319 -0
- package/vendor/mbedtls/include/psa/crypto_struct.h +527 -0
- package/vendor/mbedtls/include/psa/crypto_types.h +508 -0
- package/vendor/mbedtls/include/psa/crypto_values.h +2782 -0
- package/vendor/mbedtls/library/aes.c +2294 -0
- package/vendor/mbedtls/library/aesce.c +624 -0
- package/vendor/mbedtls/library/aesce.h +136 -0
- package/vendor/mbedtls/library/aesni.c +846 -0
- package/vendor/mbedtls/library/aesni.h +162 -0
- package/vendor/mbedtls/library/alignment.h +704 -0
- package/vendor/mbedtls/library/aria.c +969 -0
- package/vendor/mbedtls/library/asn1parse.c +468 -0
- package/vendor/mbedtls/library/asn1write.c +440 -0
- package/vendor/mbedtls/library/base64.c +322 -0
- package/vendor/mbedtls/library/base64_internal.h +45 -0
- package/vendor/mbedtls/library/bignum.c +2583 -0
- package/vendor/mbedtls/library/bignum_core.c +1240 -0
- package/vendor/mbedtls/library/bignum_core.h +872 -0
- package/vendor/mbedtls/library/bignum_core_invasive.h +38 -0
- package/vendor/mbedtls/library/bignum_internal.h +122 -0
- package/vendor/mbedtls/library/bignum_mod.c +394 -0
- package/vendor/mbedtls/library/bignum_mod.h +452 -0
- package/vendor/mbedtls/library/bignum_mod_raw.c +276 -0
- package/vendor/mbedtls/library/bignum_mod_raw.h +416 -0
- package/vendor/mbedtls/library/bignum_mod_raw_invasive.h +34 -0
- package/vendor/mbedtls/library/block_cipher.c +207 -0
- package/vendor/mbedtls/library/block_cipher_internal.h +99 -0
- package/vendor/mbedtls/library/bn_mul.h +1094 -0
- package/vendor/mbedtls/library/camellia.c +1058 -0
- package/vendor/mbedtls/library/ccm.c +777 -0
- package/vendor/mbedtls/library/chacha20.c +563 -0
- package/vendor/mbedtls/library/chacha20_internal.h +23 -0
- package/vendor/mbedtls/library/chachapoly.c +487 -0
- package/vendor/mbedtls/library/check_crypto_config.h +136 -0
- package/vendor/mbedtls/library/cipher.c +1712 -0
- package/vendor/mbedtls/library/cipher_invasive.h +28 -0
- package/vendor/mbedtls/library/cipher_wrap.c +2482 -0
- package/vendor/mbedtls/library/cipher_wrap.h +178 -0
- package/vendor/mbedtls/library/cmac.c +1067 -0
- package/vendor/mbedtls/library/common.h +487 -0
- package/vendor/mbedtls/library/constant_time.c +247 -0
- package/vendor/mbedtls/library/constant_time_impl.h +541 -0
- package/vendor/mbedtls/library/constant_time_internal.h +579 -0
- package/vendor/mbedtls/library/ctr.h +35 -0
- package/vendor/mbedtls/library/ctr_drbg.c +1016 -0
- package/vendor/mbedtls/library/debug.c +475 -0
- package/vendor/mbedtls/library/debug_internal.h +185 -0
- package/vendor/mbedtls/library/des.c +1042 -0
- package/vendor/mbedtls/library/dhm.c +700 -0
- package/vendor/mbedtls/library/ecdh.c +696 -0
- package/vendor/mbedtls/library/ecdsa.c +858 -0
- package/vendor/mbedtls/library/ecjpake.c +1216 -0
- package/vendor/mbedtls/library/ecp.c +3674 -0
- package/vendor/mbedtls/library/ecp_curves.c +6125 -0
- package/vendor/mbedtls/library/ecp_curves_new.c +9 -0
- package/vendor/mbedtls/library/ecp_internal_alt.h +287 -0
- package/vendor/mbedtls/library/ecp_invasive.h +305 -0
- package/vendor/mbedtls/library/entropy.c +680 -0
- package/vendor/mbedtls/library/entropy_poll.c +233 -0
- package/vendor/mbedtls/library/entropy_poll.h +64 -0
- package/vendor/mbedtls/library/error.c +878 -0
- package/vendor/mbedtls/library/gcm.c +1330 -0
- package/vendor/mbedtls/library/hkdf.c +161 -0
- package/vendor/mbedtls/library/hmac_drbg.c +633 -0
- package/vendor/mbedtls/library/lmots.c +789 -0
- package/vendor/mbedtls/library/lmots.h +288 -0
- package/vendor/mbedtls/library/lms.c +778 -0
- package/vendor/mbedtls/library/md.c +1108 -0
- package/vendor/mbedtls/library/md5.c +426 -0
- package/vendor/mbedtls/library/md_psa.h +26 -0
- package/vendor/mbedtls/library/md_wrap.h +46 -0
- package/vendor/mbedtls/library/memory_buffer_alloc.c +751 -0
- package/vendor/mbedtls/library/mps_common.h +181 -0
- package/vendor/mbedtls/library/mps_error.h +89 -0
- package/vendor/mbedtls/library/mps_reader.c +538 -0
- package/vendor/mbedtls/library/mps_reader.h +366 -0
- package/vendor/mbedtls/library/mps_trace.c +112 -0
- package/vendor/mbedtls/library/mps_trace.h +154 -0
- package/vendor/mbedtls/library/net_sockets.c +694 -0
- package/vendor/mbedtls/library/nist_kw.c +729 -0
- package/vendor/mbedtls/library/oid.c +1166 -0
- package/vendor/mbedtls/library/padlock.c +157 -0
- package/vendor/mbedtls/library/padlock.h +111 -0
- package/vendor/mbedtls/library/pem.c +554 -0
- package/vendor/mbedtls/library/pk.c +1602 -0
- package/vendor/mbedtls/library/pk_ecc.c +261 -0
- package/vendor/mbedtls/library/pk_internal.h +241 -0
- package/vendor/mbedtls/library/pk_wrap.c +1618 -0
- package/vendor/mbedtls/library/pk_wrap.h +138 -0
- package/vendor/mbedtls/library/pkcs12.c +437 -0
- package/vendor/mbedtls/library/pkcs5.c +500 -0
- package/vendor/mbedtls/library/pkcs7.c +787 -0
- package/vendor/mbedtls/library/pkparse.c +1392 -0
- package/vendor/mbedtls/library/pkwrite.c +631 -0
- package/vendor/mbedtls/library/pkwrite.h +121 -0
- package/vendor/mbedtls/library/platform.c +402 -0
- package/vendor/mbedtls/library/platform_util.c +258 -0
- package/vendor/mbedtls/library/poly1305.c +492 -0
- package/vendor/mbedtls/library/psa_crypto.c +9532 -0
- package/vendor/mbedtls/library/psa_crypto_aead.c +646 -0
- package/vendor/mbedtls/library/psa_crypto_aead.h +499 -0
- package/vendor/mbedtls/library/psa_crypto_cipher.c +747 -0
- package/vendor/mbedtls/library/psa_crypto_cipher.h +316 -0
- package/vendor/mbedtls/library/psa_crypto_client.c +22 -0
- package/vendor/mbedtls/library/psa_crypto_core.h +983 -0
- package/vendor/mbedtls/library/psa_crypto_core_common.h +52 -0
- package/vendor/mbedtls/library/psa_crypto_driver_wrappers.h +2896 -0
- package/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.c +256 -0
- package/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.h +31 -0
- package/vendor/mbedtls/library/psa_crypto_ecp.c +594 -0
- package/vendor/mbedtls/library/psa_crypto_ecp.h +267 -0
- package/vendor/mbedtls/library/psa_crypto_ffdh.c +361 -0
- package/vendor/mbedtls/library/psa_crypto_ffdh.h +131 -0
- package/vendor/mbedtls/library/psa_crypto_hash.c +470 -0
- package/vendor/mbedtls/library/psa_crypto_hash.h +211 -0
- package/vendor/mbedtls/library/psa_crypto_invasive.h +92 -0
- package/vendor/mbedtls/library/psa_crypto_its.h +131 -0
- package/vendor/mbedtls/library/psa_crypto_mac.c +505 -0
- package/vendor/mbedtls/library/psa_crypto_mac.h +264 -0
- package/vendor/mbedtls/library/psa_crypto_pake.c +571 -0
- package/vendor/mbedtls/library/psa_crypto_pake.h +159 -0
- package/vendor/mbedtls/library/psa_crypto_random.c +181 -0
- package/vendor/mbedtls/library/psa_crypto_random.h +72 -0
- package/vendor/mbedtls/library/psa_crypto_random_impl.h +200 -0
- package/vendor/mbedtls/library/psa_crypto_rsa.c +714 -0
- package/vendor/mbedtls/library/psa_crypto_rsa.h +321 -0
- package/vendor/mbedtls/library/psa_crypto_se.c +373 -0
- package/vendor/mbedtls/library/psa_crypto_se.h +192 -0
- package/vendor/mbedtls/library/psa_crypto_slot_management.c +1137 -0
- package/vendor/mbedtls/library/psa_crypto_slot_management.h +344 -0
- package/vendor/mbedtls/library/psa_crypto_storage.c +481 -0
- package/vendor/mbedtls/library/psa_crypto_storage.h +392 -0
- package/vendor/mbedtls/library/psa_its_file.c +254 -0
- package/vendor/mbedtls/library/psa_util.c +614 -0
- package/vendor/mbedtls/library/psa_util_internal.h +100 -0
- package/vendor/mbedtls/library/ripemd160.c +490 -0
- package/vendor/mbedtls/library/rsa.c +3121 -0
- package/vendor/mbedtls/library/rsa_alt_helpers.c +455 -0
- package/vendor/mbedtls/library/rsa_alt_helpers.h +209 -0
- package/vendor/mbedtls/library/rsa_internal.h +188 -0
- package/vendor/mbedtls/library/sha1.c +480 -0
- package/vendor/mbedtls/library/sha256.c +983 -0
- package/vendor/mbedtls/library/sha3.c +721 -0
- package/vendor/mbedtls/library/sha512.c +1115 -0
- package/vendor/mbedtls/library/ssl_cache.c +410 -0
- package/vendor/mbedtls/library/ssl_ciphersuites.c +2050 -0
- package/vendor/mbedtls/library/ssl_ciphersuites_internal.h +154 -0
- package/vendor/mbedtls/library/ssl_client.c +1023 -0
- package/vendor/mbedtls/library/ssl_client.h +22 -0
- package/vendor/mbedtls/library/ssl_cookie.c +384 -0
- package/vendor/mbedtls/library/ssl_debug_helpers.h +85 -0
- package/vendor/mbedtls/library/ssl_debug_helpers_generated.c +251 -0
- package/vendor/mbedtls/library/ssl_misc.h +3198 -0
- package/vendor/mbedtls/library/ssl_msg.c +6619 -0
- package/vendor/mbedtls/library/ssl_ticket.c +556 -0
- package/vendor/mbedtls/library/ssl_tls.c +10234 -0
- package/vendor/mbedtls/library/ssl_tls12_client.c +3688 -0
- package/vendor/mbedtls/library/ssl_tls12_server.c +4311 -0
- package/vendor/mbedtls/library/ssl_tls13_client.c +3208 -0
- package/vendor/mbedtls/library/ssl_tls13_generic.c +1793 -0
- package/vendor/mbedtls/library/ssl_tls13_invasive.h +23 -0
- package/vendor/mbedtls/library/ssl_tls13_keys.c +1918 -0
- package/vendor/mbedtls/library/ssl_tls13_keys.h +668 -0
- package/vendor/mbedtls/library/ssl_tls13_server.c +3624 -0
- package/vendor/mbedtls/library/threading.c +193 -0
- package/vendor/mbedtls/library/threading_internal.h +28 -0
- package/vendor/mbedtls/library/timing.c +152 -0
- package/vendor/mbedtls/library/version.c +32 -0
- package/vendor/mbedtls/library/version_features.c +856 -0
- package/vendor/mbedtls/library/x509.c +1776 -0
- package/vendor/mbedtls/library/x509_create.c +570 -0
- package/vendor/mbedtls/library/x509_crl.c +708 -0
- package/vendor/mbedtls/library/x509_crt.c +3311 -0
- package/vendor/mbedtls/library/x509_csr.c +648 -0
- package/vendor/mbedtls/library/x509_internal.h +101 -0
- package/vendor/mbedtls/library/x509write.c +174 -0
- package/vendor/mbedtls/library/x509write_crt.c +688 -0
- package/vendor/mbedtls/library/x509write_csr.c +336 -0
- package/vendor/quickjs-ng/CMakeLists.txt +566 -0
- package/vendor/quickjs-ng/LICENSE +24 -0
- package/vendor/quickjs-ng/README.md +24 -0
- package/vendor/quickjs-ng/api-test.c +1195 -0
- package/vendor/quickjs-ng/builtin-array-fromasync.h +119 -0
- package/vendor/quickjs-ng/builtin-iterator-zip-keyed.h +332 -0
- package/vendor/quickjs-ng/builtin-iterator-zip.h +337 -0
- package/vendor/quickjs-ng/cutils.h +1998 -0
- package/vendor/quickjs-ng/dtoa.c +1619 -0
- package/vendor/quickjs-ng/dtoa.h +87 -0
- package/vendor/quickjs-ng/gen/function_source.c +81 -0
- package/vendor/quickjs-ng/gen/hello.c +53 -0
- package/vendor/quickjs-ng/gen/hello_module.c +106 -0
- package/vendor/quickjs-ng/gen/repl.c +3036 -0
- package/vendor/quickjs-ng/gen/standalone.c +323 -0
- package/vendor/quickjs-ng/gen/test_fib.c +81 -0
- package/vendor/quickjs-ng/libregexp-opcode.h +73 -0
- package/vendor/quickjs-ng/libregexp.c +3474 -0
- package/vendor/quickjs-ng/libregexp.h +101 -0
- package/vendor/quickjs-ng/libunicode-table.h +5173 -0
- package/vendor/quickjs-ng/libunicode.c +2069 -0
- package/vendor/quickjs-ng/libunicode.h +172 -0
- package/vendor/quickjs-ng/list.h +107 -0
- package/vendor/quickjs-ng/lre-test.c +52 -0
- package/vendor/quickjs-ng/qjs.c +762 -0
- package/vendor/quickjs-ng/qjsc.c +673 -0
- package/vendor/quickjs-ng/quickjs-atom.h +280 -0
- package/vendor/quickjs-ng/quickjs-c-atomics.h +54 -0
- package/vendor/quickjs-ng/quickjs-libc.c +5037 -0
- package/vendor/quickjs-ng/quickjs-libc.h +87 -0
- package/vendor/quickjs-ng/quickjs-opcode.h +377 -0
- package/vendor/quickjs-ng/quickjs.c +64041 -0
- package/vendor/quickjs-ng/quickjs.h +1447 -0
- package/vendor/quickjs-ng/run-test262.c +2374 -0
- package/vendor/quickjs-ng/unicode_gen.c +3121 -0
- package/vendor/quickjs-ng/unicode_gen_def.h +310 -0
- package/vendor/ryu/LICENSE-Boost +23 -0
- package/vendor/ryu/common.h +114 -0
- package/vendor/ryu/d2s.c +509 -0
- package/vendor/ryu/d2s_full_table.h +367 -0
- package/vendor/ryu/d2s_intrinsics.h +357 -0
- package/vendor/ryu/d2s_small_table.h +186 -0
- package/vendor/ryu/digit_table.h +35 -0
- package/vendor/ryu/ryu.h +46 -0
- package/vendor/zlib/LICENSE +22 -0
- package/vendor/zlib/adler32.c +164 -0
- package/vendor/zlib/compress.c +75 -0
- package/vendor/zlib/crc32.c +1049 -0
- package/vendor/zlib/crc32.h +9446 -0
- package/vendor/zlib/deflate.c +2139 -0
- package/vendor/zlib/deflate.h +377 -0
- package/vendor/zlib/gzclose.c +23 -0
- package/vendor/zlib/gzguts.h +214 -0
- package/vendor/zlib/gzlib.c +582 -0
- package/vendor/zlib/gzread.c +602 -0
- package/vendor/zlib/gzwrite.c +631 -0
- package/vendor/zlib/infback.c +628 -0
- package/vendor/zlib/inffast.c +320 -0
- package/vendor/zlib/inffast.h +11 -0
- package/vendor/zlib/inffixed.h +94 -0
- package/vendor/zlib/inflate.c +1526 -0
- package/vendor/zlib/inflate.h +126 -0
- package/vendor/zlib/inftrees.c +299 -0
- package/vendor/zlib/inftrees.h +62 -0
- package/vendor/zlib/trees.c +1117 -0
- package/vendor/zlib/trees.h +128 -0
- package/vendor/zlib/uncompr.c +85 -0
- package/vendor/zlib/zconf.h +543 -0
- package/vendor/zlib/zlib.h +1938 -0
- package/vendor/zlib/zutil.c +299 -0
- package/vendor/zlib/zutil.h +254 -0
- package/README.md +0 -3
- package/index.js +0 -2
package/src/scr_url.c
ADDED
|
@@ -0,0 +1,911 @@
|
|
|
1
|
+
/* The WHATWG URL slice (scr_runtime.h has the API contract): an immutable,
|
|
2
|
+
* refcounted URL value parsed once at construction, plus the file-URL
|
|
3
|
+
* bridge pair (fileURLToPath / pathToFileURL).
|
|
4
|
+
*
|
|
5
|
+
* The parser covers the WHATWG algorithm's common ground exactly — pinned
|
|
6
|
+
* against Node by the differential corpus:
|
|
7
|
+
* - scheme lowercasing; "Invalid URL" TypeError on schemeless input
|
|
8
|
+
* - special schemes (http/https/ws/wss/ftp/file): authority parsing with
|
|
9
|
+
* host lowercasing, default-port removal (leading zeros stripped),
|
|
10
|
+
* backslash-as-slash, and any run of leading slashes tolerated
|
|
11
|
+
* (http:foo.com works); file: takes an authority only after exactly
|
|
12
|
+
* "//" (file:/x and file:x are host-less absolute paths, like Node)
|
|
13
|
+
* - dot-segment removal with %2e equivalence (case-insensitive), empty
|
|
14
|
+
* segments preserved (http://h//a stays //a)
|
|
15
|
+
* - percent-ENCODING of the WHATWG path/query/fragment/userinfo sets
|
|
16
|
+
* (space, quotes, angle brackets, braces, non-ASCII UTF-8 bytes, ...);
|
|
17
|
+
* existing %-sequences pass through verbatim (no decode, no case
|
|
18
|
+
* normalization — like Node)
|
|
19
|
+
* - non-special schemes: "//" parses an authority (host case preserved),
|
|
20
|
+
* a single "/" roots a normalized path, anything else is an OPAQUE
|
|
21
|
+
* path kept verbatim (data:text/plain,hi there)
|
|
22
|
+
*
|
|
23
|
+
* DOCUMENTED DIVERGENCES (SEMANTICS.md): non-ASCII and %-escaped hosts are
|
|
24
|
+
* rejected with "Invalid URL" (no IDNA/punycode), IPv6 hosts are rejected,
|
|
25
|
+
* and opaque paths skip the spec's C0-encode pass (kept verbatim).
|
|
26
|
+
*
|
|
27
|
+
* Failures THROW catchable TypeErrors through the exception cell with
|
|
28
|
+
* Node's messages; callers are compiler-emitted pending checks. */
|
|
29
|
+
#include "scr_runtime.h"
|
|
30
|
+
#include "scr_url_internal.h"
|
|
31
|
+
|
|
32
|
+
#include <stdio.h>
|
|
33
|
+
#include <stdlib.h>
|
|
34
|
+
#include <string.h>
|
|
35
|
+
#include <unistd.h>
|
|
36
|
+
|
|
37
|
+
ScrUrl *scr_url_retain(ScrUrl *u) {
|
|
38
|
+
if (u->rc != SIZE_MAX) u->rc++;
|
|
39
|
+
return u;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
void scr_url_release(ScrUrl *u) {
|
|
43
|
+
if (!u || u->rc == SIZE_MAX) return;
|
|
44
|
+
if (--u->rc == 0) {
|
|
45
|
+
scr_str_release(u->scheme);
|
|
46
|
+
scr_str_release(u->userinfo);
|
|
47
|
+
scr_str_release(u->host);
|
|
48
|
+
scr_str_release(u->port);
|
|
49
|
+
scr_str_release(u->path);
|
|
50
|
+
scr_str_release(u->query);
|
|
51
|
+
scr_str_release(u->fragment);
|
|
52
|
+
free(u);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
void *scr_url_retain_v(void *p) { return scr_url_retain(p); }
|
|
57
|
+
void scr_url_release_v(void *p) { scr_url_release(p); }
|
|
58
|
+
|
|
59
|
+
/* ── a tiny growable byte buffer (mirrors scr_path.c's) ──────────────── */
|
|
60
|
+
|
|
61
|
+
typedef struct {
|
|
62
|
+
char *data;
|
|
63
|
+
size_t len;
|
|
64
|
+
size_t cap;
|
|
65
|
+
} UrlBuf;
|
|
66
|
+
|
|
67
|
+
static void ub_init(UrlBuf *b) {
|
|
68
|
+
b->cap = 64;
|
|
69
|
+
b->len = 0;
|
|
70
|
+
b->data = malloc(b->cap);
|
|
71
|
+
if (!b->data) {
|
|
72
|
+
fputs("scriptc: out of memory\n", stderr);
|
|
73
|
+
abort();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static void ub_append(UrlBuf *b, const char *bytes, size_t n) {
|
|
78
|
+
if (b->len + n > b->cap) {
|
|
79
|
+
while (b->len + n > b->cap) b->cap *= 2;
|
|
80
|
+
char *grown = realloc(b->data, b->cap);
|
|
81
|
+
if (!grown) {
|
|
82
|
+
fputs("scriptc: out of memory\n", stderr);
|
|
83
|
+
abort();
|
|
84
|
+
}
|
|
85
|
+
b->data = grown;
|
|
86
|
+
}
|
|
87
|
+
memcpy(b->data + b->len, bytes, n);
|
|
88
|
+
b->len += n;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static void ub_push(UrlBuf *b, char c) { ub_append(b, &c, 1); }
|
|
92
|
+
|
|
93
|
+
static ScrStr *ub_take(UrlBuf *b) {
|
|
94
|
+
ScrStr *s = scr_str_new(b->data, b->len);
|
|
95
|
+
free(b->data);
|
|
96
|
+
return s;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* ── percent-encode sets (WHATWG) ────────────────────────────────────── */
|
|
100
|
+
|
|
101
|
+
static bool enc_always(unsigned char c) {
|
|
102
|
+
return c < 0x20 || c == 0x7f || c >= 0x80; /* C0, DEL, non-ASCII */
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static bool enc_fragment(unsigned char c) {
|
|
106
|
+
return enc_always(c) || c == ' ' || c == '"' || c == '<' || c == '>' || c == '`';
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
static bool enc_query(unsigned char c, bool special) {
|
|
110
|
+
return enc_always(c) || c == ' ' || c == '"' || c == '#' || c == '<' || c == '>' ||
|
|
111
|
+
(special && c == '\'');
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
static bool enc_path(unsigned char c) {
|
|
115
|
+
return enc_query(c, false) || c == '?' || c == '`' || c == '{' || c == '}';
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
static bool enc_userinfo(unsigned char c) {
|
|
119
|
+
return enc_path(c) || c == '/' || c == ':' || c == ';' || c == '=' || c == '@' ||
|
|
120
|
+
c == '[' || c == '\\' || c == ']' || c == '^' || c == '|';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
static void ub_push_encoded(UrlBuf *b, unsigned char c, bool (*needs)(unsigned char)) {
|
|
124
|
+
if (needs(c)) {
|
|
125
|
+
char hex[4];
|
|
126
|
+
snprintf(hex, sizeof hex, "%%%02X", c);
|
|
127
|
+
ub_append(b, hex, 3);
|
|
128
|
+
} else {
|
|
129
|
+
ub_push(b, (char)c);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/* ── parsing ─────────────────────────────────────────────────────────── */
|
|
134
|
+
|
|
135
|
+
static void scr_url_throw_invalid(void) {
|
|
136
|
+
scr_throw_error_msg(SCR_ERR_TYPE, "Invalid URL", 11);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
static bool is_special_scheme(const char *s, size_t len) {
|
|
140
|
+
static const char *specials[] = {"http", "https", "ws", "wss", "ftp", "file"};
|
|
141
|
+
for (size_t i = 0; i < 6; i++) {
|
|
142
|
+
if (strlen(specials[i]) == len && memcmp(specials[i], s, len) == 0) return true;
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* The scheme's default port as text, or NULL. */
|
|
148
|
+
static const char *default_port(const char *scheme, size_t len) {
|
|
149
|
+
if ((len == 4 && memcmp(scheme, "http", 4) == 0) || (len == 2 && memcmp(scheme, "ws", 2) == 0)) {
|
|
150
|
+
return "80";
|
|
151
|
+
}
|
|
152
|
+
if ((len == 5 && memcmp(scheme, "https", 5) == 0) || (len == 3 && memcmp(scheme, "wss", 3) == 0)) {
|
|
153
|
+
return "443";
|
|
154
|
+
}
|
|
155
|
+
if (len == 3 && memcmp(scheme, "ftp", 3) == 0) return "21";
|
|
156
|
+
return NULL;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static bool seg_is_dot(const char *s, size_t len) {
|
|
160
|
+
if (len == 1 && s[0] == '.') return true;
|
|
161
|
+
return len == 3 && s[0] == '%' && s[1] == '2' && (s[2] == 'e' || s[2] == 'E');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
static bool seg_is_dotdot(const char *s, size_t len) {
|
|
165
|
+
if (len == 2) return seg_is_dot(s, 1) && seg_is_dot(s + 1, 1);
|
|
166
|
+
if (len == 4) {
|
|
167
|
+
return (seg_is_dot(s, 1) && seg_is_dot(s + 1, 3)) || (seg_is_dot(s, 3) && seg_is_dot(s + 3, 1));
|
|
168
|
+
}
|
|
169
|
+
return len == 6 && seg_is_dot(s, 3) && seg_is_dot(s + 3, 3);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/* Rooted-path parse with WHATWG dot-segment handling: `raw` is everything
|
|
173
|
+
* after the authority (or after the scheme's slashes), '?'/'#' excluded.
|
|
174
|
+
* Backslashes act as slashes iff `special`. Output starts with '/' for
|
|
175
|
+
* every non-empty result; empty stays empty (git://host has path ""). */
|
|
176
|
+
static ScrStr *parse_rooted_path(const char *raw, size_t len, bool special) {
|
|
177
|
+
if (len == 0) return scr_str_new("", 0); /* no path at all (git://host) */
|
|
178
|
+
/* Collected segment list: one output buffer + an index of segment start
|
|
179
|
+
* offsets (popping a ".." truncates to the previous start). */
|
|
180
|
+
UrlBuf out;
|
|
181
|
+
ub_init(&out);
|
|
182
|
+
size_t seg_starts_cap = 8, seg_count = 0;
|
|
183
|
+
size_t *seg_starts = malloc(seg_starts_cap * sizeof(size_t));
|
|
184
|
+
if (!seg_starts) {
|
|
185
|
+
fputs("scriptc: out of memory\n", stderr);
|
|
186
|
+
abort();
|
|
187
|
+
}
|
|
188
|
+
size_t i = 0;
|
|
189
|
+
/* One leading separator opens the first segment (rooted). */
|
|
190
|
+
if (i < len && (raw[i] == '/' || (special && raw[i] == '\\'))) i++;
|
|
191
|
+
size_t seg_begin = i;
|
|
192
|
+
for (;; i++) {
|
|
193
|
+
bool at_end = i >= len;
|
|
194
|
+
bool is_sep = !at_end && (raw[i] == '/' || (special && raw[i] == '\\'));
|
|
195
|
+
if (!at_end && !is_sep) continue;
|
|
196
|
+
const char *seg = raw + seg_begin;
|
|
197
|
+
size_t seg_len = i - seg_begin;
|
|
198
|
+
if (seg_is_dotdot(seg, seg_len)) {
|
|
199
|
+
if (seg_count > 0) {
|
|
200
|
+
seg_count--;
|
|
201
|
+
out.len = seg_starts[seg_count];
|
|
202
|
+
}
|
|
203
|
+
if (at_end) {
|
|
204
|
+
/* Terminal "..": the popped directory's slot stays as an empty
|
|
205
|
+
* segment ("/a/.." → "/"). */
|
|
206
|
+
if (seg_count == seg_starts_cap) {
|
|
207
|
+
seg_starts_cap *= 2;
|
|
208
|
+
seg_starts = realloc(seg_starts, seg_starts_cap * sizeof(size_t));
|
|
209
|
+
if (!seg_starts) abort();
|
|
210
|
+
}
|
|
211
|
+
seg_starts[seg_count++] = out.len;
|
|
212
|
+
}
|
|
213
|
+
} else if (seg_is_dot(seg, seg_len)) {
|
|
214
|
+
if (at_end) {
|
|
215
|
+
if (seg_count == seg_starts_cap) {
|
|
216
|
+
seg_starts_cap *= 2;
|
|
217
|
+
seg_starts = realloc(seg_starts, seg_starts_cap * sizeof(size_t));
|
|
218
|
+
if (!seg_starts) abort();
|
|
219
|
+
}
|
|
220
|
+
seg_starts[seg_count++] = out.len;
|
|
221
|
+
}
|
|
222
|
+
} else {
|
|
223
|
+
if (seg_count == seg_starts_cap) {
|
|
224
|
+
seg_starts_cap *= 2;
|
|
225
|
+
seg_starts = realloc(seg_starts, seg_starts_cap * sizeof(size_t));
|
|
226
|
+
if (!seg_starts) {
|
|
227
|
+
fputs("scriptc: out of memory\n", stderr);
|
|
228
|
+
abort();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
seg_starts[seg_count++] = out.len;
|
|
232
|
+
for (size_t j = 0; j < seg_len; j++) {
|
|
233
|
+
ub_push_encoded(&out, (unsigned char)seg[j], enc_path);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (at_end) break;
|
|
237
|
+
seg_begin = i + 1;
|
|
238
|
+
}
|
|
239
|
+
/* Serialize: "/" + segment for each. */
|
|
240
|
+
UrlBuf ser;
|
|
241
|
+
ub_init(&ser);
|
|
242
|
+
for (size_t s = 0; s < seg_count; s++) {
|
|
243
|
+
size_t end = s + 1 < seg_count ? seg_starts[s + 1] : out.len;
|
|
244
|
+
ub_push(&ser, '/');
|
|
245
|
+
ub_append(&ser, out.data + seg_starts[s], end - seg_starts[s]);
|
|
246
|
+
}
|
|
247
|
+
free(out.data);
|
|
248
|
+
free(seg_starts);
|
|
249
|
+
return ub_take(&ser);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/* Parses `authority` (between the slashes and the path/query/fragment):
|
|
253
|
+
* [userinfo@]host[:port]. Returns false (throws) on invalid input. */
|
|
254
|
+
static bool parse_authority(const char *raw, size_t len, bool special, bool is_file,
|
|
255
|
+
const char *scheme, size_t scheme_len,
|
|
256
|
+
ScrStr **userinfo, ScrStr **host, ScrStr **port) {
|
|
257
|
+
/* Userinfo: up to the LAST '@'. */
|
|
258
|
+
long at = -1;
|
|
259
|
+
for (size_t i = 0; i < len; i++) {
|
|
260
|
+
if (raw[i] == '@') at = (long)i;
|
|
261
|
+
}
|
|
262
|
+
UrlBuf ub;
|
|
263
|
+
ub_init(&ub);
|
|
264
|
+
if (at >= 0) {
|
|
265
|
+
/* The FIRST ':' separates user from password and stays verbatim;
|
|
266
|
+
* every other byte encodes with the userinfo set. */
|
|
267
|
+
bool seen_colon = false;
|
|
268
|
+
for (long i = 0; i < at; i++) {
|
|
269
|
+
if (raw[i] == ':' && !seen_colon) {
|
|
270
|
+
seen_colon = true;
|
|
271
|
+
ub_push(&ub, ':');
|
|
272
|
+
} else {
|
|
273
|
+
ub_push_encoded(&ub, (unsigned char)raw[i], enc_userinfo);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
*userinfo = ub_take(&ub);
|
|
278
|
+
const char *hp = at >= 0 ? raw + at + 1 : raw;
|
|
279
|
+
size_t hp_len = at >= 0 ? len - (size_t)at - 1 : len;
|
|
280
|
+
/* host[:port] — no IPv6 ('[' rejected below). */
|
|
281
|
+
long colon = -1;
|
|
282
|
+
for (size_t i = 0; i < hp_len; i++) {
|
|
283
|
+
if (hp[i] == ':') colon = (long)i;
|
|
284
|
+
}
|
|
285
|
+
size_t host_len = colon >= 0 ? (size_t)colon : hp_len;
|
|
286
|
+
/* Validate + lowercase (special) the host. Divergence: non-ASCII and
|
|
287
|
+
* %-escapes (IDNA territory) and IPv6 are rejected outright. */
|
|
288
|
+
UrlBuf hb;
|
|
289
|
+
ub_init(&hb);
|
|
290
|
+
for (size_t i = 0; i < host_len; i++) {
|
|
291
|
+
unsigned char c = (unsigned char)hp[i];
|
|
292
|
+
if (c >= 0x80 || c == '%' || c == '[' || c == ']' || c <= 0x20 || c == '#' || c == '/' ||
|
|
293
|
+
c == '<' || c == '>' || c == '?' || c == '@' || c == '\\' || c == '^' || c == '|') {
|
|
294
|
+
free(hb.data);
|
|
295
|
+
return false;
|
|
296
|
+
}
|
|
297
|
+
if (special && c >= 'A' && c <= 'Z') c = (unsigned char)(c - 'A' + 'a');
|
|
298
|
+
ub_push(&hb, (char)c);
|
|
299
|
+
}
|
|
300
|
+
/* file: "localhost" normalizes to "" at parse time (Node). */
|
|
301
|
+
if (is_file && hb.len == 9 && memcmp(hb.data, "localhost", 9) == 0) hb.len = 0;
|
|
302
|
+
if (hb.len == 0 && special && !is_file) {
|
|
303
|
+
free(hb.data);
|
|
304
|
+
return false; /* http:// — special non-file needs a host */
|
|
305
|
+
}
|
|
306
|
+
*host = ub_take(&hb);
|
|
307
|
+
/* Port: digits only, leading zeros stripped, defaults dropped. */
|
|
308
|
+
UrlBuf pb;
|
|
309
|
+
ub_init(&pb);
|
|
310
|
+
if (colon >= 0) {
|
|
311
|
+
const char *ps = hp + colon + 1;
|
|
312
|
+
size_t ps_len = hp_len - (size_t)colon - 1;
|
|
313
|
+
size_t start = 0;
|
|
314
|
+
while (start < ps_len - (ps_len > 0 ? 1 : 0) && ps[start] == '0') start++;
|
|
315
|
+
long value = 0;
|
|
316
|
+
bool any = false;
|
|
317
|
+
for (size_t i = 0; i < ps_len; i++) {
|
|
318
|
+
if (ps[i] < '0' || ps[i] > '9') {
|
|
319
|
+
free(pb.data);
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
for (size_t i = start; i < ps_len; i++) {
|
|
324
|
+
value = value * 10 + (ps[i] - '0');
|
|
325
|
+
any = true;
|
|
326
|
+
if (value > 65535) {
|
|
327
|
+
free(pb.data);
|
|
328
|
+
return false;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (any && value != 0) {
|
|
332
|
+
char digits[8];
|
|
333
|
+
int dlen = snprintf(digits, sizeof digits, "%ld", value);
|
|
334
|
+
const char *dflt = default_port(scheme, scheme_len);
|
|
335
|
+
if (!(dflt && strlen(dflt) == (size_t)dlen && memcmp(dflt, digits, (size_t)dlen) == 0)) {
|
|
336
|
+
ub_append(&pb, digits, (size_t)dlen);
|
|
337
|
+
}
|
|
338
|
+
} else if (any) {
|
|
339
|
+
/* Port 0 is a real (non-default) port. */
|
|
340
|
+
ub_push(&pb, '0');
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
*port = ub_take(&pb);
|
|
344
|
+
return true;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/* The full constructor-path parser. Returns NULL after throwing. */
|
|
348
|
+
ScrUrl *scr_url_new(ScrStr *input) {
|
|
349
|
+
/* WHATWG pre-processing: trim leading/trailing C0-or-space, strip every
|
|
350
|
+
* TAB/LF/CR. */
|
|
351
|
+
size_t raw_len = input->len;
|
|
352
|
+
const char *raw = input->data;
|
|
353
|
+
size_t b = 0, e = raw_len;
|
|
354
|
+
while (b < e && (unsigned char)raw[b] <= 0x20) b++;
|
|
355
|
+
while (e > b && (unsigned char)raw[e - 1] <= 0x20) e--;
|
|
356
|
+
char *buf = malloc(e - b + 1);
|
|
357
|
+
if (!buf) {
|
|
358
|
+
fputs("scriptc: out of memory\n", stderr);
|
|
359
|
+
abort();
|
|
360
|
+
}
|
|
361
|
+
size_t len = 0;
|
|
362
|
+
for (size_t i = b; i < e; i++) {
|
|
363
|
+
char c = raw[i];
|
|
364
|
+
if (c == '\t' || c == '\n' || c == '\r') continue;
|
|
365
|
+
buf[len++] = c;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/* Scheme: [A-Za-z][A-Za-z0-9+\-.]* ":" — lowercased. */
|
|
369
|
+
size_t sl = 0;
|
|
370
|
+
if (len > 0 && ((buf[0] >= 'a' && buf[0] <= 'z') || (buf[0] >= 'A' && buf[0] <= 'Z'))) {
|
|
371
|
+
sl = 1;
|
|
372
|
+
while (sl < len &&
|
|
373
|
+
((buf[sl] >= 'a' && buf[sl] <= 'z') || (buf[sl] >= 'A' && buf[sl] <= 'Z') ||
|
|
374
|
+
(buf[sl] >= '0' && buf[sl] <= '9') || buf[sl] == '+' || buf[sl] == '-' ||
|
|
375
|
+
buf[sl] == '.')) {
|
|
376
|
+
sl++;
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (sl == 0 || sl >= len || buf[sl] != ':') {
|
|
380
|
+
free(buf);
|
|
381
|
+
scr_url_throw_invalid();
|
|
382
|
+
return NULL;
|
|
383
|
+
}
|
|
384
|
+
for (size_t i = 0; i < sl; i++) {
|
|
385
|
+
if (buf[i] >= 'A' && buf[i] <= 'Z') buf[i] = (char)(buf[i] - 'A' + 'a');
|
|
386
|
+
}
|
|
387
|
+
const char *scheme = buf;
|
|
388
|
+
bool special = is_special_scheme(scheme, sl);
|
|
389
|
+
bool is_file = sl == 4 && memcmp(scheme, "file", 4) == 0;
|
|
390
|
+
|
|
391
|
+
const char *rest = buf + sl + 1;
|
|
392
|
+
size_t rest_len = len - sl - 1;
|
|
393
|
+
|
|
394
|
+
/* Split off fragment, then query (they never contain '#'/'?' rules we
|
|
395
|
+
* need beyond this). */
|
|
396
|
+
size_t hash = rest_len;
|
|
397
|
+
for (size_t i = 0; i < rest_len; i++) {
|
|
398
|
+
if (rest[i] == '#') {
|
|
399
|
+
hash = i;
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
size_t qmark = hash;
|
|
404
|
+
for (size_t i = 0; i < hash; i++) {
|
|
405
|
+
if (rest[i] == '?') {
|
|
406
|
+
qmark = i;
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
const char *body = rest;
|
|
411
|
+
size_t body_len = qmark;
|
|
412
|
+
|
|
413
|
+
ScrStr *userinfo = NULL, *host = NULL, *port = NULL, *path = NULL;
|
|
414
|
+
bool has_authority = false;
|
|
415
|
+
|
|
416
|
+
if (special) {
|
|
417
|
+
size_t slashes = 0;
|
|
418
|
+
while (slashes < body_len && (body[slashes] == '/' || body[slashes] == '\\')) slashes++;
|
|
419
|
+
bool file_authority = is_file && slashes == 2;
|
|
420
|
+
bool nonfile = !is_file;
|
|
421
|
+
if (file_authority || nonfile) {
|
|
422
|
+
/* Authority: after the slashes (file: exactly two), up to the next
|
|
423
|
+
* separator. */
|
|
424
|
+
size_t astart = is_file ? 2 : slashes;
|
|
425
|
+
size_t aend = astart;
|
|
426
|
+
while (aend < body_len && body[aend] != '/' && body[aend] != '\\') aend++;
|
|
427
|
+
if (!parse_authority(body + astart, aend - astart, special, is_file, scheme, sl,
|
|
428
|
+
&userinfo, &host, &port)) {
|
|
429
|
+
scr_str_release(userinfo);
|
|
430
|
+
scr_str_release(host);
|
|
431
|
+
scr_str_release(port);
|
|
432
|
+
free(buf);
|
|
433
|
+
scr_url_throw_invalid();
|
|
434
|
+
return NULL;
|
|
435
|
+
}
|
|
436
|
+
has_authority = true;
|
|
437
|
+
path = parse_rooted_path(body + aend, body_len - aend, special);
|
|
438
|
+
if (path->len == 0) {
|
|
439
|
+
scr_str_release(path);
|
|
440
|
+
path = scr_str_new("/", 1); /* special URLs never have empty paths */
|
|
441
|
+
}
|
|
442
|
+
} else {
|
|
443
|
+
/* file: with 0, 1, or 3+ slashes — host-less absolute path. */
|
|
444
|
+
userinfo = scr_str_new("", 0);
|
|
445
|
+
host = scr_str_new("", 0);
|
|
446
|
+
port = scr_str_new("", 0);
|
|
447
|
+
has_authority = true; /* file: always serializes with "//" */
|
|
448
|
+
size_t skip = slashes > 2 ? 2 : slashes; /* keep surplus slashes as path */
|
|
449
|
+
const char *p = body + skip;
|
|
450
|
+
size_t plen = body_len - skip;
|
|
451
|
+
/* Root the path: parse_rooted_path treats one leading sep as the
|
|
452
|
+
* root; prepend one if absent so "tmp" parses as "/tmp". */
|
|
453
|
+
if (plen > 0 && (p[0] == '/' || p[0] == '\\')) {
|
|
454
|
+
path = parse_rooted_path(p, plen, special);
|
|
455
|
+
} else {
|
|
456
|
+
UrlBuf rb;
|
|
457
|
+
ub_init(&rb);
|
|
458
|
+
ub_push(&rb, '/');
|
|
459
|
+
ub_append(&rb, p, plen);
|
|
460
|
+
ScrStr *tmp = ub_take(&rb);
|
|
461
|
+
path = parse_rooted_path(tmp->data, tmp->len, special);
|
|
462
|
+
scr_str_release(tmp);
|
|
463
|
+
}
|
|
464
|
+
if (path->len == 0) {
|
|
465
|
+
scr_str_release(path);
|
|
466
|
+
path = scr_str_new("/", 1);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
} else if (body_len >= 2 && body[0] == '/' && body[1] == '/') {
|
|
470
|
+
/* Non-special authority (git://host/...): host case preserved. */
|
|
471
|
+
size_t aend = 2;
|
|
472
|
+
while (aend < body_len && body[aend] != '/') aend++;
|
|
473
|
+
if (!parse_authority(body + 2, aend - 2, false, false, scheme, sl, &userinfo, &host, &port)) {
|
|
474
|
+
scr_str_release(userinfo);
|
|
475
|
+
scr_str_release(host);
|
|
476
|
+
scr_str_release(port);
|
|
477
|
+
free(buf);
|
|
478
|
+
scr_url_throw_invalid();
|
|
479
|
+
return NULL;
|
|
480
|
+
}
|
|
481
|
+
has_authority = true;
|
|
482
|
+
path = parse_rooted_path(body + aend, body_len - aend, false);
|
|
483
|
+
} else if (body_len >= 1 && body[0] == '/') {
|
|
484
|
+
/* Rooted path, no authority (foo:/bar/../x → foo:/x). */
|
|
485
|
+
userinfo = scr_str_new("", 0);
|
|
486
|
+
host = scr_str_new("", 0);
|
|
487
|
+
port = scr_str_new("", 0);
|
|
488
|
+
path = parse_rooted_path(body, body_len, false);
|
|
489
|
+
} else {
|
|
490
|
+
/* Opaque path — kept verbatim (divergence: the spec C0-encodes). */
|
|
491
|
+
userinfo = scr_str_new("", 0);
|
|
492
|
+
host = scr_str_new("", 0);
|
|
493
|
+
port = scr_str_new("", 0);
|
|
494
|
+
path = scr_str_new(body, body_len);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
/* Query and fragment, encoded and stored WITH their sigils. */
|
|
498
|
+
UrlBuf qb;
|
|
499
|
+
ub_init(&qb);
|
|
500
|
+
if (qmark < hash) {
|
|
501
|
+
ub_push(&qb, '?');
|
|
502
|
+
for (size_t i = qmark + 1; i < hash; i++) {
|
|
503
|
+
unsigned char c = (unsigned char)rest[i];
|
|
504
|
+
if (enc_query(c, special)) {
|
|
505
|
+
char hex[4];
|
|
506
|
+
snprintf(hex, sizeof hex, "%%%02X", c);
|
|
507
|
+
ub_append(&qb, hex, 3);
|
|
508
|
+
} else {
|
|
509
|
+
ub_push(&qb, (char)c);
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
ScrStr *query = ub_take(&qb);
|
|
514
|
+
UrlBuf fb;
|
|
515
|
+
ub_init(&fb);
|
|
516
|
+
if (hash < rest_len) {
|
|
517
|
+
ub_push(&fb, '#');
|
|
518
|
+
for (size_t i = hash + 1; i < rest_len; i++) {
|
|
519
|
+
ub_push_encoded(&fb, (unsigned char)rest[i], enc_fragment);
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
ScrStr *fragment = ub_take(&fb);
|
|
523
|
+
|
|
524
|
+
ScrStr *scheme_str = scr_str_new(scheme, sl);
|
|
525
|
+
free(buf);
|
|
526
|
+
|
|
527
|
+
ScrUrl *u = malloc(sizeof(ScrUrl));
|
|
528
|
+
if (!u) {
|
|
529
|
+
fputs("scriptc: out of memory\n", stderr);
|
|
530
|
+
abort();
|
|
531
|
+
}
|
|
532
|
+
u->rc = 1;
|
|
533
|
+
u->scheme = scheme_str;
|
|
534
|
+
u->userinfo = userinfo;
|
|
535
|
+
u->host = host;
|
|
536
|
+
u->port = port;
|
|
537
|
+
u->path = path;
|
|
538
|
+
u->query = query;
|
|
539
|
+
u->fragment = fragment;
|
|
540
|
+
u->has_authority = has_authority;
|
|
541
|
+
u->sp_cache = NULL;
|
|
542
|
+
return u;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
ScrStr *scr_url_protocol(ScrUrl *u) {
|
|
546
|
+
UrlBuf b;
|
|
547
|
+
ub_init(&b);
|
|
548
|
+
ub_append(&b, u->scheme->data, u->scheme->len);
|
|
549
|
+
ub_push(&b, ':');
|
|
550
|
+
return ub_take(&b);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
ScrStr *scr_url_pathname(ScrUrl *u) { return scr_str_retain(u->path); }
|
|
554
|
+
|
|
555
|
+
/* WHATWG host getter: host[:port] — the port only when non-default (the
|
|
556
|
+
* parser already stripped defaults), "" for authority-less URLs. The
|
|
557
|
+
* normalized form findRoute-style authority compares want (lowercased
|
|
558
|
+
* host, no default :443/:80). */
|
|
559
|
+
ScrStr *scr_url_host(ScrUrl *u) {
|
|
560
|
+
if (u->port->len == 0) return scr_str_retain(u->host);
|
|
561
|
+
UrlBuf b;
|
|
562
|
+
ub_init(&b);
|
|
563
|
+
ub_append(&b, u->host->data, u->host->len);
|
|
564
|
+
ub_push(&b, ':');
|
|
565
|
+
ub_append(&b, u->port->data, u->port->len);
|
|
566
|
+
return ub_take(&b);
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/* WHATWG hostname getter: the stored port-less host verbatim ("" for
|
|
570
|
+
* authority-less URLs). Node would keep IPv6 brackets here; the parser
|
|
571
|
+
* rejects IPv6 hosts (documented divergence), so none reach this getter. */
|
|
572
|
+
ScrStr *scr_url_hostname(ScrUrl *u) { return scr_str_retain(u->host); }
|
|
573
|
+
|
|
574
|
+
ScrStr *scr_url_href(ScrUrl *u) {
|
|
575
|
+
UrlBuf b;
|
|
576
|
+
ub_init(&b);
|
|
577
|
+
ub_append(&b, u->scheme->data, u->scheme->len);
|
|
578
|
+
ub_push(&b, ':');
|
|
579
|
+
if (u->has_authority) {
|
|
580
|
+
ub_append(&b, "//", 2);
|
|
581
|
+
if (u->userinfo->len > 0) {
|
|
582
|
+
ub_append(&b, u->userinfo->data, u->userinfo->len);
|
|
583
|
+
ub_push(&b, '@');
|
|
584
|
+
}
|
|
585
|
+
ub_append(&b, u->host->data, u->host->len);
|
|
586
|
+
if (u->port->len > 0) {
|
|
587
|
+
ub_push(&b, ':');
|
|
588
|
+
ub_append(&b, u->port->data, u->port->len);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
ub_append(&b, u->path->data, u->path->len);
|
|
592
|
+
ub_append(&b, u->query->data, u->query->len);
|
|
593
|
+
ub_append(&b, u->fragment->data, u->fragment->len);
|
|
594
|
+
return ub_take(&b);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/* ── the file-URL bridge ─────────────────────────────────────────────── */
|
|
598
|
+
|
|
599
|
+
static int hex_val(char c) {
|
|
600
|
+
if (c >= '0' && c <= '9') return c - '0';
|
|
601
|
+
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
|
602
|
+
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
|
|
603
|
+
return -1;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/* fileURLToPath over a parsed URL: Node's checks, Node's messages. The
|
|
607
|
+
* posix arm rejects hosts and keeps forward slashes; the win32 arm maps
|
|
608
|
+
* hosts to UNC \\host prefixes, flips separators, and demands a drive
|
|
609
|
+
* letter otherwise. The public wrappers below select by TARGET. */
|
|
610
|
+
static ScrStr *scr_url_to_path_impl(ScrUrl *u, bool win32) {
|
|
611
|
+
if (!(u->scheme->len == 4 && memcmp(u->scheme->data, "file", 4) == 0)) {
|
|
612
|
+
scr_throw_error_msg(SCR_ERR_TYPE, "The URL must be of scheme file", 30);
|
|
613
|
+
return NULL;
|
|
614
|
+
}
|
|
615
|
+
const char *p = u->path->data;
|
|
616
|
+
size_t len = u->path->len;
|
|
617
|
+
if (win32) {
|
|
618
|
+
/* Node scans the ENCODED pathname for %2f/%2F (/) and %5c/%5C (\). */
|
|
619
|
+
for (size_t n = 0; n + 1 < len; n++) {
|
|
620
|
+
if (p[n] != '%') continue;
|
|
621
|
+
char c1 = p[n + 1];
|
|
622
|
+
int third = (n + 2 < len ? (unsigned char)p[n + 2] : 0) | 0x20;
|
|
623
|
+
if ((c1 == '2' && third == 'f') || (c1 == '5' && third == 'c')) {
|
|
624
|
+
scr_throw_error_msg(SCR_ERR_TYPE,
|
|
625
|
+
"File URL path must not include encoded \\ or / characters", 56);
|
|
626
|
+
return NULL;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
/* Forward slashes become backslashes FIRST, then percent-decoding
|
|
630
|
+
* (Node's decodeURIComponent order). Invalid sequences pass through
|
|
631
|
+
* verbatim where Node throws URIError — no URIError class exists
|
|
632
|
+
* here (documented divergence, shared with the posix arm). */
|
|
633
|
+
UrlBuf out;
|
|
634
|
+
ub_init(&out);
|
|
635
|
+
if (u->host->len > 0) {
|
|
636
|
+
/* A UNC path: \\host + pathname. (Node passes the hostname through
|
|
637
|
+
* domainToUnicode; this parser rejected non-ASCII/IDN hosts at
|
|
638
|
+
* construction, so the host is already plain ASCII.) */
|
|
639
|
+
ub_append(&out, "\\\\", 2);
|
|
640
|
+
ub_append(&out, u->host->data, u->host->len);
|
|
641
|
+
}
|
|
642
|
+
size_t path_start = out.len;
|
|
643
|
+
for (size_t i = 0; i < len; i++) {
|
|
644
|
+
if (p[i] == '/') {
|
|
645
|
+
ub_push(&out, '\\');
|
|
646
|
+
continue;
|
|
647
|
+
}
|
|
648
|
+
if (p[i] == '%' && i + 2 < len) {
|
|
649
|
+
int hi = hex_val(p[i + 1]);
|
|
650
|
+
int lo = hex_val(p[i + 2]);
|
|
651
|
+
if (hi >= 0 && lo >= 0) {
|
|
652
|
+
ub_push(&out, (char)((hi << 4) | lo));
|
|
653
|
+
i += 2;
|
|
654
|
+
continue;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
ub_push(&out, p[i]);
|
|
658
|
+
}
|
|
659
|
+
if (u->host->len > 0) return ub_take(&out);
|
|
660
|
+
/* A local path requires a drive letter: pathname[1] in [a-zA-Z] and
|
|
661
|
+
* pathname[2] === ':' (both on the DECODED, backslashed pathname). */
|
|
662
|
+
size_t plen = out.len - path_start;
|
|
663
|
+
const char *pp = out.data + path_start;
|
|
664
|
+
int letter = (plen > 1 ? (unsigned char)pp[1] : 0) | 0x20;
|
|
665
|
+
char drive_sep = plen > 2 ? pp[2] : 0;
|
|
666
|
+
if (letter < 'a' || letter > 'z' || drive_sep != ':') {
|
|
667
|
+
free(out.data);
|
|
668
|
+
scr_throw_error_msg(SCR_ERR_TYPE, "File URL path must be absolute", 30);
|
|
669
|
+
return NULL;
|
|
670
|
+
}
|
|
671
|
+
/* pathname.slice(1): the leading backslash drops. */
|
|
672
|
+
ScrStr *s = scr_str_new(pp + 1, plen - 1);
|
|
673
|
+
free(out.data);
|
|
674
|
+
return s;
|
|
675
|
+
}
|
|
676
|
+
if (u->host->len > 0) {
|
|
677
|
+
/* Parse-time normalization already emptied "localhost". */
|
|
678
|
+
const char *plat =
|
|
679
|
+
#if defined(__APPLE__)
|
|
680
|
+
"darwin";
|
|
681
|
+
#elif defined(__linux__)
|
|
682
|
+
"linux";
|
|
683
|
+
#elif defined(_WIN32)
|
|
684
|
+
"win32";
|
|
685
|
+
#else
|
|
686
|
+
"posix";
|
|
687
|
+
#endif
|
|
688
|
+
char msg[96];
|
|
689
|
+
int mlen = snprintf(msg, sizeof msg, "File URL host must be \"localhost\" or empty on %s", plat);
|
|
690
|
+
scr_throw_error_msg(SCR_ERR_TYPE, msg, (size_t)mlen);
|
|
691
|
+
return NULL;
|
|
692
|
+
}
|
|
693
|
+
UrlBuf out;
|
|
694
|
+
ub_init(&out);
|
|
695
|
+
for (size_t i = 0; i < len; i++) {
|
|
696
|
+
if (p[i] == '%' && i + 2 < len) {
|
|
697
|
+
int hi = hex_val(p[i + 1]);
|
|
698
|
+
int lo = hex_val(p[i + 2]);
|
|
699
|
+
if (hi >= 0 && lo >= 0) {
|
|
700
|
+
unsigned char decoded = (unsigned char)((hi << 4) | lo);
|
|
701
|
+
if (decoded == '/') {
|
|
702
|
+
free(out.data);
|
|
703
|
+
scr_throw_error_msg(SCR_ERR_TYPE,
|
|
704
|
+
"File URL path must not include encoded / characters", 51);
|
|
705
|
+
return NULL;
|
|
706
|
+
}
|
|
707
|
+
ub_push(&out, (char)decoded);
|
|
708
|
+
i += 2;
|
|
709
|
+
continue;
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
ub_push(&out, p[i]);
|
|
713
|
+
}
|
|
714
|
+
return ub_take(&out);
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
/* The target's arm: Node on Windows takes the win32 branch of the same
|
|
718
|
+
* dispatch (`isWindows` there is this binary's _WIN32 here). */
|
|
719
|
+
ScrStr *scr_url_to_path(ScrUrl *u) {
|
|
720
|
+
#ifdef _WIN32
|
|
721
|
+
return scr_url_to_path_impl(u, true);
|
|
722
|
+
#else
|
|
723
|
+
return scr_url_to_path_impl(u, false);
|
|
724
|
+
#endif
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/* The string-receiver form parses first (Node accepts URL strings). */
|
|
728
|
+
ScrStr *scr_url_str_to_path(ScrStr *input) {
|
|
729
|
+
ScrUrl *u = scr_url_new(input);
|
|
730
|
+
if (!u) return NULL; /* Invalid URL already thrown */
|
|
731
|
+
ScrStr *path = scr_url_to_path(u);
|
|
732
|
+
scr_url_release(u);
|
|
733
|
+
return path;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/* Assembles the file: URL value pathToFileURL returns (fields direct — no
|
|
737
|
+
* reparse). Takes ownership of host and encoded path. */
|
|
738
|
+
static ScrUrl *scr_url_new_file(ScrStr *host, ScrStr *encoded_path) {
|
|
739
|
+
ScrUrl *u = malloc(sizeof(ScrUrl));
|
|
740
|
+
if (!u) {
|
|
741
|
+
fputs("scriptc: out of memory\n", stderr);
|
|
742
|
+
abort();
|
|
743
|
+
}
|
|
744
|
+
u->rc = 1;
|
|
745
|
+
u->scheme = scr_str_new("file", 4);
|
|
746
|
+
u->userinfo = scr_str_new("", 0);
|
|
747
|
+
u->host = host;
|
|
748
|
+
u->port = scr_str_new("", 0);
|
|
749
|
+
u->path = encoded_path;
|
|
750
|
+
u->query = scr_str_new("", 0);
|
|
751
|
+
u->fragment = scr_str_new("", 0);
|
|
752
|
+
u->has_authority = true;
|
|
753
|
+
u->sp_cache = NULL;
|
|
754
|
+
return u;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
/* util.inspect-style single-quoting for ERR_INVALID_ARG_VALUE's
|
|
758
|
+
* "Received" clause ('\' and '\'' escape). */
|
|
759
|
+
static void ub_push_inspected(UrlBuf *b, const char *s, size_t len) {
|
|
760
|
+
ub_push(b, '\'');
|
|
761
|
+
for (size_t i = 0; i < len; i++) {
|
|
762
|
+
if (s[i] == '\\' || s[i] == '\'') ub_push(b, '\\');
|
|
763
|
+
ub_push(b, s[i]);
|
|
764
|
+
}
|
|
765
|
+
ub_push(b, '\'');
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
/* Node's ERR_INVALID_ARG_VALUE('path', value, reason) — a TypeError. */
|
|
769
|
+
static void scr_url_throw_arg_value(const char *reason, ScrStr *value) {
|
|
770
|
+
UrlBuf msg;
|
|
771
|
+
ub_init(&msg);
|
|
772
|
+
ub_append(&msg, "The argument 'path' ", 20);
|
|
773
|
+
ub_append(&msg, reason, strlen(reason));
|
|
774
|
+
ub_append(&msg, ". Received ", 11);
|
|
775
|
+
ub_push_inspected(&msg, value->data, value->len);
|
|
776
|
+
scr_throw_error_msg(SCR_ERR_TYPE, msg.data, msg.len);
|
|
777
|
+
free(msg.data);
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
/* Percent-encodes a raw filesystem path the way Node's
|
|
781
|
+
* bindingUrl.pathToFileURL does, reusing the parser's rooted-path
|
|
782
|
+
* machinery (WHATWG dot-segment removal with empty segments preserved,
|
|
783
|
+
* backslash-as-slash when `backslash_sep`, the enc_path set): the bytes
|
|
784
|
+
* Node encodes BEYOND that set ('%', '[', ']', '^', '|' — and '\\' when
|
|
785
|
+
* it is a path byte rather than a separator) pre-encode here so the
|
|
786
|
+
* parser passes them through. */
|
|
787
|
+
static ScrStr *scr_url_encode_file_path(const char *raw, size_t len, bool backslash_sep) {
|
|
788
|
+
UrlBuf pre;
|
|
789
|
+
ub_init(&pre);
|
|
790
|
+
for (size_t i = 0; i < len; i++) {
|
|
791
|
+
unsigned char c = (unsigned char)raw[i];
|
|
792
|
+
if (c == '%' || c == '[' || c == ']' || c == '^' || c == '|' ||
|
|
793
|
+
(c == '\\' && !backslash_sep)) {
|
|
794
|
+
char hex[4];
|
|
795
|
+
snprintf(hex, sizeof hex, "%%%02X", c);
|
|
796
|
+
ub_append(&pre, hex, 3);
|
|
797
|
+
} else {
|
|
798
|
+
ub_push(&pre, (char)c);
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
ScrStr *encoded = parse_rooted_path(pre.data, pre.len, backslash_sep);
|
|
802
|
+
free(pre.data);
|
|
803
|
+
return encoded;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
/* pathToFileURL: resolve against the cwd (Node does), keep an
|
|
807
|
+
* intentionally-trailing separator, percent-encode. The posix arm
|
|
808
|
+
* %5C-encodes backslashes (valid path bytes there); the win32 arm
|
|
809
|
+
* resolves through path.win32, flips separators, and routes UNC prefixes
|
|
810
|
+
* (\\server\share, \\?\UNC\...) into the URL host — with WHATWG
|
|
811
|
+
* dot-segment removal on the unresolved UNC remainder, exactly Node.
|
|
812
|
+
* Throws only for the win32 UNC malformations (Node's
|
|
813
|
+
* ERR_INVALID_ARG_VALUE TypeErrors). */
|
|
814
|
+
static ScrUrl *scr_url_from_path_impl(ScrStr *path, bool win32) {
|
|
815
|
+
ScrStr *resolved;
|
|
816
|
+
if (win32) {
|
|
817
|
+
bool is_unc = path->len >= 2 && path->data[0] == '\\' && path->data[1] == '\\';
|
|
818
|
+
if (is_unc) {
|
|
819
|
+
resolved = scr_str_retain(path);
|
|
820
|
+
} else {
|
|
821
|
+
ScrArr *pack = scr_arr_new(SCR_ELEM_STR, 1);
|
|
822
|
+
scr_arr_push_ref(pack, scr_str_retain(path));
|
|
823
|
+
resolved = scr_path_win32_resolve(pack);
|
|
824
|
+
scr_arr_release(pack);
|
|
825
|
+
}
|
|
826
|
+
if (is_unc || (resolved->len >= 2 && resolved->data[0] == '\\' && resolved->data[1] == '\\')) {
|
|
827
|
+
/* UNC path format: \\server\share\resource; an extended
|
|
828
|
+
* \\?\UNC\ prefix is ignored. */
|
|
829
|
+
bool extended = resolved->len >= 8 && memcmp(resolved->data, "\\\\?\\UNC\\", 8) == 0;
|
|
830
|
+
size_t prefix = extended ? 8 : 2;
|
|
831
|
+
long host_end = -1;
|
|
832
|
+
for (size_t i = prefix; i < resolved->len; i++) {
|
|
833
|
+
if (resolved->data[i] == '\\') {
|
|
834
|
+
host_end = (long)i;
|
|
835
|
+
break;
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
if (host_end == -1) {
|
|
839
|
+
scr_url_throw_arg_value("Missing UNC resource path", resolved);
|
|
840
|
+
scr_str_release(resolved);
|
|
841
|
+
return NULL;
|
|
842
|
+
}
|
|
843
|
+
if (host_end == 2) {
|
|
844
|
+
scr_url_throw_arg_value("Empty UNC servername", resolved);
|
|
845
|
+
scr_str_release(resolved);
|
|
846
|
+
return NULL;
|
|
847
|
+
}
|
|
848
|
+
/* The URL host parser lowercases ASCII and TERMINATES at the URL
|
|
849
|
+
* delimiters '/', '?', '#' (Node feeds the servername through
|
|
850
|
+
* set_hostname: "\\\\?\\C:\\x" gets an EMPTY host and stays a
|
|
851
|
+
* drive path). No IDNA (documented divergence — Node punycodes
|
|
852
|
+
* non-ASCII names), and names with ':' or '%' stay verbatim where
|
|
853
|
+
* Node aborts on a native set_hostname assertion. */
|
|
854
|
+
UrlBuf host;
|
|
855
|
+
ub_init(&host);
|
|
856
|
+
for (size_t i = prefix; i < (size_t)host_end; i++) {
|
|
857
|
+
char c = resolved->data[i];
|
|
858
|
+
if (c == '/' || c == '?' || c == '#') break;
|
|
859
|
+
if (c >= 'A' && c <= 'Z') c = (char)(c + 32);
|
|
860
|
+
ub_push(&host, c);
|
|
861
|
+
}
|
|
862
|
+
ScrStr *encoded = scr_url_encode_file_path(resolved->data + host_end,
|
|
863
|
+
resolved->len - (size_t)host_end, true);
|
|
864
|
+
scr_str_release(resolved);
|
|
865
|
+
return scr_url_new_file(ub_take(&host), encoded);
|
|
866
|
+
}
|
|
867
|
+
} else {
|
|
868
|
+
ScrArr *pack = scr_arr_new(SCR_ELEM_STR, 1);
|
|
869
|
+
scr_arr_push_ref(pack, scr_str_retain(path));
|
|
870
|
+
resolved = scr_path_resolve(pack);
|
|
871
|
+
scr_arr_release(pack);
|
|
872
|
+
}
|
|
873
|
+
/* path.resolve strips trailing slashes — Node adds an intentional one
|
|
874
|
+
* back (the input ends with a separator the resolved path lost). On
|
|
875
|
+
* win32 the input separator set is both slashes and the resolved path
|
|
876
|
+
* keeps '\\' only at a root; posix knows '/' alone. */
|
|
877
|
+
char last = path->len > 0 ? path->data[path->len - 1] : 0;
|
|
878
|
+
bool wants_trailing = win32 ? (last == '/' || last == '\\') : last == '/';
|
|
879
|
+
char resolved_last = resolved->len > 0 ? resolved->data[resolved->len - 1] : 0;
|
|
880
|
+
bool has_trailing = win32 ? resolved_last == '\\' : resolved_last == '/';
|
|
881
|
+
UrlBuf raw;
|
|
882
|
+
ub_init(&raw);
|
|
883
|
+
ub_append(&raw, resolved->data, resolved->len);
|
|
884
|
+
if (wants_trailing && !has_trailing) ub_push(&raw, '/');
|
|
885
|
+
ScrStr *encoded = scr_url_encode_file_path(raw.data, raw.len, win32);
|
|
886
|
+
free(raw.data);
|
|
887
|
+
scr_str_release(resolved);
|
|
888
|
+
return scr_url_new_file(scr_str_new("", 0), encoded);
|
|
889
|
+
}
|
|
890
|
+
|
|
891
|
+
/* The target's arm, like scr_url_to_path's. Never throws on posix. */
|
|
892
|
+
ScrUrl *scr_url_from_path(ScrStr *path) {
|
|
893
|
+
#ifdef _WIN32
|
|
894
|
+
return scr_url_from_path_impl(path, true);
|
|
895
|
+
#else
|
|
896
|
+
return scr_url_from_path_impl(path, false);
|
|
897
|
+
#endif
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
/* The win32 arms as real entry points: the host-side differential tests
|
|
901
|
+
* (test_url.c) exercise the Windows behavior from any platform, the same
|
|
902
|
+
* way Node exposes { windows: true } options on the bridge pair. */
|
|
903
|
+
ScrStr *scr_url_to_path_w32(ScrUrl *u) { return scr_url_to_path_impl(u, true); }
|
|
904
|
+
ScrUrl *scr_url_from_path_w32(ScrStr *path) { return scr_url_from_path_impl(path, true); }
|
|
905
|
+
|
|
906
|
+
/* WHATWG search getter: "" for no query AND for the bare-'?' query;
|
|
907
|
+
* "?..." verbatim otherwise. */
|
|
908
|
+
ScrStr *scr_url_search(ScrUrl *u) {
|
|
909
|
+
if (u->query->len <= 1) return scr_str_new("", 0);
|
|
910
|
+
return scr_str_retain(u->query);
|
|
911
|
+
}
|