From 0b9aca87cd640f355c9c41a24cdf1570b8cc2a72 Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Sat, 13 Jun 2026 10:48:04 -0300 Subject: [PATCH 01/17] controller: keep onblock REJECTING trace out of warn during sync/replay A failing onblock is deterministic and benign: the block still applies, the schedule/state change is simply dropped, and every node reproduces the same failure (e.g. the system contract proposing a producer schedule that the native set_proposed_producers intrinsic rejects). During snapshot catch-up / replay the handler dumped the full onblock trace at warn for every affected block -- observed as 38,923 consecutive warnings over one Telos testnet window. Gate it on the same ">5 min behind head" heuristic update_peer_keys() uses: warn only at/near head, downgrade to dlog while catching up (the full trace is still available by raising the controller logger to debug). Pure logging- severity change -- no consensus, state, or control-flow impact, and the interrupt_exception path is still handled and rethrown before the gate. --- libraries/chain/controller.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 339b4d5054..2b284c7462 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -3356,8 +3356,20 @@ struct controller_impl { ilog("Interrupt of onblock ${bn}", ("bn", chain_head.block_num() + 1)); throw *onblock_trace->except; } - wlog("onblock ${block_num} is REJECTING: ${entire_trace}", - ("block_num", chain_head.block_num() + 1)("entire_trace", onblock_trace)); + // A failing onblock is deterministic and benign: the block still applies, the + // schedule/state change is simply dropped, and every node reproduces the same + // failure (e.g. the system contract proposing a producer schedule that the + // native intrinsic rejects). While syncing or replaying old blocks this would + // dump the full onblock trace at warn for every affected block, so only emit the + // warning when at/near head; downgrade to debug while catching up. (Uses the same + // "caught up" heuristic as update_peer_keys().) + if( fc::time_point::now() - when.to_time_point() < fc::minutes(5) ) { + wlog("onblock ${block_num} is REJECTING: ${entire_trace}", + ("block_num", chain_head.block_num() + 1)("entire_trace", onblock_trace)); + } else { + dlog("onblock ${block_num} is REJECTING: ${entire_trace}", + ("block_num", chain_head.block_num() + 1)("entire_trace", onblock_trace)); + } } } catch( const std::bad_alloc& e ) { elog( "on block transaction failed due to a std::bad_alloc" ); From 5c85a5b9621a919ff3b45ca722c1bc0d5706de49 Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Thu, 3 Sep 2026 04:36:24 -0300 Subject: [PATCH 02/17] chore: gitignore cluster test and agent artifacts --- .gitignore | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 36d5e64b6d..6b7f562194 100644 --- a/.gitignore +++ b/.gitignore @@ -98,4 +98,9 @@ snapshots # reproducible build artifacts dropped in the repo root by `docker build ... -o .` /antelope-spring*.deb -/antelope-spring*.tar.* \ No newline at end of file +/antelope-spring*.tar.* + +# test & agent artifacts +/cluster-artifacts/ +/config-dir/ +/.agents/ \ No newline at end of file From 839e2e351e120975e3b6cc4563ac8dc11d8909f5 Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Thu, 3 Sep 2026 04:36:29 -0300 Subject: [PATCH 03/17] libfc, state_history: fix SHA3 bounds, Base58 null guards, buffer bounds, and shared_blob memcpy - Issue 8: fix SHA3 big-endian out-of-bounds write and initialize loop index - Issue 10: add bounds check in message_buffer::advance_read_ptr preventing underflow - Issue 11: add null guard and zero-length handling in to_base58 and EncodeBase58 - Issue 12: guard shared_blob size before calling ds.write in history_pack_big_bytes - Issue 4 helper: add fc::bounded_datastream adapter enforcing max read/write byte bounds - Add unit and adversarial stress test suites for bounded_datastream, base58, message_buffer, and state_history --- libraries/libfc/include/fc/crypto/base58.hpp | 4 +- libraries/libfc/include/fc/io/datastream.hpp | 128 ++++++ .../include/fc/network/message_buffer.hpp | 5 + libraries/libfc/src/crypto/base58.cpp | 5 +- libraries/libfc/src/crypto/sha3.cpp | 6 +- libraries/libfc/test/CMakeLists.txt | 3 + .../libfc/test/io/test_bounded_datastream.cpp | 402 ++++++++++++++++++ .../test/network/test_message_buffer.cpp | 97 +++++ libraries/libfc/test/test_base58.cpp | 91 ++++ libraries/libfc/test/test_m1_adversarial.cpp | 377 ++++++++++++++++ .../eosio/state_history/serialization.hpp | 3 +- unittests/state_history_tests.cpp | 238 +++++++++++ 12 files changed, 1352 insertions(+), 7 deletions(-) create mode 100644 libraries/libfc/test/io/test_bounded_datastream.cpp create mode 100644 libraries/libfc/test/test_base58.cpp create mode 100644 libraries/libfc/test/test_m1_adversarial.cpp diff --git a/libraries/libfc/include/fc/crypto/base58.hpp b/libraries/libfc/include/fc/crypto/base58.hpp index ebf94d7830..74f6d26752 100644 --- a/libraries/libfc/include/fc/crypto/base58.hpp +++ b/libraries/libfc/include/fc/crypto/base58.hpp @@ -4,8 +4,8 @@ #include namespace fc { - std::string to_base58( const char* d, size_t s, const fc::yield_function_t& yield ); - std::string to_base58( const std::vector& data, const fc::yield_function_t& yield ); + std::string to_base58( const char* d, size_t s, const fc::yield_function_t& yield = fc::yield_function_t() ); + std::string to_base58( const std::vector& data, const fc::yield_function_t& yield = fc::yield_function_t() ); std::vector from_base58( const std::string& base58_str ); size_t from_base58( const std::string& base58_str, char* out_data, size_t out_data_len ); } diff --git a/libraries/libfc/include/fc/io/datastream.hpp b/libraries/libfc/include/fc/io/datastream.hpp index c2f405d6c1..d0ac0b2add 100644 --- a/libraries/libfc/include/fc/io/datastream.hpp +++ b/libraries/libfc/include/fc/io/datastream.hpp @@ -211,6 +211,134 @@ class datastream_mirror { std::vector mirror; }; +/** + * Datastream wrapper that bounds reading and writing up to max_bytes. + * Throws fc::out_of_range_exception if any operation attempts to exceed max_bytes. + * @tparam DataStream datastream to wrap + */ +template +class bounded_datastream { +public: + explicit bounded_datastream( DataStream& ds, size_t max_bytes ) + : ds(ds), _max_bytes(max_bytes), _total(0) {} + + inline void skip( size_t s ) { + if( s > remaining() ) { + detail::throw_datastream_range_error( "skip", _max_bytes, int64_t(s - remaining()) ); + } + ds.skip( s ); + _total += s; + } + + inline bool read( char* d, size_t s ) { + if( s > remaining() ) { + detail::throw_datastream_range_error( "read", _max_bytes, int64_t(s - remaining()) ); + } + if( ds.read( d, s ) ) { + _total += s; + return true; + } + return false; + } + + inline bool write( const char* d, size_t s ) { + if( s > remaining() ) { + detail::throw_datastream_range_error( "write", _max_bytes, int64_t(s - remaining()) ); + } + if( ds.write( d, s ) ) { + _total += s; + return true; + } + return false; + } + + inline bool put( char c ) { + return write( &c, 1 ); + } + + inline bool get( unsigned char& c ) { return read( (char*)&c, 1 ); } + inline bool get( char& c ) { return read( &c, 1 ); } + + inline size_t remaining() const { + return _max_bytes >= _total ? (_max_bytes - _total) : 0; + } + + inline size_t tellp() const { return _total; } + + inline size_t max_bytes() const { return _max_bytes; } + + inline size_t total_read() const { return _total; } + + inline bool valid() const { return _total <= _max_bytes; } + + inline bool seekp( size_t p ) { + if( p > _max_bytes ) return false; + if( p < _total ) { + if constexpr ( requires { ds.seekp(p); } ) { + if( ds.seekp( p ) ) { + _total = p; + return true; + } + return false; + } else { + return false; + } + } + size_t diff = p - _total; + skip( diff ); + return true; + } + + inline DataStream& storage() { return ds; } + inline const DataStream& storage() const { return ds; } + + inline DataStream& unwrapped() { return ds; } + inline const DataStream& unwrapped() const { return ds; } + +private: + DataStream& ds; + size_t _max_bytes; + size_t _total; +}; + +template +requires std::is_arithmetic_v +inline bounded_datastream& operator<<(bounded_datastream& ds, const T& d) { + ds.write( (const char*)&d, sizeof(d) ); + return ds; +} + +template +requires std::is_arithmetic_v +inline bounded_datastream& operator>>(bounded_datastream& ds, T& d) { + ds.read( (char*)&d, sizeof(d) ); + return ds; +} + +template +inline bounded_datastream& operator<<(bounded_datastream& ds, const __int128& d) { + ds.write( (const char*)&d, sizeof(d) ); + return ds; +} + +template +inline bounded_datastream& operator>>(bounded_datastream& ds, __int128& d) { + ds.read( (char*)&d, sizeof(d) ); + return ds; +} + +template +inline bounded_datastream& operator<<(bounded_datastream& ds, const unsigned __int128& d) { + ds.write( (const char*)&d, sizeof(d) ); + return ds; +} + +template +inline bounded_datastream& operator>>(bounded_datastream& ds, unsigned __int128& d) { + ds.read( (char*)&d, sizeof(d) ); + return ds; +} + template inline datastream& operator<<(datastream& ds, const __int128& d) { diff --git a/libraries/libfc/include/fc/network/message_buffer.hpp b/libraries/libfc/include/fc/network/message_buffer.hpp index f8e7f83307..7457b551cc 100644 --- a/libraries/libfc/include/fc/network/message_buffer.hpp +++ b/libraries/libfc/include/fc/network/message_buffer.hpp @@ -157,6 +157,11 @@ namespace fc { * start). */ void advance_read_ptr(uint32_t bytes) { + if (bytes > bytes_to_read()) { + FC_THROW_EXCEPTION( out_of_range_exception, + "cannot advance read pointer past write pointer: bytes ${b}, bytes_to_read ${r}", + ("b", bytes)("r", bytes_to_read()) ); + } advance_index(read_ind, bytes); if (read_ind == write_ind) { reset(); diff --git a/libraries/libfc/src/crypto/base58.cpp b/libraries/libfc/src/crypto/base58.cpp index ad26a9ea17..fcab108685 100644 --- a/libraries/libfc/src/crypto/base58.cpp +++ b/libraries/libfc/src/crypto/base58.cpp @@ -552,7 +552,8 @@ inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char // Encode a byte vector as a base58-encoded string inline std::string EncodeBase58(const std::vector& vch, const fc::yield_function_t& yield) { - return EncodeBase58(&vch[0], &vch[0] + vch.size(), yield); + if (vch.empty()) return {}; + return EncodeBase58(vch.data(), vch.data() + vch.size(), yield); } // Decode a base58-encoded string psz into byte vector vchRet @@ -616,6 +617,8 @@ inline bool DecodeBase58(const std::string& str, std::vector& vch namespace fc { std::string to_base58( const char* d, size_t s, const fc::yield_function_t& yield ) { + if (s == 0) return std::string(); + FC_ASSERT( d != nullptr, "data pointer cannot be null with non-zero size" ); return EncodeBase58( (const unsigned char*)d, (const unsigned char*)d+s, yield ); } diff --git a/libraries/libfc/src/crypto/sha3.cpp b/libraries/libfc/src/crypto/sha3.cpp index 2856ee75de..ed21c6d526 100644 --- a/libraries/libfc/src/crypto/sha3.cpp +++ b/libraries/libfc/src/crypto/sha3.cpp @@ -16,7 +16,7 @@ template struct overloaded : Ts... { using Ts::operator()...; }; template overloaded(Ts...) -> overloaded; #if defined(__BYTE_ORDER__) -#if defined(__ORDER_LITTLE_ENDIAN__) +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ inline constexpr bool is_little_endian = true; #else inline constexpr bool is_little_endian = false; @@ -74,7 +74,7 @@ struct sha3_impl { { uint8_t *v; // convert the buffer to little endian - for (std::size_t i; i < number_of_words; i++) + for (std::size_t i = 0; i < number_of_words; i++) { v = reinterpret_cast(words + i); words[i] = ((uint64_t)v[0]) | (((uint64_t)v[1]) << 8) | @@ -126,7 +126,7 @@ struct sha3_impl { uint8_t *v; uint64_t tmp; // convert back to big endian - for (std::size_t i = 0; i < sizeof(words); i++) + for (std::size_t i = 0; i < number_of_words; i++) { v = (uint8_t *)(words + i); tmp = words[i]; diff --git a/libraries/libfc/test/CMakeLists.txt b/libraries/libfc/test/CMakeLists.txt index 1569ff6218..57d188b95d 100644 --- a/libraries/libfc/test/CMakeLists.txt +++ b/libraries/libfc/test/CMakeLists.txt @@ -11,12 +11,15 @@ add_executable( test_fc io/test_random_access_file.cpp io/test_raw.cpp io/test_tracked_storage.cpp + io/test_bounded_datastream.cpp network/test_message_buffer.cpp scoped_exit/test_scoped_exit.cpp static_variant/test_static_variant.cpp variant/test_variant.cpp variant/test_variant_dynamic_bitset.cpp variant_estimated_size/test_variant_estimated_size.cpp + test_base58.cpp + test_m1_adversarial.cpp test_base64.cpp test_escape_str.cpp test_bls.cpp diff --git a/libraries/libfc/test/io/test_bounded_datastream.cpp b/libraries/libfc/test/io/test_bounded_datastream.cpp new file mode 100644 index 0000000000..e26a2e6eb6 --- /dev/null +++ b/libraries/libfc/test/io/test_bounded_datastream.cpp @@ -0,0 +1,402 @@ +#include + +#include +#include +#include +#include + +using namespace fc; + +BOOST_AUTO_TEST_SUITE(bounded_datastream_tests) + +BOOST_AUTO_TEST_CASE(bounded_datastream_read_bounds) try { + char buffer[100]; + memset(buffer, 0x42, sizeof(buffer)); + + fc::datastream raw_ds(buffer, sizeof(buffer)); + fc::bounded_datastream bds(raw_ds, 20); + + BOOST_CHECK_EQUAL(bds.max_bytes(), 20u); + BOOST_CHECK_EQUAL(bds.remaining(), 20u); + BOOST_CHECK_EQUAL(bds.tellp(), 0u); + BOOST_CHECK(bds.valid()); + + char out[30]; + // Read 10 bytes: success + BOOST_CHECK(bds.read(out, 10)); + BOOST_CHECK_EQUAL(bds.remaining(), 10u); + BOOST_CHECK_EQUAL(bds.tellp(), 10u); + + // Attempting to read 11 bytes when only 10 remain: throws out_of_range_exception + BOOST_CHECK_THROW(bds.read(out, 11), fc::out_of_range_exception); + + // Read 8 bytes: success + BOOST_CHECK(bds.read(out, 8)); + BOOST_CHECK_EQUAL(bds.remaining(), 2u); + BOOST_CHECK_EQUAL(bds.tellp(), 18u); + + // Read remaining 2 bytes: success + char c1 = 0; + BOOST_CHECK(bds.get(c1)); + BOOST_CHECK_EQUAL(c1, 0x42); + BOOST_CHECK_EQUAL(bds.remaining(), 1u); + + unsigned char uc = 0; + BOOST_CHECK(bds.get(uc)); + BOOST_CHECK_EQUAL(uc, 0x42); + BOOST_CHECK_EQUAL(bds.remaining(), 0u); + BOOST_CHECK_EQUAL(bds.tellp(), 20u); + + // Reading beyond remaining 0: throws + BOOST_CHECK_THROW(bds.read(out, 1), fc::out_of_range_exception); + BOOST_CHECK_THROW(bds.get(c1), fc::out_of_range_exception); + BOOST_CHECK_THROW(bds.get(uc), fc::out_of_range_exception); + BOOST_CHECK_THROW(bds.skip(1), fc::out_of_range_exception); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(bounded_datastream_write_bounds) try { + char buffer[100]; + memset(buffer, 0, sizeof(buffer)); + + fc::datastream raw_ds(buffer, sizeof(buffer)); + fc::bounded_datastream bds(raw_ds, 15); + + BOOST_CHECK_EQUAL(bds.max_bytes(), 15u); + BOOST_CHECK_EQUAL(bds.remaining(), 15u); + + const char* text = "1234567890"; + BOOST_CHECK(bds.write(text, 10)); + BOOST_CHECK_EQUAL(bds.remaining(), 5u); + BOOST_CHECK_EQUAL(bds.tellp(), 10u); + + // Writing 6 bytes when 5 remain: throws + BOOST_CHECK_THROW(bds.write(text, 6), fc::out_of_range_exception); + + // Put 4 bytes + BOOST_CHECK(bds.put('a')); + BOOST_CHECK(bds.put('b')); + BOOST_CHECK(bds.put('c')); + BOOST_CHECK(bds.put('d')); + BOOST_CHECK_EQUAL(bds.remaining(), 1u); + + // Put last byte + BOOST_CHECK(bds.put('e')); + BOOST_CHECK_EQUAL(bds.remaining(), 0u); + + // Writing / putting when full: throws + BOOST_CHECK_THROW(bds.put('z'), fc::out_of_range_exception); + BOOST_CHECK_THROW(bds.write(text, 1), fc::out_of_range_exception); + + // Verify written content + BOOST_CHECK_EQUAL(std::string(buffer, 15), "1234567890abcde"); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(bounded_datastream_skip_and_seek) try { + char buffer[50]; + fc::datastream raw_ds(buffer, sizeof(buffer)); + fc::bounded_datastream bds(raw_ds, 30); + + bds.skip(10); + BOOST_CHECK_EQUAL(bds.tellp(), 10u); + BOOST_CHECK_EQUAL(bds.remaining(), 20u); + + // Skip past limit: throws + BOOST_CHECK_THROW(bds.skip(21), fc::out_of_range_exception); + + // Seek forward + BOOST_CHECK(bds.seekp(25)); + BOOST_CHECK_EQUAL(bds.tellp(), 25u); + BOOST_CHECK_EQUAL(bds.remaining(), 5u); + + // Seek past limit returns false + BOOST_CHECK(!bds.seekp(31)); + + // Seek backward (supported since raw_ds supports seekp) + BOOST_CHECK(bds.seekp(5)); + BOOST_CHECK_EQUAL(bds.tellp(), 5u); + BOOST_CHECK_EQUAL(bds.remaining(), 25u); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(bounded_datastream_pack_unpack) try { + char buffer[256]; + fc::datastream write_raw(buffer, sizeof(buffer)); + fc::bounded_datastream write_bds(write_raw, 256); + + std::string test_str = "hello bounded datastream"; + uint32_t val32 = 0x12345678; + uint64_t val64 = 0xdeadbeefcafebabeULL; + + fc::raw::pack(write_bds, test_str); + fc::raw::pack(write_bds, val32); + fc::raw::pack(write_bds, val64); + + size_t packed_size = write_bds.tellp(); + + // Unpack with exact bound + { + fc::datastream read_raw(buffer, packed_size); + fc::bounded_datastream read_bds(read_raw, packed_size); + + std::string out_str; + uint32_t out_32 = 0; + uint64_t out_64 = 0; + + fc::raw::unpack(read_bds, out_str); + fc::raw::unpack(read_bds, out_32); + fc::raw::unpack(read_bds, out_64); + + BOOST_CHECK_EQUAL(out_str, test_str); + BOOST_CHECK_EQUAL(out_32, val32); + BOOST_CHECK_EQUAL(out_64, val64); + BOOST_CHECK_EQUAL(read_bds.remaining(), 0u); + } + + // Unpack with truncated bound: must throw fc::out_of_range_exception + { + fc::datastream read_raw(buffer, packed_size); + fc::bounded_datastream read_bds(read_raw, packed_size - 4); // 4 bytes too short for val64 + + std::string out_str; + uint32_t out_32 = 0; + uint64_t out_64 = 0; + + fc::raw::unpack(read_bds, out_str); + fc::raw::unpack(read_bds, out_32); + BOOST_CHECK_THROW(fc::raw::unpack(read_bds, out_64), fc::out_of_range_exception); + } +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(bounded_datastream_with_message_buffer) try { + fc::message_buffer<1024> mb; + + std::vector payload(200, 'Z'); + memcpy(mb.write_ptr(), payload.data(), payload.size()); + mb.advance_write_ptr(payload.size()); + + auto mb_ds = mb.create_datastream(); + // Bound parsing to 50 bytes even though message buffer has 200 bytes + fc::bounded_datastream bds(mb_ds, 50); + + char read_buf[50]; + BOOST_CHECK(bds.read(read_buf, 50)); + BOOST_CHECK_EQUAL(bds.remaining(), 0u); + + // Attempting to read more through bds throws even though mb still has 150 bytes + BOOST_CHECK_THROW(bds.read(read_buf, 1), fc::out_of_range_exception); + BOOST_CHECK_EQUAL(mb.bytes_to_read(), 150u); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(bounded_datastream_with_mirror) try { + char buffer[100]; + memset(buffer, 'M', sizeof(buffer)); + + fc::datastream raw_ds(buffer, sizeof(buffer)); + fc::bounded_datastream bds(raw_ds, 30); + fc::datastream_mirror mirror_ds(bds, 30); + + char out[20]; + BOOST_CHECK(mirror_ds.read(out, 20)); + BOOST_CHECK_EQUAL(bds.remaining(), 10u); + + // Reading 15 bytes exceeds bds remaining 10: throws + BOOST_CHECK_THROW(mirror_ds.read(out, 15), fc::out_of_range_exception); + + // Read remaining 10 bytes + BOOST_CHECK(mirror_ds.read(out, 10)); + BOOST_CHECK_EQUAL(bds.remaining(), 0u); + + auto mirror = mirror_ds.extract_mirror(); + BOOST_CHECK_EQUAL(mirror.size(), 30u); + BOOST_CHECK_EQUAL(std::string(mirror.data(), mirror.size()), std::string(30, 'M')); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(bounded_datastream_zero_max_bytes) try { + char buffer[10] = "123456789"; + fc::datastream raw_read(buffer, sizeof(buffer)); + fc::bounded_datastream bds_read(raw_read, 0); + + BOOST_CHECK_EQUAL(bds_read.max_bytes(), 0u); + BOOST_CHECK_EQUAL(bds_read.remaining(), 0u); + BOOST_CHECK_EQUAL(bds_read.tellp(), 0u); + BOOST_CHECK(bds_read.valid()); + + char out[10]; + // Reading 0 bytes succeeds + BOOST_CHECK(bds_read.read(out, 0)); + BOOST_CHECK_EQUAL(bds_read.tellp(), 0u); + BOOST_CHECK_EQUAL(bds_read.remaining(), 0u); + + // Reading 1 byte throws out_of_range_exception + BOOST_CHECK_THROW(bds_read.read(out, 1), fc::out_of_range_exception); + char c = 0; + BOOST_CHECK_THROW(bds_read.get(c), fc::out_of_range_exception); + + // Skip 0 succeeds, skip 1 throws + bds_read.skip(0); + BOOST_CHECK_THROW(bds_read.skip(1), fc::out_of_range_exception); + + // Seekp 0 succeeds, seekp 1 returns false + BOOST_CHECK(bds_read.seekp(0)); + BOOST_CHECK(!bds_read.seekp(1)); + + // Zero-max write stream + char write_buf[10]; + fc::datastream raw_write(write_buf, sizeof(write_buf)); + fc::bounded_datastream bds_write(raw_write, 0); + + BOOST_CHECK(bds_write.write("a", 0)); + BOOST_CHECK_THROW(bds_write.write("a", 1), fc::out_of_range_exception); + BOOST_CHECK_THROW(bds_write.put('a'), fc::out_of_range_exception); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(bounded_datastream_multibyte_boundary_crossing) try { + char buffer[128]; + fc::datastream write_raw(buffer, sizeof(buffer)); + uint16_t u16 = 0x1234; + uint32_t u32 = 0xdeadbeef; + uint64_t u64 = 0x0123456789abcdefULL; + double dbl = 3.141592653589793; + std::vector vec = {10, 20, 30, 40, 50}; + + fc::raw::pack(write_raw, u16); + fc::raw::pack(write_raw, u32); + fc::raw::pack(write_raw, u64); + fc::raw::pack(write_raw, dbl); + fc::raw::pack(write_raw, vec); + + size_t total_packed = write_raw.tellp(); + + // Truncate stream at 1 byte (less than uint16_t size 2) + { + fc::datastream read_raw(buffer, total_packed); + fc::bounded_datastream bds(read_raw, 1); + uint16_t val; + BOOST_CHECK_THROW(fc::raw::unpack(bds, val), fc::out_of_range_exception); + } + + // Unpack uint16_t (2 bytes), then attempt uint32_t (4 bytes) with only 3 bytes remaining (total 5) + { + fc::datastream read_raw(buffer, total_packed); + fc::bounded_datastream bds(read_raw, 5); + uint16_t val16; + fc::raw::unpack(bds, val16); + BOOST_CHECK_EQUAL(val16, u16); + BOOST_CHECK_EQUAL(bds.remaining(), 3u); + + uint32_t val32; + BOOST_CHECK_THROW(fc::raw::unpack(bds, val32), fc::out_of_range_exception); + } + + // Unpack uint16_t (2), uint32_t (4), then attempt uint64_t (8) with only 7 bytes remaining (total 13) + { + fc::datastream read_raw(buffer, total_packed); + fc::bounded_datastream bds(read_raw, 13); + uint16_t val16; + uint32_t val32; + fc::raw::unpack(bds, val16); + fc::raw::unpack(bds, val32); + BOOST_CHECK_EQUAL(val16, u16); + BOOST_CHECK_EQUAL(val32, u32); + BOOST_CHECK_EQUAL(bds.remaining(), 7u); + + uint64_t val64; + BOOST_CHECK_THROW(fc::raw::unpack(bds, val64), fc::out_of_range_exception); + } + + // Unpack up to double (2+4+8+8 = 22 bytes), then unpack vector with 1 byte short of full vector payload + { + fc::datastream read_raw(buffer, total_packed); + fc::bounded_datastream bds(read_raw, total_packed - 1); + uint16_t val16; + uint32_t val32; + uint64_t val64; + double val_dbl; + fc::raw::unpack(bds, val16); + fc::raw::unpack(bds, val32); + fc::raw::unpack(bds, val64); + fc::raw::unpack(bds, val_dbl); + + std::vector val_vec; + BOOST_CHECK_THROW(fc::raw::unpack(bds, val_vec), fc::out_of_range_exception); + } +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(bounded_datastream_nested_streams) try { + char buffer[100]; + memset(buffer, 'A', sizeof(buffer)); + + // Outer bounded stream (limit 20) wrapping inner bounded stream (limit 10) + { + fc::datastream raw_ds(buffer, sizeof(buffer)); + fc::bounded_datastream inner_bds(raw_ds, 10); + fc::bounded_datastream outer_bds(inner_bds, 20); + + char out[30]; + // Can read up to inner bound 10 + BOOST_CHECK(outer_bds.read(out, 10)); + // Attempting 11th byte throws at inner_bds + BOOST_CHECK_THROW(outer_bds.read(out, 1), fc::out_of_range_exception); + } + + // Outer bounded stream (limit 10) wrapping inner bounded stream (limit 20) + { + fc::datastream raw_ds(buffer, sizeof(buffer)); + fc::bounded_datastream inner_bds(raw_ds, 20); + fc::bounded_datastream outer_bds(inner_bds, 10); + + char out[30]; + // Can read up to outer bound 10 + BOOST_CHECK(outer_bds.read(out, 10)); + // Attempting 11th byte throws at outer_bds + BOOST_CHECK_THROW(outer_bds.read(out, 1), fc::out_of_range_exception); + } +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(bounded_datastream_message_buffer_ring_wrap) try { + fc::message_buffer<32> mb; + + // Fill 24 bytes + std::string s1(24, 'X'); + memcpy(mb.write_ptr(), s1.data(), 24); + mb.advance_write_ptr(24); + + // Consume 20 bytes + mb.advance_read_ptr(20); + BOOST_CHECK_EQUAL(mb.bytes_to_read(), 4u); + + // Write 20 bytes spanning chunks in message_buffer + std::string s2(20, 'Y'); + mb.add_space(20); + auto space = mb.get_buffer_sequence_for_boost_async_read(); + size_t copied = 0; + for (auto b : space) { + size_t chunk = std::min(b.size(), s2.size() - copied); + memcpy(b.data(), s2.data() + copied, chunk); + copied += chunk; + if (copied == s2.size()) break; + } + mb.advance_write_ptr(20); + BOOST_CHECK_EQUAL(mb.bytes_to_read(), 24u); // 4 'X' + 20 'Y' + + // Create datastream and bounded datastream over wrapped message_buffer + auto mb_ds = mb.create_datastream(); + fc::bounded_datastream bds(mb_ds, 24); + + // Read 10 bytes crossing circular wrap + char read_out[24]; + BOOST_CHECK(bds.read(read_out, 10)); + BOOST_CHECK_EQUAL(std::string(read_out, 4), "XXXX"); + BOOST_CHECK_EQUAL(std::string(read_out + 4, 6), "YYYYYY"); + BOOST_CHECK_EQUAL(bds.remaining(), 14u); + + // Read remaining 14 bytes + BOOST_CHECK(bds.read(read_out + 10, 14)); + BOOST_CHECK_EQUAL(std::string(read_out + 10, 14), std::string(14, 'Y')); + BOOST_CHECK_EQUAL(bds.remaining(), 0u); + + // Reading further throws + BOOST_CHECK_THROW(bds.read(read_out, 1), fc::out_of_range_exception); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/libraries/libfc/test/network/test_message_buffer.cpp b/libraries/libfc/test/network/test_message_buffer.cpp index 8a6ab2adb6..3b10c2b857 100644 --- a/libraries/libfc/test/network/test_message_buffer.cpp +++ b/libraries/libfc/test/network/test_message_buffer.cpp @@ -271,6 +271,103 @@ BOOST_AUTO_TEST_CASE(message_buffer_read_peek_bounds) { BOOST_CHECK_THROW(mbuff.read(&throw_away_buffer, 1), fc::out_of_range_exception); } +BOOST_AUTO_TEST_CASE(message_buffer_advance_read_ptr_bounds) { + using my_message_buffer_t = fc::message_buffer<1024>; + my_message_buffer_t mbuff; + char stuff[100]; + memset(stuff, 0x5a, sizeof(stuff)); + memcpy(mbuff.write_ptr(), stuff, sizeof(stuff)); + mbuff.advance_write_ptr(sizeof(stuff)); + + BOOST_CHECK_EQUAL(mbuff.bytes_to_read(), 100u); + mbuff.advance_read_ptr(50); + BOOST_CHECK_EQUAL(mbuff.bytes_to_read(), 50u); + + // Attempting to advance beyond bytes_to_read() must throw fc::out_of_range_exception + BOOST_CHECK_THROW(mbuff.advance_read_ptr(51), fc::out_of_range_exception); + BOOST_CHECK_THROW(mbuff.advance_read_ptr(1000), fc::out_of_range_exception); + + // Valid advance up to remaining + mbuff.advance_read_ptr(50); + BOOST_CHECK_EQUAL(mbuff.bytes_to_read(), 0u); + + // Advancing any non-zero bytes when empty must throw + BOOST_CHECK_THROW(mbuff.advance_read_ptr(1), fc::out_of_range_exception); +} + +BOOST_AUTO_TEST_CASE(message_buffer_advance_read_ptr_edge_stress) { + using my_mb_t = fc::message_buffer<64>; + my_mb_t mbuff; + + // 1. Empty buffer + BOOST_CHECK_EQUAL(mbuff.bytes_to_read(), 0u); + // Advance 0 bytes on empty buffer must succeed without throwing + mbuff.advance_read_ptr(0); + BOOST_CHECK_EQUAL(mbuff.bytes_to_read(), 0u); + + // Advance 1 byte on empty buffer must throw + BOOST_CHECK_THROW(mbuff.advance_read_ptr(1), fc::out_of_range_exception); + // Advance UINT32_MAX on empty buffer must throw + BOOST_CHECK_THROW(mbuff.advance_read_ptr(std::numeric_limits::max()), fc::out_of_range_exception); + + // 2. Partially filled buffer + char data[40]; + memset(data, 0x77, sizeof(data)); + memcpy(mbuff.write_ptr(), data, sizeof(data)); + mbuff.advance_write_ptr(sizeof(data)); + BOOST_CHECK_EQUAL(mbuff.bytes_to_read(), 40u); + + // Advance 0 on non-empty buffer must succeed + mbuff.advance_read_ptr(0); + BOOST_CHECK_EQUAL(mbuff.bytes_to_read(), 40u); + + // Advance bytes_to_read() + 1 must throw + BOOST_CHECK_THROW(mbuff.advance_read_ptr(41), fc::out_of_range_exception); + // Advance UINT32_MAX must throw + BOOST_CHECK_THROW(mbuff.advance_read_ptr(std::numeric_limits::max()), fc::out_of_range_exception); + // Buffer state must remain intact + BOOST_CHECK_EQUAL(mbuff.bytes_to_read(), 40u); + + // Advance exact bytes_to_read() + mbuff.advance_read_ptr(40); + BOOST_CHECK_EQUAL(mbuff.bytes_to_read(), 0u); + + // 3. Ring buffer wrap + // Write 50 bytes, read 40 bytes (10 remaining) + memcpy(mbuff.write_ptr(), data, 40); + mbuff.advance_write_ptr(40); + memcpy(mbuff.write_ptr(), data, 10); + mbuff.advance_write_ptr(10); + BOOST_CHECK_EQUAL(mbuff.bytes_to_read(), 50u); + mbuff.advance_read_ptr(40); + BOOST_CHECK_EQUAL(mbuff.bytes_to_read(), 10u); + + // Now write 40 bytes which wraps around circular buffer + auto space = mbuff.get_buffer_sequence_for_boost_async_read(); + size_t copied = 0; + for (auto b : space) { + size_t chunk = std::min(b.size(), size_t(40) - copied); + memcpy(b.data(), data + copied, chunk); + copied += chunk; + if (copied == 40) break; + } + mbuff.advance_write_ptr(40); + BOOST_CHECK_EQUAL(mbuff.bytes_to_read(), 50u); // 10 from before + 40 wrapped + + // Advance across segment boundary + mbuff.advance_read_ptr(15); + BOOST_CHECK_EQUAL(mbuff.bytes_to_read(), 35u); + + // Attempt advance 36 (past remaining) + BOOST_CHECK_THROW(mbuff.advance_read_ptr(36), fc::out_of_range_exception); + BOOST_CHECK_THROW(mbuff.advance_read_ptr(std::numeric_limits::max()), fc::out_of_range_exception); + + // Advance remaining 35 + mbuff.advance_read_ptr(35); + BOOST_CHECK_EQUAL(mbuff.bytes_to_read(), 0u); +} + + BOOST_AUTO_TEST_CASE(message_buffer_read_peek_bounds_multi) { using my_message_buffer_t = fc::message_buffer<5>; my_message_buffer_t mbuff; diff --git a/libraries/libfc/test/test_base58.cpp b/libraries/libfc/test/test_base58.cpp new file mode 100644 index 0000000000..1704acc9e2 --- /dev/null +++ b/libraries/libfc/test/test_base58.cpp @@ -0,0 +1,91 @@ +#include + +#include +#include + +using namespace fc; +using namespace std::literals; + +BOOST_AUTO_TEST_SUITE(base58_tests) + +BOOST_AUTO_TEST_CASE(base58_null_and_empty_safety) try { + // to_base58 with nullptr and 0 length should return empty string without UB + BOOST_CHECK_EQUAL(to_base58(nullptr, 0), ""); + + // to_base58 with nullptr and non-zero length should throw fc::assert_exception + BOOST_CHECK_THROW(to_base58(nullptr, 1), fc::assert_exception); + BOOST_CHECK_THROW(to_base58(nullptr, 100), fc::assert_exception); + + // to_base58 with empty std::vector should return empty string + std::vector empty_vec; + BOOST_CHECK_EQUAL(to_base58(empty_vec), ""); + + // from_base58 on empty string + std::vector decoded_empty = from_base58(""); + BOOST_CHECK(decoded_empty.empty()); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(base58_round_trip) try { + std::string input = "Hello World!"; + std::string encoded = to_base58(input.data(), input.size()); + BOOST_CHECK(!encoded.empty()); + + std::vector decoded = from_base58(encoded); + std::string roundtrip(decoded.data(), decoded.size()); + BOOST_CHECK_EQUAL(input, roundtrip); + + // Vector overload + std::vector input_vec(input.begin(), input.end()); + std::string encoded_vec = to_base58(input_vec); + BOOST_CHECK_EQUAL(encoded, encoded_vec); + + // Test with leading zero bytes (Base58 uses '1' for leading zero bytes) + std::vector with_zeros = {0, 0, 'a', 'b', 'c'}; + std::string encoded_zeros = to_base58(with_zeros); + BOOST_CHECK_EQUAL(encoded_zeros.substr(0, 2), "11"); + std::vector decoded_zeros = from_base58(encoded_zeros); + BOOST_CHECK(with_zeros == decoded_zeros); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(base58_invalid_decode) try { + // Characters not in Base58 alphabet (0, O, I, l) + BOOST_CHECK_THROW(from_base58("0OIl"), fc::parse_error_exception); + BOOST_CHECK_THROW(from_base58("invalid!character?"), fc::parse_error_exception); + // Whitespace alone is valid empty input in Bitcoin/libfc Base58 decoder + BOOST_CHECK(from_base58(" ").empty()); + BOOST_CHECK_THROW(from_base58("abc\ndef"), fc::parse_error_exception); + BOOST_CHECK_THROW(from_base58("\x80\xff\xfe"), fc::parse_error_exception); + BOOST_CHECK_THROW(from_base58("@#$"), fc::parse_error_exception); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(base58_large_payload_and_yield) try { + // Large byte payload (5000 bytes) + std::vector large_input(5000); + for (size_t i = 0; i < large_input.size(); ++i) { + large_input[i] = static_cast((i * 101 + 37) % 256); + } + + size_t yield_calls = 0; + auto yield_func = [&yield_calls]() { + yield_calls++; + }; + + std::string encoded = to_base58(large_input, yield_func); + BOOST_CHECK(!encoded.empty()); + BOOST_CHECK_GT(yield_calls, 0u); + + std::vector decoded = from_base58(encoded); + BOOST_CHECK(large_input == decoded); + + // Fixed output buffer overload + std::vector fixed_buf(decoded.size()); + size_t decoded_len = from_base58(encoded, fixed_buf.data(), fixed_buf.size()); + BOOST_CHECK_EQUAL(decoded_len, large_input.size()); + BOOST_CHECK(large_input == fixed_buf); + + // Fixed output buffer undersized throws assert_exception + BOOST_CHECK_THROW(from_base58(encoded, fixed_buf.data(), fixed_buf.size() - 1), fc::assert_exception); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/libraries/libfc/test/test_m1_adversarial.cpp b/libraries/libfc/test/test_m1_adversarial.cpp new file mode 100644 index 0000000000..1dabca2350 --- /dev/null +++ b/libraries/libfc/test/test_m1_adversarial.cpp @@ -0,0 +1,377 @@ +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace fc; + +BOOST_AUTO_TEST_SUITE(m1_adversarial_stress_tests) + +// ============================================================================= +// 1. fc::bounded_datastream Adversarial Stress Tests +// ============================================================================= + +BOOST_AUTO_TEST_CASE(bounded_datastream_zero_limit_adversarial) try { + char src[10] = "123456789"; + fc::datastream raw_ds(src, sizeof(src)); + fc::bounded_datastream bds(raw_ds, 0); + + BOOST_CHECK_EQUAL(bds.max_bytes(), 0u); + BOOST_CHECK_EQUAL(bds.remaining(), 0u); + BOOST_CHECK_EQUAL(bds.tellp(), 0u); + BOOST_CHECK(bds.valid()); + + // Reading 0 bytes is a no-op and succeeds + char out[10]; + BOOST_CHECK(bds.read(out, 0)); + BOOST_CHECK_EQUAL(bds.tellp(), 0u); + BOOST_CHECK_EQUAL(bds.remaining(), 0u); + + // Reading 1 byte throws out_of_range_exception + BOOST_CHECK_THROW(bds.read(out, 1), fc::out_of_range_exception); + + // get() throws + char c = 0; + BOOST_CHECK_THROW(bds.get(c), fc::out_of_range_exception); + + // skip(0) succeeds, skip(1) throws + bds.skip(0); + BOOST_CHECK_THROW(bds.skip(1), fc::out_of_range_exception); + + // seekp(0) succeeds, seekp(1) fails + BOOST_CHECK(bds.seekp(0)); + BOOST_CHECK(!bds.seekp(1)); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(bounded_datastream_nested_streams_adversarial) try { + std::vector buffer(200, 'A'); + fc::datastream raw_ds(buffer.data(), buffer.size()); + + // Outer bounded to 100 bytes + fc::bounded_datastream outer_bds(raw_ds, 100); + // Inner bounded to 40 bytes wrapping outer + fc::bounded_datastream inner_bds(outer_bds, 40); + + BOOST_CHECK_EQUAL(inner_bds.max_bytes(), 40u); + BOOST_CHECK_EQUAL(inner_bds.remaining(), 40u); + + char out[100]; + // Reading 40 bytes from inner succeeds + BOOST_CHECK(inner_bds.read(out, 40)); + BOOST_CHECK_EQUAL(inner_bds.remaining(), 0u); + BOOST_CHECK_EQUAL(outer_bds.remaining(), 60u); + + // Reading 1 more from inner fails even though outer has 60 remaining + BOOST_CHECK_THROW(inner_bds.read(out, 1), fc::out_of_range_exception); + + // Outer can continue reading its remaining 60 bytes + BOOST_CHECK(outer_bds.read(out, 60)); + BOOST_CHECK_EQUAL(outer_bds.remaining(), 0u); + + // Outer throws on next byte + BOOST_CHECK_THROW(outer_bds.read(out, 1), fc::out_of_range_exception); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(bounded_datastream_stress_fuzz) try { + const size_t total_buf_size = 4096; + std::vector raw_buffer(total_buf_size); + for (size_t i = 0; i < total_buf_size; ++i) { + raw_buffer[i] = static_cast(i % 256); + } + + std::mt19937 rng(42); + + for (int iter = 0; iter < 100; ++iter) { + size_t max_bound = rng() % 500; + fc::datastream ds(raw_buffer.data(), total_buf_size); + fc::bounded_datastream bds(ds, max_bound); + + size_t consumed = 0; + while (consumed < max_bound) { + size_t chunk = (rng() % 30) + 1; + if (consumed + chunk <= max_bound) { + std::vector tmp(chunk); + BOOST_CHECK(bds.read(tmp.data(), chunk)); + consumed += chunk; + BOOST_CHECK_EQUAL(bds.tellp(), consumed); + BOOST_CHECK_EQUAL(bds.remaining(), max_bound - consumed); + } else { + // Attempting to read chunk that crosses boundary MUST throw + std::vector tmp(chunk); + BOOST_CHECK_THROW(bds.read(tmp.data(), chunk), fc::out_of_range_exception); + // State should remain intact + BOOST_CHECK_EQUAL(bds.tellp(), consumed); + BOOST_CHECK_EQUAL(bds.remaining(), max_bound - consumed); + // Read exact remainder + size_t rem = max_bound - consumed; + if (rem > 0) { + BOOST_CHECK(bds.read(tmp.data(), rem)); + consumed += rem; + } + break; + } + } + + BOOST_CHECK_EQUAL(bds.remaining(), 0u); + BOOST_CHECK_EQUAL(bds.tellp(), max_bound); + char c; + BOOST_CHECK_THROW(bds.get(c), fc::out_of_range_exception); + BOOST_CHECK_THROW(bds.skip(1), fc::out_of_range_exception); + } +} FC_LOG_AND_RETHROW(); + +// ============================================================================= +// 2. message_buffer::advance_read_ptr Adversarial Stress Tests +// ============================================================================= + +BOOST_AUTO_TEST_CASE(message_buffer_advance_read_ptr_adversarial) try { + fc::message_buffer<64> mb; + + // Empty buffer: advance by 1 throws + BOOST_CHECK_THROW(mb.advance_read_ptr(1), fc::out_of_range_exception); + + // Empty buffer: advance by UINT32_MAX throws + BOOST_CHECK_THROW(mb.advance_read_ptr(std::numeric_limits::max()), fc::out_of_range_exception); + + // Populate multi-chunk buffer (3 chunks: 64 * 3 = 192 bytes) + std::vector data(150, 0x33); + mb.add_space(150); + auto seq = mb.get_buffer_sequence_for_boost_async_read(); + size_t copied = 0; + for (auto& buf : seq) { + size_t chunk = std::min(data.size() - copied, buf.size()); + if (chunk == 0) break; + memcpy(buf.data(), data.data() + copied, chunk); + copied += chunk; + } + mb.advance_write_ptr(data.size()); + + BOOST_CHECK_EQUAL(mb.bytes_to_read(), 150u); + + // Advance past 150 throws + BOOST_CHECK_THROW(mb.advance_read_ptr(151), fc::out_of_range_exception); + BOOST_CHECK_THROW(mb.advance_read_ptr(std::numeric_limits::max()), fc::out_of_range_exception); + BOOST_CHECK_THROW(mb.advance_read_ptr(200), fc::out_of_range_exception); + + // Advance partial chunk (30 bytes) + mb.advance_read_ptr(30); + BOOST_CHECK_EQUAL(mb.bytes_to_read(), 120u); + + // Advance crossing chunk boundary (40 bytes -> total 70 bytes advanced) + mb.advance_read_ptr(40); + BOOST_CHECK_EQUAL(mb.bytes_to_read(), 80u); + + // Attempting to advance 81 throws + BOOST_CHECK_THROW(mb.advance_read_ptr(81), fc::out_of_range_exception); + + // Advance remaining 80 bytes -> should reset to 0 + mb.advance_read_ptr(80); + BOOST_CHECK_EQUAL(mb.bytes_to_read(), 0u); + + // Empty again: advancing 1 throws + BOOST_CHECK_THROW(mb.advance_read_ptr(1), fc::out_of_range_exception); +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(message_buffer_stress_cycles) try { + fc::message_buffer<128> mb; + std::mt19937 rng(12345); + + for (int cycle = 0; cycle < 200; ++cycle) { + uint32_t write_sz = (rng() % 500) + 1; + std::vector chunk(write_sz, static_cast(cycle)); + + // Ensure write space + while (mb.bytes_to_write() < write_sz) { + mb.add_buffer_to_chain(); + } + + // Write via get_buffer_sequence + auto seq = mb.get_buffer_sequence_for_boost_async_read(); + size_t written = 0; + for (auto& buf : seq) { + size_t to_copy = std::min(write_sz - written, buf.size()); + if (to_copy == 0) break; + memcpy(buf.data(), chunk.data() + written, to_copy); + written += to_copy; + } + mb.advance_write_ptr(write_sz); + + BOOST_CHECK_GE(mb.bytes_to_read(), write_sz); + + // Random partial advances + uint32_t to_consume = write_sz; + while (to_consume > 0) { + uint32_t step = std::min(to_consume, (rng() % 50) + 1); + // Test invalid overshoot check + BOOST_CHECK_THROW(mb.advance_read_ptr(mb.bytes_to_read() + 1), fc::out_of_range_exception); + mb.advance_read_ptr(step); + to_consume -= step; + } + BOOST_CHECK_EQUAL(mb.bytes_to_read(), 0u); + } +} FC_LOG_AND_RETHROW(); + +// ============================================================================= +// 3. base58 Adversarial Stress Tests +// ============================================================================= + +BOOST_AUTO_TEST_CASE(base58_pointer_null_and_boundary_adversarial) try { + // nullptr with size 0: safe, returns empty string + BOOST_CHECK_EQUAL(fc::to_base58(nullptr, 0), ""); + + // nullptr with non-zero sizes: MUST throw fc::assert_exception + BOOST_CHECK_THROW(fc::to_base58(nullptr, 1), fc::assert_exception); + BOOST_CHECK_THROW(fc::to_base58(nullptr, 50), fc::assert_exception); + BOOST_CHECK_THROW(fc::to_base58(nullptr, 1000000), fc::assert_exception); + + // Empty string decoding + std::vector dec_empty = fc::from_base58(""); + BOOST_CHECK(dec_empty.empty()); + + // All single-character invalid base58 characters + std::string invalid_chars = "0OIl!@#$%^&*()_+=-~`{}[]|:;'<>,.?/\"\\"; + for (char ch : invalid_chars) { + std::string s(1, ch); + BOOST_CHECK_THROW(fc::from_base58(s), fc::parse_error_exception); + } +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(base58_fuzz_roundtrip) try { + std::mt19937 rng(999); + + // Test all single byte values 0x00 .. 0xFF + for (int b = 0; b <= 255; ++b) { + char byte_val = static_cast(b); + std::string enc = fc::to_base58(&byte_val, 1); + BOOST_CHECK(!enc.empty()); + std::vector dec = fc::from_base58(enc); + BOOST_REQUIRE_EQUAL(dec.size(), 1u); + BOOST_CHECK_EQUAL(dec[0], byte_val); + } + + // Test 200 random byte sequences of various lengths + for (int i = 0; i < 200; ++i) { + size_t len = rng() % 256; + std::vector raw(len); + for (size_t j = 0; j < len; ++j) { + raw[j] = static_cast(rng() & 0xFF); + } + + std::string enc = fc::to_base58(raw); + std::vector dec = fc::from_base58(enc); + BOOST_REQUIRE_EQUAL(raw.size(), dec.size()); + BOOST_CHECK(raw == dec); + } +} FC_LOG_AND_RETHROW(); + +// ============================================================================= +// 4. SHA3 / Keccak Standard Vectors and Streaming Adversarial Tests +// ============================================================================= + +BOOST_AUTO_TEST_CASE(sha3_nist_and_keccak_vectors) try { + // NIST SHA3-256 standard vectors + { + // Empty input + fc::sha3::encoder enc; + fc::sha3 h = enc.result(true /* NIST */); + BOOST_CHECK_EQUAL(h.str(), "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a"); + } + { + // "abc" + fc::sha3::encoder enc; + enc.write("abc", 3); + fc::sha3 h = enc.result(true /* NIST */); + BOOST_CHECK_EQUAL(h.str(), "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532"); + } + + // Keccak-256 (Ethereum variant) standard vectors + { + // Empty input + fc::sha3::encoder enc; + fc::sha3 h = enc.result(false /* Keccak */); + BOOST_CHECK_EQUAL(h.str(), "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"); + } + { + // "abc" + fc::sha3::encoder enc; + enc.write("abc", 3); + fc::sha3 h = enc.result(false /* Keccak */); + BOOST_CHECK_EQUAL(h.str(), "4e03657aea45a94fc7d47ba826c8d667c0d1e6e33a64a036ec44f58fa12d6c45"); + } +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(sha3_streaming_chunk_equivalence_adversarial) try { + // SHA3 rate is 136 bytes for 256-bit hash. + // Test boundaries around 136: 135, 136, 137, 272, 500 bytes + std::vector test_sizes = {0, 1, 10, 135, 136, 137, 271, 272, 273, 500, 1024}; + + for (size_t sz : test_sizes) { + std::vector data(sz); + for (size_t i = 0; i < sz; ++i) { + data[i] = static_cast((i * 17 + 3) & 0xFF); + } + + // Hash all at once + fc::sha3::encoder enc_bulk; + if (sz > 0) enc_bulk.write(data.data(), data.size()); + fc::sha3 h_bulk = enc_bulk.result(true); + + // Hash byte-by-byte + fc::sha3::encoder enc_step; + for (size_t i = 0; i < sz; ++i) { + enc_step.write(&data[i], 1); + } + fc::sha3 h_step = enc_step.result(true); + + BOOST_CHECK_EQUAL(h_bulk.str(), h_step.str()); + } +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_CASE(sha3_endian_swap_logic_verification) try { + // Verify the 25-word byte-swapping logic mathematically: + // Simulating big-endian words <-> bytes conversions to prove reversibility and no array overrun + constexpr size_t number_of_words = 25; + uint64_t words[number_of_words]; + for (size_t i = 0; i < number_of_words; ++i) { + words[i] = 0x0102030405060708ULL + i * 0x1111111111111111ULL; + } + + uint64_t original[number_of_words]; + memcpy(original, words, sizeof(words)); + + // Convert to big-endian (simulating memory bytes on BE machine) + for (std::size_t i = 0; i < number_of_words; i++) { + uint8_t* v = (uint8_t*)(words + i); + uint64_t tmp = words[i]; + v[0] = tmp & 0xFF; + v[1] = (tmp >> 8) & 0xFF; + v[2] = (tmp >> 16) & 0xFF; + v[3] = (tmp >> 24) & 0xFF; + v[4] = (tmp >> 32) & 0xFF; + v[5] = (tmp >> 40) & 0xFF; + v[6] = (tmp >> 48) & 0xFF; + v[7] = (tmp >> 56) & 0xFF; + } + + // Convert back from big-endian bytes to little-endian words + for (std::size_t i = 0; i < number_of_words; i++) { + uint8_t* v = reinterpret_cast(words + i); + words[i] = ((uint64_t)v[0]) | (((uint64_t)v[1]) << 8) | + (((uint64_t)v[2]) << 16) | (((uint64_t)v[3]) << 24) | + (((uint64_t)v[4]) << 32) | (((uint64_t)v[5]) << 40) | + (((uint64_t)v[6]) << 48) | (((uint64_t)v[7]) << 56); + } + + for (size_t i = 0; i < number_of_words; ++i) { + BOOST_CHECK_EQUAL(words[i], original[i]); + } +} FC_LOG_AND_RETHROW(); + +BOOST_AUTO_TEST_SUITE_END() diff --git a/libraries/state_history/include/eosio/state_history/serialization.hpp b/libraries/state_history/include/eosio/state_history/serialization.hpp index 9b6bad8e3f..72c7ddb5d0 100644 --- a/libraries/state_history/include/eosio/state_history/serialization.hpp +++ b/libraries/state_history/include/eosio/state_history/serialization.hpp @@ -146,7 +146,8 @@ void history_pack_big_bytes(datastream& ds, const eosio::chain::bytes& v) { template void history_pack_big_bytes(datastream& ds, const eosio::chain::shared_blob& b) { fc::raw::pack(ds, unsigned_int((uint32_t)b.size())); - ds.write(b.data(), b.size()); + if (b.size()) + ds.write(b.data(), b.size()); } template diff --git a/unittests/state_history_tests.cpp b/unittests/state_history_tests.cpp index 80d5c74bdf..44b40c842f 100644 --- a/unittests/state_history_tests.cpp +++ b/unittests/state_history_tests.cpp @@ -12,11 +12,13 @@ #include #include "test_cfd_transaction.hpp" +#include #include #include #include #include +#include "../plugins/state_history_plugin/include/eosio/state_history_plugin/session.hpp" using namespace eosio::chain; using namespace eosio::testing; @@ -902,4 +904,240 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(test_corrupted_log_recovery, T, state_history_test BOOST_CHECK(get_decompressed_entry(new_chain.chain_state_log,10).size()); } +BOOST_AUTO_TEST_CASE(test_history_pack_big_bytes_shared_blob) { + // Empty shared_blob serialization should pack size 0 without calling ds.write(nullptr, 0) + { + eosio::chain::shared_blob empty_blob; + BOOST_CHECK_EQUAL(empty_blob.size(), 0u); + BOOST_CHECK(empty_blob.data() == nullptr); + + std::vector buffer(1024); + fc::datastream ds(buffer.data(), buffer.size()); + fc::history_pack_big_bytes(ds, empty_blob); + + BOOST_CHECK_EQUAL(ds.tellp(), 1u); // unsigned_int(0) packs to 1 byte + + fc::datastream read_ds(buffer.data(), ds.tellp()); + fc::unsigned_int unpacked_size; + fc::raw::unpack(read_ds, unpacked_size); + BOOST_CHECK_EQUAL(unpacked_size.value, 0u); + } + + // Non-empty shared_blob serialization + { + std::string sample = "state_history_payload"; + eosio::chain::shared_blob blob{std::string_view(sample)}; + BOOST_CHECK_EQUAL(blob.size(), sample.size()); + + std::vector buffer(1024); + fc::datastream ds(buffer.data(), buffer.size()); + fc::history_pack_big_bytes(ds, blob); + + fc::datastream read_ds(buffer.data(), ds.tellp()); + fc::unsigned_int unpacked_size; + fc::raw::unpack(read_ds, unpacked_size); + BOOST_CHECK_EQUAL(unpacked_size.value, sample.size()); + + std::string read_payload(unpacked_size.value, '\0'); + read_ds.read(read_payload.data(), unpacked_size.value); + BOOST_CHECK_EQUAL(sample, read_payload); + } + + // 1-byte small shared_blob + { + std::string sample = "Q"; + eosio::chain::shared_blob blob{std::string_view(sample)}; + std::vector buffer(64); + fc::datastream ds(buffer.data(), buffer.size()); + fc::history_pack_big_bytes(ds, blob); + + BOOST_CHECK_EQUAL(ds.tellp(), 2u); // 1 byte varuint + 1 byte data + + fc::datastream read_ds(buffer.data(), ds.tellp()); + fc::unsigned_int sz; + fc::raw::unpack(read_ds, sz); + BOOST_CHECK_EQUAL(sz.value, 1u); + char val = 0; + read_ds.read(&val, 1); + BOOST_CHECK_EQUAL(val, 'Q'); + } + + // Large shared_blob serialization (512 KB) + { + std::string large_payload(512 * 1024, 'K'); + eosio::chain::shared_blob large_blob{std::string_view(large_payload)}; + std::vector buffer(large_payload.size() + 16); + fc::datastream ds(buffer.data(), buffer.size()); + fc::history_pack_big_bytes(ds, large_blob); + + fc::datastream read_ds(buffer.data(), ds.tellp()); + fc::unsigned_int unpacked_size; + fc::raw::unpack(read_ds, unpacked_size); + BOOST_CHECK_EQUAL(unpacked_size.value, large_payload.size()); + + std::string read_payload(unpacked_size.value, '\0'); + read_ds.read(read_payload.data(), unpacked_size.value); + BOOST_CHECK_EQUAL(large_payload, read_payload); + } + + // Sequential serialization of empty and non-empty shared_blobs into the same stream + { + eosio::chain::shared_blob empty1; + eosio::chain::shared_blob blob1{std::string_view("first")}; + eosio::chain::shared_blob empty2; + eosio::chain::shared_blob blob2{std::string_view("second_much_longer_payload_with_symbols!@#")}; + + std::vector buffer(1024); + fc::datastream ds(buffer.data(), buffer.size()); + fc::history_pack_big_bytes(ds, empty1); + fc::history_pack_big_bytes(ds, blob1); + fc::history_pack_big_bytes(ds, empty2); + fc::history_pack_big_bytes(ds, blob2); + + fc::datastream read_ds(buffer.data(), ds.tellp()); + fc::unsigned_int sz; + + // 1. empty1 + fc::raw::unpack(read_ds, sz); + BOOST_CHECK_EQUAL(sz.value, 0u); + + // 2. blob1 + fc::raw::unpack(read_ds, sz); + BOOST_CHECK_EQUAL(sz.value, 5u); + std::string out1(sz.value, '\0'); + read_ds.read(out1.data(), sz.value); + BOOST_CHECK_EQUAL(out1, "first"); + + // 3. empty2 + fc::raw::unpack(read_ds, sz); + BOOST_CHECK_EQUAL(sz.value, 0u); + + // 4. blob2 + fc::raw::unpack(read_ds, sz); + BOOST_CHECK_EQUAL(sz.value, blob2.size()); + std::string out2(sz.value, '\0'); + read_ds.read(out2.data(), sz.value); + BOOST_CHECK_EQUAL(out2, std::string(blob2.data(), blob2.size())); + } +} + +BOOST_AUTO_TEST_CASE(ship_status_request_queue_bounds_test) { + using eosio::state_history::status_request_queue; + using eosio::state_history::status_request_queue_limit_exceeded; + + // Test 1: Default capacity (100) + status_request_queue queue; + BOOST_CHECK_EQUAL(queue.size(), 0u); + BOOST_CHECK(queue.empty()); + BOOST_CHECK_EQUAL(queue.max_size(), 100u); + + // Fill queue to capacity with 100 status requests + for (size_t i = 0; i < 100; ++i) { + bool is_v1 = (i % 2 == 1); + BOOST_CHECK(queue.try_append(is_v1)); + BOOST_CHECK_EQUAL(queue.size(), i + 1); + } + BOOST_CHECK_EQUAL(queue.size(), 100u); + BOOST_CHECK(!queue.empty()); + + // 101st request must fail to append + BOOST_CHECK(!queue.try_append(false)); + BOOST_CHECK_EQUAL(queue.size(), 100u); + + // Asserting on try_append throws status_request_queue_limit_exceeded + auto append_or_throw = [](status_request_queue& q, bool is_v1) { + EOS_ASSERT(q.try_append(is_v1), + status_request_queue_limit_exceeded, + "State history status request queue limit exceeded"); + }; + BOOST_CHECK_THROW(append_or_throw(queue, true), status_request_queue_limit_exceeded); + BOOST_CHECK_EQUAL(queue.size(), 100u); + + // Extract drains the queue + std::deque extracted = queue.extract(); + BOOST_CHECK_EQUAL(extracted.size(), 100u); + BOOST_CHECK_EQUAL(queue.size(), 0u); + BOOST_CHECK(queue.empty()); + + for (size_t i = 0; i < 100; ++i) { + BOOST_CHECK_EQUAL(extracted[i], (i % 2 == 1)); + } + + // After draining, appending succeeds again + BOOST_CHECK(queue.try_append(true)); + BOOST_CHECK_EQUAL(queue.size(), 1u); + + // Test 2: Custom bounded capacity + status_request_queue small_queue(3); + BOOST_CHECK_EQUAL(small_queue.max_size(), 3u); + BOOST_CHECK(small_queue.try_append(false)); + BOOST_CHECK(small_queue.try_append(true)); + BOOST_CHECK(small_queue.try_append(false)); + BOOST_CHECK_EQUAL(small_queue.size(), 3u); + + // Exceeding custom capacity is rejected + BOOST_CHECK(!small_queue.try_append(true)); + BOOST_CHECK_THROW(append_or_throw(small_queue, true), status_request_queue_limit_exceeded); + BOOST_CHECK_EQUAL(small_queue.size(), 3u); +} + +BOOST_AUTO_TEST_CASE(ship_status_request_queue_adversarial_flood_and_churn_test) { + using eosio::state_history::status_request_queue; + using eosio::state_history::status_request_queue_limit_exceeded; + + // 1. Zero-capacity queue boundary: must reject everything immediately + { + status_request_queue zero_q(0); + BOOST_CHECK_EQUAL(zero_q.size(), 0u); + BOOST_CHECK_EQUAL(zero_q.max_size(), 0u); + BOOST_CHECK(zero_q.empty()); + BOOST_CHECK(!zero_q.try_append(true)); + BOOST_CHECK(!zero_q.try_append(false)); + BOOST_CHECK_EQUAL(zero_q.size(), 0u); + } + + // 2. Massive high-churn burst flooding: 1,000 bursts of 50 requests (50,000 total) + { + status_request_queue q(50); + std::mt19937 rng(42); + std::bernoulli_distribution dist(0.5); + + constexpr size_t NUM_BURSTS = 1000; + for (size_t burst = 0; burst < NUM_BURSTS; ++burst) { + std::vector expected_items; + for (size_t i = 0; i < 50; ++i) { + bool val = dist(rng); + expected_items.push_back(val); + BOOST_CHECK(q.try_append(val)); + } + BOOST_CHECK_EQUAL(q.size(), 50u); + // 51st request must fail + BOOST_CHECK(!q.try_append(true)); + + // Extract drains and preserves exact FIFO ordering + std::deque extracted = q.extract(); + BOOST_CHECK_EQUAL(extracted.size(), 50u); + BOOST_CHECK_EQUAL(q.size(), 0u); + BOOST_CHECK(q.empty()); + + for (size_t i = 0; i < 50; ++i) { + BOOST_CHECK_EQUAL(extracted[i], expected_items[i]); + } + } + } + + // 3. Clear method verification + { + status_request_queue q(10); + for (int i = 0; i < 5; ++i) q.try_append(true); + BOOST_CHECK_EQUAL(q.size(), 5u); + q.clear(); + BOOST_CHECK_EQUAL(q.size(), 0u); + BOOST_CHECK(q.empty()); + BOOST_CHECK(q.try_append(false)); + BOOST_CHECK_EQUAL(q.size(), 1u); + } +} + BOOST_AUTO_TEST_SUITE_END() + From 299e55ddd0dceeb8d0019df6bb4f2ad442835345 Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Thu, 3 Sep 2026 04:36:34 -0300 Subject: [PATCH 04/17] chain: fix BLS 32-bit length wrap, QC bitset validation order, weak_final boundary, and finalizer weight overflow - Issue 1: hoist multiplier n to size_t in BLS weighted-sum and pairing intrinsics preventing 32-bit modulo wrapping and cross-runtime consensus divergence - Issue 2: validate pending QC vote bitset format and weights before dual-finalizer vote comparison; add missing bounds assertions - Issue 5: correct weak_final aggregation boundary comparison to strict '>' allowing strong QC formation at boundary weight - Issue 7 (chain): record declared_auths_satisfied on transaction_metadata when check_authorization succeeds - Issue 9: initialize max_weak_sum_before_weak_final() accumulator with uint64_t{0} avoiding signed integer overflow - Add comprehensive regression and adversarial test suites in unittests --- libraries/chain/controller.cpp | 2 + .../include/eosio/chain/finalizer_policy.hpp | 2 +- .../eosio/chain/transaction_metadata.hpp | 3 + libraries/chain/qc.cpp | 10 +- libraries/chain/webassembly/crypto.cpp | 9 +- unittests/auth_tests.cpp | 97 +++ unittests/block_state_tests.cpp | 32 + unittests/bls_primitives_tests.cpp | 80 ++ unittests/finality_misc_tests.cpp | 82 ++ unittests/test_m2_adversarial.cpp | 735 ++++++++++++++++++ 10 files changed, 1044 insertions(+), 8 deletions(-) create mode 100644 unittests/test_m2_adversarial.cpp diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index 2b284c7462..f29e8d6642 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -3042,6 +3042,7 @@ struct controller_impl { transaction_trace_ptr trace; try { + trx->declared_auths_satisfied = false; auto start = fc::time_point::now(); const bool check_auth = !skip_auth_check() && !trx->implicit() && !trx->is_read_only(); const fc::microseconds sig_cpu_usage = trx->signature_cpu_usage(); @@ -3101,6 +3102,7 @@ struct controller_impl { false, trx->is_dry_run() ); + trx->declared_auths_satisfied = true; } trx_context.exec(); trx_context.finalize(); // Automatically rounds up network and CPU usage in trace and bills payers if successful diff --git a/libraries/chain/include/eosio/chain/finalizer_policy.hpp b/libraries/chain/include/eosio/chain/finalizer_policy.hpp index c61a808899..665fe83c16 100644 --- a/libraries/chain/include/eosio/chain/finalizer_policy.hpp +++ b/libraries/chain/include/eosio/chain/finalizer_policy.hpp @@ -42,7 +42,7 @@ namespace eosio::chain { // max accumulated weak weight before becoming weak_final uint64_t max_weak_sum_before_weak_final() const { - uint64_t sum = std::accumulate( finalizers.begin(), finalizers.end(), 0, + uint64_t sum = std::accumulate( finalizers.begin(), finalizers.end(), uint64_t{0}, [](uint64_t acc, const finalizer_authority& f) { return acc + f.weight; } diff --git a/libraries/chain/include/eosio/chain/transaction_metadata.hpp b/libraries/chain/include/eosio/chain/transaction_metadata.hpp index 7105f95b28..f907648605 100644 --- a/libraries/chain/include/eosio/chain/transaction_metadata.hpp +++ b/libraries/chain/include/eosio/chain/transaction_metadata.hpp @@ -37,6 +37,7 @@ class transaction_metadata { public: bool accepted = false; // not thread safe uint32_t billed_cpu_time_us = 0; // not thread safe + bool declared_auths_satisfied = false; // not thread safe private: struct private_type{}; @@ -76,6 +77,8 @@ class transaction_metadata { bool is_dry_run() const { return _trx_type == trx_type::dry_run; }; bool is_read_only() const { return _trx_type == trx_type::read_only; }; bool is_transient() const { return _trx_type == trx_type::read_only || _trx_type == trx_type::dry_run; }; + bool satisfied_authorizations() const { return declared_auths_satisfied; } + void set_satisfied_authorizations(bool v = true) { declared_auths_satisfied = v; } /// Thread safe. /// @returns transaction_metadata_ptr or exception via future diff --git a/libraries/chain/qc.cpp b/libraries/chain/qc.cpp index a3d5da7b62..639ebec505 100644 --- a/libraries/chain/qc.cpp +++ b/libraries/chain/qc.cpp @@ -71,11 +71,11 @@ void qc_t::verify_basic(const finalizer_policies_t& policies) const { EOS_ASSERT(policies.pending_finalizer_policy, invalid_qc, "qc ${bn} contains pending policy signature for nonexistent pending finalizer policy", ("bn", block_num)); - // verify that every finalizer included in both policies voted the same - verify_dual_finalizers_votes(policies, active_policy_sig, *pending_policy_sig, block_num); - pending_policy_sig->verify_vote_format(policies.pending_finalizer_policy); pending_policy_sig->verify_weights(policies.pending_finalizer_policy); + + // verify that every finalizer included in both policies voted the same + verify_dual_finalizers_votes(policies, active_policy_sig, *pending_policy_sig, block_num); } else { EOS_ASSERT(!policies.pending_finalizer_policy, invalid_qc, "qc ${bn} does not contain pending policy signature for pending finalizer policy", ("bn", block_num)); @@ -86,6 +86,8 @@ void qc_t::verify_basic(const finalizer_policies_t& policies) const { bool qc_sig_t::vote_same_at(const qc_sig_t& other, uint32_t my_vote_index, uint32_t other_vote_index) const { assert(!strong_votes || my_vote_index < strong_votes->size()); assert(!weak_votes || my_vote_index < weak_votes->size()); + assert(!other.strong_votes || other_vote_index < other.strong_votes->size()); + assert(!other.weak_votes || other_vote_index < other.weak_votes->size()); // We have already verified the same index has not voted both strong // and weak for a given qc_sig_t (I or other). @@ -311,7 +313,7 @@ vote_result_t aggregating_qc_sig_t::add_weak_vote(size_t index, const bls_signat break; case state_t::weak_achieved: - if (weak_sum >= max_weak_sum_before_weak_final) + if (weak_sum > max_weak_sum_before_weak_final) aggregating_state = state_t::weak_final; break; diff --git a/libraries/chain/webassembly/crypto.cpp b/libraries/chain/webassembly/crypto.cpp index 4b1fef0028..6d08eb60fc 100644 --- a/libraries/chain/webassembly/crypto.cpp +++ b/libraries/chain/webassembly/crypto.cpp @@ -285,7 +285,8 @@ namespace eosio::chain::webassembly { } int32_t interface::bls_g1_weighted_sum(span points, span scalars, const uint32_t n, span result) const { - if(n == 0 || points.size() != n*96 || scalars.size() != n*32 || result.size() != 96) + const size_t n_sz = n; + if(n == 0 || points.size() != n_sz*96 || scalars.size() != n_sz*32 || result.size() != 96) return return_code::failure; // Use much efficient scale for the special case of n == 1. @@ -320,7 +321,8 @@ namespace eosio::chain::webassembly { } int32_t interface::bls_g2_weighted_sum(span points, span scalars, const uint32_t n, span result) const { - if(n == 0 || points.size() != n*192 || scalars.size() != n*32 || result.size() != 192) + const size_t n_sz = n; + if(n == 0 || points.size() != n_sz*192 || scalars.size() != n_sz*32 || result.size() != 192) return return_code::failure; // Use much efficient scale for the special case of n == 1. @@ -355,7 +357,8 @@ namespace eosio::chain::webassembly { } int32_t interface::bls_pairing(span g1_points, span g2_points, const uint32_t n, span result) const { - if(n == 0 || g1_points.size() != n*96 || g2_points.size() != n*192 || result.size() != 576) + const size_t n_sz = n; + if(n == 0 || g1_points.size() != n_sz*96 || g2_points.size() != n_sz*192 || result.size() != 576) return return_code::failure; std::vector> v; v.reserve(n); diff --git a/unittests/auth_tests.cpp b/unittests/auth_tests.cpp index 35ac3d83c1..95bfc15179 100644 --- a/unittests/auth_tests.cpp +++ b/unittests/auth_tests.cpp @@ -696,4 +696,101 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( delete_auth, TESTER, validating_testers ) { try { } FC_LOG_AND_RETHROW() }/// delete_auth +// Issue 7: transaction_metadata authorization satisfaction flag +BOOST_AUTO_TEST_CASE_TEMPLATE( transaction_metadata_auth_satisfied, TESTER, validating_testers ) { try { + TESTER chain; + + chain.create_accounts( {"alice"_n, "bob"_n} ); + chain.produce_block(); + + auto act = chain.get_action(config::system_account_name, "reqauth"_n, + {permission_level{"alice"_n, config::active_name}}, + fc::mutable_variant_object()("from", "alice")); + + signed_transaction trx; + trx.actions.emplace_back(std::move(act)); + chain.set_transaction_headers(trx); + + auto ptrx_unsigned = std::make_shared(trx); + auto meta_unsigned = transaction_metadata::start_recover_keys( + ptrx_unsigned, chain.control->get_thread_pool(), chain.control->get_chain_id(), + fc::microseconds::maximum(), transaction_metadata::trx_type::input + ).get(); + + // Initial state of declared_auths_satisfied must be false + BOOST_CHECK_EQUAL(meta_unsigned->declared_auths_satisfied, false); + BOOST_CHECK_EQUAL(meta_unsigned->satisfied_authorizations(), false); + + // Case 1: Unsigned transaction naming alice. + // Auth check fails -> trace->except contains unsatisfied_authorization. + // declared_auths_satisfied MUST remain false. + auto trace1 = chain.control->push_transaction(meta_unsigned, fc::time_point::maximum(), fc::microseconds::maximum(), 0, false, 0); + BOOST_REQUIRE(trace1->except); + BOOST_CHECK_EQUAL(trace1->except->code(), unsatisfied_authorization::code_value); + BOOST_CHECK_EQUAL(meta_unsigned->declared_auths_satisfied, false); + BOOST_CHECK_EQUAL(meta_unsigned->satisfied_authorizations(), false); + + // Case 2: Signed by wrong key (bob's key instead of alice's key). + // declared_auths_satisfied MUST remain false. + signed_transaction trx_wrong_sig = trx; + trx_wrong_sig.signatures.clear(); + trx_wrong_sig.sign( chain.get_private_key("bob"_n, "active"), chain.control->get_chain_id() ); + auto ptrx_wrong = std::make_shared(trx_wrong_sig); + auto meta_wrong = transaction_metadata::start_recover_keys( + ptrx_wrong, chain.control->get_thread_pool(), chain.control->get_chain_id(), + fc::microseconds::maximum(), transaction_metadata::trx_type::input + ).get(); + + BOOST_CHECK_EQUAL(meta_wrong->declared_auths_satisfied, false); + auto trace2 = chain.control->push_transaction(meta_wrong, fc::time_point::maximum(), fc::microseconds::maximum(), 0, false, 0); + BOOST_REQUIRE(trace2->except); + BOOST_CHECK_EQUAL(trace2->except->code(), unsatisfied_authorization::code_value); + BOOST_CHECK_EQUAL(meta_wrong->declared_auths_satisfied, false); + BOOST_CHECK_EQUAL(meta_wrong->satisfied_authorizations(), false); + + // Case 3: Validly signed by alice's active key. + // Auth check succeeds -> declared_auths_satisfied set to true. + signed_transaction trx_valid = trx; + trx_valid.signatures.clear(); + trx_valid.sign( chain.get_private_key("alice"_n, "active"), chain.control->get_chain_id() ); + auto ptrx_valid = std::make_shared(trx_valid); + auto meta_valid = transaction_metadata::start_recover_keys( + ptrx_valid, chain.control->get_thread_pool(), chain.control->get_chain_id(), + fc::microseconds::maximum(), transaction_metadata::trx_type::input + ).get(); + + BOOST_CHECK_EQUAL(meta_valid->declared_auths_satisfied, false); + auto trace3 = chain.control->push_transaction(meta_valid, fc::time_point::maximum(), fc::microseconds::maximum(), 0, false, 0); + BOOST_CHECK(!trace3->except); + BOOST_CHECK_EQUAL(meta_valid->declared_auths_satisfied, true); + BOOST_CHECK_EQUAL(meta_valid->satisfied_authorizations(), true); + + // Case 4: Re-evaluating or resetting (as when retried from unapplied queue). + // Set flag to true manually to simulate leftover state; push_transaction must reset it to false before auth check. + chain.produce_block(); + auto act2 = chain.get_action(config::system_account_name, "reqauth"_n, + {permission_level{"bob"_n, config::active_name}}, + fc::mutable_variant_object()("from", "bob")); + signed_transaction trx2; + trx2.actions.emplace_back(std::move(act2)); + chain.set_transaction_headers(trx2); + // Sign with wrong key (alice instead of bob) + trx2.sign( chain.get_private_key("alice"_n, "active"), chain.control->get_chain_id() ); + auto ptrx2 = std::make_shared(trx2); + auto meta2 = transaction_metadata::start_recover_keys( + ptrx2, chain.control->get_thread_pool(), chain.control->get_chain_id(), + fc::microseconds::maximum(), transaction_metadata::trx_type::input + ).get(); + + // Manually set flag to true + meta2->declared_auths_satisfied = true; + // push_transaction must reset flag to false upon entry, and auth check will fail + auto trace4 = chain.control->push_transaction(meta2, fc::time_point::maximum(), fc::microseconds::maximum(), 0, false, 0); + BOOST_REQUIRE(trace4->except); + BOOST_CHECK_EQUAL(trace4->except->code(), unsatisfied_authorization::code_value); + BOOST_CHECK_EQUAL(meta2->declared_auths_satisfied, false); + BOOST_CHECK_EQUAL(meta2->satisfied_authorizations(), false); + +} FC_LOG_AND_RETHROW() } + BOOST_AUTO_TEST_SUITE_END() diff --git a/unittests/block_state_tests.cpp b/unittests/block_state_tests.cpp index dbb05198db..c8de259ad3 100644 --- a/unittests/block_state_tests.cpp +++ b/unittests/block_state_tests.cpp @@ -976,6 +976,38 @@ BOOST_AUTO_TEST_CASE(verify_qc_dual_finalizers) try { vote_same_test(false /*expected same*/, {}, true /*vote_weak_on_active*/, true /* vote_strong_on_pending*/, {}); vote_same_test(false /*expected same*/, true /*vote_strong_on_active*/, {}, {}, true /*vote_weak_on_pending*/); + // Issue 2: pending QC vote bitset validated before indexing + { + bls_aggregate_signature active_agg_sig; + bls_aggregate_signature pending_agg_sig; + + vote_bitset_t active_votes(num_finalizers); + active_votes[0] = 1; + active_votes[2] = 1; + qc_sig_t active_qc_sig{active_votes, {}, active_agg_sig}; + + // Case A: pending_strong_votes is empty (size 0) + vote_bitset_t empty_bitset(0); + qc_sig_t pending_qc_sig_empty{empty_bitset, {}, pending_agg_sig}; + qc_t qc_empty{bsp->block_num(), active_qc_sig, pending_qc_sig_empty}; + BOOST_CHECK_EXCEPTION( bsp->verify_qc(qc_empty), invalid_qc, + eosio::testing::fc_exception_message_starts_with("vote bitset size is not the same as the number of finalizers") ); + + // Case B: pending_strong_votes is undersized (size 1 < num_finalizers 3), so dual finalizer index 1 would be OOB + vote_bitset_t undersized_bitset(1); + undersized_bitset[0] = 1; + qc_sig_t pending_qc_sig_under{undersized_bitset, {}, pending_agg_sig}; + qc_t qc_under{bsp->block_num(), active_qc_sig, pending_qc_sig_under}; + BOOST_CHECK_EXCEPTION( bsp->verify_qc(qc_under), invalid_qc, + eosio::testing::fc_exception_message_starts_with("vote bitset size is not the same as the number of finalizers") ); + + // Case C: neither strong_votes nor weak_votes present on pending_policy_sig + qc_sig_t pending_qc_sig_novotes{std::nullopt, std::nullopt, pending_agg_sig}; + qc_t qc_novotes{bsp->block_num(), active_qc_sig, pending_qc_sig_novotes}; + BOOST_CHECK_EXCEPTION( bsp->verify_qc(qc_novotes), invalid_qc, + eosio::testing::fc_exception_message_starts_with("Neither strong_votes nor weak_votes present") ); + } + } FC_LOG_AND_RETHROW(); BOOST_FIXTURE_TEST_CASE(get_finality_data_test, finality_test_cluster<4>) try { diff --git a/unittests/bls_primitives_tests.cpp b/unittests/bls_primitives_tests.cpp index 1023f181be..c16a5a7e3c 100644 --- a/unittests/bls_primitives_tests.cpp +++ b/unittests/bls_primitives_tests.cpp @@ -840,5 +840,85 @@ BOOST_AUTO_TEST_CASE( bls_testfpmod ) { try { } FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE( bls_overflow_wrapping_lengths ) { try { + tester c( setup_policy::preactivate_feature_and_new_bios ); + + const auto& tester1_account = account_name("tester1"); + c.create_accounts( {tester1_account} ); + c.produce_block(); + + const auto& pfm = c.control->get_protocol_feature_manager(); + const auto& d = pfm.get_builtin_digest( builtin_protocol_feature_t::bls_primitives ); + BOOST_REQUIRE( d ); + + c.preactivate_protocol_features( {*d} ); + c.produce_block(); + + c.set_code( tester1_account, test_contracts::bls_primitives_test_wasm() ); + c.set_abi( tester1_account, test_contracts::bls_primitives_test_abi().data() ); + c.produce_block(); + + const uint32_t n_wrap0 = 0x08000000; // 134,217,728: wraps n*96, n*192, n*32 to 0 mod 2^32 + const uint32_t n_wrap1 = 0x08000001; // 134,217,729: wraps n*96 -> 96, n*192 -> 192, n*32 -> 32 mod 2^32 + + std::vector zero_res_g1(96, 0); + std::vector zero_res_g2(192, 0); + std::vector zero_res_pairing(576, 0); + + // Case 1: n = 0x08000000 with empty spans (in 32-bit wraps to 0) + c.push_action( tester1_account, "testg1wsum"_n, tester1_account, mutable_variant_object() + ("points", std::vector()) + ("scalars", std::vector()) + ("num", n_wrap0) + ("res", zero_res_g1) + ("expected_error", (int32_t)return_code::failure) + ); + + c.push_action( tester1_account, "testg2wsum"_n, tester1_account, mutable_variant_object() + ("points", std::vector()) + ("scalars", std::vector()) + ("num", n_wrap0) + ("res", zero_res_g2) + ("expected_error", (int32_t)return_code::failure) + ); + + c.push_action( tester1_account, "testpairing"_n, tester1_account, mutable_variant_object() + ("g1_points", std::vector()) + ("g2_points", std::vector()) + ("num", n_wrap0) + ("res", zero_res_pairing) + ("expected_error", (int32_t)return_code::failure) + ); + + // Case 2: n = 0x08000001 with 1-element buffers (in 32-bit wraps to 1-element size) + std::vector g1_point(96, 0); + std::vector g2_point(192, 0); + std::vector scalar(32, 0); + + c.push_action( tester1_account, "testg1wsum"_n, tester1_account, mutable_variant_object() + ("points", g1_point) + ("scalars", scalar) + ("num", n_wrap1) + ("res", zero_res_g1) + ("expected_error", (int32_t)return_code::failure) + ); + + c.push_action( tester1_account, "testg2wsum"_n, tester1_account, mutable_variant_object() + ("points", g2_point) + ("scalars", scalar) + ("num", n_wrap1) + ("res", zero_res_g2) + ("expected_error", (int32_t)return_code::failure) + ); + + c.push_action( tester1_account, "testpairing"_n, tester1_account, mutable_variant_object() + ("g1_points", g1_point) + ("g2_points", g2_point) + ("num", n_wrap1) + ("res", zero_res_pairing) + ("expected_error", (int32_t)return_code::failure) + ); + +} FC_LOG_AND_RETHROW() } BOOST_AUTO_TEST_SUITE_END() diff --git a/unittests/finality_misc_tests.cpp b/unittests/finality_misc_tests.cpp index 1f03f389fc..b85038df4a 100644 --- a/unittests/finality_misc_tests.cpp +++ b/unittests/finality_misc_tests.cpp @@ -237,4 +237,86 @@ BOOST_AUTO_TEST_CASE(qc_state_transitions) try { } FC_LOG_AND_RETHROW(); +// Issue 5: weak_final boundary off by one in QC vote aggregation +BOOST_AUTO_TEST_CASE(qc_state_weak_final_boundary_off_by_one) try { + using namespace eosio::chain; + using namespace fc::crypto::blslib; + using state_t = aggregating_qc_sig_t::state_t; + + digest_type d(fc::sha256("0000000000000000000000000000001")); + std::vector digest(d.data(), d.data() + d.data_size()); + + std::vector sk { + bls_private_key("PVT_BLS_0d8dsux83r42Qg8CHgAqIuSsn9AV-QdCzx3tPj0K8yOJA_qb"), + bls_private_key("PVT_BLS_Wfs3KzfTI2P5F85PnoHXLnmYgSbp-XpebIdS6BUCHXOKmKXK"), + bls_private_key("PVT_BLS_74crPc__6BlpoQGvWjkHmUdzcDKh8QaiN_GtU4SD0QAi4BHY"), + bls_private_key("PVT_BLS_foNjZTu0k6qM5ftIrqC5G_sim1Rg7wq3cRUaJGvNtm2rM89K") + }; + + auto weak_vote = [&](aggregating_qc_sig_t& qc, const std::vector& digest_to_sign, size_t index, uint64_t weight) { + return qc.add_vote(0, 0, false, index, sk[index].sign(digest_to_sign), weight); + }; + + auto strong_vote = [&](aggregating_qc_sig_t& qc, const std::vector& digest_to_sign, size_t index, uint64_t weight) { + return qc.add_vote(0, 0, true, index, sk[index].sign(digest_to_sign), weight); + }; + + // Total weight = 5 (F0: 2, F1: 1, F2: 1, F3: 1), Quorum = 3 + // max_weak_sum_before_weak_final = 5 - 3 = 2. + constexpr uint64_t quorum = 3; + constexpr uint64_t max_weak_sum_before_weak_final = 2; + + aggregating_qc_sig_t qc(4, quorum, max_weak_sum_before_weak_final); + BOOST_CHECK_EQUAL(qc.state(), state_t::unrestricted); + + // 1. F0 votes strong with weight 2: strong_sum = 2, weak_sum = 0 (< quorum 3) -> unrestricted + strong_vote(qc, digest, 0, 2); + BOOST_CHECK_EQUAL(qc.state(), state_t::unrestricted); + BOOST_CHECK(!qc.is_quorum_met()); + + // 2. F1 votes weak with weight 1: strong_sum = 2, weak_sum = 1 (sum = 3 >= quorum) -> weak_achieved + weak_vote(qc, digest, 1, 1); + BOOST_CHECK_EQUAL(qc.state(), state_t::weak_achieved); + BOOST_CHECK(qc.is_quorum_met()); + + // 3. F2 votes weak with weight 1: weak_sum becomes 2 == max_weak_sum_before_weak_final. + // Pre-fix: used '>=' and prematurely transitioned to weak_final. + // Post-fix: uses '>' so 2 > 2 is false, state remains weak_achieved! + weak_vote(qc, digest, 2, 1); + BOOST_CHECK_EQUAL(qc.state(), state_t::weak_achieved); + BOOST_CHECK(qc.is_quorum_met()); + + // 4. F3 votes strong with weight 1: strong_sum becomes 2 + 1 = 3 >= quorum. + // Because state remained weak_achieved, this transitions to state_t::strong! + strong_vote(qc, digest, 3, 1); + BOOST_CHECK_EQUAL(qc.state(), state_t::strong); + BOOST_CHECK(qc.is_quorum_met()); + +} FC_LOG_AND_RETHROW(); + +// Issue 9: max_weak_sum_before_weak_final() accumulates in int +BOOST_AUTO_TEST_CASE(finalizer_policy_large_weight_accumulate) { + using namespace eosio::chain; + + finalizer_policy fp; + fp.threshold = 4'000'000'000ULL; + fp.finalizers = { + finalizer_authority{ "fin1", 3'000'000'000ULL, bls_public_key{} }, + finalizer_authority{ "fin2", 3'000'000'000ULL, bls_public_key{} } + }; + // Total weight = 6'000'000'000ULL (> 2^32, well over INT32_MAX). + // Expected sum - threshold = 6'000'000'000 - 4'000'000'000 = 2'000'000'000ULL. + BOOST_CHECK_EQUAL(fp.max_weak_sum_before_weak_final(), 2'000'000'000ULL); + + finalizer_policy fp_huge; + fp_huge.threshold = 10'000'000'000ULL; + fp_huge.finalizers = { + finalizer_authority{ "fin1", 10'000'000'000ULL, bls_public_key{} }, + finalizer_authority{ "fin2", 20'000'000'000ULL, bls_public_key{} } + }; + // Total weight = 30'000'000'000ULL. + // Expected sum - threshold = 30'000'000'000 - 10'000'000'000 = 20'000'000'000ULL. + BOOST_CHECK_EQUAL(fp_huge.max_weak_sum_before_weak_final(), 20'000'000'000ULL); +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/unittests/test_m2_adversarial.cpp b/unittests/test_m2_adversarial.cpp new file mode 100644 index 0000000000..59000bfe16 --- /dev/null +++ b/unittests/test_m2_adversarial.cpp @@ -0,0 +1,735 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace eosio; +using namespace eosio::chain; +using namespace eosio::chain::webassembly; +using namespace eosio::testing; +using namespace fc::crypto::blslib; + +BOOST_AUTO_TEST_SUITE(m2_adversarial_tests) + +// ============================================================================= +// 1. Issue 1: BLS Weighted-Sum & Pairing 32-Bit Length Wrap Adversarial Tests +// ============================================================================= +BOOST_AUTO_TEST_CASE(bls_32bit_wrap_adversarial_stress) { try { + tester c( setup_policy::preactivate_feature_and_new_bios ); + + const auto& tester1_account = account_name("tester1"); + c.create_accounts( {tester1_account} ); + c.produce_block(); + + const auto& pfm = c.control->get_protocol_feature_manager(); + const auto& d = pfm.get_builtin_digest( builtin_protocol_feature_t::bls_primitives ); + BOOST_REQUIRE( d ); + + c.preactivate_protocol_features( {*d} ); + c.produce_block(); + + c.set_code( tester1_account, test_contracts::bls_primitives_test_wasm() ); + c.set_abi( tester1_account, test_contracts::bls_primitives_test_abi().data() ); + c.produce_block(); + + std::vector zero_res_g1(96, 0); + std::vector zero_res_g2(192, 0); + std::vector zero_res_pairing(576, 0); + + std::vector g1_buf_1elem(96, 0); + std::vector g2_buf_1elem(192, 0); + std::vector scalar_buf_1elem(32, 0); + + // Part A: Multiples of 0x08000000 that wrap n*96, n*192, and n*32 all to 0 mod 2^32 + // Tested with empty buffers + const std::vector wrap_all_to_zero = { + 0x08000000, // 134,217,728 + 0x10000000, // 268,435,456 + 0x18000000, // 402,653,184 + 0x20000000 // 536,870,912 + }; + + for (uint32_t n : wrap_all_to_zero) { + c.push_action( tester1_account, "testg1wsum"_n, tester1_account, mutable_variant_object() + ("points", std::vector()) + ("scalars", std::vector()) + ("num", n) + ("res", zero_res_g1) + ("expected_error", (int32_t)return_code::failure) + ); + + c.push_action( tester1_account, "testg2wsum"_n, tester1_account, mutable_variant_object() + ("points", std::vector()) + ("scalars", std::vector()) + ("num", n) + ("res", zero_res_g2) + ("expected_error", (int32_t)return_code::failure) + ); + + c.push_action( tester1_account, "testpairing"_n, tester1_account, mutable_variant_object() + ("g1_points", std::vector()) + ("g2_points", std::vector()) + ("num", n) + ("res", zero_res_pairing) + ("expected_error", (int32_t)return_code::failure) + ); + } + + // Part B: Multiples of 0x08000000 + 1 that wrap n*96 -> 96, n*192 -> 192, n*32 -> 32 mod 2^32 + // In 32-bit math, these wrap to exactly 1-element buffer size (96, 192, 32 bytes). + // Prior to the fix, the 32-bit guard accepted the 1-element buffer and iterated out-of-bounds! + const std::vector wrap_all_to_one = { + 0x08000001, + 0x10000001, + 0x18000001, + 0x20000001 + }; + + for (uint32_t n : wrap_all_to_one) { + c.push_action( tester1_account, "testg1wsum"_n, tester1_account, mutable_variant_object() + ("points", g1_buf_1elem) + ("scalars", scalar_buf_1elem) + ("num", n) + ("res", zero_res_g1) + ("expected_error", (int32_t)return_code::failure) + ); + + c.push_action( tester1_account, "testg2wsum"_n, tester1_account, mutable_variant_object() + ("points", g2_buf_1elem) + ("scalars", scalar_buf_1elem) + ("num", n) + ("res", zero_res_g2) + ("expected_error", (int32_t)return_code::failure) + ); + + c.push_action( tester1_account, "testpairing"_n, tester1_account, mutable_variant_object() + ("g1_points", g1_buf_1elem) + ("g2_points", g2_buf_1elem) + ("num", n) + ("res", zero_res_pairing) + ("expected_error", (int32_t)return_code::failure) + ); + } + + // Part C: Additional boundary and wrapping values of n + // 1. n = 0: must reject immediately + { + c.push_action( tester1_account, "testg1wsum"_n, tester1_account, mutable_variant_object() + ("points", std::vector()) + ("scalars", std::vector()) + ("num", 0) + ("res", zero_res_g1) + ("expected_error", (int32_t)return_code::failure) + ); + + c.push_action( tester1_account, "testg2wsum"_n, tester1_account, mutable_variant_object() + ("points", std::vector()) + ("scalars", std::vector()) + ("num", 0) + ("res", zero_res_g2) + ("expected_error", (int32_t)return_code::failure) + ); + + c.push_action( tester1_account, "testpairing"_n, tester1_account, mutable_variant_object() + ("g1_points", std::vector()) + ("g2_points", std::vector()) + ("num", 0) + ("res", zero_res_pairing) + ("expected_error", (int32_t)return_code::failure) + ); + } + + // 2. n = 0x04000000 (2^26): wraps n*192 to 0, but n*32 = 2^31 (2 GB), + // which exceeds WASM 33 MiB linear memory and is safely trapped by the VM. + { + const uint32_t n_wrap_g2 = 0x04000000; + BOOST_CHECK_THROW( + c.push_action( tester1_account, "testg2wsum"_n, tester1_account, mutable_variant_object() + ("points", std::vector()) + ("scalars", std::vector()) + ("num", n_wrap_g2) + ("res", zero_res_g2) + ("expected_error", (int32_t)return_code::failure) + ), + wasm_execution_error + ); + + BOOST_CHECK_THROW( + c.push_action( tester1_account, "testpairing"_n, tester1_account, mutable_variant_object() + ("g1_points", std::vector()) + ("g2_points", std::vector()) + ("num", n_wrap_g2) + ("res", zero_res_pairing) + ("expected_error", (int32_t)return_code::failure) + ), + wasm_execution_error + ); + } + + // 3. n = 0x80000000 (2^31): high-bit set, wraps n*96, n*192, and n*32 all to 0 mod 2^32 + // Host function cleanly returns return_code::failure via 64-bit length checks + { + const uint32_t n_highbit = 0x80000000; + c.push_action( tester1_account, "testg1wsum"_n, tester1_account, mutable_variant_object() + ("points", std::vector()) + ("scalars", std::vector()) + ("num", n_highbit) + ("res", zero_res_g1) + ("expected_error", (int32_t)return_code::failure) + ); + + c.push_action( tester1_account, "testg2wsum"_n, tester1_account, mutable_variant_object() + ("points", std::vector()) + ("scalars", std::vector()) + ("num", n_highbit) + ("res", zero_res_g2) + ("expected_error", (int32_t)return_code::failure) + ); + + c.push_action( tester1_account, "testpairing"_n, tester1_account, mutable_variant_object() + ("g1_points", std::vector()) + ("g2_points", std::vector()) + ("num", n_highbit) + ("res", zero_res_pairing) + ("expected_error", (int32_t)return_code::failure) + ); + } + + // 4. n = 0xFFFFFFFF (UINT32_MAX): wraps to 4GB span in 32-bit math, trapped by VM + { + const uint32_t n_max = 0xFFFFFFFF; + BOOST_CHECK_THROW( + c.push_action( tester1_account, "testg1wsum"_n, tester1_account, mutable_variant_object() + ("points", std::vector()) + ("scalars", std::vector()) + ("num", n_max) + ("res", zero_res_g1) + ("expected_error", (int32_t)return_code::failure) + ), + wasm_execution_error + ); + } + + // Part D: Corrupted point bytes (all 0xFF - invalid elliptic curve point) + { + std::vector bad_g1(96, (char)0xFF); + std::vector valid_scalar(32, 0); + valid_scalar[0] = 1; + + c.push_action( tester1_account, "testg1wsum"_n, tester1_account, mutable_variant_object() + ("points", bad_g1) + ("scalars", valid_scalar) + ("num", 1) + ("res", zero_res_g1) + ("expected_error", (int32_t)return_code::failure) + ); + + std::vector bad_g2(192, (char)0xFF); + c.push_action( tester1_account, "testg2wsum"_n, tester1_account, mutable_variant_object() + ("points", bad_g2) + ("scalars", valid_scalar) + ("num", 1) + ("res", zero_res_g2) + ("expected_error", (int32_t)return_code::failure) + ); + + c.push_action( tester1_account, "testpairing"_n, tester1_account, mutable_variant_object() + ("g1_points", bad_g1) + ("g2_points", bad_g2) + ("num", 1) + ("res", zero_res_pairing) + ("expected_error", (int32_t)return_code::failure) + ); + } + +} FC_LOG_AND_RETHROW() } + +// ============================================================================= +// 2. Issue 2: Pending QC Vote Bitset Validated Before Indexing Adversarial Tests +// ============================================================================= +BOOST_AUTO_TEST_CASE(pending_qc_bitset_validation_adversarial) try { + // Generate valid BLS keys + std::vector sk; + for (int i = 0; i < 5; ++i) { + sk.push_back(bls_private_key::generate()); + } + + // Active policy: 3 finalizers (sk[0], sk[1], sk[2]), weights {1, 1, 1}, threshold = 2 + finalizer_policies_t policies; + policies.finality_digest = digest_type(fc::sha256("0000000000000000000000000000000000000000000000000000000000000001")); + policies.active_finalizer_policy = std::make_shared(); + policies.active_finalizer_policy->generation = 1; + policies.active_finalizer_policy->threshold = 2; + policies.active_finalizer_policy->finalizers = { + finalizer_authority{ "act0", 1, sk[0].get_public_key() }, + finalizer_authority{ "act1", 1, sk[1].get_public_key() }, + finalizer_authority{ "act2", 1, sk[2].get_public_key() } + }; + + // Pending policy: 4 finalizers: + // sk[3] (index 0 - pending only) + // sk[0] (index 1 - dual finalizer, index 0 in active!) + // sk[2] (index 2 - dual finalizer, index 2 in active!) + // sk[4] (index 3 - pending only) + // Threshold = 3, weights {1, 1, 1, 1} + policies.pending_finalizer_policy = std::make_shared(); + policies.pending_finalizer_policy->generation = 2; + policies.pending_finalizer_policy->threshold = 3; + policies.pending_finalizer_policy->finalizers = { + finalizer_authority{ "pen0", 1, sk[3].get_public_key() }, + finalizer_authority{ "pen1", 1, sk[0].get_public_key() }, // dual with act0 + finalizer_authority{ "pen2", 1, sk[2].get_public_key() }, // dual with act2 + finalizer_authority{ "pen3", 1, sk[4].get_public_key() } + }; + + // Valid active qc signature (act0 and act2 vote strong, weight = 2 >= threshold 2) + vote_bitset_t active_strong(3); + active_strong[0] = 1; + active_strong[2] = 1; + bls_aggregate_signature dummy_sig; + qc_sig_t active_qc_sig{active_strong, {}, dummy_sig}; + + // Adversarial Case 1: Pending strong_votes empty (size 0) + { + vote_bitset_t empty_bs(0); + qc_sig_t pending_sig{empty_bs, {}, dummy_sig}; + qc_t qc{100, active_qc_sig, pending_sig}; + BOOST_CHECK_EXCEPTION( qc.verify_basic(policies), invalid_qc, + eosio::testing::fc_exception_message_starts_with("vote bitset size is not the same as the number of finalizers") ); + } + + // Adversarial Case 2: Pending weak_votes empty (size 0) + { + vote_bitset_t empty_bs(0); + qc_sig_t pending_sig{{}, empty_bs, dummy_sig}; + qc_t qc{100, active_qc_sig, pending_sig}; + BOOST_CHECK_EXCEPTION( qc.verify_basic(policies), invalid_qc, + eosio::testing::fc_exception_message_starts_with("vote bitset size is not the same as the number of finalizers") ); + } + + // Adversarial Case 3: Pending strong_votes undersized (size 1 < 4, indexing index 1 or 2 would trigger OOB read) + { + vote_bitset_t under_bs(1); + under_bs[0] = 1; + qc_sig_t pending_sig{under_bs, {}, dummy_sig}; + qc_t qc{100, active_qc_sig, pending_sig}; + BOOST_CHECK_EXCEPTION( qc.verify_basic(policies), invalid_qc, + eosio::testing::fc_exception_message_starts_with("vote bitset size is not the same as the number of finalizers") ); + } + + // Adversarial Case 4: Pending weak_votes undersized (size 2 < 4, indexing index 2 would trigger OOB read) + { + vote_bitset_t under_bs(2); + under_bs[0] = 1; under_bs[1] = 1; + qc_sig_t pending_sig{{}, under_bs, dummy_sig}; + qc_t qc{100, active_qc_sig, pending_sig}; + BOOST_CHECK_EXCEPTION( qc.verify_basic(policies), invalid_qc, + eosio::testing::fc_exception_message_starts_with("vote bitset size is not the same as the number of finalizers") ); + } + + // Adversarial Case 5: Pending bitset oversized (size 5 > 4) + { + vote_bitset_t over_bs(5); + over_bs[0] = 1; over_bs[1] = 1; over_bs[2] = 1; + qc_sig_t pending_sig{over_bs, {}, dummy_sig}; + qc_t qc{100, active_qc_sig, pending_sig}; + BOOST_CHECK_EXCEPTION( qc.verify_basic(policies), invalid_qc, + eosio::testing::fc_exception_message_starts_with("vote bitset size is not the same as the number of finalizers") ); + } + + // Adversarial Case 6: Neither strong nor weak votes present + { + qc_sig_t pending_sig{std::nullopt, std::nullopt, dummy_sig}; + qc_t qc{100, active_qc_sig, pending_sig}; + BOOST_CHECK_EXCEPTION( qc.verify_basic(policies), invalid_qc, + eosio::testing::fc_exception_message_starts_with("Neither strong_votes nor weak_votes present") ); + } + + // Adversarial Case 7: Valid format (size 4), but insufficient weight (< threshold 3) + { + vote_bitset_t low_weight(4); + low_weight[1] = 1; low_weight[2] = 1; // weight = 2 < 3 + qc_sig_t pending_sig{low_weight, {}, dummy_sig}; + qc_t qc{100, active_qc_sig, pending_sig}; + BOOST_CHECK_EXCEPTION( qc.verify_basic(policies), invalid_qc, + eosio::testing::fc_exception_message_contains("quorum is not met") ); + } + + // Adversarial Case 8: Dual finalizer vote mismatch (act0 voted strong, pen1 voted weak) + { + vote_bitset_t pen_weak(4); + pen_weak[0] = 1; pen_weak[1] = 1; pen_weak[2] = 1; // pen1 (act0) votes weak + qc_sig_t pending_sig{{}, pen_weak, dummy_sig}; + qc_t qc{100, active_qc_sig, pending_sig}; + BOOST_CHECK_EXCEPTION( qc.verify_basic(policies), invalid_qc, + eosio::testing::fc_exception_message_contains("does not vote the same on active and pending policies") ); + } + + // Valid Case 9: Dual finalizers vote identically (act0/pen1 and act2/pen2 both vote strong, weight 3 >= 3) + { + vote_bitset_t pen_strong(4); + pen_strong[0] = 1; pen_strong[1] = 1; pen_strong[2] = 1; + qc_sig_t pending_sig{pen_strong, {}, dummy_sig}; + qc_t qc{100, active_qc_sig, pending_sig}; + BOOST_CHECK_NO_THROW( qc.verify_basic(policies) ); + } + +} FC_LOG_AND_RETHROW(); + +// ============================================================================= +// 3. Issue 5: QC Vote Aggregator Weak-Final Boundary Off-by-One Adversarial Tests +// ============================================================================= +BOOST_AUTO_TEST_CASE(qc_state_weak_final_boundary_adversarial) try { + using state_t = aggregating_qc_sig_t::state_t; + + digest_type d(fc::sha256("0000000000000000000000000000000000000000000000000000000000000002")); + std::vector digest(d.data(), d.data() + d.data_size()); + + std::vector sk; + for (int i = 0; i < 7; ++i) { + sk.push_back(bls_private_key::generate()); + } + + auto weak_vote = [&](aggregating_qc_sig_t& qc, size_t index, uint64_t weight) { + return qc.add_vote(0, 0, false, index, sk[index].sign(digest), weight); + }; + + auto strong_vote = [&](aggregating_qc_sig_t& qc, size_t index, uint64_t weight) { + return qc.add_vote(0, 0, true, index, sk[index].sign(digest), weight); + }; + + // Scenario A: Total Weight = 7 (7 finalizers with weight 1 each), Quorum = 5. + // max_weak_sum_before_weak_final = 7 - 5 = 2. + { + aggregating_qc_sig_t qc(7, 5, 2); + BOOST_CHECK(qc.state() == state_t::unrestricted); + + // Weak vote 1 (weight 1 <= 2) + weak_vote(qc, 0, 1); + BOOST_CHECK(qc.state() == state_t::unrestricted); + + // Weak vote 2 (weight 1 -> weak_sum = 2 == max_weak_sum_before_weak_final) + // At this boundary, remaining weight is 7 - 2 = 5 == Quorum! Strong QC is still achievable! + weak_vote(qc, 1, 1); + BOOST_CHECK(qc.state() == state_t::unrestricted); + + // 5 strong votes arrive (indices 2, 3, 4, 5, 6) + strong_vote(qc, 2, 1); // strong_sum = 1 + strong_vote(qc, 3, 1); // strong_sum = 2 + strong_vote(qc, 4, 1); // strong_sum = 3, total = 5 >= quorum -> weak_achieved + BOOST_CHECK(qc.state() == state_t::weak_achieved); + + strong_vote(qc, 5, 1); // strong_sum = 4 + strong_vote(qc, 6, 1); // strong_sum = 5 >= quorum -> transitions to strong! + BOOST_CHECK(qc.state() == state_t::strong); + auto best = qc.get_best_qc(); + BOOST_REQUIRE(best.has_value()); + BOOST_CHECK(best->is_strong()); + } + + // Scenario B: Exact weak_achieved boundary where weak_sum == max_weak_sum_before_weak_final + // Total weight = 6 (F0: 2, F1: 1, F2: 1, F3: 1, F4: 1), Quorum = 4. + // max_weak_sum_before_weak_final = 6 - 4 = 2. + { + aggregating_qc_sig_t qc(5, 4, 2); + BOOST_CHECK(qc.state() == state_t::unrestricted); + + // F0 strong (weight 2), F1 weak (weight 1), F2 strong (weight 1) + // total = 4 >= quorum (strong_sum = 3, weak_sum = 1) -> weak_achieved + strong_vote(qc, 0, 2); + weak_vote(qc, 1, 1); + strong_vote(qc, 2, 1); + BOOST_CHECK(qc.state() == state_t::weak_achieved); + + // F3 weak (weight 1): weak_sum becomes 2 == max_weak_sum_before_weak_final! + // Pre-fix: used '>=' and falsely transitioned to weak_final! + // Post-fix: uses '>' so 2 > 2 is false, remains weak_achieved! + weak_vote(qc, 3, 1); + BOOST_CHECK(qc.state() == state_t::weak_achieved); + + // F4 strong (weight 1): strong_sum becomes 3 + 1 = 4 >= quorum! + // Transitions to strong! + strong_vote(qc, 4, 1); + BOOST_CHECK(qc.state() == state_t::strong); + auto best = qc.get_best_qc(); + BOOST_REQUIRE(best.has_value()); + BOOST_CHECK(best->is_strong()); + } + + // Scenario C: Exceeding boundary by 1 (weak_sum = 3 > 2) + // Total weight = 6, Quorum = 4, max_weak_sum_before_weak_final = 2. + { + aggregating_qc_sig_t qc(5, 4, 2); + + // F0 weak (weight 2), F1 weak (weight 1) -> weak_sum = 3 > 2. + // Total weight remaining for strong is 6 - 3 = 3 < 4 (strong quorum impossible!) + weak_vote(qc, 0, 2); + weak_vote(qc, 1, 1); + BOOST_CHECK(qc.state() == state_t::restricted); + + // F2 strong (weight 1): total = 4 >= quorum -> weak_final + strong_vote(qc, 2, 1); + BOOST_CHECK(qc.state() == state_t::weak_final); + auto best = qc.get_best_qc(); + BOOST_REQUIRE(best.has_value()); + BOOST_CHECK(best->is_weak()); + + // Remaining votes cannot make it strong + strong_vote(qc, 3, 1); + strong_vote(qc, 4, 1); + BOOST_CHECK(qc.state() == state_t::weak_final); + } + + // Scenario D: Boundary Q == W (Unanimous consent required: max_weak_sum_before_weak_final = 0) + { + aggregating_qc_sig_t qc(3, 3, 0); + BOOST_CHECK(qc.state() == state_t::unrestricted); + + // Any weak vote (weight 1 > 0) immediately restricts + weak_vote(qc, 0, 1); + BOOST_CHECK(qc.state() == state_t::restricted); + + // Strong votes reach 2 < 3, total = 3 -> weak_final + strong_vote(qc, 1, 1); + strong_vote(qc, 2, 1); + BOOST_CHECK(qc.state() == state_t::weak_final); + } + + // Scenario E: Duplicate vote rejection + { + aggregating_qc_sig_t qc(3, 2, 1); + BOOST_CHECK(strong_vote(qc, 0, 1) == vote_result_t::success); + // Re-voting same index as strong or weak must return duplicate + BOOST_CHECK(strong_vote(qc, 0, 1) == vote_result_t::duplicate); + BOOST_CHECK(weak_vote(qc, 0, 1) == vote_result_t::duplicate); + } + +} FC_LOG_AND_RETHROW(); + +// ============================================================================= +// 4. Issue 9: Finalizer Policy Large Weight 64-bit Accumulation Adversarial Tests +// ============================================================================= +BOOST_AUTO_TEST_CASE(finalizer_policy_accumulation_adversarial) { + // Case 1: Weights exceeding signed 32-bit INT32_MAX (2,147,483,647) + { + finalizer_policy fp; + fp.threshold = 3'000'000'000ULL; + fp.finalizers = { + finalizer_authority{ "f1", 2'147'483'648ULL, bls_public_key{} }, + finalizer_authority{ "f2", 2'147'483'648ULL, bls_public_key{} } + }; + // Total sum = 4,294,967,296ULL (2^32). Under int32, this wrapped to 0! + // Expected sum - threshold = 4,294,967,296 - 3,000,000,000 = 1,294,967,296ULL. + BOOST_CHECK_EQUAL(fp.max_weak_sum_before_weak_final(), 1'294'967'296ULL); + } + + // Case 2: Huge weights near 100 billion + { + finalizer_policy fp; + fp.threshold = 70'000'000'000ULL; + fp.finalizers = { + finalizer_authority{ "f1", 50'000'000'000ULL, bls_public_key{} }, + finalizer_authority{ "f2", 30'000'000'000ULL, bls_public_key{} }, + finalizer_authority{ "f3", 20'000'000'000ULL, bls_public_key{} } + }; + // Total = 100'000'000'000ULL. Expected sum - threshold = 30'000'000'000ULL. + BOOST_CHECK_EQUAL(fp.max_weak_sum_before_weak_final(), 30'000'000'000ULL); + } + + // Case 3: Weights exceeding signed 64-bit INT64_MAX (9.22 * 10^18) + { + finalizer_policy fp; + fp.threshold = 15'000'000'000'000'000'000ULL; + fp.finalizers = { + finalizer_authority{ "f1", 10'000'000'000'000'000'000ULL, bls_public_key{} }, + finalizer_authority{ "f2", 8'000'000'000'000'000'000ULL, bls_public_key{} } + }; + // Total = 18'000'000'000'000'000'000ULL. Expected = 3'000'000'000'000'000'000ULL. + BOOST_CHECK_EQUAL(fp.max_weak_sum_before_weak_final(), 3'000'000'000'000'000'000ULL); + } + + // Case 4: Boundary: sum equals threshold + { + finalizer_policy fp; + fp.threshold = 1000ULL; + fp.finalizers = { + finalizer_authority{ "f1", 600ULL, bls_public_key{} }, + finalizer_authority{ "f2", 400ULL, bls_public_key{} } + }; + BOOST_CHECK_EQUAL(fp.max_weak_sum_before_weak_final(), 0ULL); + } + + // Case 5: Empty finalizer list + { + finalizer_policy fp; + fp.threshold = 0ULL; + BOOST_CHECK_EQUAL(fp.max_weak_sum_before_weak_final(), 0ULL); + } +} + +// ============================================================================= +// 5. Issue 7: Chain-Side Authorization Satisfaction Tracking Adversarial Tests +// ============================================================================= +BOOST_AUTO_TEST_CASE_TEMPLATE(auth_satisfied_tracking_adversarial, TESTER, validating_testers) { try { + TESTER chain; + + chain.create_accounts( {"victim"_n, "attacker"_n, "partner"_n} ); + chain.produce_block(); + + // --- Adversarial Attack 1: Attacker constructs transaction naming victim without signature --- + { + auto act = chain.get_action(eosio::chain::config::system_account_name, "reqauth"_n, + {permission_level{"victim"_n, eosio::chain::config::active_name}}, + fc::mutable_variant_object()("from", "victim")); + signed_transaction trx; + trx.actions.emplace_back(std::move(act)); + chain.set_transaction_headers(trx); + + auto ptrx = std::make_shared(trx); + auto meta = transaction_metadata::start_recover_keys( + ptrx, chain.control->get_thread_pool(), chain.control->get_chain_id(), + fc::microseconds::maximum(), transaction_metadata::trx_type::input + ).get(); + + BOOST_CHECK_EQUAL(meta->satisfied_authorizations(), false); + auto trace = chain.control->push_transaction(meta, fc::time_point::maximum(), fc::microseconds::maximum(), 0, false, 0); + BOOST_REQUIRE(trace->except); + BOOST_CHECK_EQUAL(trace->except->code(), unsatisfied_authorization::code_value); + // CRITICAL: declared_auths_satisfied MUST remain false so victim is NOT blamed + BOOST_CHECK_EQUAL(meta->satisfied_authorizations(), false); + BOOST_CHECK_EQUAL(meta->declared_auths_satisfied, false); + } + + // --- Adversarial Attack 2: Attacker signs with attacker's key while naming victim --- + { + auto act = chain.get_action(eosio::chain::config::system_account_name, "reqauth"_n, + {permission_level{"victim"_n, eosio::chain::config::active_name}}, + fc::mutable_variant_object()("from", "victim")); + signed_transaction trx; + trx.actions.emplace_back(std::move(act)); + chain.set_transaction_headers(trx); + trx.sign( chain.get_private_key("attacker"_n, "active"), chain.control->get_chain_id() ); + + auto ptrx = std::make_shared(trx); + auto meta = transaction_metadata::start_recover_keys( + ptrx, chain.control->get_thread_pool(), chain.control->get_chain_id(), + fc::microseconds::maximum(), transaction_metadata::trx_type::input + ).get(); + + BOOST_CHECK_EQUAL(meta->satisfied_authorizations(), false); + auto trace = chain.control->push_transaction(meta, fc::time_point::maximum(), fc::microseconds::maximum(), 0, false, 0); + BOOST_REQUIRE(trace->except); + BOOST_CHECK_EQUAL(trace->except->code(), unsatisfied_authorization::code_value); + // CRITICAL: attacker cannot blame victim + BOOST_CHECK_EQUAL(meta->satisfied_authorizations(), false); + } + + // --- Adversarial Attack 3: Multi-auth action where only 1 of 2 required parties signs --- + { + auto act = chain.get_action(eosio::chain::config::system_account_name, "reqauth"_n, + {permission_level{"victim"_n, eosio::chain::config::active_name}, + permission_level{"partner"_n, eosio::chain::config::active_name}}, + fc::mutable_variant_object()("from", "victim")); + signed_transaction trx; + trx.actions.emplace_back(std::move(act)); + chain.set_transaction_headers(trx); + // Only partner signs, victim did not sign + trx.sign( chain.get_private_key("partner"_n, "active"), chain.control->get_chain_id() ); + + auto ptrx = std::make_shared(trx); + auto meta = transaction_metadata::start_recover_keys( + ptrx, chain.control->get_thread_pool(), chain.control->get_chain_id(), + fc::microseconds::maximum(), transaction_metadata::trx_type::input + ).get(); + + auto trace = chain.control->push_transaction(meta, fc::time_point::maximum(), fc::microseconds::maximum(), 0, false, 0); + BOOST_REQUIRE(trace->except); + BOOST_CHECK_EQUAL(trace->except->code(), unsatisfied_authorization::code_value); + // Incomplete authorizations must NOT be marked satisfied + BOOST_CHECK_EQUAL(meta->satisfied_authorizations(), false); + + // Now both sign + trx.signatures.clear(); + trx.sign( chain.get_private_key("victim"_n, "active"), chain.control->get_chain_id() ); + trx.sign( chain.get_private_key("partner"_n, "active"), chain.control->get_chain_id() ); + + auto ptrx_both = std::make_shared(trx); + auto meta_both = transaction_metadata::start_recover_keys( + ptrx_both, chain.control->get_thread_pool(), chain.control->get_chain_id(), + fc::microseconds::maximum(), transaction_metadata::trx_type::input + ).get(); + + auto trace_both = chain.control->push_transaction(meta_both, fc::time_point::maximum(), fc::microseconds::maximum(), 0, false, 0); + BOOST_CHECK(!trace_both->except); + // Both signed -> satisfied + BOOST_CHECK_EQUAL(meta_both->satisfied_authorizations(), true); + } + + // --- Adversarial Attack 4: Transaction with valid auths that FAILS in execution --- + // (e.g. deleting 'owner' permission which is rejected by system contract assert) + // In this case, auth WAS satisfied, so failure billing SHOULD apply to authorizer. + { + chain.produce_block(); + auto act = chain.get_action(eosio::chain::config::system_account_name, "deleteauth"_n, + {permission_level{"victim"_n, eosio::chain::config::owner_name}}, + fc::mutable_variant_object() + ("account", "victim") + ("permission", "owner")); + + signed_transaction trx; + trx.actions.emplace_back(std::move(act)); + chain.set_transaction_headers(trx); + trx.sign( chain.get_private_key("victim"_n, "owner"), chain.control->get_chain_id() ); + + auto ptrx = std::make_shared(trx); + auto meta = transaction_metadata::start_recover_keys( + ptrx, chain.control->get_thread_pool(), chain.control->get_chain_id(), + fc::microseconds::maximum(), transaction_metadata::trx_type::input + ).get(); + + auto trace = chain.control->push_transaction(meta, fc::time_point::maximum(), fc::microseconds::maximum(), 0, false, 0); + // Execution failed (system contract assert: cannot delete owner) + BOOST_REQUIRE(trace->except); + BOOST_CHECK_NE(trace->except->code(), unsatisfied_authorization::code_value); + // Authorization WAS satisfied before exec failed! + BOOST_CHECK_EQUAL(meta->satisfied_authorizations(), true); + } + + // --- Adversarial Attack 5: Poisoned cache / retry simulation --- + // Simulate unapplied transaction queue retry where metadata object was previously marked satisfied = true + { + chain.produce_block(); + auto act = chain.get_action(eosio::chain::config::system_account_name, "reqauth"_n, + {permission_level{"victim"_n, eosio::chain::config::active_name}}, + fc::mutable_variant_object()("from", "victim")); + signed_transaction trx; + trx.actions.emplace_back(std::move(act)); + chain.set_transaction_headers(trx); + // Sign with attacker key + trx.sign( chain.get_private_key("attacker"_n, "active"), chain.control->get_chain_id() ); + + auto ptrx = std::make_shared(trx); + auto meta = transaction_metadata::start_recover_keys( + ptrx, chain.control->get_thread_pool(), chain.control->get_chain_id(), + fc::microseconds::maximum(), transaction_metadata::trx_type::input + ).get(); + + // Poison the metadata object to simulate leftover true + meta->declared_auths_satisfied = true; + BOOST_CHECK_EQUAL(meta->satisfied_authorizations(), true); + + // push_transaction must reset it to false upon entry! + auto trace = chain.control->push_transaction(meta, fc::time_point::maximum(), fc::microseconds::maximum(), 0, false, 0); + BOOST_REQUIRE(trace->except); + BOOST_CHECK_EQUAL(trace->except->code(), unsatisfied_authorization::code_value); + BOOST_CHECK_EQUAL(meta->satisfied_authorizations(), false); + } + +} FC_LOG_AND_RETHROW() } + +BOOST_AUTO_TEST_SUITE_END() From 62bb6547ff190feb07b399ac2892a4762735c131 Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Thu, 3 Sep 2026 04:36:39 -0300 Subject: [PATCH 05/17] plugins: bound P2P frame parsers, fix block progress timers, subjectively bill verified auths, and bound SHiP queue - Issue 3: only mark block progress for blocks already held; default p2p-disable-block-nack to true for producing nodes - Issue 4: bound P2P frame parsers using fc::bounded_datastream to prevent stream desync and consuming bytes from pipelined frames; add advance_to_frame_end() - Issue 6: bound SHiP queued_status_requests to prevent unbounded queue growth and memory exhaustion - Issue 7 (producer): gate subjective failure billing and account failure tracking on declared_auths_satisfied to prevent DoS against victim accounts - Issue 13: validate host and port syntax in connect() prior to inserting into supplied_peers - Add unit, plugin, and cluster integration tests --- .../include/eosio/net_plugin/net_utils.hpp | 24 + plugins/net_plugin/net_plugin.cpp | 58 +- plugins/net_plugin/tests/CMakeLists.txt | 1 + plugins/net_plugin/tests/test_net_plugin.cpp | 699 ++++++++++++++++++ plugins/producer_plugin/producer_plugin.cpp | 9 +- .../eosio/state_history_plugin/session.hpp | 46 +- tests/subjective_billing_test.py | 20 +- unittests/subjective_billing_tests.cpp | 176 +++++ 8 files changed, 1007 insertions(+), 26 deletions(-) create mode 100644 plugins/net_plugin/tests/test_net_plugin.cpp diff --git a/plugins/net_plugin/include/eosio/net_plugin/net_utils.hpp b/plugins/net_plugin/include/eosio/net_plugin/net_utils.hpp index 92e718a9b0..e8debe370b 100644 --- a/plugins/net_plugin/include/eosio/net_plugin/net_utils.hpp +++ b/plugins/net_plugin/include/eosio/net_plugin/net_utils.hpp @@ -157,6 +157,30 @@ namespace detail { return {std::move(listen_addr), block_sync_rate_limit}; } + enum class block_notice_action { + have_block, + missing_previous, + missing_with_previous + }; + + inline block_notice_action classify_block_notice(bool have_block, bool have_previous) { + if (have_block) { + return block_notice_action::have_block; + } + if (!have_previous) { + return block_notice_action::missing_previous; + } + return block_notice_action::missing_with_previous; + } + + inline bool block_notice_marks_progress(block_notice_action action) { + return action == block_notice_action::have_block; + } + + inline bool block_notice_marks_progress(bool have_block) { + return have_block; + } + } // namespace eosio::net_utils FC_REFLECT(eosio::net_utils::endpoint, (host)(port)) diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index 0539f47c87..d312dcaaff 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -917,6 +917,11 @@ namespace eosio { bool process_next_block_message(uint32_t message_length); bool process_next_trx_message(uint32_t message_length); bool process_next_vote_message(uint32_t message_length); + void advance_to_frame_end(size_t remaining) { + if (remaining > 0) { + pending_message_buffer.advance_read_ptr(remaining); + } + } void update_endpoints(const tcp::endpoint& endpoint = tcp::endpoint()); void send_gossip_bp_peers_initial_message(); @@ -2990,7 +2995,8 @@ namespace eosio { auto now = latest_msg_time = std::chrono::steady_clock::now(); // if next message is a block we already have, exit early - auto peek_ds = pending_message_buffer.create_peek_datastream(); + auto raw_peek_ds = pending_message_buffer.create_peek_datastream(); + fc::bounded_datastream peek_ds( raw_peek_ds, message_length ); unsigned_int which{}; fc::raw::unpack( peek_ds, which ); @@ -3004,9 +3010,11 @@ namespace eosio { } else if( net_msg == msg_type_t::vote_message ) { return process_next_vote_message( message_length ); } else { - auto ds = pending_message_buffer.create_datastream(); + auto raw_ds = pending_message_buffer.create_datastream(); + fc::bounded_datastream ds( raw_ds, message_length ); net_message msg; fc::raw::unpack( ds, msg ); + advance_to_frame_end( ds.remaining() ); msg_handler m( shared_from_this() ); std::visit( m, msg ); } @@ -3021,7 +3029,8 @@ namespace eosio { // called from connection strand bool connection::process_next_block_message(uint32_t message_length) { - auto peek_ds = pending_message_buffer.create_peek_datastream(); + auto raw_peek_ds = pending_message_buffer.create_peek_datastream(); + fc::bounded_datastream peek_ds( raw_peek_ds, message_length ); unsigned_int which{}; fc::raw::unpack( peek_ds, which ); // throw away block_header bh; @@ -3070,12 +3079,14 @@ namespace eosio { return true; } - auto mb_ds = pending_message_buffer.create_datastream(); + auto raw_mb_ds = pending_message_buffer.create_datastream(); + fc::bounded_datastream mb_ds( raw_mb_ds, message_length ); fc::raw::unpack( mb_ds, which ); fc::datastream_mirror ds(mb_ds, message_length); shared_ptr ptr = std::make_shared(); fc::raw::unpack( ds, *ptr ); + advance_to_frame_end( mb_ds.remaining() ); bool has_webauthn_sig = ptr->producer_signature.is_webauthn(); @@ -3111,12 +3122,14 @@ namespace eosio { const unsigned long trx_in_progress_sz = this->trx_in_progress_size.load(); - auto ds = pending_message_buffer.create_datastream(); + auto raw_ds = pending_message_buffer.create_datastream(); + fc::bounded_datastream ds( raw_ds, message_length ); unsigned_int which{}; fc::raw::unpack( ds, which ); // shared_ptr needed here because packed_transaction_ptr is shared_ptr std::shared_ptr ptr = std::make_shared(); fc::raw::unpack( ds, *ptr ); + advance_to_frame_end( ds.remaining() ); if( trx_in_progress_sz > def_max_trx_in_progress_size) { char reason[72]; snprintf(reason, 72, "Dropping trx, too many trx in progress %lu bytes", trx_in_progress_sz); @@ -3150,12 +3163,14 @@ namespace eosio { return true; } - auto ds = pending_message_buffer.create_datastream(); + auto raw_ds = pending_message_buffer.create_datastream(); + fc::bounded_datastream ds( raw_ds, message_length ); unsigned_int which{}; fc::raw::unpack( ds, which ); assert(to_msg_type_t(which) == msg_type_t::vote_message); // verified by caller vote_message_ptr ptr = std::make_shared(); fc::raw::unpack( ds, *ptr ); + advance_to_frame_end( ds.remaining() ); handle_message( ptr ); return true; @@ -3735,10 +3750,17 @@ namespace eosio { if (block_header::num_from_id(msg.id) <= fork_db_root_num) return; - latest_blk_time = std::chrono::steady_clock::now(); - if (my_impl->dispatcher.have_block(msg.id)) { + const bool have_blk = my_impl->dispatcher.have_block(msg.id); + const bool have_prev = my_impl->dispatcher.have_block(msg.previous); + const auto notice_action = net_utils::classify_block_notice(have_blk, have_prev); + + if (net_utils::block_notice_marks_progress(notice_action)) { + latest_blk_time = std::chrono::steady_clock::now(); + } + + if (notice_action == net_utils::block_notice_action::have_block) { my_impl->dispatcher.add_peer_block(msg.id, connection_id); - } else if (!my_impl->dispatcher.have_block(msg.previous)) { // still don't have previous block + } else if (notice_action == net_utils::block_notice_action::missing_previous) { // still don't have previous block peer_dlog(this, "Received unknown block notice, checking already requested"); request_message req; req.req_blocks.mode = normal; @@ -4392,7 +4414,20 @@ namespace eosio { resp_expected_period = def_resp_expected_wait; max_nodes_per_host = options.at( "p2p-max-nodes-per-host" ).as(); p2p_accept_transactions = options.at( "p2p-accept-transactions" ).as(); - p2p_disable_block_nack = options.at( "p2p-disable-block-nack" ).as(); + bool has_producers = false; + if (options.count("producer-name")) { + const auto& prods = options.at("producer-name").as>(); + has_producers = !prods.empty(); + } + if (options.count("p2p-disable-block-nack")) { + if (options.at("p2p-disable-block-nack").defaulted() && has_producers) { + p2p_disable_block_nack = true; + } else { + p2p_disable_block_nack = options.at("p2p-disable-block-nack").as(); + } + } else { + p2p_disable_block_nack = has_producers; + } use_socket_read_watermark = options.at( "use-socket-read-watermark" ).as(); keepalive_interval = std::chrono::milliseconds( options.at( "p2p-keepalive-interval-ms" ).as() ); @@ -4775,6 +4810,9 @@ namespace eosio { // called by API string connections_manager::connect( const string& host, const string& p2p_address ) { + if (auto [h, port, type] = net_utils::split_host_port_type(host); h.empty()) { + return "invalid peer address"; + } std::unique_lock g( connections_mtx ); supplied_peers.insert(host); g.unlock(); diff --git a/plugins/net_plugin/tests/CMakeLists.txt b/plugins/net_plugin/tests/CMakeLists.txt index 9db6e9da34..a1360bf2a2 100644 --- a/plugins/net_plugin/tests/CMakeLists.txt +++ b/plugins/net_plugin/tests/CMakeLists.txt @@ -1,6 +1,7 @@ add_executable( test_net_plugin auto_bp_peering_unittest.cpp rate_limit_parse_unittest.cpp + test_net_plugin.cpp main.cpp ) target_link_libraries( test_net_plugin net_plugin eosio_testing eosio_chain_wrap ) diff --git a/plugins/net_plugin/tests/test_net_plugin.cpp b/plugins/net_plugin/tests/test_net_plugin.cpp new file mode 100644 index 0000000000..cc16eb1e16 --- /dev/null +++ b/plugins/net_plugin/tests/test_net_plugin.cpp @@ -0,0 +1,699 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +BOOST_AUTO_TEST_SUITE(net_plugin_milestone3_tests) + +// ============================================================================= +// Issue 3 Tests: Block notices for missing blocks count as block progress +// ============================================================================= + +BOOST_AUTO_TEST_CASE(test_classify_block_notice_progress) { + using namespace eosio::net_utils; + + // 1. Have block, have previous -> have_block: marks block progress + auto a1 = classify_block_notice(true, true); + BOOST_CHECK(a1 == block_notice_action::have_block); + BOOST_CHECK(block_notice_marks_progress(a1)); + BOOST_CHECK(block_notice_marks_progress(true)); + + // 2. Have block, missing previous -> have_block: marks block progress + auto a2 = classify_block_notice(true, false); + BOOST_CHECK(a2 == block_notice_action::have_block); + BOOST_CHECK(block_notice_marks_progress(a2)); + BOOST_CHECK(block_notice_marks_progress(true)); + + // 3. Missing block, missing previous -> missing_previous: does NOT mark progress + auto a3 = classify_block_notice(false, false); + BOOST_CHECK(a3 == block_notice_action::missing_previous); + BOOST_CHECK(!block_notice_marks_progress(a3)); + BOOST_CHECK(!block_notice_marks_progress(false)); + + // 4. Missing block, have previous -> missing_with_previous: does NOT mark progress + auto a4 = classify_block_notice(false, true); + BOOST_CHECK(a4 == block_notice_action::missing_with_previous); + BOOST_CHECK(!block_notice_marks_progress(a4)); + BOOST_CHECK(!block_notice_marks_progress(false)); +} + +BOOST_AUTO_TEST_CASE(test_p2p_disable_block_nack_default_for_producers) { + namespace bpo = boost::program_options; + bpo::options_description desc("Test Options"); + desc.add_options() + ("p2p-disable-block-nack", bpo::value()->default_value(false), "disable nack") + ("producer-name", bpo::value>()->composing()->multitoken(), "producers"); + + auto eval_disable_nack = [](const bpo::variables_map& options) -> bool { + bool has_producers = false; + if (options.count("producer-name")) { + const auto& prods = options.at("producer-name").as>(); + has_producers = !prods.empty(); + } + if (options.count("p2p-disable-block-nack")) { + if (options.at("p2p-disable-block-nack").defaulted() && has_producers) { + return true; + } else { + return options.at("p2p-disable-block-nack").as(); + } + } else { + return has_producers; + } + }; + + // Case A: No producers configured, defaulted p2p-disable-block-nack -> false + { + bpo::variables_map vm; + const char* args[] = {"test_app"}; + bpo::store(bpo::parse_command_line(1, args, desc), vm); + bpo::notify(vm); + BOOST_CHECK_EQUAL(eval_disable_nack(vm), false); + } + + // Case B: Producer configured, defaulted p2p-disable-block-nack -> true + { + bpo::variables_map vm; + const char* args[] = {"test_app", "--producer-name", "producer1"}; + bpo::store(bpo::parse_command_line(3, args, desc), vm); + bpo::notify(vm); + BOOST_CHECK_EQUAL(eval_disable_nack(vm), true); + } + + // Case C: Producer configured, explicit --p2p-disable-block-nack=false -> false + { + bpo::variables_map vm; + const char* args[] = {"test_app", "--producer-name", "producer1", "--p2p-disable-block-nack=false"}; + bpo::store(bpo::parse_command_line(4, args, desc), vm); + bpo::notify(vm); + BOOST_CHECK_EQUAL(eval_disable_nack(vm), false); + } + + // Case D: No producer, explicit --p2p-disable-block-nack=true -> true + { + bpo::variables_map vm; + const char* args[] = {"test_app", "--p2p-disable-block-nack=true"}; + bpo::store(bpo::parse_command_line(2, args, desc), vm); + bpo::notify(vm); + BOOST_CHECK_EQUAL(eval_disable_nack(vm), true); + } +} + +// ============================================================================= +// Issue 4 Tests: P2P frame parsers bounded to declared length +// ============================================================================= + +template +void append_to_message_buffer(fc::message_buffer& mb, const void* data, size_t size) { + if (mb.bytes_to_write() < size) { + mb.add_space(size - mb.bytes_to_write()); + } + memcpy(mb.write_ptr(), data, size); + mb.advance_write_ptr(size); +} + +BOOST_AUTO_TEST_CASE(test_p2p_frame_parser_bounds_and_alignment) { + fc::message_buffer<1024*1024> mb; + + // Frame 1: handshake_message with 16 bytes of trailing padding declared in message_length + eosio::handshake_message hello1; + hello1.p2p_address = "peer1:9876"; + hello1.os = "linux"; + hello1.agent = "test"; + + std::vector hello1_bytes = fc::raw::pack(hello1); + uint32_t payload_len = hello1_bytes.size(); + uint32_t padding_len = 16; + uint32_t declared_len1 = payload_len + padding_len; + + // Frame 2: handshake_message immediately following Frame 1 + eosio::handshake_message hello2; + hello2.p2p_address = "peer2:9876"; + hello2.os = "linux"; + hello2.agent = "test2"; + std::vector hello2_bytes = fc::raw::pack(hello2); + uint32_t declared_len2 = hello2_bytes.size(); + + // Frame 1: header + payload + padding + append_to_message_buffer(mb, &declared_len1, sizeof(declared_len1)); + append_to_message_buffer(mb, hello1_bytes.data(), hello1_bytes.size()); + std::vector padding(padding_len, 'P'); + append_to_message_buffer(mb, padding.data(), padding.size()); + + // Frame 2: header + payload + append_to_message_buffer(mb, &declared_len2, sizeof(declared_len2)); + append_to_message_buffer(mb, hello2_bytes.data(), hello2_bytes.size()); + + // Read Frame 1 header + uint32_t read_len1 = 0; + auto idx1 = mb.read_index(); + mb.peek(&read_len1, sizeof(read_len1), idx1); + BOOST_CHECK_EQUAL(read_len1, declared_len1); + mb.advance_read_ptr(sizeof(read_len1)); + + // Unpack Frame 1 through bounded_datastream + { + auto raw_ds = mb.create_datastream(); + fc::bounded_datastream bds(raw_ds, read_len1); + eosio::handshake_message unpacked1; + fc::raw::unpack(bds, unpacked1); + BOOST_CHECK_EQUAL(unpacked1.p2p_address, hello1.p2p_address); + BOOST_CHECK_EQUAL(unpacked1.agent, hello1.agent); + BOOST_CHECK_EQUAL(bds.remaining(), padding_len); + + // Advance read pointer past padding to exact frame end + mb.advance_read_ptr(bds.remaining()); + } + + // Frame 2 header MUST now be exactly at the read index + uint32_t read_len2 = 0; + auto idx2 = mb.read_index(); + mb.peek(&read_len2, sizeof(read_len2), idx2); + BOOST_CHECK_EQUAL(read_len2, declared_len2); + mb.advance_read_ptr(sizeof(read_len2)); + + // Unpack Frame 2 through bounded_datastream + { + auto raw_ds = mb.create_datastream(); + fc::bounded_datastream bds(raw_ds, read_len2); + eosio::handshake_message unpacked2; + fc::raw::unpack(bds, unpacked2); + BOOST_CHECK_EQUAL(unpacked2.p2p_address, hello2.p2p_address); + BOOST_CHECK_EQUAL(unpacked2.agent, hello2.agent); + BOOST_CHECK_EQUAL(bds.remaining(), 0u); + mb.advance_read_ptr(bds.remaining()); + } + + // Buffer completely consumed + BOOST_CHECK_EQUAL(mb.bytes_to_read(), 0u); +} + +BOOST_AUTO_TEST_CASE(test_p2p_frame_parser_truncated_frame_throws) { + fc::message_buffer<1024*1024> mb; + + eosio::handshake_message hello; + hello.p2p_address = "long_peer_address_for_test:9876"; + hello.agent = "some_long_agent_name"; + std::vector bytes = fc::raw::pack(hello); + + // Place full bytes into buffer, but declare bounded length shorter than actual payload + uint32_t truncated_len = bytes.size() / 2; + append_to_message_buffer(mb, bytes.data(), bytes.size()); + + auto raw_ds = mb.create_datastream(); + fc::bounded_datastream bds(raw_ds, truncated_len); + + eosio::handshake_message unpacked; + // Bounded stream must throw out_of_range_exception rather than reading past truncated bound + BOOST_CHECK_THROW(fc::raw::unpack(bds, unpacked), fc::out_of_range_exception); +} + +// ============================================================================= +// Issue 13 Tests: connect() retains invalid peers in supplied_peers +// ============================================================================= + +BOOST_AUTO_TEST_CASE(test_connect_invalid_peer_syntax_rejection) { + using namespace eosio::net_utils; + + // Valid addresses must parse cleanly + { + auto [h, p, t] = split_host_port_type("127.0.0.1:9876"); + BOOST_CHECK_EQUAL(h, "127.0.0.1"); + BOOST_CHECK_EQUAL(p, "9876"); + BOOST_CHECK(t.empty()); + } + { + auto [h, p, t] = split_host_port_type("p2p.eos.io:9876:blk"); + BOOST_CHECK_EQUAL(h, "p2p.eos.io"); + BOOST_CHECK_EQUAL(p, "9876"); + BOOST_CHECK_EQUAL(t, "blk"); + } + { + auto [h, p, t] = split_host_port_type("[2001:db8::1]:9876:trx"); + BOOST_CHECK_EQUAL(h, "2001:db8::1"); + BOOST_CHECK_EQUAL(p, "9876"); + BOOST_CHECK_EQUAL(t, "trx"); + } + + // Malformed addresses that must return empty host + std::vector invalid_addresses = { + "", + ":8888", + "localhost", + "foo:bar:baz:extra:more", + "[2001:db8::1:9876", + "2001:db8::1:9876", + " " + }; + + for (const auto& addr : invalid_addresses) { + auto [h, p, t] = split_host_port_type(addr); + BOOST_CHECK_MESSAGE(h.empty(), "Expected empty host for invalid address: " + addr); + } + + // Verify connect() behavior: validation before insertion prevents retention of invalid peers + std::set supplied_peers; + auto connect_fn = [&](const std::string& host) -> std::string { + if (auto [h, port, type] = split_host_port_type(host); h.empty()) { + return "invalid peer address"; + } + supplied_peers.insert(host); + return "added connection"; + }; + + for (const auto& addr : invalid_addresses) { + std::string res = connect_fn(addr); + BOOST_CHECK_EQUAL(res, "invalid peer address"); + } + + // supplied_peers must NOT retain any of the invalid addresses + BOOST_CHECK(supplied_peers.empty()); + BOOST_CHECK_EQUAL(supplied_peers.size(), 0u); + + // Valid address succeeds and enters supplied_peers + std::string valid_res = connect_fn("192.168.1.100:9876"); + BOOST_CHECK_EQUAL(valid_res, "added connection"); + BOOST_CHECK_EQUAL(supplied_peers.size(), 1u); + BOOST_CHECK_EQUAL(*supplied_peers.begin(), "192.168.1.100:9876"); +} + +// ============================================================================= +// Adversarial Stress Tests: Issue 3 (Block notices & Watchdog Keepalive Stall) +// ============================================================================= + +BOOST_AUTO_TEST_CASE(test_adversarial_block_notice_stall_and_watchdog) { + using namespace eosio::net_utils; + + // Emulate connection keepalive watchdog state + std::chrono::steady_clock::time_point latest_blk_time = std::chrono::steady_clock::now(); + const auto initial_time = latest_blk_time; + + // Sleep slightly so any time update would be measurably strictly greater + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + + // Attacker Scenario: An unauthenticated peer floods 500 block notices for unknown blocks + for (int i = 0; i < 500; ++i) { + bool have_block = false; + bool have_previous = (i % 2 == 1); // Alternates between missing_previous and missing_with_previous + + auto action = classify_block_notice(have_block, have_previous); + if (block_notice_marks_progress(action)) { + latest_blk_time = std::chrono::steady_clock::now(); + } + + // Verify that neither missing_previous nor missing_with_previous marks progress + BOOST_CHECK(!block_notice_marks_progress(action)); + BOOST_CHECK(!block_notice_marks_progress(have_block)); + } + + // VERDICT: latest_blk_time must remain completely unmodified after 500 malicious notices! + BOOST_CHECK(latest_blk_time == initial_time); + + // Edge Case: Extreme IDs - all-zeros ID, self-referential cycle (prev == id) + { + auto cycle_action = classify_block_notice(false, false); + BOOST_CHECK(!block_notice_marks_progress(cycle_action)); + if (block_notice_marks_progress(cycle_action)) { + latest_blk_time = std::chrono::steady_clock::now(); + } + BOOST_CHECK(latest_blk_time == initial_time); + } + + // Contrast: Honest block notice arrives (have_block == true) + { + auto honest_action = classify_block_notice(true, false); + BOOST_CHECK(block_notice_marks_progress(honest_action)); + if (block_notice_marks_progress(honest_action)) { + latest_blk_time = std::chrono::steady_clock::now(); + } + // Must have advanced + BOOST_CHECK(latest_blk_time > initial_time); + } +} + +BOOST_AUTO_TEST_CASE(test_adversarial_p2p_disable_block_nack_permutations) { + namespace bpo = boost::program_options; + bpo::options_description desc("Test Options"); + desc.add_options() + ("p2p-disable-block-nack", bpo::value()->default_value(false), "disable nack") + ("producer-name", bpo::value>()->composing()->multitoken(), "producers"); + + auto eval_disable_nack = [](const bpo::variables_map& options) -> bool { + bool has_producers = false; + if (options.count("producer-name")) { + const auto& prods = options.at("producer-name").as>(); + has_producers = !prods.empty(); + } + if (options.count("p2p-disable-block-nack")) { + if (options.at("p2p-disable-block-nack").defaulted() && has_producers) { + return true; + } else { + return options.at("p2p-disable-block-nack").as(); + } + } else { + return has_producers; + } + }; + + // Permutation 1: Multiple producers configured (bp1, bp2, bp3), defaulted nack -> true + { + bpo::variables_map vm; + const char* args[] = {"app", "--producer-name", "bp1", "--producer-name", "bp2", "--producer-name", "bp3"}; + bpo::store(bpo::parse_command_line(7, args, desc), vm); + bpo::notify(vm); + BOOST_CHECK_EQUAL(eval_disable_nack(vm), true); + } + + // Permutation 2: Multiple producers, explicit false -> false + { + bpo::variables_map vm; + const char* args[] = {"app", "--producer-name", "bp1", "--p2p-disable-block-nack=false"}; + bpo::store(bpo::parse_command_line(4, args, desc), vm); + bpo::notify(vm); + BOOST_CHECK_EQUAL(eval_disable_nack(vm), false); + } + + // Permutation 3: No producers, explicit true -> true + { + bpo::variables_map vm; + const char* args[] = {"app", "--p2p-disable-block-nack=true"}; + bpo::store(bpo::parse_command_line(2, args, desc), vm); + bpo::notify(vm); + BOOST_CHECK_EQUAL(eval_disable_nack(vm), true); + } + + // Permutation 4: Empty string producer -> vector has 1 element (""), has_producers is true + { + bpo::variables_map vm; + const char* args[] = {"app", "--producer-name", ""}; + bpo::store(bpo::parse_command_line(3, args, desc), vm); + bpo::notify(vm); + BOOST_CHECK_EQUAL(eval_disable_nack(vm), true); + } +} + +// ============================================================================= +// Adversarial Stress Tests: Issue 4 (Bounded Datastream & Frame Alignment) +// ============================================================================= + +BOOST_AUTO_TEST_CASE(test_adversarial_bounded_datastream_primitives_stress) { + std::vector backing(1024, 'X'); + fc::datastream raw_ds(backing.data(), backing.size()); + + // Zero boundary + fc::bounded_datastream bds0(raw_ds, 0); + BOOST_CHECK_EQUAL(bds0.remaining(), 0u); + BOOST_CHECK_EQUAL(bds0.max_bytes(), 0u); + BOOST_CHECK_EQUAL(bds0.tellp(), 0u); + BOOST_CHECK(bds0.valid()); + + char dummy = 0; + BOOST_CHECK_THROW(bds0.read(&dummy, 1), fc::out_of_range_exception); + BOOST_CHECK_THROW(bds0.skip(1), fc::out_of_range_exception); + BOOST_CHECK_THROW(bds0.write(&dummy, 1), fc::out_of_range_exception); + BOOST_CHECK_THROW(bds0.put('a'), fc::out_of_range_exception); + BOOST_CHECK_THROW(bds0.get(dummy), fc::out_of_range_exception); + BOOST_CHECK(!bds0.seekp(1)); + BOOST_CHECK(bds0.seekp(0)); + + // Arithmetic types insertion/extraction through operator<< and operator>> + std::vector mem(256); + { + fc::datastream out_raw(mem.data(), mem.size()); + fc::bounded_datastream out_bds(out_raw, mem.size()); + + uint8_t u8 = 42; + uint16_t u16 = 12345; + uint32_t u32 = 0xDEADBEEF; + uint64_t u64 = 0xFEEDFACEDEADBEEFULL; + + out_bds << u8 << u16 << u32 << u64; + BOOST_CHECK_EQUAL(out_bds.tellp(), sizeof(u8) + sizeof(u16) + sizeof(u32) + sizeof(u64)); + } + + { + fc::datastream in_raw(mem.data(), mem.size()); + fc::bounded_datastream in_bds(in_raw, sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint32_t) + sizeof(uint64_t)); + + uint8_t r8 = 0; + uint16_t r16 = 0; + uint32_t r32 = 0; + uint64_t r64 = 0; + + in_bds >> r8 >> r16 >> r32 >> r64; + BOOST_CHECK_EQUAL(r8, 42); + BOOST_CHECK_EQUAL(r16, 12345); + BOOST_CHECK_EQUAL(r32, 0xDEADBEEF); + BOOST_CHECK_EQUAL(r64, 0xFEEDFACEDEADBEEFULL); + BOOST_CHECK_EQUAL(in_bds.remaining(), 0u); + + // Attempt to read past bound + uint8_t overflow_byte = 0; + BOOST_CHECK_THROW(in_bds >> overflow_byte, fc::out_of_range_exception); + } +} + +BOOST_AUTO_TEST_CASE(test_adversarial_multipacket_frame_pipeline_desync) { + fc::message_buffer<1024 * 1024> mb; + + // Construct 5 different messages with various padding lengths + // Frame 1: handshake_message with 27 bytes padding + eosio::handshake_message msg1; + msg1.p2p_address = "peer1:9876"; + msg1.os = "linux"; + msg1.agent = "agent1"; + std::vector b1 = fc::raw::pack(msg1); + uint32_t pad1 = 27; + uint32_t decl1 = b1.size() + pad1; + + // Frame 2: go_away_message with 15 bytes padding + eosio::go_away_message msg2; + msg2.reason = eosio::go_away_reason::duplicate; + msg2.node_id = fc::sha256::hash("node2"); + std::vector b2 = fc::raw::pack(msg2); + uint32_t pad2 = 15; + uint32_t decl2 = b2.size() + pad2; + + // Frame 3: notice_message with 33 bytes padding + eosio::notice_message msg3; + msg3.known_trx.mode = eosio::id_list_modes::normal; + msg3.known_blocks.mode = eosio::id_list_modes::normal; + std::vector b3 = fc::raw::pack(msg3); + uint32_t pad3 = 33; + uint32_t decl3 = b3.size() + pad3; + + // Frame 4: another handshake_message with 0 bytes padding + eosio::handshake_message msg4; + msg4.p2p_address = "peer4:9876"; + msg4.os = "bsd"; + msg4.agent = "agent4"; + std::vector b4 = fc::raw::pack(msg4); + uint32_t pad4 = 0; + uint32_t decl4 = b4.size() + pad4; + + // Helper lambda to append frame with padding + auto append_frame = [&](uint32_t decl_len, const std::vector& payload, uint32_t pad_len) { + append_to_message_buffer(mb, &decl_len, sizeof(decl_len)); + append_to_message_buffer(mb, payload.data(), payload.size()); + if (pad_len > 0) { + std::vector pad(pad_len, 0xAA); + append_to_message_buffer(mb, pad.data(), pad.size()); + } + }; + + // Pipeline all 4 frames consecutively into the message buffer + append_frame(decl1, b1, pad1); + append_frame(decl2, b2, pad2); + append_frame(decl3, b3, pad3); + append_frame(decl4, b4, pad4); + + // Emulate the read loop unpack logic with advance_to_frame_end + auto unpack_frame = [&](auto& unpacked_dest, uint32_t expected_decl_len, uint32_t expected_pad) { + uint32_t read_len = 0; + auto idx = mb.read_index(); + mb.peek(&read_len, sizeof(read_len), idx); + BOOST_CHECK_EQUAL(read_len, expected_decl_len); + mb.advance_read_ptr(sizeof(read_len)); + + auto raw_ds = mb.create_datastream(); + fc::bounded_datastream bds(raw_ds, read_len); + fc::raw::unpack(bds, unpacked_dest); + BOOST_CHECK_EQUAL(bds.remaining(), expected_pad); + + // Crucial: advance_to_frame_end skips remaining padding bytes + mb.advance_read_ptr(bds.remaining()); + }; + + // Unpack Frame 1 + eosio::handshake_message out1; + unpack_frame(out1, decl1, pad1); + BOOST_CHECK_EQUAL(out1.p2p_address, msg1.p2p_address); + BOOST_CHECK_EQUAL(out1.agent, msg1.agent); + + // Unpack Frame 2 + eosio::go_away_message out2; + unpack_frame(out2, decl2, pad2); + BOOST_CHECK(out2.reason == msg2.reason); + BOOST_CHECK_EQUAL(out2.node_id, msg2.node_id); + + // Unpack Frame 3 + eosio::notice_message out3; + unpack_frame(out3, decl3, pad3); + BOOST_CHECK(out3.known_trx.mode == msg3.known_trx.mode); + + // Unpack Frame 4 + eosio::handshake_message out4; + unpack_frame(out4, decl4, pad4); + BOOST_CHECK_EQUAL(out4.p2p_address, msg4.p2p_address); + BOOST_CHECK_EQUAL(out4.agent, msg4.agent); + + // Entire pipeline must be completely consumed with zero trailing bytes desynchronization + BOOST_CHECK_EQUAL(mb.bytes_to_read(), 0u); +} + +BOOST_AUTO_TEST_CASE(test_adversarial_frame_truncation_underdeclared_length) { + fc::message_buffer<1024 * 1024> mb; + + eosio::handshake_message hello; + hello.p2p_address = "127.0.0.1:9876"; + hello.agent = "test_agent"; + std::vector bytes = fc::raw::pack(hello); + + // Test various declared lengths shorter than actual required size + std::vector short_lengths = { 0, 1, 2, 5, static_cast(bytes.size() - 1) }; + + for (uint32_t short_len : short_lengths) { + append_to_message_buffer(mb, bytes.data(), bytes.size()); + auto raw_ds = mb.create_datastream(); + fc::bounded_datastream bds(raw_ds, short_len); + + eosio::handshake_message out; + BOOST_CHECK_THROW(fc::raw::unpack(bds, out), fc::out_of_range_exception); + + // Clean buffer for next iteration + mb.advance_read_ptr(mb.bytes_to_read()); + } +} + +// ============================================================================= +// Adversarial Stress Tests: Issue 13 (connect() Malformed Address Matrix) +// ============================================================================= + +BOOST_AUTO_TEST_CASE(test_adversarial_connect_fuzz_addresses) { + using namespace eosio::net_utils; + + // Category 1: Addresses that split_host_port_type defines as syntactically invalid (empty host or port) + std::vector syntactically_invalid_addresses = { + "", + " ", + "\t\n\r", + ":8888", + ":0", + ":-1", + ":", + "localhost", + "127.0.0.1", + "p2p.eos.io", + "[2001:db8::1", + "2001:db8::1:9876", + "[2001:db8::1]:", + "a:b:c:d:e:f:g:h", + std::string(4096, 'A'), + std::string(4096, 'B') + ":9876" + }; + + std::set supplied_peers; + auto connect_fn = [&](const std::string& host) -> std::string { + if (auto [h, port, type] = split_host_port_type(host); h.empty()) { + return "invalid peer address"; + } + supplied_peers.insert(host); + return "added connection"; + }; + + for (const auto& addr : syntactically_invalid_addresses) { + std::string res = connect_fn(addr); + BOOST_CHECK_MESSAGE(res == "invalid peer address", "Failed to reject syntactically invalid address: " + addr); + } + + // supplied_peers must be completely empty after all attacks! + BOOST_CHECK_EQUAL(supplied_peers.size(), 0u); + BOOST_CHECK(supplied_peers.empty()); + + // Category 2: Addresses that have valid host:port syntax pass split_host_port_type gate + std::vector syntactically_valid_addresses = { + "127.0.0.1:9876", + "node.eos.io:8888", + "[2001:db8::1]:9876", + "peer:9876:blk", + "peer:9876:trx" + }; + + for (const auto& addr : syntactically_valid_addresses) { + std::string res = connect_fn(addr); + BOOST_CHECK_EQUAL(res, "added connection"); + } + BOOST_CHECK_EQUAL(supplied_peers.size(), syntactically_valid_addresses.size()); +} + +BOOST_AUTO_TEST_CASE(test_adversarial_connect_concurrency_stress) { + using namespace eosio::net_utils; + + std::mutex supplied_peers_mtx; + std::set supplied_peers; + + auto connect_thread_fn = [&](const std::string& host) -> std::string { + if (auto [h, port, type] = split_host_port_type(host); h.empty()) { + return "invalid peer address"; + } + std::lock_guard lock(supplied_peers_mtx); + supplied_peers.insert(host); + return "added connection"; + }; + + constexpr size_t NUM_THREADS = 8; + constexpr size_t OPS_PER_THREAD = 100; + + std::vector> futures; + for (size_t t = 0; t < NUM_THREADS; ++t) { + futures.push_back(std::async(std::launch::async, [&, t]() { + for (size_t i = 0; i < OPS_PER_THREAD; ++i) { + // Alternating valid and invalid calls + if (i % 2 == 0) { + std::string invalid_addr = "malformed_node_" + std::to_string(t) + "_" + std::to_string(i); + auto res = connect_thread_fn(invalid_addr); + BOOST_CHECK_EQUAL(res, "invalid peer address"); + } else { + std::string valid_addr = "10.0." + std::to_string(t) + "." + std::to_string(i) + ":9876"; + auto res = connect_thread_fn(valid_addr); + BOOST_CHECK_EQUAL(res, "added connection"); + } + } + })); + } + + for (auto& f : futures) { + f.get(); + } + + // Only valid addresses should have entered supplied_peers + std::lock_guard lock(supplied_peers_mtx); + BOOST_CHECK_EQUAL(supplied_peers.size(), NUM_THREADS * (OPS_PER_THREAD / 2)); + for (const auto& peer : supplied_peers) { + auto [h, p, t] = split_host_port_type(peer); + BOOST_CHECK(!h.empty()); + BOOST_CHECK(!p.empty()); + } +} + +BOOST_AUTO_TEST_SUITE_END() + diff --git a/plugins/producer_plugin/producer_plugin.cpp b/plugins/producer_plugin/producer_plugin.cpp index b724e134c5..a93f61bc27 100644 --- a/plugins/producer_plugin/producer_plugin.cpp +++ b/plugins/producer_plugin/producer_plugin.cpp @@ -2635,16 +2635,17 @@ producer_plugin_impl::handle_push_result(const transaction_metadata_ptr& pr.failed = true; const fc::exception& e = *trace->except; if (e.code() != tx_duplicate::code_value) { - fc_tlog(_log, "Subjective bill for failed ${a}: ${b} elapsed ${t}us, time ${r}us", - ("a", first_auth)("b", sub_bill)("t", trace->elapsed)("r", end - start)); - if (!disable_subjective_enforcement) // subjectively bill failure when producing since not in objective cpu account billing + if (!disable_subjective_enforcement && trx->satisfied_authorizations()) { + fc_tlog(_log, "Subjective bill for failed ${a}: ${b} elapsed ${t}us, time ${r}us", + ("a", first_auth)("b", sub_bill)("t", trace->elapsed)("r", end - start)); subjective_bill.subjective_bill_failure(first_auth, trace->elapsed, fc::time_point::now()); + } log_trx_results(trx, trace); // this failed our configured maximum transaction time, we don't want to replay it fc_tlog(_log, "Failed ${c} trx, auth: ${a}, prev billed: ${p}us, ran: ${r}us, id: ${id}, except: ${e}", ("c", e.code())("a", first_auth)("p", prev_billed_cpu_time_us)("r", end - start)("id", trx->id())("e", e)); - if (!disable_subjective_enforcement) + if (!disable_subjective_enforcement && trx->satisfied_authorizations()) _account_fails.add(first_auth, e); } if (next) { diff --git a/plugins/state_history_plugin/include/eosio/state_history_plugin/session.hpp b/plugins/state_history_plugin/include/eosio/state_history_plugin/session.hpp index e3b95a2b24..d224e1ca6e 100644 --- a/plugins/state_history_plugin/include/eosio/state_history_plugin/session.hpp +++ b/plugins/state_history_plugin/include/eosio/state_history_plugin/session.hpp @@ -5,11 +5,16 @@ #include #include +#include +#include #include #include #include #include +#include +#include +#include #include #include @@ -17,6 +22,39 @@ extern const char* const state_history_plugin_abi; namespace eosio::state_history { +using appbase::app; + +FC_DECLARE_DERIVED_EXCEPTION( status_request_queue_limit_exceeded, chain::plugin_exception, + 3240001, "State history status request queue limit exceeded" ); + +class status_request_queue { +public: + static constexpr size_t default_max_size = 100; + + explicit status_request_queue(size_t max_size = default_max_size) : _max_size(max_size) {} + + bool try_append(bool is_v1) { + if (_queue.size() >= _max_size) { + return false; + } + _queue.emplace_back(is_v1); + return true; + } + + std::deque extract() { + return std::move(_queue); + } + + size_t size() const { return _queue.size(); } + bool empty() const { return _queue.empty(); } + size_t max_size() const { return _max_size; } + void clear() { _queue.clear(); } + +private: + std::deque _queue; + size_t _max_size; +}; + class session_base { public: session_base() = default; @@ -152,7 +190,9 @@ class session final : public session_base { */ std::visit(chain::overloaded { [&self]>>(const GetStatusRequestV0orV1&) { - self.queued_status_requests.emplace_back(std::is_same_v); + EOS_ASSERT(self.queued_status_requests.try_append(std::is_same_v), + status_request_queue_limit_exceeded, + "State history status request queue limit exceeded"); }, [&self]>>(const GetBlocksRequestV0orV1& gbr) { self.current_blocks_request_v1_finality.reset(); @@ -240,7 +280,7 @@ class session final : public session_base { /** * This lambda executes on the main thread; upon returning, the enclosing coroutine continues execution on the connection's strand */ - status_requests = std::move(self.queued_status_requests); + status_requests = self.queued_status_requests.extract(); //decide what block -- if any -- to send out const chain::block_num_type latest_to_consider = self.current_blocks_request.irreversible_only ? @@ -321,7 +361,7 @@ class session final : public session_base { std::atomic_flag has_logged_exception; //left as atomic_flag for useful test_and_set() interface ///these items must only ever be touched on the main thread - std::deque queued_status_requests; //false for v0, true for v1 + status_request_queue queued_status_requests; get_blocks_request_v0 current_blocks_request; std::optional current_blocks_request_v1_finality; //unset: current request is v0; set means v1; true/false is if finality requested diff --git a/tests/subjective_billing_test.py b/tests/subjective_billing_test.py index c6685808a2..543c63db15 100755 --- a/tests/subjective_billing_test.py +++ b/tests/subjective_billing_test.py @@ -161,16 +161,18 @@ assert(subjectiveBilling["used"] == 0) - # Sleep for 1 min - time.sleep(60) - - # Verify subjective decay - acct1 = fdnode.getAccountSubjectiveInfo("account1") + # Wait for subjective decay to reach 0 originalUsed = decaySubjectiveBilling["used"] - finalUsed = acct1["used"] - - Print('Original Fast decay node subjective billing: {}'.format(decaySubjectiveBilling["used"])) - Print('End decay node subjective billing: {}'.format(acct1["used"])) + Print('Original Fast decay node subjective billing: {}'.format(originalUsed)) + for _ in range(30): + time.sleep(5) + acct1 = fdnode.getAccountSubjectiveInfo("account1") + finalUsed = acct1["used"] + Print('Decaying node subjective billing: {}'.format(finalUsed)) + if finalUsed == 0: + break + + Print('End decay node subjective billing: {}'.format(finalUsed)) assert(finalUsed == 0) testSuccessful = True diff --git a/unittests/subjective_billing_tests.cpp b/unittests/subjective_billing_tests.cpp index 4cb25fbaf9..efe9d2531d 100644 --- a/unittests/subjective_billing_tests.cpp +++ b/unittests/subjective_billing_tests.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -127,6 +128,181 @@ BOOST_AUTO_TEST_CASE( subjective_bill_test ) { } +BOOST_AUTO_TEST_CASE( producer_failure_billing_satisfied_auths_test ) { + account_name victim = "victim"_n; + account_name legit = "legit"_n; + + signed_transaction trx1; + trx1.actions.emplace_back(vector{{victim, config::active_name}}, + "eosio"_n, "action"_n, bytes{}); + auto packed_trx1 = std::make_shared(trx1); + auto meta_unauth = transaction_metadata::create_no_recover_keys(packed_trx1, transaction_metadata::trx_type::input); + + // Fresh transaction metadata MUST have satisfied_authorizations() == false + BOOST_CHECK_EQUAL(meta_unauth->satisfied_authorizations(), false); + + signed_transaction trx2; + trx2.actions.emplace_back(vector{{legit, config::active_name}}, + "eosio"_n, "action"_n, bytes{}); + auto packed_trx2 = std::make_shared(trx2); + auto meta_auth = transaction_metadata::create_no_recover_keys(packed_trx2, transaction_metadata::trx_type::input); + meta_auth->set_satisfied_authorizations(true); + BOOST_CHECK_EQUAL(meta_auth->satisfied_authorizations(), true); + + // Emulate producer_plugin_impl::handle_push_result failure logic + struct mock_account_failures { + std::map fails; + void add(const account_name& a, const fc::exception&) { + fails[a]++; + } + uint32_t count(const account_name& a) const { + auto it = fails.find(a); + return it != fails.end() ? it->second : 0; + } + }; + + auto handle_failure = [](const transaction_metadata_ptr& trx, + account_name first_auth, + fc::microseconds elapsed, + const fc::exception& e, + subjective_billing& sub_bill, + mock_account_failures& acc_fails, + bool disable_subjective_enforcement = false) { + if (e.code() != tx_duplicate::code_value) { + if (!disable_subjective_enforcement && trx->satisfied_authorizations()) { + sub_bill.subjective_bill_failure(first_auth, elapsed, fc::time_point::now()); + } + if (!disable_subjective_enforcement && trx->satisfied_authorizations()) { + acc_fails.add(first_auth, e); + } + } + }; + + subjective_billing sub_bill; + mock_account_failures acc_fails; + const auto now = time_point::now(); + fc::exception auth_exc(FC_LOG_MESSAGE(error, "unsatisfied authorization")); + fc::exception assert_exc(FC_LOG_MESSAGE(error, "assertion failure")); + + // Test 1: Unauthorized transaction fails (e.g. attacker claims victim as first_auth) + // Because satisfied_authorizations() is false, victim must NOT be billed or marked with failure + handle_failure(meta_unauth, victim, fc::microseconds(2000), auth_exc, sub_bill, acc_fails); + BOOST_CHECK_EQUAL(sub_bill.get_subjective_bill(victim, now), 0); + BOOST_CHECK_EQUAL(acc_fails.count(victim), 0u); + + // Repeat 50 times to simulate brute-force / DoS attack targeting victim + for (int i = 0; i < 50; ++i) { + handle_failure(meta_unauth, victim, fc::microseconds(2000), auth_exc, sub_bill, acc_fails); + } + BOOST_CHECK_EQUAL(sub_bill.get_subjective_bill(victim, now), 0); + BOOST_CHECK_EQUAL(acc_fails.count(victim), 0u); + + // Test 2: Legitimate transaction with satisfied authorizations fails during execution + // Because satisfied_authorizations() is true, legit MUST be billed and marked with failure + handle_failure(meta_auth, legit, fc::microseconds(2000), assert_exc, sub_bill, acc_fails); + BOOST_CHECK_EQUAL(sub_bill.get_subjective_bill(legit, now), 2000); + BOOST_CHECK_EQUAL(acc_fails.count(legit), 1u); + + // Test 3: If disable_subjective_enforcement is true, neither is billed + subjective_billing sub_bill2; + mock_account_failures acc_fails2; + handle_failure(meta_auth, legit, fc::microseconds(2000), assert_exc, sub_bill2, acc_fails2, true); + BOOST_CHECK_EQUAL(sub_bill2.get_subjective_bill(legit, now), 0); +} + +BOOST_AUTO_TEST_CASE( producer_failure_billing_adversarial_multi_victim_dos_test ) { + // Emulate producer failure billing structures + struct mock_account_failures { + std::map fails; + void add(const account_name& a, const fc::exception&) { + fails[a]++; + } + uint32_t count(const account_name& a) const { + auto it = fails.find(a); + return it != fails.end() ? it->second : 0; + } + }; + + auto handle_failure = [](const transaction_metadata_ptr& trx, + account_name first_auth, + fc::microseconds elapsed, + const fc::exception& e, + subjective_billing& sub_bill, + mock_account_failures& acc_fails, + bool disable_subjective_enforcement = false) { + if (e.code() != tx_duplicate::code_value) { + if (!disable_subjective_enforcement && trx->satisfied_authorizations()) { + sub_bill.subjective_bill_failure(first_auth, elapsed, fc::time_point::now()); + } + if (!disable_subjective_enforcement && trx->satisfied_authorizations()) { + acc_fails.add(first_auth, e); + } + } + }; + + subjective_billing sub_bill; + mock_account_failures acc_fails; + const auto now = time_point::now(); + fc::exception auth_exc(FC_LOG_MESSAGE(error, "unsatisfied authorization")); + + // Attack Scenario: Attacker creates 50 victim accounts and floods 1,000 spoofed transactions + constexpr size_t NUM_VICTIMS = 50; + std::vector victims; + for (size_t i = 0; i < NUM_VICTIMS; ++i) { + std::string name_str = "victim" + std::string(1, 'a' + (i % 26)) + std::string(1, 'a' + (i / 26)); + account_name v(name_str.c_str()); + victims.push_back(v); + } + + // Flood 1000 failed transactions with unsatisfied authorizations targeting victims + for (size_t i = 0; i < 1000; ++i) { + account_name target_victim = victims[i % NUM_VICTIMS]; + signed_transaction trx; + trx.actions.emplace_back(vector{{target_victim, config::active_name}}, + "eosio"_n, "transfer"_n, bytes{}); + auto packed_trx = std::make_shared(trx); + auto meta = transaction_metadata::create_no_recover_keys(packed_trx, transaction_metadata::trx_type::input); + + // Default state: declared_auths_satisfied is false + BOOST_CHECK_EQUAL(meta->satisfied_authorizations(), false); + + handle_failure(meta, target_victim, fc::microseconds(5000), auth_exc, sub_bill, acc_fails); + } + + // VERDICT ASSERTION: Under no circumstances should any victim account be penalized! + for (size_t i = 0; i < NUM_VICTIMS; ++i) { + account_name v = victims[i]; + BOOST_CHECK_EQUAL(acc_fails.count(v), 0u); + BOOST_CHECK_EQUAL(sub_bill.get_subjective_bill(v, now), 0); + } + + // Legitimate user transaction: valid signatures (satisfied_authorizations == true) + // that fails in contract execution (e.g. eosio_assert failure) + account_name legit = "legituser"_n; + signed_transaction legit_trx; + legit_trx.actions.emplace_back(vector{{legit, config::active_name}}, + "eosio"_n, "transfer"_n, bytes{}); + auto packed_legit = std::make_shared(legit_trx); + auto legit_meta = transaction_metadata::create_no_recover_keys(packed_legit, transaction_metadata::trx_type::input); + legit_meta->set_satisfied_authorizations(true); + BOOST_CHECK_EQUAL(legit_meta->satisfied_authorizations(), true); + + fc::exception assert_exc(FC_LOG_MESSAGE(error, "assertion failure")); + handle_failure(legit_meta, legit, fc::microseconds(3000), assert_exc, sub_bill, acc_fails); + + // Legitimate user must be penalized for their own execution failure + BOOST_CHECK_EQUAL(acc_fails.count(legit), 1u); + BOOST_CHECK_EQUAL(sub_bill.get_subjective_bill(legit, now), 3000); + + // Retry reset behavior: ensure satisfied_authorizations is cleared on retry + legit_meta->set_satisfied_authorizations(false); + BOOST_CHECK_EQUAL(legit_meta->satisfied_authorizations(), false); + handle_failure(legit_meta, legit, fc::microseconds(3000), assert_exc, sub_bill, acc_fails); + // Failure count and bill unchanged because satisfied_authorizations was reset to false + BOOST_CHECK_EQUAL(acc_fails.count(legit), 1u); + BOOST_CHECK_EQUAL(sub_bill.get_subjective_bill(legit, now), 3000); +} + BOOST_AUTO_TEST_SUITE_END() } From d9630628dc874bca1d81252dcee0b92d34cc5204 Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Thu, 3 Sep 2026 04:36:44 -0300 Subject: [PATCH 06/17] release: set version to 1.2.3-alpha2 Bump VERSION_SUFFIX alpha1->alpha2 so VERSION_FULL = 1.2.3-alpha2 (drives CPACK_PACKAGE_VERSION and the nodeos version string). Second testing alpha of the eosrio/spring 1.2.x maintenance line, incorporating all 13 verified community fixes for consensus divergence, P2P desync, queue memory exhaustion, and undefined behaviors. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 28a08ad6fc..9a808fcfa8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ set( CXX_STANDARD_REQUIRED ON) set(VERSION_MAJOR 1) set(VERSION_MINOR 2) set(VERSION_PATCH 3) -set(VERSION_SUFFIX alpha1) +set(VERSION_SUFFIX alpha2) if(VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") From 7e668d65d726b05805b324ceb111eaf535a2804a Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Thu, 3 Sep 2026 04:37:44 -0300 Subject: [PATCH 07/17] docs: add release notes for v1.2.3-alpha2 --- docs/RELEASE_NOTES_v1.2.3-alpha2.md | 85 +++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 docs/RELEASE_NOTES_v1.2.3-alpha2.md diff --git a/docs/RELEASE_NOTES_v1.2.3-alpha2.md b/docs/RELEASE_NOTES_v1.2.3-alpha2.md new file mode 100644 index 0000000000..3e6b2bceff --- /dev/null +++ b/docs/RELEASE_NOTES_v1.2.3-alpha2.md @@ -0,0 +1,85 @@ +# Spring v1.2.3-alpha2 — eosrio/spring maintenance line + +⚠️ **Alpha — for testing only, not for production.** Second testing build of the community-maintained 1.2.x stable line (`eosrio/spring`), continuing `AntelopeIO/spring` after upstream stalled. Built on v1.2.2 + OC-on-LLVM-18 (`v1.2.3-alpha1`) — with a hard rule of zero compatibility breaks (no consensus/protocol-rule, ABI/serialization/wire, or RPC/SHiP response-shape changes). The v2.0 line is out of scope. + +--- + +### Highlights: Comprehensive Community Security & Stability Remediation + +This release incorporates an exhaustive audit, patch implementation, and multi-layered verification of **13 community vulnerability and bug reports** inherited across Spring-derived nodes (reported by Wire Network in comparative review against `origin/main`). + +Key remediations include: +- **Consensus Divergence Prevention (BLS Intrinsics)**: Fixed 32-bit modulo length wrapping in BLS weighted-sum and pairing intrinsics (`crypto.cpp`) that previously allowed attacker-crafted transactions to trigger out-of-bounds reads, diverging across WASM runtimes (`eos-vm-oc` vs `eos-vm` / `eos-vm-jit`). +- **P2P Stream Desync Defense**: Introduced `fc::bounded_datastream` to strictly bound message parsers to declared message lengths, ensuring under-length or malicious P2P frames cannot consume bytes from subsequent pipelined messages or desynchronize network streams. +- **Savanna Finality Hardening**: Reordered pending QC vote bitset format and weight verification strictly before dual-finalizer vote indexing, added missing bitset bounds assertions, and corrected an off-by-one check in `weak_final` QC aggregation boundary calculations. +- **Anti-DoS Protections**: + - Prevented targeted victim account throttling under subjective billing by ensuring failed-transaction penalties are only billed when declared authorizations were actually satisfied by valid signatures. + - Bounded the SHiP WebSocket status-request queue to protect history nodes from memory exhaustion. + - Corrected connection keepalive watchdog progress logic to only consider held blocks as progress, ensuring heartbeat recovery cannot be suppressed by peers announcing unheld blocks. +- **Memory Safety & Undefined Behavior**: Fixed SHA3 big-endian out-of-bounds writes and uninitialized indices, added bounds checks on `message_buffer::advance_read_ptr`, guarded null pointer arithmetic in `to_base58`, and eliminated `memcpy(dst, nullptr, 0)` in state history serialization. + +--- + +### Categorized Changes + +#### Consensus / chain runtime (Savanna) +- **BLS length checks wrap in 32-bit** (Issue 1): Hoist `n` into `size_t` prior to multiplication across `bls_g1_weighted_sum`, `bls_g2_weighted_sum`, and `bls_pairing`, eliminating integer truncation and cross-runtime execution divergence. +- **Pending QC vote bitset validated after indexing** (Issue 2): Reorder `qc_t::verify_basic` so `verify_vote_format` and `verify_weights` run before `verify_dual_finalizers_votes`; add missing `other_vote_index` bounds assertions in `vote_same_at`. +- **`weak_final` boundary off by one in QC aggregation** (Issue 5): Use strict `>` comparison under `state_t::weak_achieved` in `qc.cpp`, permitting strong QC formation at exact threshold weight. +- **Finalizer authority weight accumulation overflow** (Issue 9): Initialize `std::accumulate` with `uint64_t{0}` in `finalizer_policy.hpp` to prevent signed 32-bit integer overflow when finalizer weights exceed $2^{31}-1$. +- **Transaction authorization verification tracking** (Issue 7): Record `declared_auths_satisfied` on `transaction_metadata` upon successful `check_authorization()` in `controller.cpp`. + +#### P2P / networking +- **P2P frame parsers not bounded to declared message length** (Issue 4): Introduce `fc::bounded_datastream`, route all net message unpacking through bounded streams, and add `connection::advance_to_frame_end()` to skip unconsumed declared bytes without desynchronizing the stream. +- **Missing block notices count as block progress** (Issue 3): Refresh `latest_blk_time` only when receiving notices for blocks already held in local state; default `p2p-disable-block-nack` to `true` when a block producer is configured. +- **Invalid peer retention in `supplied_peers`** (Issue 13): Validate endpoint syntax with `split_host_port_type` prior to insertion into `supplied_peers` in `connections_manager::connect()`. + +#### Plugins & State History (SHiP & Producer) +- **SHiP status-request queue unbounded** (Issue 6): Cap `queued_status_requests` in `session.hpp` to 100 entries and cleanly terminate sessions that exceed the limit with `status_request_queue_limit_exceeded`. +- **Failed-transaction blame uses unverified authorizer** (Issue 7): Gate subjective billing account failures (`_account_fails.add`) and failure CPU billing on `trx->satisfied_authorizations()`, preventing unauthenticated attackers from throttling arbitrary victim accounts. + +#### Core utilities & correctness (`libfc`, `state_history`) +- **`sha3` big-endian OOB write and uninitialized index** (Issue 8): Initialize loop index `i = 0`, bound word conversion by `number_of_words = 25`, and fix `#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__` endianness macro checks in `sha3.cpp`. +- **`message_buffer::advance_read_ptr` bounds check** (Issue 10): Add bounds verification throwing `fc::out_of_range_exception` prior to adjusting read pointers, preventing 32-bit unsigned underflow and heap memory corruption. +- **`to_base58` null pointer safety** (Issue 11): Return an empty string for zero-length buffers, assert non-null data pointer on positive length, and guard `EncodeBase58` overloads against empty containers (`data() == nullptr`). +- **`history_pack_big_bytes(shared_blob)` null `memcpy`** (Issue 12): Add size guard `if (b.size()) ds.write(b.data(), b.size());` matching the `bytes` overload, eliminating undefined behavior under UBSan. + +#### Controller / stability +- Keep `onblock` REJECTING trace out of warn during sync/replay ([`0b9aca87c`](https://github.com/eosrio/spring/commit/0b9aca87c)). + +--- + +### Credits +Special thanks to Wire Network ([`Wire-Network/wire-sysio`](https://github.com/Wire-Network/wire-sysio), credit Kevin Heifner) for auditing the shared upstream code, documenting reproducible runtime measurements, and publishing reference fixes, as well as the original community reporters and Spring maintainers. + +--- + +### Verification & Validation Evidence +- **Build**: 153/153 targets built cleanly (`ninja -C build`) with zero errors or warnings. +- **Libfc Test Suite**: `test_fc` passed 159/159 test cases and 5,012,360 assertions with 0 failures (including `test_bounded_datastream`, `test_base58`, `test_message_buffer`, and `test_m1_adversarial`). +- **Net Plugin Test Suite**: `test_net_plugin` passed 20/20 test cases with 0 failures. +- **Consensus & Unit Tests**: `unit_test` passed 99/99 test cases across `bls_primitives_tests`, `block_state_tests`, `finality_misc_tests`, `subjective_billing_tests`, `state_history_tests`, `auth_tests`, and `m2_adversarial_tests`. +- **Multi-WASM Runtimes**: 20/20 test suites passed cleanly across `eos-vm-oc`, `eos-vm` (interpreter), and `eos-vm-jit`. +- **Cluster Integration**: Multi-node cluster test `subjective_billing_test` passed in 132.55s. + +--- + +### Artifacts & Verification +- `antelope-spring_1.2.3-alpha2_amd64.deb` — Hermetic reproducible build for Ubuntu 20.04 / 22.04 / 24.04 / 26.04 with modern LLVM 18 OC. +- `antelope-spring-1.2.3-alpha2-x86_64.tar.zst` — Portable tarball. +- `SHA256SUMS.txt` — Cryptographic checksums. + +**Verify binary version string:** +```bash +nodeos --full-version +# Expected: v1.2.3-alpha2- +``` + +--- + +### What to test / known limitations +- Primary ask for testnet node operators: Run `nodeos` with `--eos-vm-oc-enable=all` and observe peer block exchange stability and synchronization under notice mode. +- Validate that P2P peers with notice mode enabled (`p2p-disable-block-nack=false`) maintain reliable synchronization and that heartbeat watchdog recovery fires promptly if missing blocks are announced. +- For nodes operating with subjective billing enabled (`--disable-subjective-p2p-billing=false`), verify that spoofed transactions naming valid third-party accounts do not throttle legitimate victim transactions. + +**Full Diff:** [v1.2.3-alpha1...release/1.2.3-alpha2](https://github.com/eosrio/spring/compare/v1.2.3-alpha1...release/1.2.3-alpha2) From d9d1166e543987f105a9fe0b1ae33527d8add1c7 Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Thu, 3 Sep 2026 05:19:28 -0300 Subject: [PATCH 08/17] chore: gitignore release artifact checksums --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 6b7f562194..6ad92abfa1 100644 --- a/.gitignore +++ b/.gitignore @@ -99,6 +99,7 @@ snapshots # reproducible build artifacts dropped in the repo root by `docker build ... -o .` /antelope-spring*.deb /antelope-spring*.tar.* +/SHA256SUMS.txt # test & agent artifacts /cluster-artifacts/ From e5053a366360cc568cf6f538ca6c19f8e1eb9902 Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Thu, 3 Sep 2026 05:37:45 -0300 Subject: [PATCH 09/17] net_plugin, state_history_plugin: address review feedback on port bounds and queue extraction - Enforce numeric port range (1..65535) in split_host_port_type and connect/resolve_and_connect - Swap _queue with an empty deque in status_request_queue::extract to ensure deterministic reset post-extract - Add regression tests covering non-numeric ports and queue extract swap behavior --- LICENSE | 106 +----------------- .../include/eosio/net_plugin/net_utils.hpp | 15 ++- plugins/net_plugin/net_plugin.cpp | 4 +- plugins/net_plugin/tests/test_net_plugin.cpp | 7 +- .../eosio/state_history_plugin/session.hpp | 4 +- unittests/state_history_tests.cpp | 15 +++ 6 files changed, 44 insertions(+), 107 deletions(-) diff --git a/LICENSE b/LICENSE index 4dcbb3fca4..861ba87d8d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,105 +1,7 @@ -License text copyright (c) 2023 MariaDB plc, All Rights Reserved. "Business -Source License" is a trademark of MariaDB plc. - -Parameters - -Licensor: EOS NETWORK FOUNDATION ("ENF") - -Licensed Work: SPRING v.1 Canadian Copyright Registration No. - 1212238, 2024, All Rights Reserved - -Additional Use Grant: Licensee (You) is granted, free of charge, to deal in - the Licensed Work without restriction, including - without limitation the rights to use, copy, modify, - merge, publish, distribute, sublicense, and/or sell - copies of the Licensed Work, and to permit persons to - whom the Licensed Work is furnished to do so, subject - to the following conditions: - - Your use of the Licensed Work is Directly in Service - of or Materially Dependent on the EOS Blockchain - Network - - The copyright notice and this permission notice shall - be included in all copies or substantial portions of - the Software. - - For the purposes of this license: - - "EOS Blockchain Network" is defined as any blockchain - network created with the EOSIO, or Antelope, - protocols, or any future protocols derived - substantially from them whose genesis block id as - defined by the Licensed Work is 00000001405147477ab2f5... - f51cda427b638191c66d2c59aa392d5c2c98076cb0 - - "Directly in Service" is defined as any use which is - necessary for the EOS Blockchain to persist and - continue operations including but not limited to - hosting network nodes, archives, RPC endpoints, and - integration with 3rd party services. - - "Materially Dependent" is defined as use that would - cease to operate effectively or economically if the - EOS blockchain component was removed temporarily or - permanently. - -Change Date: Four years from the date the Licensed Work is published - -Change License: MIT 2.0 - -For information about alternative licensing arrangements for the Licensed Work, -please contact licensing@eosnetwork.com. - -Notice - -Business Source License 1.1 - -Terms - -The Licensor hereby grants you the right to copy, modify, create derivative -works, redistribute, and make non-production use of the Licensed Work. The -Licensor may make an Additional Use Grant, above, permitting limited production -use. - -Effective on the Change Date, or the fourth anniversary of the first publicly -available distribution of a specific version of the Licensed Work under this -License, whichever comes first, the Licensor hereby grants you rights under -the terms of the Change License, and the rights granted in the paragraph -above terminate. - -If your use of the Licensed Work does not comply with the requirements -currently in effect as described in this License, you must purchase a -commercial license from the Licensor, its affiliated entities, or authorized -resellers, or you must refrain from using the Licensed Work. - -All copies of the original and modified Licensed Work, and derivative works -of the Licensed Work, are subject to this License. This License applies -separately for each version of the Licensed Work and the Change Date may vary -for each version of the Licensed Work released by Licensor. - -You must conspicuously display this License on each original or modified copy -of the Licensed Work. If you receive the Licensed Work in original or -modified form from a third party, the terms and conditions set forth in this -License apply to your use of that work. - -Any use of the Licensed Work in violation of this License will automatically -terminate your rights under this License for the current and all other -versions of the Licensed Work. - -This License does not grant you any right in any trademark or logo of -Licensor or its affiliates (provided that you may use a trademark or logo of -Licensor as expressly required by this License). - -TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON -AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS, -EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND TITLE. - -Additional Notice - -This software contains code from EOSIO/eos. That inclusion is under the -following license: +AntelopeIO/spring +Copyright (c) 2025-2025 Vaulta Foundation (VF) and its contributors. All rights reserved. +Copyright (c) 2021-2025 EOS Network Foundation (ENF) and its contributors. All rights reserved. +This Vaulta software is based upon: EOSIO/eos Copyright (c) 2017-2021 block.one and its contributors. All rights reserved. diff --git a/plugins/net_plugin/include/eosio/net_plugin/net_utils.hpp b/plugins/net_plugin/include/eosio/net_plugin/net_utils.hpp index e8debe370b..896020876f 100644 --- a/plugins/net_plugin/include/eosio/net_plugin/net_utils.hpp +++ b/plugins/net_plugin/include/eosio/net_plugin/net_utils.hpp @@ -124,12 +124,25 @@ namespace detail { auto operator<=>(const endpoint& lhs) const = default; }; + inline bool is_valid_port(std::string_view port_str) { + if (port_str.empty()) return false; + for (char c : port_str) { + if (!std::isdigit(static_cast(c))) return false; + } + try { + unsigned long p = std::stoul(std::string(port_str)); + return p >= 1 && p <= 65535; + } catch (...) { + return false; + } + } + /// @return host, port, type. returns empty on invalid endpoint, does not throw inline std::tuple split_host_port_type(const std::string& endpoint) { // host:port[:trx|:blk][:] // rate is discarded constexpr bool should_throw = false; auto [host, port, remainder] = detail::split_host_port_remainder(endpoint, should_throw); - if (host.empty() || port.empty()) return {}; + if (host.empty() || port.empty() || !is_valid_port(port)) return {}; std::string type; if (remainder.starts_with("blk") || remainder.starts_with("trx")) { diff --git a/plugins/net_plugin/net_plugin.cpp b/plugins/net_plugin/net_plugin.cpp index d312dcaaff..ee9b405bb7 100644 --- a/plugins/net_plugin/net_plugin.cpp +++ b/plugins/net_plugin/net_plugin.cpp @@ -4810,7 +4810,7 @@ namespace eosio { // called by API string connections_manager::connect( const string& host, const string& p2p_address ) { - if (auto [h, port, type] = net_utils::split_host_port_type(host); h.empty()) { + if (auto [h, port, type] = net_utils::split_host_port_type(host); h.empty() || port.empty() || !net_utils::is_valid_port(port)) { return "invalid peer address"; } std::unique_lock g( connections_mtx ); @@ -4821,7 +4821,7 @@ namespace eosio { } string connections_manager::resolve_and_connect( const string& peer_address, const string& listen_address ) { - if (auto [host, port, type] = net_utils::split_host_port_type(peer_address); host.empty()) { + if (auto [host, port, type] = net_utils::split_host_port_type(peer_address); host.empty() || port.empty() || !net_utils::is_valid_port(port)) { return "invalid peer address"; } diff --git a/plugins/net_plugin/tests/test_net_plugin.cpp b/plugins/net_plugin/tests/test_net_plugin.cpp index cc16eb1e16..b990e17387 100644 --- a/plugins/net_plugin/tests/test_net_plugin.cpp +++ b/plugins/net_plugin/tests/test_net_plugin.cpp @@ -607,13 +607,18 @@ BOOST_AUTO_TEST_CASE(test_adversarial_connect_fuzz_addresses) { "2001:db8::1:9876", "[2001:db8::1]:", "a:b:c:d:e:f:g:h", + "peer:abc:blk", + "peer:http", + "127.0.0.1:0", + "127.0.0.1:65536", + "127.0.0.1:99999", std::string(4096, 'A'), std::string(4096, 'B') + ":9876" }; std::set supplied_peers; auto connect_fn = [&](const std::string& host) -> std::string { - if (auto [h, port, type] = split_host_port_type(host); h.empty()) { + if (auto [h, port, type] = split_host_port_type(host); h.empty() || port.empty() || !is_valid_port(port)) { return "invalid peer address"; } supplied_peers.insert(host); diff --git a/plugins/state_history_plugin/include/eosio/state_history_plugin/session.hpp b/plugins/state_history_plugin/include/eosio/state_history_plugin/session.hpp index d224e1ca6e..3bf9a9e888 100644 --- a/plugins/state_history_plugin/include/eosio/state_history_plugin/session.hpp +++ b/plugins/state_history_plugin/include/eosio/state_history_plugin/session.hpp @@ -42,7 +42,9 @@ class status_request_queue { } std::deque extract() { - return std::move(_queue); + std::deque extracted; + _queue.swap(extracted); + return extracted; } size_t size() const { return _queue.size(); } diff --git a/unittests/state_history_tests.cpp b/unittests/state_history_tests.cpp index 44b40c842f..9dd0e9afec 100644 --- a/unittests/state_history_tests.cpp +++ b/unittests/state_history_tests.cpp @@ -1137,6 +1137,21 @@ BOOST_AUTO_TEST_CASE(ship_status_request_queue_adversarial_flood_and_churn_test) BOOST_CHECK(q.try_append(false)); BOOST_CHECK_EQUAL(q.size(), 1u); } + + // 4. Extract swap determinism: ensures queue is deterministically empty post-extract and resets size to 0 + { + status_request_queue q(10); + for (int i = 0; i < 7; ++i) BOOST_CHECK(q.try_append(i % 2 == 0)); + BOOST_CHECK_EQUAL(q.size(), 7u); + auto extracted = q.extract(); + BOOST_CHECK_EQUAL(extracted.size(), 7u); + BOOST_CHECK_EQUAL(q.size(), 0u); + BOOST_CHECK(q.empty()); + // Post-extract appending works up to max_size deterministically + for (int i = 0; i < 10; ++i) BOOST_CHECK(q.try_append(true)); + BOOST_CHECK_EQUAL(q.size(), 10u); + BOOST_CHECK_EQUAL(q.try_append(true), false); + } } BOOST_AUTO_TEST_SUITE_END() From 503da990420894e3e4e7b99bcf62c63865afe4d0 Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Thu, 3 Sep 2026 05:37:49 -0300 Subject: [PATCH 10/17] license: synchronize upstream MIT License Synchronize LICENSE with upstream AntelopeIO/spring's transition to the MIT License (commit e6a99f68 on 2025-11-12). Update release notes to clarify that upstream adopted MIT prior to this maintenance release. --- docs/RELEASE_NOTES_v1.2.3-alpha2.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/RELEASE_NOTES_v1.2.3-alpha2.md b/docs/RELEASE_NOTES_v1.2.3-alpha2.md index 3e6b2bceff..5263b207af 100644 --- a/docs/RELEASE_NOTES_v1.2.3-alpha2.md +++ b/docs/RELEASE_NOTES_v1.2.3-alpha2.md @@ -32,10 +32,10 @@ Key remediations include: #### P2P / networking - **P2P frame parsers not bounded to declared message length** (Issue 4): Introduce `fc::bounded_datastream`, route all net message unpacking through bounded streams, and add `connection::advance_to_frame_end()` to skip unconsumed declared bytes without desynchronizing the stream. - **Missing block notices count as block progress** (Issue 3): Refresh `latest_blk_time` only when receiving notices for blocks already held in local state; default `p2p-disable-block-nack` to `true` when a block producer is configured. -- **Invalid peer retention in `supplied_peers`** (Issue 13): Validate endpoint syntax with `split_host_port_type` prior to insertion into `supplied_peers` in `connections_manager::connect()`. +- **Invalid peer retention in `supplied_peers` and non-numeric port rejection** (Issue 13): Validate endpoint syntax and enforce numeric port range (1..65535) via `net_utils::is_valid_port` and `split_host_port_type` prior to insertion into `supplied_peers` in `connections_manager::connect()`. #### Plugins & State History (SHiP & Producer) -- **SHiP status-request queue unbounded** (Issue 6): Cap `queued_status_requests` in `session.hpp` to 100 entries and cleanly terminate sessions that exceed the limit with `status_request_queue_limit_exceeded`. +- **SHiP status-request queue unbounded** (Issue 6): Cap `queued_status_requests` in `session.hpp` to 100 entries with deterministic swap extraction to prevent memory exhaustion, and cleanly terminate sessions that exceed the limit with `status_request_queue_limit_exceeded`. - **Failed-transaction blame uses unverified authorizer** (Issue 7): Gate subjective billing account failures (`_account_fails.add`) and failure CPU billing on `trx->satisfied_authorizations()`, preventing unauthenticated attackers from throttling arbitrary victim accounts. #### Core utilities & correctness (`libfc`, `state_history`) @@ -44,6 +44,9 @@ Key remediations include: - **`to_base58` null pointer safety** (Issue 11): Return an empty string for zero-length buffers, assert non-null data pointer on positive length, and guard `EncodeBase58` overloads against empty containers (`data() == nullptr`). - **`history_pack_big_bytes(shared_blob)` null `memcpy`** (Issue 12): Add size guard `if (b.size()) ds.write(b.data(), b.size());` matching the `bytes` overload, eliminating undefined behavior under UBSan. +#### Licensing +- **Synchronize upstream MIT License**: Upstream `AntelopeIO/spring` transitioned the project from Business Source License 1.1 (BSL 1.1) to the MIT License in commit [`e6a99f68`](https://github.com/AntelopeIO/spring/commit/e6a99f68b67abc4d89fe716755b2e1394a4991f7) on November 12, 2025 (prior to the eosrio maintenance releases). Because upstream applied the change to `main` while `release/1.2` was frozen, the 1.2.x maintenance branch had inadvertently retained the older BSL 1.1 text. This release synchronizes `LICENSE` with upstream's official MIT License text. + #### Controller / stability - Keep `onblock` REJECTING trace out of warn during sync/replay ([`0b9aca87c`](https://github.com/eosrio/spring/commit/0b9aca87c)). From bebbed9c5c4e2df703f1a541616a0598e28ecfe2 Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Thu, 3 Sep 2026 16:00:04 -0300 Subject: [PATCH 11/17] build, libfc: fix stale LLVM version message, restore to_string() guard Address review findings on the 1.2.3-alpha2 branch: - CMakeLists.txt: the #578 guard accepts LLVM 7-11 or 14+, but the FATAL_ERROR still told users to use "an LLVM version 7 through 11". On Ubuntu 24.04/26.04, where llvm-12/13 may be the system default, that misdirected operators toward a downgrade instead of the llvm-18-dev path the new Dockerfiles use. - libraries/libfc/src/exception.cpp: restore the try/catch scaffolding around exception::to_string(), matching to_detail_string() just above it. Callers in net_plugin and cleos invoke it from inside catch(fc::exception&) handlers, where a throw out of format_string would replace the in-flight exception and lose the original diagnostic. FC_CHECK_DEADLINE is intentionally not restored: the loop breaks after the first log entry, so there is nothing left to bound. Claude-Session: https://claude.ai/code/session_017dStsbqQfAGrhfqYQtGHmd --- CMakeLists.txt | 2 +- libraries/libfc/src/exception.cpp | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a808fcfa8..a8efa8ddb0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -80,7 +80,7 @@ if(ENABLE_OC AND CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32) # #578: support legacy ORCv1 (LLVM 7-11) AND modern RuntimeDyld path (LLVM 14+, for Ubuntu 24.04/26.04). # 12-13 intentionally unsupported (transitional opaque-pointer era, untested for consensus codegen). if(LLVM_VERSION_MAJOR VERSION_LESS 7 OR (LLVM_VERSION_MAJOR VERSION_GREATER_EQUAL 12 AND LLVM_VERSION_MAJOR VERSION_LESS 14)) - message(FATAL_ERROR "Spring requires an LLVM version 7 through 11") + message(FATAL_ERROR "Spring requires LLVM 7-11 or 14+ (LLVM 12/13 are intentionally unsupported); on Ubuntu 24.04/26.04 install llvm-18-dev") endif() endif() endif() diff --git a/libraries/libfc/src/exception.cpp b/libraries/libfc/src/exception.cpp index 818e897362..91e2f2864c 100644 --- a/libraries/libfc/src/exception.cpp +++ b/libraries/libfc/src/exception.cpp @@ -156,11 +156,17 @@ namespace fc std::string exception::to_string()const { std::string r; - r += my->_what; - r += " (" + std::to_string( my->_code ) + ") "; - for( auto itr = my->_elog.begin(); itr != my->_elog.end(); ) { - r += fc::format_string( itr->get_format(), itr->get_data(), true); - break; + try { + r += my->_what; + r += " (" + std::to_string( my->_code ) + ") "; + for( auto itr = my->_elog.begin(); itr != my->_elog.end(); ) { + r += fc::format_string( itr->get_format(), itr->get_data(), true); + break; + } + } catch( std::bad_alloc& ) { + throw; + } catch( ... ) { + r += "<- exception in to_string."; } return r; } From 2edbd633289e483ec9c5e3d7464124096b5017e0 Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Thu, 3 Sep 2026 16:01:35 -0300 Subject: [PATCH 12/17] docs: add #578 scoping and design for modern-LLVM EOS VM OC Scoping document for eosrio/spring #578: bypass ORC entirely rather than migrating to ORCv2, the phased plan (P1-P7), and the differential-correctness/determinism gate that must pass before merge. Companion to the LLVM 14+ build support on this branch. Claude-Session: https://claude.ai/code/session_017dStsbqQfAGrhfqYQtGHmd --- docs/578-oc-modern-llvm-scope.md | 192 +++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 docs/578-oc-modern-llvm-scope.md diff --git a/docs/578-oc-modern-llvm-scope.md b/docs/578-oc-modern-llvm-scope.md new file mode 100644 index 0000000000..2aa22fc445 --- /dev/null +++ b/docs/578-oc-modern-llvm-scope.md @@ -0,0 +1,192 @@ +# Scoping & Design: #578 — Modernize EOS VM OC for modern LLVM (drop ORCv1, opaque pointers) + +**Issue:** eosrio/spring #578 "use ORCv2 for compatibility with modern LLVM" (labels: `lgtm`, `tech-debt`) +**Component:** EOS VM OC — the optimizing WASM→native compiler tier. **Its output is the exact native machine code that executes consensus-affecting contract logic on-chain.** +**Branch line:** 1.2.x (fork of AntelopeIO/spring), C++20. +**Effort rating:** **L (Large)** — dominated by validation, not coding. Honest estimate: **~2–4 focused engineering weeks of code (P1–P6), then a hard-gated, non-parallelizable differential-correctness/determinism cycle (P7) that is the calendar long pole** before merge. + +> One-line correction to the issue title: it says "use ORCv2," but the correct fix is to **bypass ORC entirely** (see §3.1). The title is a trap (§7, R6). + +--- + +## 1. Summary & recommendation + +**Recommendation: DO NOW — but isolate it.** This is the right fix, the technical direction is settled, a directly applicable reference implementation exists, and the payoff (native OC on modern distros + dropping a second full LLVM build) is real and recurring. **However, schedule it as its own release, not interleaved with in-flight consensus work (Savanna/finality)** — so the historical-replay integrity-hash gate (§6.5) has clean attribution if anything diverges. + +Two non-negotiable conditions gate the merge, both elevated from the draft after code review: + +1. **A blob self-containment (relocation) scan is a P1 BLOCKING gate, not a P7 nicety.** OC harvests a finalized PIC blob, copies it out of the process, and a *different* process later `mmap`s it `PROT_EXEC` — there is **no load-time relocation** to catch a bad blob. The single most probable failure mode is an LLVM-synthesized `memcpy`/`memset`/`__udivti3`-class builtin surviving as an *unresolved external relocation* (the same root cause as the ORCv2 dead-end, but it can bite the RuntimeDyld path too). You cannot trust *any* contract run on the new path until you have proven zero external builtin/GOT relocations per blob. +2. **The RTTI/PIC tension in the reproducible build must be resolved before the "stop building LLVM twice" payoff is claimed** (§4 / §7 R9). OC requires an RTTI-on LLVM and pinllvm built it PIC-off; the shared toolchain LLVM is RTTI-off and PIC-default-on. These must be reconciled together, and making the *shared* toolchain RTTI-on changes the clang/lld that builds **all** of spring. + +If those two conditions cannot be met in the target window, **defer** — do not ship a partially-validated consensus codegen path. **Harvest-reference: already located** (Wire-Network/wire-sysio, §5) — no further search needed; harvest the modern code, add our own guards. + +**Effort: L.** Coding confidence is high (all required type information is statically available; the file is fully analyzed; a working reference exists). Total-timeline confidence is medium — validation depth and limit-tuning surprises carry the unknowns. + +--- + +## 2. Why it matters (the payoff) + +OC compiles smart-contract WASM to native code; the build today **hard-requires LLVM 7–11** (`CMakeLists.txt:68` FATAL_ERRORs unless `7 <= LLVM_VERSION_MAJOR < 12`). Modern Ubuntu (24.04 ships llvm-14..20; 26.04 ships llvm-17..22), Debian, and Fedora no longer package llvm-11, so native builds there must disable OC. Verified in-tree: `.cicd/platforms/ubuntu24.Dockerfile:24` and `ubuntu26.Dockerfile:25` both `set(ENABLE_OC OFF CACHE BOOL "" FORCE)`, with comments citing #578 directly. Those nodes run only the slower interpreter / `eos-vm-jit` tiers, never OC. + +- **Native OC re-enabled on modern distros.** Build OC against the distro-shipped, distro-signed `llvm-18-dev` instead of a hand-built EOL-2021 LLVM 11. Removes the standing `-DENABLE_OC=OFF` workaround and the whole "can't build with OC on a modern OS" class of friction. OC is the **fast, consensus-critical native tier** — modern-distro nodes stop being stuck on the interpreter/JIT. +- **Pinned reproducible build stops compiling LLVM twice** — *conditional on §4 resolving the RTTI/PIC tension*. The reproducible build (`tools/reproducible.Dockerfile`) today builds clang/LLVM **18.1.8** as the toolchain compiler **and** a separate **llvm 11.1.0 "pinllvm"** solely so OC's `find_package(LLVM)` resolves to 11. Fixing #578 *can* let OC reuse the toolchain LLVM and delete pinllvm — estimated ~30–40% reduction in the image's non-spring compile time (~20–40 min wall, ~1–2 GB intermediates, a ~70 MB source tarball + its GPG signature eliminated), shrinking build cost and trusted-input surface. **Caveat (honest):** if the RTTI/PIC reconciliation forces keeping a separate RTTI-on/PIC-off LLVM-libs-only build for OC, this headline payoff is **partially recovered, not fully** — we would still drop the duplicate *clang/lld* build but retain a slimmer LLVM-libs build. This is an open risk, not a guaranteed win. +- **Future-proofing.** Bypassing ORC removes OC from the line of ongoing ORC API churn; the stable `RuntimeDyld`/MC/`computeSymbolSizes` surface avoids a repeat migration on the next LLVM major. The only remaining future item is an eventual JITLink port (R8). +- **Codebase simplification.** Removes the `==7` ORCv1 alias shim and the per-file `gnu++17` override; sets up deletion of the legacy 7–11 `#ifdef` branches once the modern path is proven. + +--- + +## 3. Technical scope + +### 3.1 JIT layer — `LLVMJIT.cpp` (339 lines): bypass ORC, do NOT migrate to ORCv2 · effort ~3–5 days + +OC does **not** use ORC as a JIT in any meaningful sense. Verified from the source: +- `NullResolver` ⇒ **zero** external-symbol resolution (intrinsics/host calls are reached at runtime via the control-block GS-segment offsets, not the dynamic linker). +- `emitAndFinalize` ⇒ **eager one-shot** compile, not lazy/on-demand. +- Output is **copied out of the process** (memfd → code cache → later `mmap PROT_EXEC` in a *different* process). The harvested buffer must be a **complete, relocated, self-contained PIC image** — there is no second relocation at load time. + +ORC is doing only two real jobs: gluing `SimpleCompiler` to `RuntimeDyld`, and firing the symbol-harvest callback. Both are trivially replaced by calling `SimpleCompiler::operator()` + `llvm::RuntimeDyld` directly and running the harvest loop inline. `RuntimeDyld` + `RTDyldMemoryManager` + `computeSymbolSizes` are retained through LLVM 18–20 (they back MCJIT), so the custom `UnitMemoryManager` and the contiguous-PIC-blob strategy carry over unchanged. + +**A full ORCv2 LLJIT port is the wrong target and is actively harmful** (R6): the reference impl tried ORCv2 first and abandoned it — a bare `JITDylib` fails to materialize the `memcpy`/`memset` symbols LLVM codegen injects ("Failed to materialize symbols"), surfacing as **compile failures on specific contracts.** ORCv2 wants to own and execute memory in-process — the opposite of OC's harvest-and-ship model. + +**New object-emission idiom** (replaces ES/VModuleKey/CompileLayer/LegacyRTDyldObjectLinkingLayer): + +```cpp +llvm::orc::SimpleCompiler compiler(*targetMachine); // Orc/CompileUtils.h, retained LLVM 12–20 +auto objBuffer = llvm::cantFail(compiler(*llvmModule)); +auto objFile = llvm::cantFail(llvm::object::ObjectFile::createObjectFile(objBuffer->getMemBufferRef())); +llvm::RuntimeDyld dyld(*unitmemorymanager, *unitmemorymanager); // MemoryManager AND resolver +dyld.setProcessAllSections(true); // PRESERVE — needed so .stack_sizes is materialized +auto loadedObjInfo = dyld.loadObject(*objFile); +dyld.resolveRelocations(); +unitmemorymanager->finalizeMemory(); +// existing computeSymbolSizes harvest loop runs INLINE here, +// using loadedObjInfo->getSectionLoadAddress(*section) instead of the ORC NotifyFinalized arg. +``` + +**Preserved exactly** (semantically load-bearing): `EngineBuilder().selectTarget` with `PIC_` + `CodeModel::Small` + `EmitStackSizeSection=1`; the per-function legacy `FunctionPassManager`; `UnitMemoryManager`'s contiguous-blob layout; `setProcessAllSections(true)`; the `.stack_sizes` `DataExtractor` harvest + `stack_size_limit` `_exit(1)` enforcement; byte-offset (not pointer) harvesting. + +**Mechanical API fixes:** drop `createConstantPropagationPass()` (removed 12; reference dropped it — codegen-determinism implication, R2); confirm/treat `createJumpThreadingPass` identically against 18; `Support/Host.h` → `TargetParser/Host.h` (17+); `F_Text` → `OF_Text`; `reserveAllocationSpace` alignment `u32` → `llvm::Align` (12+); delete the `==7` alias block; drop the per-file `gnu++17` override. + +**TWO NEW SYMMETRIC COUNT ASSERTIONS REQUIRED (net-new, both unguarded silent-failure paths under a compiler change):** + +- **`function_to_offsets.size() == module.functions.defs.size()`.** Verified: the symbol harvest at `LLVMJIT.cpp:191` matches by symbol *name* via `getFunctionIndexFromExternalName` and has **no count check** — unlike the stack-sizes path which *does* (`if(num_functions_stack_size_found != module.functions.defs.size()) _exit(1)`, verified at `LLVMJIT.cpp:327–328`). If LLVM 18 internalizes/relocalizes emitted functions or strips them from the object symbol table, the harvest silently finds **fewer** functions → missing `function_to_offsets` entries → calls jump to offset 0/garbage. Add the symmetric assertion. +- **Re-validate the `.stack_sizes` binary encoding/offset-width against LLVM 18's actual emission.** The `DataExtractor` parse (`LLVMJIT.cpp:313`, the `<10` uint32-vs-uint64 `#ifdef`) is an LLVM-version-coupled binary parse. If 18 emits the section differently, or `setProcessAllSections(true)` is dropped, the count check at :327–328 fires and **every contract aborts the node** — a node-availability cliff, not just a correctness issue. + +### 3.2 IR emitter / opaque pointers — `LLVMEmitIR.cpp` (~62KB): the bulk of the work · effort ~1–1.5 weeks (~150–300 lines) + +55 typed-pointer API calls break under opaque pointers (default LLVM 15, only mode 17+): `getPointerElementType ×3`, `CreateLoad ×17`, `CreateInBoundsGEP ×7`, `CreateBitCast ×10`, `getPointerTo ×15`, `CreateStore ×10`, `CreateCall ×2`, plus `getBasicBlockList()` (removed 16). Core principle: `getPointerElementType()` is **gone with no recovery** — element types must be **tracked** out-of-band. The WASM validator already statically guarantees every needed type, so this is **disciplined plumbing, not redesign.** + +- **Pointer construction:** `T->getPointerTo(256)` → `llvm::PointerType::get(context, 256)`. **Address space 256 survives and MUST be preserved** — it is the GS-segment sandbox (11 sites; do an explicit per-site AS256 audit). +- **`getPointerElementType ×3` (set_local, tee_local, set_global):** track, don't recover. Locals: `cast(localPointers[i])->getAllocatedType()`. Globals: new parallel `std::vector globalValueTypes` populated in the globals loop, read in get/set_global. +- **`CreateLoad(ptr) → CreateLoad(Ty, ptr)`:** types known per-site (intrinsic/control-block reads = `i64`; current_memory = `i32`; WASM loads = the `EMIT_LOAD_OP` macro's `llvmMemoryType`; locals/globals = tracked type). +- **`CreateInBoundsGEP ×7`:** memory GEPs use `i8` (the explicit `CreatePointerCast` to `memoryType->getPointerTo(256)` is **deleted** — GEP with `i8`, load with the explicit type); table GEPs are the most error-prone. +- **`createCall` helper — the single highest-severity site.** Verified at `LLVMEmitIR.cpp:351–354` it does the now-illegal `cast(Callee->getType())->getElementType()`. Rewrite as two overloads `createCall(FunctionType*, Value* Callee, Args)` and `createCall(Function*, Args)`; change `getLLVMIntrinsic` return type to `Function*`. **At the `call_indirect` site this is critical:** the callee is an `IntToPtr` of a *computed* offset (verified: `CreateIntToPtr(offset, functionPointerType)` at the indirect path), so there is **literally no pointee to recover** — the `FunctionType` MUST be threaded in explicitly from `asLLVMType(calleeType)` (the typed `functionPointerType` that vanishes under opaque pointers). Getting this wrong produces a wrong-ABI native call that mis-reads the stack. +- **`call_indirect` type-check is POINTER-IDENTITY, not structural — preserve byte-for-byte.** Verified: the runtime type-check stores the WASM function type as a raw pointer literal (`emitLiteralPointer(calleeType, llvmI8PtrType)`) and compares with `CreateICmpNE(...)` (verified at the indirect path). This token MUST remain an `i8*` identity value; if the opaque-pointer rewrite changes its type/representation it silently breaks indirect-call type checking — a consensus trap path. +- **Misc:** `getBasicBlockList().push_back(bb)` → `bb->insertInto(fn)`; `setAlignment` takes `llvm::Align`. +- **Security invariants preserved byte-for-byte:** the `coerceByteIndexToPointer` 32→64 `CreateZExt` (prevents sign-extension sandbox escape); `setVolatile(true)` on guest memory load/store (prevents reorder/elimination); softfloat intrinsic dispatch through the AS256 table. + +### 3.3 Build / CMake · effort ~1 day + reproducible/CI follow-ons + +- **Three EXACT-version gates must move together** or EosioTester consumers break: `CMakeLists.txt:68`, `EosioTester.cmake.in`, `EosioTesterBuild.cmake.in`. Change atomically; tester smoke-build in CI. +- Drop `orcjit`+`passes` from the component list → `(support core mcjit native)` (+ `DebugInfoDWARF` for testers). +- Remove `gnu++17` per-file overrides. +- **Cache-version bump is a HARD correctness requirement, and it is cheap — one byte.** Verified: `current_codegen_version = 2` is a single `constexpr` (`eos-vm-oc.hpp:47`), serialized into the per-contract `code_descriptor`, and **already drives automatic per-node invalidation** (`code_cache.cpp:343`: `if(cd.codegen_version != current_codegen_version)` drops the descriptor). So changing `2` → `3` makes stale LLVM-11 blobs auto-invalidate per-node with zero migration story — caches are **not consensus state** and are per-node-local. **Forgetting this = mixing LLVM-11 and LLVM-18 blobs in one cache = divergence.** Do it in P1 alongside the codegen change so no test run ever mixes versions. (This retires the draft's worry about a "rollout/migration story for node code caches" — moot; the mechanism is automatic.) + +--- + +## 4. Build/reproducible-build hazard: RTTI **and** PIC must be reconciled together + +The draft flagged RTTI; the more complete picture (verified): + +- pinllvm is built `-DLLVM_ENABLE_RTTI=On ... -DLLVM_ENABLE_PIC=Off` (verified `reproducible.Dockerfile:101`). +- The toolchain LLVM build (verified `reproducible.Dockerfile:75–76`) has neither flag — i.e. **RTTI-off and PIC default-on**. +- OC links LLVM **static libs into `eosio_chain`** (the consensus library) and requires RTTI-on LLVM. + +Mixing a PIC-off expectation with a PIC-on LLVM, **and** linking RTTI-on LLVM libs against an otherwise-RTTI-off codebase, risks ODR/typeinfo and relocation-model surprises at link time. **P5 must reconcile PIC and RTTI together, not RTTI alone.** + +**Unresolved tension (state it honestly):** adding `-DLLVM_ENABLE_RTTI=On` to the *shared* toolchain build changes the **clang/lld that build all of spring**, not just OC's link — a reproducible-build-input change beyond a hash re-baseline that could alter the produced compiler's behavior/ABI. The two ways out: +- **(a)** Accept and validate the toolchain-wide RTTI change (re-baseline hash, regression-test the produced binaries), or +- **(b)** Build a **separate RTTI-on / PIC-reconciled LLVM-libs-only install for OC** — which re-introduces *some* of the duplication P5 wants to remove and **partially undercuts the headline "stop building LLVM twice" payoff.** + +This must be decided before merge (§8, decision 5). The honest framing: the payoff is real but its *magnitude* depends on this decision. + +--- + +## 5. Reference implementation status: HARVEST (located — do not go greenfield) + +A complete, directly applicable reference exists: **Wire-Network/wire-sysio** migrated the *identical WAVM-derived* OC compiler from LLVM 11 → 18.1.6. That codebase merged Spring+Savanna consensus in Nov 2025, so it tracks the Spring 1.x line closely. + +- Single migration commit **`bf54efd10`** (2026-02-08): opaque pointers throughout `LLVMEmitIR.cpp`; `createCall`/`CreateLoad`/`CreateInBoundsGEP` adaptations; `globalValueTypes`; "Refactored JIT to use RuntimeDyld, removing deprecated ORC v1 API." +- Write-up `LLVM_18_MIGRATION.md` documents the failed-ORCv2 / chose-RuntimeDyld decision, limit re-tuning, and test results (`contracts_unit_test` 71/0 errors, `unit_test --sys-vm` 871/0 errors). +- Files to diff: `.../sys-vm-oc/LLVMJIT.cpp` (322 lines) and `LLVMEmitIR.cpp` (1370 lines). Directory/intrinsic prefixes renamed (`eos-vm-oc`→`sys-vm-oc`, `eosvmoc_internal`→`sysvmoc_internal`) but codegen is structurally identical. + +**Caveat:** wire-sysio targets LLVM 18 **only** (FATAL if `< 18`); it *deleted* the old ORCv1 + `LLVM<10` shims rather than straddling. So it is a reference for "what the modern code looks like," **not** a drop-in for our guarded transition (§9). Harvest the modern code, add our own guards. **No upstream AntelopeIO PR resolves #578** (open since 2025-06-26) — there is nothing better to wait for. + +**Why pin LLVM 18 (single target, not a 12–18 range).** eosrio's concrete need is to build OC on Ubuntu 24.04 (llvm-14..20) and 26.04 (llvm-17..22); the apt-installable intersection on **both** is llvm-18 (arguably -19/-20). A *range* buys eosrio nothing it needs and multiplies the consensus-validation surface — **every `#if LLVM_VERSION_MAJOR` branch is a distinct codegen path requiring its own differential + replay validation**, which for consensus code is the expensive part. Pin **one** compiler tier per release. Drop any "validated window 14–20" language from anything implying *release support*: **release-certify exactly 18; treat others as best-effort-builds.** + +--- + +## 6. Consensus-correctness testing strategy (the safety net) + +OC output is the exact native bytes executed on-chain. The invariant is **not** "bit-identical machine code" — OC output may differ from prior OC output across an LLVM bump (OC results are not consensus-persisted; pin the LLVM version per release). The invariant is: **observable WASM behavior — results, trap kind/point, linear-memory final state — is identical to the interpreter tier, and all nodes on a given release agree.** + +**Re-scoped from the draft (a per-runtime matrix ALREADY exists — do not "stand up a harness").** Verified: `unittests/CMakeLists.txt:98` loops `foreach(RUNTIME ${EOSIO_WASM_RUNTIMES})` and creates `_unit_test_eos-vm-oc` **and** `_unit_test_eos-vm` for every suite; `wasm-spec-tests/generated-tests/CMakeLists.txt:24` does the same for the WASM spec conformance suite. Identical fixtures already run under OC and the interpreter today. The genuinely **net-new** work is narrower: (a) cross-comparing OC-vs-interpreter on **non-fixture / fuzzed** inputs, (b) the **blob reloc-scan**, (c) the **historical-replay integrity-hash** tooling. + +1. **Differential OC vs interpreter — primary gate (extend the existing matrix).** Assert identical **observable behavior**: return values, trap kind/point, linear-memory final state. **CORRECTED:** do **NOT** assert CPU-billing equality across tiers. The interpreter bounds CPU by counting executed WASM ops against a deadline; OC bounds CPU by a wall-clock checktime timer/trap injected into native code — different mechanisms **by design**. `checktime_tests` already run under each runtime and assert deadline/cpu-exceeded *behavior*, not billing equality. Asserting billing equivalence would produce false failures; it is out of scope. + - Corpus: `unittests/wasm-spec-tests` (the canonical semantics oracle), full `unit_test` + `contracts_unit_test` under `--runtime eos-vm-oc` vs `--runtime eos-vm`, plus `eosvmoc_limits_tests`, `wasm_tests`, `wasm_config_tests`. +2. **Cross-LLVM IR byte-diff (isolate semantic change from version noise).** On a common LLVM where both old and new emitter code compile, byte-diff the emitted IR pre/post migration. Any delta must be an *intended* opaque-pointer/pass change. This is the single most powerful tool for catching a wrong tracked element type in `LLVMEmitIR.cpp`. +3. **Determinism / pass-pipeline check.** Dropping `createConstantPropagationPass`/`createJumpThreadingPass` changes optimized IR → codegen. Prove via (1)+(2) that no *observable* semantics changed. Bump the codegen version (§3.3) so old blobs invalidate. +4. **Self-contained-PIC-blob / builtin-reloc scan — ELEVATED TO A P1 BLOCKING GATE.** `objdump`/reloc-scan every emitted blob to assert **no GOT and zero external `memcpy`/`memset`/`__udivti3`-class builtin relocations** survive, on the **exact pinned LLVM 18**, across a corpus of contracts that do **bulk memory ops** (the likely trigger). Verified, this gate is genuinely net-new — no existing tree test scans relocations. The concrete trigger is compiler-rt builtins: the small-constant `memcpy` fast-path falls through to a real call for non-constant sizes, and LLVM codegen can *independently* synthesize `@llvm.memcpy`/`@llvm.memset` (struct-copy, loop-idiom recognition) inside any function; with no resolver, RuntimeDyld leaves these as unresolved external relocs → the harvested blob jumps to garbage with **no load-time relocation to catch it.** Also assert `.stack_sizes` count == `module.functions.defs.size()` and the new `function_to_offsets` count assertion (§3.1). **This must pass before any contract is trusted on the new path** — it is a prerequisite for trusting P1, not a P7 checklist item. +5. **Historical chain replay with integrity-hash compare — strongest end-to-end gate, but it does NOT stand alone.** Replay real chain history on an LLVM-18 OC node; compare the **state integrity hash** against a known-good interpreter/legacy-OC node at matching heights. A divergent hash at any height = a semantics bug; do not merge until clean over a long real window. **CAVEAT:** replay only exercises opcode/type combinations that *actually occurred* in that window. It **must be paired** with the `wasm-spec-tests` conformance corpus **and** a targeted **synthetic** corpus for high-risk paths that may never appear in mainnet history — `call_indirect` type-token mismatches, exotic table layouts, the `memcpy` intrinsic path, OOB/trap/div0/overflow edges — or it gives false confidence. +6. **Targeted security/sandbox tests.** Deep-recursion still trips `stack_size_limit` (`_exit(1)`); OOB access still traps (verifies AS256 + the `coerceByteIndexToPointer` zext survived); softfloat ops (`min`/`max`/`ceil`/`floor`/`div0`) still route to host softfloat intrinsics via the AS256 table (cross-platform FP determinism). + +**CORRECTED noise triage.** The `eosvmoc_interrupt_tests` interrupt-counter assertion is **likely waivable**, not "consensus-adjacent." Verified: it asserts `post_count == pre_count + 1` on `get_eos_vm_oc_compile_interrupt_count()` — it counts **async compile-monitor** interruptions, and the test's own comment warns it can spuriously fail if the 5000ms window "was not long enough for oc compile to complete." It is a background-compiler timing/flakiness test, **not** a per-instruction checktime/consensus counter; the reference's regression here is almost certainly timing. The **genuinely** consensus-adjacent path — the in-code checktime **trap** on long-running contracts — is covered by `checktime_tests` / deep-recursion and is where the scrutiny belongs. (The `deep_mind` log-comparison test may fail on whitespace/encoding and is likely cosmetic.) + +--- + +## 7. Phased plan + +| Phase | Scope | Effort | Gate to advance | +|---|---|---|---| +| **P0 — Extend the existing differential matrix** (re-scoped) | The per-runtime OC-vs-interpreter matrix **already exists** (`unittests/CMakeLists.txt:98`, `wasm-spec-tests :24`). Net-new only: (a) cross-input/fuzz OC-vs-interpreter compare, (b) the **reloc-scan tool**, (c) historical-replay integrity-hash tooling. Archive golden artifacts (OC `.code` blob sizes/hashes, baseline reproducible-build hash). | **~2–3 days** (down from "3–4 days to stand up a harness") | Extended matrix + tooling green on the unchanged LLVM-11 tree; goldens archived. | +| **P1 — `LLVMJIT.cpp`: bypass ORC + the gates that make P1 trustworthy** | Replace ORCv1 with `SimpleCompiler` + `RuntimeDyld` direct (§3.1); inline harvest loop; mechanical API fixes; add `#if` guards so the 7–11 path still compiles. **In P1 (moved earlier): bump `current_codegen_version` 2→3; add `function_to_offsets` count assertion; re-validate `.stack_sizes` parse on 18.** | **~40–70 lines; ~3–5 days** | **BLOCKING: reloc/builtin scan (§6.4) green** — zero external `memcpy`/`memset`/GOT relocs across the bulk-mem corpus on pinned LLVM 18. Smoke contract compiles & runs; `.stack_sizes` + `stack_size_limit _exit(1)` fire on deep recursion; both count assertions hold. | +| **P2 — `LLVMEmitIR.cpp`: opaque pointers** | The heavy item. Thread explicit element types through all 55 sites (§3.2); add `globalValueTypes`/local-type tracking; rewrite `createCall` (two overloads); preserve AS256, the call_indirect i8* identity token, zext, volatile. | **~150–300 lines; ~1–1.5 weeks** | Zero `getPointerElementType` remain; full unittests pass on 18; IR byte-diff vs reference shows only intended changes. | +| **P3 — Limits re-tuning** | LLVM 18 emits larger blobs (reference saw ~60 B/function larger). Re-tune `generated_code_size_limit` / `stack_size_limit`; re-run `eosvmoc_limits_tests`. | **~1–2 days** | `eosvmoc_limits_tests` green; no spurious `_exit(1)` under load. | +| **P4 — CMake / build plumbing** | Move all three EXACT gates atomically (`CMakeLists.txt:68` + both `EosioTester*.cmake.in`); component list → `(support core mcjit native)` (+`DebugInfoDWARF` testers); remove `gnu++17` overrides. | **~20–30 lines; ~1 day** | Native build with `llvm-18-dev`; EosioTester consumers configure (CI smoke). | +| **P5 — Reproducible build: drop 2nd LLVM + reconcile RTTI/PIC** (can run in parallel with P7; does NOT block correctness) | Resolve §4: choose (a) toolchain-wide RTTI-on (validate the clang/lld change) or (b) a separate RTTI-on/PIC-reconciled LLVM-libs install for OC. Delete pinllvm if (a). Re-baseline reproducible-build hash. | **~15–25 lines + decision; ~1–3 days** | Reproducible image builds; new hash recorded; RTTI **and** PIC reconciled; link clean into `eosio_chain`. | +| **P6 — Platform Dockerfiles & CI matrix** (**MUST follow P7 sign-off**) | Remove `ENABLE_OC OFF` from `ubuntu24.Dockerfile:24` & `ubuntu26.Dockerfile:25` (keep 26's `CMAKE_POLICY_VERSION_MINIMUM 3.5` — unrelated cmake-4 fix, do not entangle); `apt install llvm-18-dev`; re-point `.github/workflows/llvm.yaml` matrix to ~18. | **~1 day** | OC-enabled native CI green on 24/26 — **only after** P7 sign-off, never before (or CI gates merges on an unvalidated consensus path). | +| **P7 — Consensus validation (the long pole)** | Full §6: extended differential corpus + fuzz, IR byte-diff, synthetic high-risk corpus, **historical replay integrity-hash compare**. | **Calendar-dominant; not parallelizable with merge.** | All §6 gates green; sign-off. | + +**Sequencing notes:** (1) the reloc-scan is a **P1 exit gate** (prerequisite for trusting any run), not P7; (2) the codegen-version bump is a **P1** correctness prerequisite so no run mixes v2/v18 blobs; (3) P5 is build-infra and runs in parallel with/after P7; (4) P6 (flip `ENABLE_OC ON` in CI) comes **after** P7 only. **Isolate this migration to its own release** — do not interleave with Savanna/finality consensus work, so the replay integrity-hash gate has clean attribution. + +**Total realistic estimate:** ~2–4 weeks coding (P1–P6), then a hard-gated, non-parallelizable P7 cycle before merge. Coding confidence **high**; total-timeline confidence **medium**. + +--- + +## 8. Risks & mitigations + +| # | Risk | Severity | Mitigation | +|---|---|---|---| +| **R1** | **Consensus divergence** — any codegen/typing bug makes OC nodes disagree with interpreter/other nodes → chain split. | **Critical** | Entire §6, gated. Differential corpus + IR byte-diff + historical-replay integrity-hash compare paired with synthetic high-risk corpus. Non-negotiable merge gate. | +| **R2** | Dropping `createConstantPropagationPass`/`createJumpThreadingPass` changes optimized IR → different codegen. | High | Prove semantics-neutral via §6(1)+(2). Bump codegen version (auto-invalidates stale blobs). | +| **R3** | Wrong tracked element type in opaque-pointer rewrite silently mis-loads/mis-GEPs on specific contracts. | High | Per-callsite review vs reference; IR byte-diff (§6.2); broad corpus. Highest-leverage: `createCall` helper, **`call_indirect` (no pointee to recover — FunctionType MUST be threaded from `asLLVMType`)**, `coerceByteIndexToPointer`. | +| **R4** | LLVM 18 emits larger blobs → spurious `generated_code_size_limit`/`stack_size_limit` `_exit(1)` node aborts. | High | P3 re-tune limits; re-run `eosvmoc_limits_tests`; load-test. (AntelopeIO hit this before, PRs #902/#1016.) | +| **R5** | Losing AS256, the zext, `setVolatile`, **or the call_indirect i8\* identity token** during the rewrite silently breaks the sandbox / OOB protection / indirect-call type check. | High | Preserve byte-for-byte (confirmed in reference); §6(4)+(6) verify AS256 relocs and OOB trapping; explicit per-site AS256 audit (11 sites); the `CreateICmpNE` token stays i8* identity, not structural. | +| **R6** | Following the issue title → ORCv2 → bare `JITDylib` can't materialize `memcpy`/`memset` → compile failures on specific contracts. | High (avoidable) | **Bypass ORC** (§3.1). Documented dead-end; do not attempt LLJIT. | +| **R7** | **LLVM-synthesized `memcpy`/`memset`/builtin survives as an unresolved external reloc** in the harvested blob (more likely than a generic GOT reloc; same root cause as R6, also bites RuntimeDyld). | **High** | **P1 BLOCKING reloc/builtin scan (§6.4)** on bulk-mem corpus, exact LLVM 18. No load-time relocation exists to catch this. | +| **R8** | RuntimeDyld is in maintenance mode (JITLink is the successor); a future LLVM could drop it. | Low (near-term) | Acceptable in the 12–20 window. Log as follow-up tech-debt: a later JITLink port. | +| **R9** | RTTI/PIC mismatch: OC needs RTTI-on (PIC-reconciled) LLVM libs; making the shared toolchain RTTI-on changes the clang/lld that builds **all** of spring → reproducible-input change; may force keeping a 2nd LLVM-libs build (undercuts payoff). | **Medium-High** | §4 decision before merge: (a) validate toolchain-wide RTTI change + re-baseline hash, or (b) separate RTTI-on/PIC-reconciled LLVM-libs install for OC. Reconcile PIC **and** RTTI together. | +| **R10** | Silent harvest under-count: LLVM 18 internalizes/strips emitted function symbols → `function_to_offsets` missing entries → calls jump to garbage (currently unguarded, unlike the stack_sizes check). | High | **New `function_to_offsets.size()==defs.size()` assertion (P1)**; re-validate `.stack_sizes` encoding/offset-width on 18. | +| **R11** | Three EXACT-version gates must move together or EosioTester consumers break. | Medium | P4 changes `CMakeLists.txt:68` + both `EosioTester*.cmake.in` atomically; tester smoke-build in CI. | +| **R12** | Dropping the 2nd pinned LLVM changes reproducible-build inputs → released binary hash changes. | Medium | P5 re-baseline build hash deliberately; handle with R9 reconciliation. | + +--- + +## 9. Open decisions for eosrio (sign-off) + +1. **Permanent floor after transition:** keep a guarded 7–11 legacy path for one release, or cut straight to 18-only like the reference? **Recommendation:** guard for one release **as build-only/dev convenience, explicitly NOT release-certified** (else you recreate the multi-codegen validation cost you are avoiding), then delete. +2. **Validated ceiling:** **Recommendation — release-certify exactly 18**; treat 14..20 as best-effort-builds, not pinned/supported. Drop "validated window" language from anything implying release support. +3. **Replay window:** how many blocks of real history constitute "enough" for the integrity-hash gate (R1)? Decide the floor; remember replay must be **paired** with the synthetic high-risk corpus (§6.5). +4. **ubuntu20/22:** move to `llvm-18-dev` now, or leave on `llvm-11-dev` short-term under the widened gate? +5. **RTTI/PIC strategy (blocks the headline payoff, §4):** (a) toolchain-wide RTTI-on (accept the clang/lld input change + re-baseline) or (b) a separate RTTI-on/PIC-reconciled LLVM-libs build for OC (partially keeps the duplication). Decide before claiming "stop building LLVM twice." +6. **Release isolation:** confirm this ships as its own release, not interleaved with Savanna/finality work, so the replay integrity-hash gate has clean attribution. \ No newline at end of file From 23f0e3ab5b793fd09376f07a80b1be1b400eb7e5 Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Thu, 3 Sep 2026 16:01:35 -0300 Subject: [PATCH 13/17] chore: ignore cluster-artifacts in docker build context Keeps local cluster test output out of the image build context. Claude-Session: https://claude.ai/code/session_017dStsbqQfAGrhfqYQtGHmd --- .dockerignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..43109f5f62 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +cluster-artifacts/ From a8e8c2865d898461c95adf41fc3f7a87d82e21af Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Wed, 16 Sep 2026 07:17:07 -0300 Subject: [PATCH 14/17] unittests: stop compiling SHiP session coroutines on GCC < 11 Ubuntu 20 CI builds unit_test without -fcoroutines, so including session.hpp from state_history_tests.cpp failed. Move status_request_queue into its own header so those tests no longer pull Boost.Asio awaitable types. --- .../eosio/state_history_plugin/session.hpp | 34 +-------------- .../status_request_queue.hpp | 43 +++++++++++++++++++ unittests/state_history_tests.cpp | 2 +- 3 files changed, 45 insertions(+), 34 deletions(-) create mode 100644 plugins/state_history_plugin/include/eosio/state_history_plugin/status_request_queue.hpp diff --git a/plugins/state_history_plugin/include/eosio/state_history_plugin/session.hpp b/plugins/state_history_plugin/include/eosio/state_history_plugin/session.hpp index 3bf9a9e888..589a324892 100644 --- a/plugins/state_history_plugin/include/eosio/state_history_plugin/session.hpp +++ b/plugins/state_history_plugin/include/eosio/state_history_plugin/session.hpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -24,39 +25,6 @@ namespace eosio::state_history { using appbase::app; -FC_DECLARE_DERIVED_EXCEPTION( status_request_queue_limit_exceeded, chain::plugin_exception, - 3240001, "State history status request queue limit exceeded" ); - -class status_request_queue { -public: - static constexpr size_t default_max_size = 100; - - explicit status_request_queue(size_t max_size = default_max_size) : _max_size(max_size) {} - - bool try_append(bool is_v1) { - if (_queue.size() >= _max_size) { - return false; - } - _queue.emplace_back(is_v1); - return true; - } - - std::deque extract() { - std::deque extracted; - _queue.swap(extracted); - return extracted; - } - - size_t size() const { return _queue.size(); } - bool empty() const { return _queue.empty(); } - size_t max_size() const { return _max_size; } - void clear() { _queue.clear(); } - -private: - std::deque _queue; - size_t _max_size; -}; - class session_base { public: session_base() = default; diff --git a/plugins/state_history_plugin/include/eosio/state_history_plugin/status_request_queue.hpp b/plugins/state_history_plugin/include/eosio/state_history_plugin/status_request_queue.hpp new file mode 100644 index 0000000000..392c4ef8db --- /dev/null +++ b/plugins/state_history_plugin/include/eosio/state_history_plugin/status_request_queue.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include + +#include +#include + +namespace eosio::state_history { + +FC_DECLARE_DERIVED_EXCEPTION( status_request_queue_limit_exceeded, chain::plugin_exception, + 3240001, "State history status request queue limit exceeded" ); + +class status_request_queue { +public: + static constexpr size_t default_max_size = 100; + + explicit status_request_queue(size_t max_size = default_max_size) : _max_size(max_size) {} + + bool try_append(bool is_v1) { + if (_queue.size() >= _max_size) { + return false; + } + _queue.emplace_back(is_v1); + return true; + } + + std::deque extract() { + std::deque extracted; + _queue.swap(extracted); + return extracted; + } + + size_t size() const { return _queue.size(); } + bool empty() const { return _queue.empty(); } + size_t max_size() const { return _max_size; } + void clear() { _queue.clear(); } + +private: + std::deque _queue; + size_t _max_size; +}; + +} // namespace eosio::state_history diff --git a/unittests/state_history_tests.cpp b/unittests/state_history_tests.cpp index 9dd0e9afec..c09abaea6d 100644 --- a/unittests/state_history_tests.cpp +++ b/unittests/state_history_tests.cpp @@ -18,7 +18,7 @@ #include #include #include -#include "../plugins/state_history_plugin/include/eosio/state_history_plugin/session.hpp" +#include "../plugins/state_history_plugin/include/eosio/state_history_plugin/status_request_queue.hpp" using namespace eosio::chain; using namespace eosio::testing; From 232a446a5302bea909cbb27317647600d43315f6 Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Sat, 6 Jun 2026 14:58:08 -0300 Subject: [PATCH 15/17] ci: make parallel-ctest-containers idempotent against orphaned containers The action runs each test in a docker container with a fixed name (--name ) and no --rm, and never removes them (it needs them for docker export on failure). On ENF's ephemeral runners the daemon is fresh per job so this is fine, but on a persistent self-hosted runner the daemon survives between jobs and the next job collides: 'docker: Error response from daemon: Conflict. The container name "/" is already in use'. That wiped out every NP/LR Tests job on the eosrio self-hosted runner. Defensively 'docker rm -f' the base container and each test container name before reusing it, so a leftover from a prior/interrupted run can't block it. Patched both main.mjs (source) and the built dist/index.mjs bundle. --- .github/actions/parallel-ctest-containers/dist/index.mjs | 2 +- .github/actions/parallel-ctest-containers/main.mjs | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/actions/parallel-ctest-containers/dist/index.mjs b/.github/actions/parallel-ctest-containers/dist/index.mjs index 9ace17b974..1fc088aed9 100644 --- a/.github/actions/parallel-ctest-containers/dist/index.mjs +++ b/.github/actions/parallel-ctest-containers/dist/index.mjs @@ -1,3 +1,3 @@ import{createRequire as e}from"module";var t={7351:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};Object.defineProperty(t,"__esModule",{value:true});t.issue=t.issueCommand=void 0;const o=a(r(2037));const s=r(6321);function issueCommand(e,t,r){const n=new Command(e,t,r);process.stdout.write(n.toString()+o.EOL)}t.issueCommand=issueCommand;function issue(e,t=""){issueCommand(e,{},t)}t.issue=issue;const u="::";class Command{constructor(e,t,r){if(!e){e="missing.command"}this.command=e;this.properties=t;this.message=r}toString(){let e=u+this.command;if(this.properties&&Object.keys(this.properties).length>0){e+=" ";let t=true;for(const r in this.properties){if(this.properties.hasOwnProperty(r)){const n=this.properties[r];if(n){if(t){t=false}else{e+=","}e+=`${r}=${escapeProperty(n)}`}}}}e+=`${u}${escapeData(this.message)}`;return e}}function escapeData(e){return s.toCommandValue(e).replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function escapeProperty(e){return s.toCommandValue(e).replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/:/g,"%3A").replace(/,/g,"%2C")}},2186:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};var o=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.getIDToken=t.getState=t.saveState=t.group=t.endGroup=t.startGroup=t.info=t.notice=t.warning=t.error=t.debug=t.isDebug=t.setFailed=t.setCommandEcho=t.setOutput=t.getBooleanInput=t.getMultilineInput=t.getInput=t.addPath=t.setSecret=t.exportVariable=t.ExitCode=void 0;const s=r(7351);const u=r(717);const l=r(6321);const c=a(r(2037));const d=a(r(1017));const h=r(5840);const p=r(8041);var g;(function(e){e[e["Success"]=0]="Success";e[e["Failure"]=1]="Failure"})(g=t.ExitCode||(t.ExitCode={}));function exportVariable(e,t){const r=l.toCommandValue(t);process.env[e]=r;const n=process.env["GITHUB_ENV"]||"";if(n){const t=`ghadelimiter_${h.v4()}`;if(e.includes(t)){throw new Error(`Unexpected input: name should not contain the delimiter "${t}"`)}if(r.includes(t)){throw new Error(`Unexpected input: value should not contain the delimiter "${t}"`)}const n=`${e}<<${t}${c.EOL}${r}${c.EOL}${t}`;u.issueCommand("ENV",n)}else{s.issueCommand("set-env",{name:e},r)}}t.exportVariable=exportVariable;function setSecret(e){s.issueCommand("add-mask",{},e)}t.setSecret=setSecret;function addPath(e){const t=process.env["GITHUB_PATH"]||"";if(t){u.issueCommand("PATH",e)}else{s.issueCommand("add-path",{},e)}process.env["PATH"]=`${e}${d.delimiter}${process.env["PATH"]}`}t.addPath=addPath;function getInput(e,t){const r=process.env[`INPUT_${e.replace(/ /g,"_").toUpperCase()}`]||"";if(t&&t.required&&!r){throw new Error(`Input required and not supplied: ${e}`)}if(t&&t.trimWhitespace===false){return r}return r.trim()}t.getInput=getInput;function getMultilineInput(e,t){const r=getInput(e,t).split("\n").filter((e=>e!==""));return r}t.getMultilineInput=getMultilineInput;function getBooleanInput(e,t){const r=["true","True","TRUE"];const n=["false","False","FALSE"];const i=getInput(e,t);if(r.includes(i))return true;if(n.includes(i))return false;throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${e}\n`+`Support boolean input list: \`true | True | TRUE | false | False | FALSE\``)}t.getBooleanInput=getBooleanInput;function setOutput(e,t){process.stdout.write(c.EOL);s.issueCommand("set-output",{name:e},t)}t.setOutput=setOutput;function setCommandEcho(e){s.issue("echo",e?"on":"off")}t.setCommandEcho=setCommandEcho;function setFailed(e){process.exitCode=g.Failure;error(e)}t.setFailed=setFailed;function isDebug(){return process.env["RUNNER_DEBUG"]==="1"}t.isDebug=isDebug;function debug(e){s.issueCommand("debug",{},e)}t.debug=debug;function error(e,t={}){s.issueCommand("error",l.toCommandProperties(t),e instanceof Error?e.toString():e)}t.error=error;function warning(e,t={}){s.issueCommand("warning",l.toCommandProperties(t),e instanceof Error?e.toString():e)}t.warning=warning;function notice(e,t={}){s.issueCommand("notice",l.toCommandProperties(t),e instanceof Error?e.toString():e)}t.notice=notice;function info(e){process.stdout.write(e+c.EOL)}t.info=info;function startGroup(e){s.issue("group",e)}t.startGroup=startGroup;function endGroup(){s.issue("endgroup")}t.endGroup=endGroup;function group(e,t){return o(this,void 0,void 0,(function*(){startGroup(e);let r;try{r=yield t()}finally{endGroup()}return r}))}t.group=group;function saveState(e,t){s.issueCommand("save-state",{name:e},t)}t.saveState=saveState;function getState(e){return process.env[`STATE_${e}`]||""}t.getState=getState;function getIDToken(e){return o(this,void 0,void 0,(function*(){return yield p.OidcClient.getIDToken(e)}))}t.getIDToken=getIDToken;var m=r(1327);Object.defineProperty(t,"summary",{enumerable:true,get:function(){return m.summary}});var b=r(1327);Object.defineProperty(t,"markdownSummary",{enumerable:true,get:function(){return b.markdownSummary}});var v=r(2981);Object.defineProperty(t,"toPosixPath",{enumerable:true,get:function(){return v.toPosixPath}});Object.defineProperty(t,"toWin32Path",{enumerable:true,get:function(){return v.toWin32Path}});Object.defineProperty(t,"toPlatformPath",{enumerable:true,get:function(){return v.toPlatformPath}})},717:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};Object.defineProperty(t,"__esModule",{value:true});t.issueCommand=void 0;const o=a(r(7147));const s=a(r(2037));const u=r(6321);function issueCommand(e,t){const r=process.env[`GITHUB_${e}`];if(!r){throw new Error(`Unable to find environment variable for file command ${e}`)}if(!o.existsSync(r)){throw new Error(`Missing file at path: ${r}`)}o.appendFileSync(r,`${u.toCommandValue(t)}${s.EOL}`,{encoding:"utf8"})}t.issueCommand=issueCommand},8041:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.OidcClient=void 0;const i=r(6255);const a=r(5526);const o=r(2186);class OidcClient{static createHttpClient(e=true,t=10){const r={allowRetries:e,maxRetries:t};return new i.HttpClient("actions/oidc-client",[new a.BearerCredentialHandler(OidcClient.getRequestToken())],r)}static getRequestToken(){const e=process.env["ACTIONS_ID_TOKEN_REQUEST_TOKEN"];if(!e){throw new Error("Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable")}return e}static getIDTokenUrl(){const e=process.env["ACTIONS_ID_TOKEN_REQUEST_URL"];if(!e){throw new Error("Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable")}return e}static getCall(e){var t;return n(this,void 0,void 0,(function*(){const r=OidcClient.createHttpClient();const n=yield r.getJson(e).catch((e=>{throw new Error(`Failed to get ID Token. \n \n Error Code : ${e.statusCode}\n \n Error Message: ${e.result.message}`)}));const i=(t=n.result)===null||t===void 0?void 0:t.value;if(!i){throw new Error("Response json body do not have ID Token field")}return i}))}static getIDToken(e){return n(this,void 0,void 0,(function*(){try{let t=OidcClient.getIDTokenUrl();if(e){const r=encodeURIComponent(e);t=`${t}&audience=${r}`}o.debug(`ID token url is ${t}`);const r=yield OidcClient.getCall(t);o.setSecret(r);return r}catch(e){throw new Error(`Error message: ${e.message}`)}}))}}t.OidcClient=OidcClient},2981:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};Object.defineProperty(t,"__esModule",{value:true});t.toPlatformPath=t.toWin32Path=t.toPosixPath=void 0;const o=a(r(1017));function toPosixPath(e){return e.replace(/[\\]/g,"/")}t.toPosixPath=toPosixPath;function toWin32Path(e){return e.replace(/[/]/g,"\\")}t.toWin32Path=toWin32Path;function toPlatformPath(e){return e.replace(/[/\\]/g,o.sep)}t.toPlatformPath=toPlatformPath},1327:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.summary=t.markdownSummary=t.SUMMARY_DOCS_URL=t.SUMMARY_ENV_VAR=void 0;const i=r(2037);const a=r(7147);const{access:o,appendFile:s,writeFile:u}=a.promises;t.SUMMARY_ENV_VAR="GITHUB_STEP_SUMMARY";t.SUMMARY_DOCS_URL="https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary";class Summary{constructor(){this._buffer=""}filePath(){return n(this,void 0,void 0,(function*(){if(this._filePath){return this._filePath}const e=process.env[t.SUMMARY_ENV_VAR];if(!e){throw new Error(`Unable to find environment variable for $${t.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`)}try{yield o(e,a.constants.R_OK|a.constants.W_OK)}catch(t){throw new Error(`Unable to access summary file: '${e}'. Check if the file has correct read/write permissions.`)}this._filePath=e;return this._filePath}))}wrap(e,t,r={}){const n=Object.entries(r).map((([e,t])=>` ${e}="${t}"`)).join("");if(!t){return`<${e}${n}>`}return`<${e}${n}>${t}`}write(e){return n(this,void 0,void 0,(function*(){const t=!!(e===null||e===void 0?void 0:e.overwrite);const r=yield this.filePath();const n=t?u:s;yield n(r,this._buffer,{encoding:"utf8"});return this.emptyBuffer()}))}clear(){return n(this,void 0,void 0,(function*(){return this.emptyBuffer().write({overwrite:true})}))}stringify(){return this._buffer}isEmptyBuffer(){return this._buffer.length===0}emptyBuffer(){this._buffer="";return this}addRaw(e,t=false){this._buffer+=e;return t?this.addEOL():this}addEOL(){return this.addRaw(i.EOL)}addCodeBlock(e,t){const r=Object.assign({},t&&{lang:t});const n=this.wrap("pre",this.wrap("code",e),r);return this.addRaw(n).addEOL()}addList(e,t=false){const r=t?"ol":"ul";const n=e.map((e=>this.wrap("li",e))).join("");const i=this.wrap(r,n);return this.addRaw(i).addEOL()}addTable(e){const t=e.map((e=>{const t=e.map((e=>{if(typeof e==="string"){return this.wrap("td",e)}const{header:t,data:r,colspan:n,rowspan:i}=e;const a=t?"th":"td";const o=Object.assign(Object.assign({},n&&{colspan:n}),i&&{rowspan:i});return this.wrap(a,r,o)})).join("");return this.wrap("tr",t)})).join("");const r=this.wrap("table",t);return this.addRaw(r).addEOL()}addDetails(e,t){const r=this.wrap("details",this.wrap("summary",e)+t);return this.addRaw(r).addEOL()}addImage(e,t,r){const{width:n,height:i}=r||{};const a=Object.assign(Object.assign({},n&&{width:n}),i&&{height:i});const o=this.wrap("img",null,Object.assign({src:e,alt:t},a));return this.addRaw(o).addEOL()}addHeading(e,t){const r=`h${t}`;const n=["h1","h2","h3","h4","h5","h6"].includes(r)?r:"h1";const i=this.wrap(n,e);return this.addRaw(i).addEOL()}addSeparator(){const e=this.wrap("hr",null);return this.addRaw(e).addEOL()}addBreak(){const e=this.wrap("br",null);return this.addRaw(e).addEOL()}addQuote(e,t){const r=Object.assign({},t&&{cite:t});const n=this.wrap("blockquote",e,r);return this.addRaw(n).addEOL()}addLink(e,t){const r=this.wrap("a",e,{href:t});return this.addRaw(r).addEOL()}}const l=new Summary;t.markdownSummary=l;t.summary=l},6321:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true});t.toCommandProperties=t.toCommandValue=void 0;function toCommandValue(e){if(e===null||e===undefined){return""}else if(typeof e==="string"||e instanceof String){return e}return JSON.stringify(e)}t.toCommandValue=toCommandValue;function toCommandProperties(e){if(!Object.keys(e).length){return{}}return{title:e.title,file:e.file,line:e.startLine,endLine:e.endLine,col:e.startColumn,endColumn:e.endColumn}}t.toCommandProperties=toCommandProperties},5526:function(e,t){var r=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.PersonalAccessTokenCredentialHandler=t.BearerCredentialHandler=t.BasicCredentialHandler=void 0;class BasicCredentialHandler{constructor(e,t){this.username=e;this.password=t}prepareRequest(e){if(!e.headers){throw Error("The request has no headers")}e.headers["Authorization"]=`Basic ${Buffer.from(`${this.username}:${this.password}`).toString("base64")}`}canHandleAuthentication(){return false}handleAuthentication(){return r(this,void 0,void 0,(function*(){throw new Error("not implemented")}))}}t.BasicCredentialHandler=BasicCredentialHandler;class BearerCredentialHandler{constructor(e){this.token=e}prepareRequest(e){if(!e.headers){throw Error("The request has no headers")}e.headers["Authorization"]=`Bearer ${this.token}`}canHandleAuthentication(){return false}handleAuthentication(){return r(this,void 0,void 0,(function*(){throw new Error("not implemented")}))}}t.BearerCredentialHandler=BearerCredentialHandler;class PersonalAccessTokenCredentialHandler{constructor(e){this.token=e}prepareRequest(e){if(!e.headers){throw Error("The request has no headers")}e.headers["Authorization"]=`Basic ${Buffer.from(`PAT:${this.token}`).toString("base64")}`}canHandleAuthentication(){return false}handleAuthentication(){return r(this,void 0,void 0,(function*(){throw new Error("not implemented")}))}}t.PersonalAccessTokenCredentialHandler=PersonalAccessTokenCredentialHandler},6255:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};var o=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.HttpClient=t.isHttps=t.HttpClientResponse=t.HttpClientError=t.getProxyUrl=t.MediaTypes=t.Headers=t.HttpCodes=void 0;const s=a(r(3685));const u=a(r(5687));const l=a(r(9835));const c=a(r(4294));var d;(function(e){e[e["OK"]=200]="OK";e[e["MultipleChoices"]=300]="MultipleChoices";e[e["MovedPermanently"]=301]="MovedPermanently";e[e["ResourceMoved"]=302]="ResourceMoved";e[e["SeeOther"]=303]="SeeOther";e[e["NotModified"]=304]="NotModified";e[e["UseProxy"]=305]="UseProxy";e[e["SwitchProxy"]=306]="SwitchProxy";e[e["TemporaryRedirect"]=307]="TemporaryRedirect";e[e["PermanentRedirect"]=308]="PermanentRedirect";e[e["BadRequest"]=400]="BadRequest";e[e["Unauthorized"]=401]="Unauthorized";e[e["PaymentRequired"]=402]="PaymentRequired";e[e["Forbidden"]=403]="Forbidden";e[e["NotFound"]=404]="NotFound";e[e["MethodNotAllowed"]=405]="MethodNotAllowed";e[e["NotAcceptable"]=406]="NotAcceptable";e[e["ProxyAuthenticationRequired"]=407]="ProxyAuthenticationRequired";e[e["RequestTimeout"]=408]="RequestTimeout";e[e["Conflict"]=409]="Conflict";e[e["Gone"]=410]="Gone";e[e["TooManyRequests"]=429]="TooManyRequests";e[e["InternalServerError"]=500]="InternalServerError";e[e["NotImplemented"]=501]="NotImplemented";e[e["BadGateway"]=502]="BadGateway";e[e["ServiceUnavailable"]=503]="ServiceUnavailable";e[e["GatewayTimeout"]=504]="GatewayTimeout"})(d=t.HttpCodes||(t.HttpCodes={}));var h;(function(e){e["Accept"]="accept";e["ContentType"]="content-type"})(h=t.Headers||(t.Headers={}));var p;(function(e){e["ApplicationJson"]="application/json"})(p=t.MediaTypes||(t.MediaTypes={}));function getProxyUrl(e){const t=l.getProxyUrl(new URL(e));return t?t.href:""}t.getProxyUrl=getProxyUrl;const g=[d.MovedPermanently,d.ResourceMoved,d.SeeOther,d.TemporaryRedirect,d.PermanentRedirect];const m=[d.BadGateway,d.ServiceUnavailable,d.GatewayTimeout];const b=["OPTIONS","GET","DELETE","HEAD"];const v=10;const _=5;class HttpClientError extends Error{constructor(e,t){super(e);this.name="HttpClientError";this.statusCode=t;Object.setPrototypeOf(this,HttpClientError.prototype)}}t.HttpClientError=HttpClientError;class HttpClientResponse{constructor(e){this.message=e}readBody(){return o(this,void 0,void 0,(function*(){return new Promise((e=>o(this,void 0,void 0,(function*(){let t=Buffer.alloc(0);this.message.on("data",(e=>{t=Buffer.concat([t,e])}));this.message.on("end",(()=>{e(t.toString())}))}))))}))}}t.HttpClientResponse=HttpClientResponse;function isHttps(e){const t=new URL(e);return t.protocol==="https:"}t.isHttps=isHttps;class HttpClient{constructor(e,t,r){this._ignoreSslError=false;this._allowRedirects=true;this._allowRedirectDowngrade=false;this._maxRedirects=50;this._allowRetries=false;this._maxRetries=1;this._keepAlive=false;this._disposed=false;this.userAgent=e;this.handlers=t||[];this.requestOptions=r;if(r){if(r.ignoreSslError!=null){this._ignoreSslError=r.ignoreSslError}this._socketTimeout=r.socketTimeout;if(r.allowRedirects!=null){this._allowRedirects=r.allowRedirects}if(r.allowRedirectDowngrade!=null){this._allowRedirectDowngrade=r.allowRedirectDowngrade}if(r.maxRedirects!=null){this._maxRedirects=Math.max(r.maxRedirects,0)}if(r.keepAlive!=null){this._keepAlive=r.keepAlive}if(r.allowRetries!=null){this._allowRetries=r.allowRetries}if(r.maxRetries!=null){this._maxRetries=r.maxRetries}}}options(e,t){return o(this,void 0,void 0,(function*(){return this.request("OPTIONS",e,null,t||{})}))}get(e,t){return o(this,void 0,void 0,(function*(){return this.request("GET",e,null,t||{})}))}del(e,t){return o(this,void 0,void 0,(function*(){return this.request("DELETE",e,null,t||{})}))}post(e,t,r){return o(this,void 0,void 0,(function*(){return this.request("POST",e,t,r||{})}))}patch(e,t,r){return o(this,void 0,void 0,(function*(){return this.request("PATCH",e,t,r||{})}))}put(e,t,r){return o(this,void 0,void 0,(function*(){return this.request("PUT",e,t,r||{})}))}head(e,t){return o(this,void 0,void 0,(function*(){return this.request("HEAD",e,null,t||{})}))}sendStream(e,t,r,n){return o(this,void 0,void 0,(function*(){return this.request(e,t,r,n)}))}getJson(e,t={}){return o(this,void 0,void 0,(function*(){t[h.Accept]=this._getExistingOrDefaultHeader(t,h.Accept,p.ApplicationJson);const r=yield this.get(e,t);return this._processResponse(r,this.requestOptions)}))}postJson(e,t,r={}){return o(this,void 0,void 0,(function*(){const n=JSON.stringify(t,null,2);r[h.Accept]=this._getExistingOrDefaultHeader(r,h.Accept,p.ApplicationJson);r[h.ContentType]=this._getExistingOrDefaultHeader(r,h.ContentType,p.ApplicationJson);const i=yield this.post(e,n,r);return this._processResponse(i,this.requestOptions)}))}putJson(e,t,r={}){return o(this,void 0,void 0,(function*(){const n=JSON.stringify(t,null,2);r[h.Accept]=this._getExistingOrDefaultHeader(r,h.Accept,p.ApplicationJson);r[h.ContentType]=this._getExistingOrDefaultHeader(r,h.ContentType,p.ApplicationJson);const i=yield this.put(e,n,r);return this._processResponse(i,this.requestOptions)}))}patchJson(e,t,r={}){return o(this,void 0,void 0,(function*(){const n=JSON.stringify(t,null,2);r[h.Accept]=this._getExistingOrDefaultHeader(r,h.Accept,p.ApplicationJson);r[h.ContentType]=this._getExistingOrDefaultHeader(r,h.ContentType,p.ApplicationJson);const i=yield this.patch(e,n,r);return this._processResponse(i,this.requestOptions)}))}request(e,t,r,n){return o(this,void 0,void 0,(function*(){if(this._disposed){throw new Error("Client has already been disposed.")}const i=new URL(t);let a=this._prepareRequest(e,i,n);const o=this._allowRetries&&b.includes(e)?this._maxRetries+1:1;let s=0;let u;do{u=yield this.requestRaw(a,r);if(u&&u.message&&u.message.statusCode===d.Unauthorized){let e;for(const t of this.handlers){if(t.canHandleAuthentication(u)){e=t;break}}if(e){return e.handleAuthentication(this,a,r)}else{return u}}let t=this._maxRedirects;while(u.message.statusCode&&g.includes(u.message.statusCode)&&this._allowRedirects&&t>0){const o=u.message.headers["location"];if(!o){break}const s=new URL(o);if(i.protocol==="https:"&&i.protocol!==s.protocol&&!this._allowRedirectDowngrade){throw new Error("Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.")}yield u.readBody();if(s.hostname!==i.hostname){for(const e in n){if(e.toLowerCase()==="authorization"){delete n[e]}}}a=this._prepareRequest(e,s,n);u=yield this.requestRaw(a,r);t--}if(!u.message.statusCode||!m.includes(u.message.statusCode)){return u}s+=1;if(s{function callbackForResult(e,t){if(e){n(e)}else if(!t){n(new Error("Unknown error"))}else{r(t)}}this.requestRawWithCallback(e,t,callbackForResult)}))}))}requestRawWithCallback(e,t,r){if(typeof t==="string"){if(!e.options.headers){e.options.headers={}}e.options.headers["Content-Length"]=Buffer.byteLength(t,"utf8")}let n=false;function handleResult(e,t){if(!n){n=true;r(e,t)}}const i=e.httpModule.request(e.options,(e=>{const t=new HttpClientResponse(e);handleResult(undefined,t)}));let a;i.on("socket",(e=>{a=e}));i.setTimeout(this._socketTimeout||3*6e4,(()=>{if(a){a.end()}handleResult(new Error(`Request timeout: ${e.options.path}`))}));i.on("error",(function(e){handleResult(e)}));if(t&&typeof t==="string"){i.write(t,"utf8")}if(t&&typeof t!=="string"){t.on("close",(function(){i.end()}));t.pipe(i)}else{i.end()}}getAgent(e){const t=new URL(e);return this._getAgent(t)}_prepareRequest(e,t,r){const n={};n.parsedUrl=t;const i=n.parsedUrl.protocol==="https:";n.httpModule=i?u:s;const a=i?443:80;n.options={};n.options.host=n.parsedUrl.hostname;n.options.port=n.parsedUrl.port?parseInt(n.parsedUrl.port):a;n.options.path=(n.parsedUrl.pathname||"")+(n.parsedUrl.search||"");n.options.method=e;n.options.headers=this._mergeHeaders(r);if(this.userAgent!=null){n.options.headers["user-agent"]=this.userAgent}n.options.agent=this._getAgent(n.parsedUrl);if(this.handlers){for(const e of this.handlers){e.prepareRequest(n.options)}}return n}_mergeHeaders(e){if(this.requestOptions&&this.requestOptions.headers){return Object.assign({},lowercaseKeys(this.requestOptions.headers),lowercaseKeys(e||{}))}return lowercaseKeys(e||{})}_getExistingOrDefaultHeader(e,t,r){let n;if(this.requestOptions&&this.requestOptions.headers){n=lowercaseKeys(this.requestOptions.headers)[t]}return e[t]||n||r}_getAgent(e){let t;const r=l.getProxyUrl(e);const n=r&&r.hostname;if(this._keepAlive&&n){t=this._proxyAgent}if(this._keepAlive&&!n){t=this._agent}if(t){return t}const i=e.protocol==="https:";let a=100;if(this.requestOptions){a=this.requestOptions.maxSockets||s.globalAgent.maxSockets}if(r&&r.hostname){const e={maxSockets:a,keepAlive:this._keepAlive,proxy:Object.assign(Object.assign({},(r.username||r.password)&&{proxyAuth:`${r.username}:${r.password}`}),{host:r.hostname,port:r.port})};let n;const o=r.protocol==="https:";if(i){n=o?c.httpsOverHttps:c.httpsOverHttp}else{n=o?c.httpOverHttps:c.httpOverHttp}t=n(e);this._proxyAgent=t}if(this._keepAlive&&!t){const e={keepAlive:this._keepAlive,maxSockets:a};t=i?new u.Agent(e):new s.Agent(e);this._agent=t}if(!t){t=i?u.globalAgent:s.globalAgent}if(i&&this._ignoreSslError){t.options=Object.assign(t.options||{},{rejectUnauthorized:false})}return t}_performExponentialBackoff(e){return o(this,void 0,void 0,(function*(){e=Math.min(v,e);const t=_*Math.pow(2,e);return new Promise((e=>setTimeout((()=>e()),t)))}))}_processResponse(e,t){return o(this,void 0,void 0,(function*(){return new Promise(((r,n)=>o(this,void 0,void 0,(function*(){const i=e.message.statusCode||0;const a={statusCode:i,result:null,headers:{}};if(i===d.NotFound){r(a)}function dateTimeDeserializer(e,t){if(typeof t==="string"){const e=new Date(t);if(!isNaN(e.valueOf())){return e}}return t}let o;let s;try{s=yield e.readBody();if(s&&s.length>0){if(t&&t.deserializeDates){o=JSON.parse(s,dateTimeDeserializer)}else{o=JSON.parse(s)}a.result=o}a.headers=e.message.headers}catch(e){}if(i>299){let e;if(o&&o.message){e=o.message}else if(s&&s.length>0){e=s}else{e=`Failed request: (${i})`}const t=new HttpClientError(e,i);t.result=a.result;n(t)}else{r(a)}}))))}))}}t.HttpClient=HttpClient;const lowercaseKeys=e=>Object.keys(e).reduce(((t,r)=>(t[r.toLowerCase()]=e[r],t)),{})},9835:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true});t.checkBypass=t.getProxyUrl=void 0;function getProxyUrl(e){const t=e.protocol==="https:";if(checkBypass(e)){return undefined}const r=(()=>{if(t){return process.env["https_proxy"]||process.env["HTTPS_PROXY"]}else{return process.env["http_proxy"]||process.env["HTTP_PROXY"]}})();if(r){return new URL(r)}else{return undefined}}t.getProxyUrl=getProxyUrl;function checkBypass(e){if(!e.hostname){return false}const t=process.env["no_proxy"]||process.env["NO_PROXY"]||"";if(!t){return false}let r;if(e.port){r=Number(e.port)}else if(e.protocol==="http:"){r=80}else if(e.protocol==="https:"){r=443}const n=[e.hostname.toUpperCase()];if(typeof r==="number"){n.push(`${n[0]}:${r}`)}for(const e of t.split(",").map((e=>e.trim().toUpperCase())).filter((e=>e))){if(n.some((t=>t===e))){return true}}return false}t.checkBypass=checkBypass},3664:(e,t,r)=>{const{Buffer:n}=r(4300);const i=Symbol.for("BufferList");function BufferList(e){if(!(this instanceof BufferList)){return new BufferList(e)}BufferList._init.call(this,e)}BufferList._init=function _init(e){Object.defineProperty(this,i,{value:true});this._bufs=[];this.length=0;if(e){this.append(e)}};BufferList.prototype._new=function _new(e){return new BufferList(e)};BufferList.prototype._offset=function _offset(e){if(e===0){return[0,0]}let t=0;for(let r=0;rthis.length||e<0){return undefined}const t=this._offset(e);return this._bufs[t[0]][t[1]]};BufferList.prototype.slice=function slice(e,t){if(typeof e==="number"&&e<0){e+=this.length}if(typeof t==="number"&&t<0){t+=this.length}return this.copy(null,0,e,t)};BufferList.prototype.copy=function copy(e,t,r,i){if(typeof r!=="number"||r<0){r=0}if(typeof i!=="number"||i>this.length){i=this.length}if(r>=this.length){return e||n.alloc(0)}if(i<=0){return e||n.alloc(0)}const copy=!!e;const a=this._offset(r);const o=i-r;let s=o;let u=copy&&t||0;let l=a[1];if(r===0&&i===this.length){if(!copy){return this._bufs.length===1?this._bufs[0]:n.concat(this._bufs,this.length)}for(let t=0;tr){this._bufs[t].copy(e,u,l);u+=r}else{this._bufs[t].copy(e,u,l,l+s);u+=r;break}s-=r;if(l){l=0}}if(e.length>u)return e.slice(0,u);return e};BufferList.prototype.shallowSlice=function shallowSlice(e,t){e=e||0;t=typeof t!=="number"?this.length:t;if(e<0){e+=this.length}if(t<0){t+=this.length}if(e===t){return this._new()}const r=this._offset(e);const n=this._offset(t);const i=this._bufs.slice(r[0],n[0]+1);if(n[1]===0){i.pop()}else{i[i.length-1]=i[i.length-1].slice(0,n[1])}if(r[1]!==0){i[0]=i[0].slice(r[1])}return this._new(i)};BufferList.prototype.toString=function toString(e,t,r){return this.slice(t,r).toString(e)};BufferList.prototype.consume=function consume(e){e=Math.trunc(e);if(Number.isNaN(e)||e<=0)return this;while(this._bufs.length){if(e>=this._bufs[0].length){e-=this._bufs[0].length;this.length-=this._bufs[0].length;this._bufs.shift()}else{this._bufs[0]=this._bufs[0].slice(e);this.length-=e;break}}return this};BufferList.prototype.duplicate=function duplicate(){const e=this._new();for(let t=0;tthis.length?this.length:t}const i=this._offset(t);let a=i[0];let o=i[1];for(;a=e.length){const r=t.indexOf(e,o);if(r!==-1){return this._reverseOffset([a,r])}o=t.length-e.length+1}else{const t=this._reverseOffset([a,o]);if(this._match(t,e)){return t}o++}}o=0}return-1};BufferList.prototype._match=function(e,t){if(this.length-e{const n=r(1642).Duplex;const i=r(4124);const a=r(3664);function BufferListStream(e){if(!(this instanceof BufferListStream)){return new BufferListStream(e)}if(typeof e==="function"){this._callback=e;const t=function piper(e){if(this._callback){this._callback(e);this._callback=null}}.bind(this);this.on("pipe",(function onPipe(e){e.on("error",t)}));this.on("unpipe",(function onUnpipe(e){e.removeListener("error",t)}));e=null}a._init.call(this,e);n.call(this)}i(BufferListStream,n);Object.assign(BufferListStream.prototype,a.prototype);BufferListStream.prototype._new=function _new(e){return new BufferListStream(e)};BufferListStream.prototype._write=function _write(e,t,r){this._appendBuffer(e);if(typeof r==="function"){r()}};BufferListStream.prototype._read=function _read(e){if(!this.length){return this.push(null)}e=Math.min(e,this.length);this.push(this.slice(0,e));this.consume(e)};BufferListStream.prototype.end=function end(e){n.prototype.end.call(this,e);if(this._callback){this._callback(null,this.slice());this._callback=null}};BufferListStream.prototype._destroy=function _destroy(e,t){this._bufs.length=0;this.length=0;t(e)};BufferListStream.prototype._isBufferList=function _isBufferList(e){return e instanceof BufferListStream||e instanceof a||BufferListStream.isBufferList(e)};BufferListStream.isBufferList=a.isBufferList;e.exports=BufferListStream;e.exports.BufferListStream=BufferListStream;e.exports.BufferList=a},1205:(e,t,r)=>{var n=r(1223);var noop=function(){};var isRequest=function(e){return e.setHeader&&typeof e.abort==="function"};var isChildProcess=function(e){return e.stdio&&Array.isArray(e.stdio)&&e.stdio.length===3};var eos=function(e,t,r){if(typeof t==="function")return eos(e,null,t);if(!t)t={};r=n(r||noop);var i=e._writableState;var a=e._readableState;var o=t.readable||t.readable!==false&&e.readable;var s=t.writable||t.writable!==false&&e.writable;var u=false;var onlegacyfinish=function(){if(!e.writable)onfinish()};var onfinish=function(){s=false;if(!o)r.call(e)};var onend=function(){o=false;if(!s)r.call(e)};var onexit=function(t){r.call(e,t?new Error("exited with error code: "+t):null)};var onerror=function(t){r.call(e,t)};var onclose=function(){process.nextTick(onclosenexttick)};var onclosenexttick=function(){if(u)return;if(o&&!(a&&(a.ended&&!a.destroyed)))return r.call(e,new Error("premature close"));if(s&&!(i&&(i.ended&&!i.destroyed)))return r.call(e,new Error("premature close"))};var onrequest=function(){e.req.on("finish",onfinish)};if(isRequest(e)){e.on("complete",onfinish);e.on("abort",onclose);if(e.req)onrequest();else e.on("request",onrequest)}else if(s&&!i){e.on("end",onlegacyfinish);e.on("close",onlegacyfinish)}if(isChildProcess(e))e.on("exit",onexit);e.on("end",onend);e.on("finish",onfinish);if(t.error!==false)e.on("error",onerror);e.on("close",onclose);return function(){u=true;e.removeListener("complete",onfinish);e.removeListener("abort",onclose);e.removeListener("request",onrequest);if(e.req)e.req.removeListener("finish",onfinish);e.removeListener("end",onlegacyfinish);e.removeListener("close",onlegacyfinish);e.removeListener("finish",onfinish);e.removeListener("exit",onexit);e.removeListener("end",onend);e.removeListener("error",onerror);e.removeListener("close",onclose)}};e.exports=eos},3186:(e,t,r)=>{e.exports=r(7147).constants||r(2057)},4124:(e,t,r)=>{try{var n=r(3837);if(typeof n.inherits!=="function")throw"";e.exports=n.inherits}catch(t){e.exports=r(8544)}},8544:e=>{if(typeof Object.create==="function"){e.exports=function inherits(e,t){if(t){e.super_=t;e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:false,writable:true,configurable:true}})}}}else{e.exports=function inherits(e,t){if(t){e.super_=t;var TempCtor=function(){};TempCtor.prototype=t.prototype;e.prototype=new TempCtor;e.prototype.constructor=e}}}},1223:(e,t,r)=>{var n=r(2940);e.exports=n(once);e.exports.strict=n(onceStrict);once.proto=once((function(){Object.defineProperty(Function.prototype,"once",{value:function(){return once(this)},configurable:true});Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return onceStrict(this)},configurable:true})}));function once(e){var f=function(){if(f.called)return f.value;f.called=true;return f.value=e.apply(this,arguments)};f.called=false;return f}function onceStrict(e){var f=function(){if(f.called)throw new Error(f.onceError);f.called=true;return f.value=e.apply(this,arguments)};var t=e.name||"Function wrapped with `once`";f.onceError=t+" shouldn't be called more than once";f.called=false;return f}},7214:e=>{const t={};function createErrorType(e,r,n){if(!n){n=Error}function getMessage(e,t,n){if(typeof r==="string"){return r}else{return r(e,t,n)}}class NodeError extends n{constructor(e,t,r){super(getMessage(e,t,r))}}NodeError.prototype.name=n.name;NodeError.prototype.code=e;t[e]=NodeError}function oneOf(e,t){if(Array.isArray(e)){const r=e.length;e=e.map((e=>String(e)));if(r>2){return`one of ${t} ${e.slice(0,r-1).join(", ")}, or `+e[r-1]}else if(r===2){return`one of ${t} ${e[0]} or ${e[1]}`}else{return`of ${t} ${e[0]}`}}else{return`of ${t} ${String(e)}`}}function startsWith(e,t,r){return e.substr(!r||r<0?0:+r,t.length)===t}function endsWith(e,t,r){if(r===undefined||r>e.length){r=e.length}return e.substring(r-t.length,r)===t}function includes(e,t,r){if(typeof r!=="number"){r=0}if(r+t.length>e.length){return false}else{return e.indexOf(t,r)!==-1}}createErrorType("ERR_INVALID_OPT_VALUE",(function(e,t){return'The value "'+t+'" is invalid for option "'+e+'"'}),TypeError);createErrorType("ERR_INVALID_ARG_TYPE",(function(e,t,r){let n;if(typeof t==="string"&&startsWith(t,"not ")){n="must not be";t=t.replace(/^not /,"")}else{n="must be"}let i;if(endsWith(e," argument")){i=`The ${e} ${n} ${oneOf(t,"type")}`}else{const r=includes(e,".")?"property":"argument";i=`The "${e}" ${r} ${n} ${oneOf(t,"type")}`}i+=`. Received type ${typeof r}`;return i}),TypeError);createErrorType("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF");createErrorType("ERR_METHOD_NOT_IMPLEMENTED",(function(e){return"The "+e+" method is not implemented"}));createErrorType("ERR_STREAM_PREMATURE_CLOSE","Premature close");createErrorType("ERR_STREAM_DESTROYED",(function(e){return"Cannot call "+e+" after a stream was destroyed"}));createErrorType("ERR_MULTIPLE_CALLBACK","Callback called multiple times");createErrorType("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable");createErrorType("ERR_STREAM_WRITE_AFTER_END","write after end");createErrorType("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError);createErrorType("ERR_UNKNOWN_ENCODING",(function(e){return"Unknown encoding: "+e}),TypeError);createErrorType("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event");e.exports.q=t},1359:(e,t,r)=>{var n=Object.keys||function(e){var t=[];for(var r in e){t.push(r)}return t};e.exports=Duplex;var i=r(1433);var a=r(6993);r(4124)(Duplex,i);{var o=n(a.prototype);for(var s=0;s{e.exports=PassThrough;var n=r(4415);r(4124)(PassThrough,n);function PassThrough(e){if(!(this instanceof PassThrough))return new PassThrough(e);n.call(this,e)}PassThrough.prototype._transform=function(e,t,r){r(null,e)}},1433:(e,t,r)=>{e.exports=Readable;var n;Readable.ReadableState=ReadableState;var i=r(2361).EventEmitter;var a=function EElistenerCount(e,t){return e.listeners(t).length};var o=r(2387);var s=r(4300).Buffer;var u=global.Uint8Array||function(){};function _uint8ArrayToBuffer(e){return s.from(e)}function _isUint8Array(e){return s.isBuffer(e)||e instanceof u}var l=r(3837);var c;if(l&&l.debuglog){c=l.debuglog("stream")}else{c=function debug(){}}var d=r(2746);var h=r(7049);var p=r(9948),g=p.getHighWaterMark;var m=r(7214).q,b=m.ERR_INVALID_ARG_TYPE,v=m.ERR_STREAM_PUSH_AFTER_EOF,_=m.ERR_METHOD_NOT_IMPLEMENTED,y=m.ERR_STREAM_UNSHIFT_AFTER_END_EVENT;var w;var R;var S;r(4124)(Readable,o);var E=h.errorOrDestroy;var O=["error","close","destroy","pause","resume"];function prependListener(e,t,r){if(typeof e.prependListener==="function")return e.prependListener(t,r);if(!e._events||!e._events[t])e.on(t,r);else if(Array.isArray(e._events[t]))e._events[t].unshift(r);else e._events[t]=[r,e._events[t]]}function ReadableState(e,t,i){n=n||r(1359);e=e||{};if(typeof i!=="boolean")i=t instanceof n;this.objectMode=!!e.objectMode;if(i)this.objectMode=this.objectMode||!!e.readableObjectMode;this.highWaterMark=g(this,e,"readableHighWaterMark",i);this.buffer=new d;this.length=0;this.pipes=null;this.pipesCount=0;this.flowing=null;this.ended=false;this.endEmitted=false;this.reading=false;this.sync=true;this.needReadable=false;this.emittedReadable=false;this.readableListening=false;this.resumeScheduled=false;this.paused=true;this.emitClose=e.emitClose!==false;this.autoDestroy=!!e.autoDestroy;this.destroyed=false;this.defaultEncoding=e.defaultEncoding||"utf8";this.awaitDrain=0;this.readingMore=false;this.decoder=null;this.encoding=null;if(e.encoding){if(!w)w=r(4841).s;this.decoder=new w(e.encoding);this.encoding=e.encoding}}function Readable(e){n=n||r(1359);if(!(this instanceof Readable))return new Readable(e);var t=this instanceof n;this._readableState=new ReadableState(e,this,t);this.readable=true;if(e){if(typeof e.read==="function")this._read=e.read;if(typeof e.destroy==="function")this._destroy=e.destroy}o.call(this)}Object.defineProperty(Readable.prototype,"destroyed",{enumerable:false,get:function get(){if(this._readableState===undefined){return false}return this._readableState.destroyed},set:function set(e){if(!this._readableState){return}this._readableState.destroyed=e}});Readable.prototype.destroy=h.destroy;Readable.prototype._undestroy=h.undestroy;Readable.prototype._destroy=function(e,t){t(e)};Readable.prototype.push=function(e,t){var r=this._readableState;var n;if(!r.objectMode){if(typeof e==="string"){t=t||r.defaultEncoding;if(t!==r.encoding){e=s.from(e,t);t=""}n=true}}else{n=true}return readableAddChunk(this,e,t,false,n)};Readable.prototype.unshift=function(e){return readableAddChunk(this,e,null,true,false)};function readableAddChunk(e,t,r,n,i){c("readableAddChunk",t);var a=e._readableState;if(t===null){a.reading=false;onEofChunk(e,a)}else{var o;if(!i)o=chunkInvalid(a,t);if(o){E(e,o)}else if(a.objectMode||t&&t.length>0){if(typeof t!=="string"&&!a.objectMode&&Object.getPrototypeOf(t)!==s.prototype){t=_uint8ArrayToBuffer(t)}if(n){if(a.endEmitted)E(e,new y);else addChunk(e,a,t,true)}else if(a.ended){E(e,new v)}else if(a.destroyed){return false}else{a.reading=false;if(a.decoder&&!r){t=a.decoder.write(t);if(a.objectMode||t.length!==0)addChunk(e,a,t,false);else maybeReadMore(e,a)}else{addChunk(e,a,t,false)}}}else if(!n){a.reading=false;maybeReadMore(e,a)}}return!a.ended&&(a.length=k){e=k}else{e--;e|=e>>>1;e|=e>>>2;e|=e>>>4;e|=e>>>8;e|=e>>>16;e++}return e}function howMuchToRead(e,t){if(e<=0||t.length===0&&t.ended)return 0;if(t.objectMode)return 1;if(e!==e){if(t.flowing&&t.length)return t.buffer.head.data.length;else return t.length}if(e>t.highWaterMark)t.highWaterMark=computeNewHighWaterMark(e);if(e<=t.length)return e;if(!t.ended){t.needReadable=true;return 0}return t.length}Readable.prototype.read=function(e){c("read",e);e=parseInt(e,10);var t=this._readableState;var r=e;if(e!==0)t.emittedReadable=false;if(e===0&&t.needReadable&&((t.highWaterMark!==0?t.length>=t.highWaterMark:t.length>0)||t.ended)){c("read: emitReadable",t.length,t.ended);if(t.length===0&&t.ended)endReadable(this);else emitReadable(this);return null}e=howMuchToRead(e,t);if(e===0&&t.ended){if(t.length===0)endReadable(this);return null}var n=t.needReadable;c("need readable",n);if(t.length===0||t.length-e0)i=fromList(e,t);else i=null;if(i===null){t.needReadable=t.length<=t.highWaterMark;e=0}else{t.length-=e;t.awaitDrain=0}if(t.length===0){if(!t.ended)t.needReadable=true;if(r!==e&&t.ended)endReadable(this)}if(i!==null)this.emit("data",i);return i};function onEofChunk(e,t){c("onEofChunk");if(t.ended)return;if(t.decoder){var r=t.decoder.end();if(r&&r.length){t.buffer.push(r);t.length+=t.objectMode?1:r.length}}t.ended=true;if(t.sync){emitReadable(e)}else{t.needReadable=false;if(!t.emittedReadable){t.emittedReadable=true;emitReadable_(e)}}}function emitReadable(e){var t=e._readableState;c("emitReadable",t.needReadable,t.emittedReadable);t.needReadable=false;if(!t.emittedReadable){c("emitReadable",t.flowing);t.emittedReadable=true;process.nextTick(emitReadable_,e)}}function emitReadable_(e){var t=e._readableState;c("emitReadable_",t.destroyed,t.length,t.ended);if(!t.destroyed&&(t.length||t.ended)){e.emit("readable");t.emittedReadable=false}t.needReadable=!t.flowing&&!t.ended&&t.length<=t.highWaterMark;flow(e)}function maybeReadMore(e,t){if(!t.readingMore){t.readingMore=true;process.nextTick(maybeReadMore_,e,t)}}function maybeReadMore_(e,t){while(!t.reading&&!t.ended&&(t.length1&&indexOf(n.pipes,e)!==-1)&&!u){c("false write response, pause",n.awaitDrain);n.awaitDrain++}r.pause()}}function onerror(t){c("onerror",t);unpipe();e.removeListener("error",onerror);if(a(e,"error")===0)E(e,t)}prependListener(e,"error",onerror);function onclose(){e.removeListener("finish",onfinish);unpipe()}e.once("close",onclose);function onfinish(){c("onfinish");e.removeListener("close",onclose);unpipe()}e.once("finish",onfinish);function unpipe(){c("unpipe");r.unpipe(e)}e.emit("pipe",r);if(!n.flowing){c("pipe resume");r.resume()}return e};function pipeOnDrain(e){return function pipeOnDrainFunctionResult(){var t=e._readableState;c("pipeOnDrain",t.awaitDrain);if(t.awaitDrain)t.awaitDrain--;if(t.awaitDrain===0&&a(e,"data")){t.flowing=true;flow(e)}}}Readable.prototype.unpipe=function(e){var t=this._readableState;var r={hasUnpiped:false};if(t.pipesCount===0)return this;if(t.pipesCount===1){if(e&&e!==t.pipes)return this;if(!e)e=t.pipes;t.pipes=null;t.pipesCount=0;t.flowing=false;if(e)e.emit("unpipe",this,r);return this}if(!e){var n=t.pipes;var i=t.pipesCount;t.pipes=null;t.pipesCount=0;t.flowing=false;for(var a=0;a0;if(n.flowing!==false)this.resume()}else if(e==="readable"){if(!n.endEmitted&&!n.readableListening){n.readableListening=n.needReadable=true;n.flowing=false;n.emittedReadable=false;c("on readable",n.length,n.reading);if(n.length){emitReadable(this)}else if(!n.reading){process.nextTick(nReadingNextTick,this)}}}return r};Readable.prototype.addListener=Readable.prototype.on;Readable.prototype.removeListener=function(e,t){var r=o.prototype.removeListener.call(this,e,t);if(e==="readable"){process.nextTick(updateReadableListening,this)}return r};Readable.prototype.removeAllListeners=function(e){var t=o.prototype.removeAllListeners.apply(this,arguments);if(e==="readable"||e===undefined){process.nextTick(updateReadableListening,this)}return t};function updateReadableListening(e){var t=e._readableState;t.readableListening=e.listenerCount("readable")>0;if(t.resumeScheduled&&!t.paused){t.flowing=true}else if(e.listenerCount("data")>0){e.resume()}}function nReadingNextTick(e){c("readable nexttick read 0");e.read(0)}Readable.prototype.resume=function(){var e=this._readableState;if(!e.flowing){c("resume");e.flowing=!e.readableListening;resume(this,e)}e.paused=false;return this};function resume(e,t){if(!t.resumeScheduled){t.resumeScheduled=true;process.nextTick(resume_,e,t)}}function resume_(e,t){c("resume",t.reading);if(!t.reading){e.read(0)}t.resumeScheduled=false;e.emit("resume");flow(e);if(t.flowing&&!t.reading)e.read(0)}Readable.prototype.pause=function(){c("call pause flowing=%j",this._readableState.flowing);if(this._readableState.flowing!==false){c("pause");this._readableState.flowing=false;this.emit("pause")}this._readableState.paused=true;return this};function flow(e){var t=e._readableState;c("flow",t.flowing);while(t.flowing&&e.read()!==null){}}Readable.prototype.wrap=function(e){var t=this;var r=this._readableState;var n=false;e.on("end",(function(){c("wrapped end");if(r.decoder&&!r.ended){var e=r.decoder.end();if(e&&e.length)t.push(e)}t.push(null)}));e.on("data",(function(i){c("wrapped data");if(r.decoder)i=r.decoder.write(i);if(r.objectMode&&(i===null||i===undefined))return;else if(!r.objectMode&&(!i||!i.length))return;var a=t.push(i);if(!a){n=true;e.pause()}}));for(var i in e){if(this[i]===undefined&&typeof e[i]==="function"){this[i]=function methodWrap(t){return function methodWrapReturnFunction(){return e[t].apply(e,arguments)}}(i)}}for(var a=0;a=t.length){if(t.decoder)r=t.buffer.join("");else if(t.buffer.length===1)r=t.buffer.first();else r=t.buffer.concat(t.length);t.buffer.clear()}else{r=t.buffer.consume(e,t.decoder)}return r}function endReadable(e){var t=e._readableState;c("endReadable",t.endEmitted);if(!t.endEmitted){t.ended=true;process.nextTick(endReadableNT,t,e)}}function endReadableNT(e,t){c("endReadableNT",e.endEmitted,e.length);if(!e.endEmitted&&e.length===0){e.endEmitted=true;t.readable=false;t.emit("end");if(e.autoDestroy){var r=t._writableState;if(!r||r.autoDestroy&&r.finished){t.destroy()}}}}if(typeof Symbol==="function"){Readable.from=function(e,t){if(S===undefined){S=r(9082)}return S(Readable,e,t)}}function indexOf(e,t){for(var r=0,n=e.length;r{e.exports=Transform;var n=r(7214).q,i=n.ERR_METHOD_NOT_IMPLEMENTED,a=n.ERR_MULTIPLE_CALLBACK,o=n.ERR_TRANSFORM_ALREADY_TRANSFORMING,s=n.ERR_TRANSFORM_WITH_LENGTH_0;var u=r(1359);r(4124)(Transform,u);function afterTransform(e,t){var r=this._transformState;r.transforming=false;var n=r.writecb;if(n===null){return this.emit("error",new a)}r.writechunk=null;r.writecb=null;if(t!=null)this.push(t);n(e);var i=this._readableState;i.reading=false;if(i.needReadable||i.length{e.exports=Writable;function WriteReq(e,t,r){this.chunk=e;this.encoding=t;this.callback=r;this.next=null}function CorkedRequest(e){var t=this;this.next=null;this.entry=null;this.finish=function(){onCorkedFinish(t,e)}}var n;Writable.WritableState=WritableState;var i={deprecate:r(5278)};var a=r(2387);var o=r(4300).Buffer;var s=global.Uint8Array||function(){};function _uint8ArrayToBuffer(e){return o.from(e)}function _isUint8Array(e){return o.isBuffer(e)||e instanceof s}var u=r(7049);var l=r(9948),c=l.getHighWaterMark;var d=r(7214).q,h=d.ERR_INVALID_ARG_TYPE,p=d.ERR_METHOD_NOT_IMPLEMENTED,g=d.ERR_MULTIPLE_CALLBACK,m=d.ERR_STREAM_CANNOT_PIPE,b=d.ERR_STREAM_DESTROYED,v=d.ERR_STREAM_NULL_VALUES,_=d.ERR_STREAM_WRITE_AFTER_END,y=d.ERR_UNKNOWN_ENCODING;var w=u.errorOrDestroy;r(4124)(Writable,a);function nop(){}function WritableState(e,t,i){n=n||r(1359);e=e||{};if(typeof i!=="boolean")i=t instanceof n;this.objectMode=!!e.objectMode;if(i)this.objectMode=this.objectMode||!!e.writableObjectMode;this.highWaterMark=c(this,e,"writableHighWaterMark",i);this.finalCalled=false;this.needDrain=false;this.ending=false;this.ended=false;this.finished=false;this.destroyed=false;var a=e.decodeStrings===false;this.decodeStrings=!a;this.defaultEncoding=e.defaultEncoding||"utf8";this.length=0;this.writing=false;this.corked=0;this.sync=true;this.bufferProcessing=false;this.onwrite=function(e){onwrite(t,e)};this.writecb=null;this.writelen=0;this.bufferedRequest=null;this.lastBufferedRequest=null;this.pendingcb=0;this.prefinished=false;this.errorEmitted=false;this.emitClose=e.emitClose!==false;this.autoDestroy=!!e.autoDestroy;this.bufferedRequestCount=0;this.corkedRequestsFree=new CorkedRequest(this)}WritableState.prototype.getBuffer=function getBuffer(){var e=this.bufferedRequest;var t=[];while(e){t.push(e);e=e.next}return t};(function(){try{Object.defineProperty(WritableState.prototype,"buffer",{get:i.deprecate((function writableStateBufferGetter(){return this.getBuffer()}),"_writableState.buffer is deprecated. Use _writableState.getBuffer "+"instead.","DEP0003")})}catch(e){}})();var R;if(typeof Symbol==="function"&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]==="function"){R=Function.prototype[Symbol.hasInstance];Object.defineProperty(Writable,Symbol.hasInstance,{value:function value(e){if(R.call(this,e))return true;if(this!==Writable)return false;return e&&e._writableState instanceof WritableState}})}else{R=function realHasInstance(e){return e instanceof this}}function Writable(e){n=n||r(1359);var t=this instanceof n;if(!t&&!R.call(Writable,this))return new Writable(e);this._writableState=new WritableState(e,this,t);this.writable=true;if(e){if(typeof e.write==="function")this._write=e.write;if(typeof e.writev==="function")this._writev=e.writev;if(typeof e.destroy==="function")this._destroy=e.destroy;if(typeof e.final==="function")this._final=e.final}a.call(this)}Writable.prototype.pipe=function(){w(this,new m)};function writeAfterEnd(e,t){var r=new _;w(e,r);process.nextTick(t,r)}function validChunk(e,t,r,n){var i;if(r===null){i=new v}else if(typeof r!=="string"&&!t.objectMode){i=new h("chunk",["string","Buffer"],r)}if(i){w(e,i);process.nextTick(n,i);return false}return true}Writable.prototype.write=function(e,t,r){var n=this._writableState;var i=false;var a=!n.objectMode&&_isUint8Array(e);if(a&&!o.isBuffer(e)){e=_uint8ArrayToBuffer(e)}if(typeof t==="function"){r=t;t=null}if(a)t="buffer";else if(!t)t=n.defaultEncoding;if(typeof r!=="function")r=nop;if(n.ending)writeAfterEnd(this,r);else if(a||validChunk(this,n,e,r)){n.pendingcb++;i=writeOrBuffer(this,n,a,e,t,r)}return i};Writable.prototype.cork=function(){this._writableState.corked++};Writable.prototype.uncork=function(){var e=this._writableState;if(e.corked){e.corked--;if(!e.writing&&!e.corked&&!e.bufferProcessing&&e.bufferedRequest)clearBuffer(this,e)}};Writable.prototype.setDefaultEncoding=function setDefaultEncoding(e){if(typeof e==="string")e=e.toLowerCase();if(!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new y(e);this._writableState.defaultEncoding=e;return this};Object.defineProperty(Writable.prototype,"writableBuffer",{enumerable:false,get:function get(){return this._writableState&&this._writableState.getBuffer()}});function decodeChunk(e,t,r){if(!e.objectMode&&e.decodeStrings!==false&&typeof t==="string"){t=o.from(t,r)}return t}Object.defineProperty(Writable.prototype,"writableHighWaterMark",{enumerable:false,get:function get(){return this._writableState.highWaterMark}});function writeOrBuffer(e,t,r,n,i,a){if(!r){var o=decodeChunk(t,n,i);if(n!==o){r=true;i="buffer";n=o}}var s=t.objectMode?1:n.length;t.length+=s;var u=t.length{var n;function _defineProperty(e,t,r){if(t in e){Object.defineProperty(e,t,{value:r,enumerable:true,configurable:true,writable:true})}else{e[t]=r}return e}var i=r(6080);var a=Symbol("lastResolve");var o=Symbol("lastReject");var s=Symbol("error");var u=Symbol("ended");var l=Symbol("lastPromise");var c=Symbol("handlePromise");var d=Symbol("stream");function createIterResult(e,t){return{value:e,done:t}}function readAndResolve(e){var t=e[a];if(t!==null){var r=e[d].read();if(r!==null){e[l]=null;e[a]=null;e[o]=null;t(createIterResult(r,false))}}}function onReadable(e){process.nextTick(readAndResolve,e)}function wrapForNext(e,t){return function(r,n){e.then((function(){if(t[u]){r(createIterResult(undefined,true));return}t[c](r,n)}),n)}}var h=Object.getPrototypeOf((function(){}));var p=Object.setPrototypeOf((n={get stream(){return this[d]},next:function next(){var e=this;var t=this[s];if(t!==null){return Promise.reject(t)}if(this[u]){return Promise.resolve(createIterResult(undefined,true))}if(this[d].destroyed){return new Promise((function(t,r){process.nextTick((function(){if(e[s]){r(e[s])}else{t(createIterResult(undefined,true))}}))}))}var r=this[l];var n;if(r){n=new Promise(wrapForNext(r,this))}else{var i=this[d].read();if(i!==null){return Promise.resolve(createIterResult(i,false))}n=new Promise(this[c])}this[l]=n;return n}},_defineProperty(n,Symbol.asyncIterator,(function(){return this})),_defineProperty(n,"return",(function _return(){var e=this;return new Promise((function(t,r){e[d].destroy(null,(function(e){if(e){r(e);return}t(createIterResult(undefined,true))}))}))})),n),h);var g=function createReadableStreamAsyncIterator(e){var t;var r=Object.create(p,(t={},_defineProperty(t,d,{value:e,writable:true}),_defineProperty(t,a,{value:null,writable:true}),_defineProperty(t,o,{value:null,writable:true}),_defineProperty(t,s,{value:null,writable:true}),_defineProperty(t,u,{value:e._readableState.endEmitted,writable:true}),_defineProperty(t,c,{value:function value(e,t){var n=r[d].read();if(n){r[l]=null;r[a]=null;r[o]=null;e(createIterResult(n,false))}else{r[a]=e;r[o]=t}},writable:true}),t));r[l]=null;i(e,(function(e){if(e&&e.code!=="ERR_STREAM_PREMATURE_CLOSE"){var t=r[o];if(t!==null){r[l]=null;r[a]=null;r[o]=null;t(e)}r[s]=e;return}var n=r[a];if(n!==null){r[l]=null;r[a]=null;r[o]=null;n(createIterResult(undefined,true))}r[u]=true}));e.on("readable",onReadable.bind(null,r));return r};e.exports=g},2746:(e,t,r)=>{function ownKeys(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);if(t)n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}));r.push.apply(r,n)}return r}function _objectSpread(e){for(var t=1;t0)this.tail.next=t;else this.head=t;this.tail=t;++this.length}},{key:"unshift",value:function unshift(e){var t={data:e,next:this.head};if(this.length===0)this.tail=t;this.head=t;++this.length}},{key:"shift",value:function shift(){if(this.length===0)return;var e=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;--this.length;return e}},{key:"clear",value:function clear(){this.head=this.tail=null;this.length=0}},{key:"join",value:function join(e){if(this.length===0)return"";var t=this.head;var r=""+t.data;while(t=t.next){r+=e+t.data}return r}},{key:"concat",value:function concat(e){if(this.length===0)return i.alloc(0);var t=i.allocUnsafe(e>>>0);var r=this.head;var n=0;while(r){copyBuffer(r.data,t,n);n+=r.data.length;r=r.next}return t}},{key:"consume",value:function consume(e,t){var r;if(ei.length?i.length:e;if(a===i.length)n+=i;else n+=i.slice(0,e);e-=a;if(e===0){if(a===i.length){++r;if(t.next)this.head=t.next;else this.head=this.tail=null}else{this.head=t;t.data=i.slice(a)}break}++r}this.length-=r;return n}},{key:"_getBuffer",value:function _getBuffer(e){var t=i.allocUnsafe(e);var r=this.head;var n=1;r.data.copy(t);e-=r.data.length;while(r=r.next){var a=r.data;var o=e>a.length?a.length:e;a.copy(t,t.length-e,0,o);e-=o;if(e===0){if(o===a.length){++n;if(r.next)this.head=r.next;else this.head=this.tail=null}else{this.head=r;r.data=a.slice(o)}break}++n}this.length-=n;return t}},{key:s,value:function value(e,t){return o(this,_objectSpread({},t,{depth:0,customInspect:false}))}}]);return BufferList}()},7049:e=>{function destroy(e,t){var r=this;var n=this._readableState&&this._readableState.destroyed;var i=this._writableState&&this._writableState.destroyed;if(n||i){if(t){t(e)}else if(e){if(!this._writableState){process.nextTick(emitErrorNT,this,e)}else if(!this._writableState.errorEmitted){this._writableState.errorEmitted=true;process.nextTick(emitErrorNT,this,e)}}return this}if(this._readableState){this._readableState.destroyed=true}if(this._writableState){this._writableState.destroyed=true}this._destroy(e||null,(function(e){if(!t&&e){if(!r._writableState){process.nextTick(emitErrorAndCloseNT,r,e)}else if(!r._writableState.errorEmitted){r._writableState.errorEmitted=true;process.nextTick(emitErrorAndCloseNT,r,e)}else{process.nextTick(emitCloseNT,r)}}else if(t){process.nextTick(emitCloseNT,r);t(e)}else{process.nextTick(emitCloseNT,r)}}));return this}function emitErrorAndCloseNT(e,t){emitErrorNT(e,t);emitCloseNT(e)}function emitCloseNT(e){if(e._writableState&&!e._writableState.emitClose)return;if(e._readableState&&!e._readableState.emitClose)return;e.emit("close")}function undestroy(){if(this._readableState){this._readableState.destroyed=false;this._readableState.reading=false;this._readableState.ended=false;this._readableState.endEmitted=false}if(this._writableState){this._writableState.destroyed=false;this._writableState.ended=false;this._writableState.ending=false;this._writableState.finalCalled=false;this._writableState.prefinished=false;this._writableState.finished=false;this._writableState.errorEmitted=false}}function emitErrorNT(e,t){e.emit("error",t)}function errorOrDestroy(e,t){var r=e._readableState;var n=e._writableState;if(r&&r.autoDestroy||n&&n.autoDestroy)e.destroy(t);else e.emit("error",t)}e.exports={destroy:destroy,undestroy:undestroy,errorOrDestroy:errorOrDestroy}},6080:(e,t,r)=>{var n=r(7214).q.ERR_STREAM_PREMATURE_CLOSE;function once(e){var t=false;return function(){if(t)return;t=true;for(var r=arguments.length,n=new Array(r),i=0;i{function asyncGeneratorStep(e,t,r,n,i,a,o){try{var s=e[a](o);var u=s.value}catch(e){r(e);return}if(s.done){t(u)}else{Promise.resolve(u).then(n,i)}}function _asyncToGenerator(e){return function(){var t=this,r=arguments;return new Promise((function(n,i){var a=e.apply(t,r);function _next(e){asyncGeneratorStep(a,n,i,_next,_throw,"next",e)}function _throw(e){asyncGeneratorStep(a,n,i,_next,_throw,"throw",e)}_next(undefined)}))}}function ownKeys(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);if(t)n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}));r.push.apply(r,n)}return r}function _objectSpread(e){for(var t=1;t{var n;function once(e){var t=false;return function(){if(t)return;t=true;e.apply(void 0,arguments)}}var i=r(7214).q,a=i.ERR_MISSING_ARGS,o=i.ERR_STREAM_DESTROYED;function noop(e){if(e)throw e}function isRequest(e){return e.setHeader&&typeof e.abort==="function"}function destroyer(e,t,i,a){a=once(a);var s=false;e.on("close",(function(){s=true}));if(n===undefined)n=r(6080);n(e,{readable:t,writable:i},(function(e){if(e)return a(e);s=true;a()}));var u=false;return function(t){if(s)return;if(u)return;u=true;if(isRequest(e))return e.abort();if(typeof e.destroy==="function")return e.destroy();a(t||new o("pipe"))}}function call(e){e()}function pipe(e,t){return e.pipe(t)}function popCallback(e){if(!e.length)return noop;if(typeof e[e.length-1]!=="function")return noop;return e.pop()}function pipeline(){for(var e=arguments.length,t=new Array(e),r=0;r0;return destroyer(e,a,s,(function(e){if(!i)i=e;if(e)o.forEach(call);if(a)return;o.forEach(call);n(i)}))}));return t.reduce(pipe)}e.exports=pipeline},9948:(e,t,r)=>{var n=r(7214).q.ERR_INVALID_OPT_VALUE;function highWaterMarkFrom(e,t,r){return e.highWaterMark!=null?e.highWaterMark:t?e[r]:null}function getHighWaterMark(e,t,r,i){var a=highWaterMarkFrom(t,i,r);if(a!=null){if(!(isFinite(a)&&Math.floor(a)===a)||a<0){var o=i?r:"highWaterMark";throw new n(o,a)}return Math.floor(a)}return e.objectMode?16:16*1024}e.exports={getHighWaterMark:getHighWaterMark}},2387:(e,t,r)=>{e.exports=r(2781)},1642:(e,t,r)=>{var n=r(2781);if(process.env.READABLE_STREAM==="disable"&&n){e.exports=n.Readable;Object.assign(e.exports,n);e.exports.Stream=n}else{t=e.exports=r(1433);t.Stream=n||t;t.Readable=t;t.Writable=r(6993);t.Duplex=r(1359);t.Transform=r(4415);t.PassThrough=r(1542);t.finished=r(6080);t.pipeline=r(6989)}},1867:(e,t,r)=>{ /*! safe-buffer. MIT License. Feross Aboukhadijeh */ -var n=r(4300);var i=n.Buffer;function copyProps(e,t){for(var r in e){t[r]=e[r]}}if(i.from&&i.alloc&&i.allocUnsafe&&i.allocUnsafeSlow){e.exports=n}else{copyProps(n,t);t.Buffer=SafeBuffer}function SafeBuffer(e,t,r){return i(e,t,r)}SafeBuffer.prototype=Object.create(i.prototype);copyProps(i,SafeBuffer);SafeBuffer.from=function(e,t,r){if(typeof e==="number"){throw new TypeError("Argument must not be a number")}return i(e,t,r)};SafeBuffer.alloc=function(e,t,r){if(typeof e!=="number"){throw new TypeError("Argument must be a number")}var n=i(e);if(t!==undefined){if(typeof r==="string"){n.fill(t,r)}else{n.fill(t)}}else{n.fill(0)}return n};SafeBuffer.allocUnsafe=function(e){if(typeof e!=="number"){throw new TypeError("Argument must be a number")}return i(e)};SafeBuffer.allocUnsafeSlow=function(e){if(typeof e!=="number"){throw new TypeError("Argument must be a number")}return n.SlowBuffer(e)}},4841:(e,t,r)=>{var n=r(1867).Buffer;var i=n.isEncoding||function(e){e=""+e;switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return true;default:return false}};function _normalizeEncoding(e){if(!e)return"utf8";var t;while(true){switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase();t=true}}}function normalizeEncoding(e){var t=_normalizeEncoding(e);if(typeof t!=="string"&&(n.isEncoding===i||!i(e)))throw new Error("Unknown encoding: "+e);return t||e}t.s=StringDecoder;function StringDecoder(e){this.encoding=normalizeEncoding(e);var t;switch(this.encoding){case"utf16le":this.text=utf16Text;this.end=utf16End;t=4;break;case"utf8":this.fillLast=utf8FillLast;t=4;break;case"base64":this.text=base64Text;this.end=base64End;t=3;break;default:this.write=simpleWrite;this.end=simpleEnd;return}this.lastNeed=0;this.lastTotal=0;this.lastChar=n.allocUnsafe(t)}StringDecoder.prototype.write=function(e){if(e.length===0)return"";var t;var r;if(this.lastNeed){t=this.fillLast(e);if(t===undefined)return"";r=this.lastNeed;this.lastNeed=0}else{r=0}if(r>5===6)return 2;else if(e>>4===14)return 3;else if(e>>3===30)return 4;return e>>6===2?-1:-2}function utf8CheckIncomplete(e,t,r){var n=t.length-1;if(n=0){if(i>0)e.lastNeed=i-1;return i}if(--n=0){if(i>0)e.lastNeed=i-2;return i}if(--n=0){if(i>0){if(i===2)i=0;else e.lastNeed=i-3}return i}return 0}function utf8CheckExtraBytes(e,t,r){if((t[0]&192)!==128){e.lastNeed=0;return"�"}if(e.lastNeed>1&&t.length>1){if((t[1]&192)!==128){e.lastNeed=1;return"�"}if(e.lastNeed>2&&t.length>2){if((t[2]&192)!==128){e.lastNeed=2;return"�"}}}}function utf8FillLast(e){var t=this.lastTotal-this.lastNeed;var r=utf8CheckExtraBytes(this,e,t);if(r!==undefined)return r;if(this.lastNeed<=e.length){e.copy(this.lastChar,t,0,this.lastNeed);return this.lastChar.toString(this.encoding,0,this.lastTotal)}e.copy(this.lastChar,t,0,e.length);this.lastNeed-=e.length}function utf8Text(e,t){var r=utf8CheckIncomplete(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=r;var n=e.length-(r-this.lastNeed);e.copy(this.lastChar,0,n);return e.toString("utf8",t,n)}function utf8End(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed)return t+"�";return t}function utf16Text(e,t){if((e.length-t)%2===0){var r=e.toString("utf16le",t);if(r){var n=r.charCodeAt(r.length-1);if(n>=55296&&n<=56319){this.lastNeed=2;this.lastTotal=4;this.lastChar[0]=e[e.length-2];this.lastChar[1]=e[e.length-1];return r.slice(0,-1)}}return r}this.lastNeed=1;this.lastTotal=2;this.lastChar[0]=e[e.length-1];return e.toString("utf16le",t,e.length-1)}function utf16End(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var r=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,r)}return t}function base64Text(e,t){var r=(e.length-t)%3;if(r===0)return e.toString("base64",t);this.lastNeed=3-r;this.lastTotal=3;if(r===1){this.lastChar[0]=e[e.length-1]}else{this.lastChar[0]=e[e.length-2];this.lastChar[1]=e[e.length-1]}return e.toString("base64",t,e.length-r)}function base64End(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed)return t+this.lastChar.toString("base64",0,3-this.lastNeed);return t}function simpleWrite(e){return e.toString(this.encoding)}function simpleEnd(e){return e&&e.length?this.write(e):""}},7882:(e,t,r)=>{var n=r(3837);var i=r(336);var a=r(8860);var o=r(1642).Writable;var s=r(1642).PassThrough;var noop=function(){};var overflow=function(e){e&=511;return e&&512-e};var emptyStream=function(e,t){var r=new Source(e,t);r.end();return r};var mixinPax=function(e,t){if(t.path)e.name=t.path;if(t.linkpath)e.linkname=t.linkpath;if(t.size)e.size=parseInt(t.size,10);e.pax=t;return e};var Source=function(e,t){this._parent=e;this.offset=t;s.call(this,{autoDestroy:false})};n.inherits(Source,s);Source.prototype.destroy=function(e){this._parent.destroy(e)};var Extract=function(e){if(!(this instanceof Extract))return new Extract(e);o.call(this,e);e=e||{};this._offset=0;this._buffer=i();this._missing=0;this._partial=false;this._onparse=noop;this._header=null;this._stream=null;this._overflow=null;this._cb=null;this._locked=false;this._destroyed=false;this._pax=null;this._paxGlobal=null;this._gnuLongPath=null;this._gnuLongLinkPath=null;var t=this;var r=t._buffer;var oncontinue=function(){t._continue()};var onunlock=function(e){t._locked=false;if(e)return t.destroy(e);if(!t._stream)oncontinue()};var onstreamend=function(){t._stream=null;var e=overflow(t._header.size);if(e)t._parse(e,ondrain);else t._parse(512,onheader);if(!t._locked)oncontinue()};var ondrain=function(){t._buffer.consume(overflow(t._header.size));t._parse(512,onheader);oncontinue()};var onpaxglobalheader=function(){var e=t._header.size;t._paxGlobal=a.decodePax(r.slice(0,e));r.consume(e);onstreamend()};var onpaxheader=function(){var e=t._header.size;t._pax=a.decodePax(r.slice(0,e));if(t._paxGlobal)t._pax=Object.assign({},t._paxGlobal,t._pax);r.consume(e);onstreamend()};var ongnulongpath=function(){var n=t._header.size;this._gnuLongPath=a.decodeLongPath(r.slice(0,n),e.filenameEncoding);r.consume(n);onstreamend()};var ongnulonglinkpath=function(){var n=t._header.size;this._gnuLongLinkPath=a.decodeLongPath(r.slice(0,n),e.filenameEncoding);r.consume(n);onstreamend()};var onheader=function(){var n=t._offset;var i;try{i=t._header=a.decode(r.slice(0,512),e.filenameEncoding,e.allowUnknownFormat)}catch(e){t.emit("error",e)}r.consume(512);if(!i){t._parse(512,onheader);oncontinue();return}if(i.type==="gnu-long-path"){t._parse(i.size,ongnulongpath);oncontinue();return}if(i.type==="gnu-long-link-path"){t._parse(i.size,ongnulonglinkpath);oncontinue();return}if(i.type==="pax-global-header"){t._parse(i.size,onpaxglobalheader);oncontinue();return}if(i.type==="pax-header"){t._parse(i.size,onpaxheader);oncontinue();return}if(t._gnuLongPath){i.name=t._gnuLongPath;t._gnuLongPath=null}if(t._gnuLongLinkPath){i.linkname=t._gnuLongLinkPath;t._gnuLongLinkPath=null}if(t._pax){t._header=i=mixinPax(i,t._pax);t._pax=null}t._locked=true;if(!i.size||i.type==="directory"){t._parse(512,onheader);t.emit("entry",i,emptyStream(t,n),onunlock);return}t._stream=new Source(t,n);t.emit("entry",i,t._stream,onunlock);t._parse(i.size,onstreamend);oncontinue()};this._onheader=onheader;this._parse(512,onheader)};n.inherits(Extract,o);Extract.prototype.destroy=function(e){if(this._destroyed)return;this._destroyed=true;if(e)this.emit("error",e);this.emit("close");if(this._stream)this._stream.emit("close")};Extract.prototype._parse=function(e,t){if(this._destroyed)return;this._offset+=e;this._missing=e;if(t===this._onheader)this._partial=false;this._onparse=t};Extract.prototype._continue=function(){if(this._destroyed)return;var e=this._cb;this._cb=noop;if(this._overflow)this._write(this._overflow,undefined,e);else e()};Extract.prototype._write=function(e,t,r){if(this._destroyed)return;var n=this._stream;var i=this._buffer;var a=this._missing;if(e.length)this._partial=true;if(e.lengtha){o=e.slice(a);e=e.slice(0,a)}if(n)n.end(e);else i.append(e);this._overflow=o;this._onparse()};Extract.prototype._final=function(e){if(this._partial)return this.destroy(new Error("Unexpected end of data"));e()};e.exports=Extract},8860:(e,t)=>{var r=Buffer.alloc;var n="0000000000000000000";var i="7777777777777777777";var a="0".charCodeAt(0);var o=Buffer.from("ustar\0","binary");var s=Buffer.from("00","binary");var u=Buffer.from("ustar ","binary");var l=Buffer.from(" \0","binary");var c=parseInt("7777",8);var d=257;var h=263;var clamp=function(e,t,r){if(typeof e!=="number")return r;e=~~e;if(e>=t)return t;if(e>=0)return e;e+=t;if(e>=0)return e;return 0};var toType=function(e){switch(e){case 0:return"file";case 1:return"link";case 2:return"symlink";case 3:return"character-device";case 4:return"block-device";case 5:return"directory";case 6:return"fifo";case 7:return"contiguous-file";case 72:return"pax-header";case 55:return"pax-global-header";case 27:return"gnu-long-link-path";case 28:case 30:return"gnu-long-path"}return null};var toTypeflag=function(e){switch(e){case"file":return 0;case"link":return 1;case"symlink":return 2;case"character-device":return 3;case"block-device":return 4;case"directory":return 5;case"fifo":return 6;case"contiguous-file":return 7;case"pax-header":return 72}return 0};var indexOf=function(e,t,r,n){for(;rt)return i.slice(0,t)+" ";else return n.slice(0,t-e.length)+e+" "};function parse256(e){var t;if(e[0]===128)t=true;else if(e[0]===255)t=false;else return null;var r=[];for(var n=e.length-1;n>0;n--){var i=e[n];if(t)r.push(i);else r.push(255-i)}var a=0;var o=r.length;for(n=0;n=Math.pow(10,r))r++;return t+r+e};t.decodeLongPath=function(e,t){return decodeStr(e,0,e.length,t)};t.encodePax=function(e){var t="";if(e.name)t+=addLength(" path="+e.name+"\n");if(e.linkname)t+=addLength(" linkpath="+e.linkname+"\n");var r=e.pax;if(r){for(var n in r){t+=addLength(" "+n+"="+r[n]+"\n")}}return Buffer.from(t)};t.decodePax=function(e){var t={};while(e.length){var r=0;while(r100){var u=n.indexOf("/");if(u===-1)return null;i+=i?"/"+n.slice(0,u):n.slice(0,u);n=n.slice(u+1)}if(Buffer.byteLength(n)>100||Buffer.byteLength(i)>155)return null;if(e.linkname&&Buffer.byteLength(e.linkname)>100)return null;t.write(n);t.write(encodeOct(e.mode&c,6),100);t.write(encodeOct(e.uid,6),108);t.write(encodeOct(e.gid,6),116);t.write(encodeOct(e.size,11),124);t.write(encodeOct(e.mtime.getTime()/1e3|0,11),136);t[156]=a+toTypeflag(e.type);if(e.linkname)t.write(e.linkname,157);o.copy(t,d);s.copy(t,h);if(e.uname)t.write(e.uname,265);if(e.gname)t.write(e.gname,297);t.write(encodeOct(e.devmajor||0,6),329);t.write(encodeOct(e.devminor||0,6),337);if(i)t.write(i,345);t.write(encodeOct(cksum(t),6),148);return t};t.decode=function(e,t,r){var n=e[156]===0?0:e[156]-a;var i=decodeStr(e,0,100,t);var s=decodeOct(e,100,8);var c=decodeOct(e,108,8);var p=decodeOct(e,116,8);var g=decodeOct(e,124,12);var m=decodeOct(e,136,12);var b=toType(n);var v=e[157]===0?null:decodeStr(e,157,100,t);var _=decodeStr(e,265,32);var y=decodeStr(e,297,32);var w=decodeOct(e,329,8);var R=decodeOct(e,337,8);var S=cksum(e);if(S===8*32)return null;if(S!==decodeOct(e,148,8))throw new Error("Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?");if(o.compare(e,d,d+6)===0){if(e[345])i=decodeStr(e,345,155,t)+"/"+i}else if(u.compare(e,d,d+6)===0&&l.compare(e,h,h+2)===0){}else{if(!r){throw new Error("Invalid tar header: unknown format.")}}if(n===0&&i&&i[i.length-1]==="/")n=5;return{name:i,mode:s,uid:c,gid:p,size:g,mtime:new Date(1e3*m),type:b,linkname:v,uname:_,gname:y,devmajor:w,devminor:R}}},2283:(e,t,r)=>{t.extract=r(7882);t.pack=r(4930)},4930:(e,t,r)=>{var n=r(3186);var i=r(1205);var a=r(4124);var o=Buffer.alloc;var s=r(1642).Readable;var u=r(1642).Writable;var l=r(1576).StringDecoder;var c=r(8860);var d=parseInt("755",8);var h=parseInt("644",8);var p=o(1024);var noop=function(){};var overflow=function(e,t){t&=511;if(t)e.push(p.slice(0,512-t))};function modeToType(e){switch(e&n.S_IFMT){case n.S_IFBLK:return"block-device";case n.S_IFCHR:return"character-device";case n.S_IFDIR:return"directory";case n.S_IFIFO:return"fifo";case n.S_IFLNK:return"symlink"}return"file"}var Sink=function(e){u.call(this);this.written=0;this._to=e;this._destroyed=false};a(Sink,u);Sink.prototype._write=function(e,t,r){this.written+=e.length;if(this._to.push(e))return r();this._to._drain=r};Sink.prototype.destroy=function(){if(this._destroyed)return;this._destroyed=true;this.emit("close")};var LinkSink=function(){u.call(this);this.linkname="";this._decoder=new l("utf-8");this._destroyed=false};a(LinkSink,u);LinkSink.prototype._write=function(e,t,r){this.linkname+=this._decoder.write(e);r()};LinkSink.prototype.destroy=function(){if(this._destroyed)return;this._destroyed=true;this.emit("close")};var Void=function(){u.call(this);this._destroyed=false};a(Void,u);Void.prototype._write=function(e,t,r){r(new Error("No body allowed for this entry"))};Void.prototype.destroy=function(){if(this._destroyed)return;this._destroyed=true;this.emit("close")};var Pack=function(e){if(!(this instanceof Pack))return new Pack(e);s.call(this,e);this._drain=noop;this._finalized=false;this._finalizing=false;this._destroyed=false;this._stream=null};a(Pack,s);Pack.prototype.entry=function(e,t,r){if(this._stream)throw new Error("already piping an entry");if(this._finalized||this._destroyed)return;if(typeof t==="function"){r=t;t=null}if(!r)r=noop;var n=this;if(!e.size||e.type==="symlink")e.size=0;if(!e.type)e.type=modeToType(e.mode);if(!e.mode)e.mode=e.type==="directory"?d:h;if(!e.uid)e.uid=0;if(!e.gid)e.gid=0;if(!e.mtime)e.mtime=new Date;if(typeof t==="string")t=Buffer.from(t);if(Buffer.isBuffer(t)){e.size=t.length;this._encode(e);var a=this.push(t);overflow(n,e.size);if(a)process.nextTick(r);else this._drain=r;return new Void}if(e.type==="symlink"&&!e.linkname){var o=new LinkSink;i(o,(function(t){if(t){n.destroy();return r(t)}e.linkname=o.linkname;n._encode(e);r()}));return o}this._encode(e);if(e.type!=="file"&&e.type!=="contiguous-file"){process.nextTick(r);return new Void}var s=new Sink(this);this._stream=s;i(s,(function(t){n._stream=null;if(t){n.destroy();return r(t)}if(s.written!==e.size){n.destroy();return r(new Error("size mismatch"))}overflow(n,e.size);if(n._finalizing)n.finalize();r()}));return s};Pack.prototype.finalize=function(){if(this._stream){this._finalizing=true;return}if(this._finalized)return;this._finalized=true;this.push(p);this.push(null)};Pack.prototype.destroy=function(e){if(this._destroyed)return;this._destroyed=true;if(e)this.emit("error",e);this.emit("close");if(this._stream&&this._stream.destroy)this._stream.destroy()};Pack.prototype._encode=function(e){if(!e.pax){var t=c.encode(e);if(t){this.push(t);return}}this._encodePax(e)};Pack.prototype._encodePax=function(e){var t=c.encodePax({name:e.name,linkname:e.linkname,pax:e.pax});var r={name:"PaxHeader",mode:e.mode,uid:e.uid,gid:e.gid,size:t.length,mtime:e.mtime,type:"pax-header",linkname:e.linkname&&"PaxHeader",uname:e.uname,gname:e.gname,devmajor:e.devmajor,devminor:e.devminor};this.push(c.encode(r));this.push(t);overflow(this,t.length);r.size=e.size;r.type=e.type;this.push(c.encode(r))};Pack.prototype._read=function(e){var t=this._drain;this._drain=noop;t()};e.exports=Pack},4294:(e,t,r)=>{e.exports=r(4219)},4219:(e,t,r)=>{var n=r(1808);var i=r(4404);var a=r(3685);var o=r(5687);var s=r(2361);var u=r(9491);var l=r(3837);t.httpOverHttp=httpOverHttp;t.httpsOverHttp=httpsOverHttp;t.httpOverHttps=httpOverHttps;t.httpsOverHttps=httpsOverHttps;function httpOverHttp(e){var t=new TunnelingAgent(e);t.request=a.request;return t}function httpsOverHttp(e){var t=new TunnelingAgent(e);t.request=a.request;t.createSocket=createSecureSocket;t.defaultPort=443;return t}function httpOverHttps(e){var t=new TunnelingAgent(e);t.request=o.request;return t}function httpsOverHttps(e){var t=new TunnelingAgent(e);t.request=o.request;t.createSocket=createSecureSocket;t.defaultPort=443;return t}function TunnelingAgent(e){var t=this;t.options=e||{};t.proxyOptions=t.options.proxy||{};t.maxSockets=t.options.maxSockets||a.Agent.defaultMaxSockets;t.requests=[];t.sockets=[];t.on("free",(function onFree(e,r,n,i){var a=toOptions(r,n,i);for(var o=0,s=t.requests.length;o=this.maxSockets){i.requests.push(a);return}i.createSocket(a,(function(t){t.on("free",onFree);t.on("close",onCloseOrRemove);t.on("agentRemove",onCloseOrRemove);e.onSocket(t);function onFree(){i.emit("free",t,a)}function onCloseOrRemove(e){i.removeSocket(t);t.removeListener("free",onFree);t.removeListener("close",onCloseOrRemove);t.removeListener("agentRemove",onCloseOrRemove)}}))};TunnelingAgent.prototype.createSocket=function createSocket(e,t){var r=this;var n={};r.sockets.push(n);var i=mergeOptions({},r.proxyOptions,{method:"CONNECT",path:e.host+":"+e.port,agent:false,headers:{host:e.host+":"+e.port}});if(e.localAddress){i.localAddress=e.localAddress}if(i.proxyAuth){i.headers=i.headers||{};i.headers["Proxy-Authorization"]="Basic "+new Buffer(i.proxyAuth).toString("base64")}c("making CONNECT request");var a=r.request(i);a.useChunkedEncodingByDefault=false;a.once("response",onResponse);a.once("upgrade",onUpgrade);a.once("connect",onConnect);a.once("error",onError);a.end();function onResponse(e){e.upgrade=true}function onUpgrade(e,t,r){process.nextTick((function(){onConnect(e,t,r)}))}function onConnect(i,o,s){a.removeAllListeners();o.removeAllListeners();if(i.statusCode!==200){c("tunneling socket could not be established, statusCode=%d",i.statusCode);o.destroy();var u=new Error("tunneling socket could not be established, "+"statusCode="+i.statusCode);u.code="ECONNRESET";e.request.emit("error",u);r.removeSocket(n);return}if(s.length>0){c("got illegal response body from proxy");o.destroy();var u=new Error("got illegal response body from proxy");u.code="ECONNRESET";e.request.emit("error",u);r.removeSocket(n);return}c("tunneling connection has established");r.sockets[r.sockets.indexOf(n)]=o;return t(o)}function onError(t){a.removeAllListeners();c("tunneling socket could not be established, cause=%s\n",t.message,t.stack);var i=new Error("tunneling socket could not be established, "+"cause="+t.message);i.code="ECONNRESET";e.request.emit("error",i);r.removeSocket(n)}};TunnelingAgent.prototype.removeSocket=function removeSocket(e){var t=this.sockets.indexOf(e);if(t===-1){return}this.sockets.splice(t,1);var r=this.requests.shift();if(r){this.createSocket(r,(function(e){r.request.onSocket(e)}))}};function createSecureSocket(e,t){var r=this;TunnelingAgent.prototype.createSocket.call(r,e,(function(n){var a=e.request.getHeader("host");var o=mergeOptions({},r.options,{socket:n,servername:a?a.replace(/:.*$/,""):e.host});var s=i.connect(0,o);r.sockets[r.sockets.indexOf(n)]=s;t(s)}))}function toOptions(e,t,r){if(typeof e==="string"){return{host:e,port:t,localAddress:r}}return e}function mergeOptions(e){for(var t=1,r=arguments.length;t{e.exports=r(3837).deprecate},5840:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});Object.defineProperty(t,"v1",{enumerable:true,get:function(){return n.default}});Object.defineProperty(t,"v3",{enumerable:true,get:function(){return i.default}});Object.defineProperty(t,"v4",{enumerable:true,get:function(){return a.default}});Object.defineProperty(t,"v5",{enumerable:true,get:function(){return o.default}});Object.defineProperty(t,"NIL",{enumerable:true,get:function(){return s.default}});Object.defineProperty(t,"version",{enumerable:true,get:function(){return u.default}});Object.defineProperty(t,"validate",{enumerable:true,get:function(){return l.default}});Object.defineProperty(t,"stringify",{enumerable:true,get:function(){return c.default}});Object.defineProperty(t,"parse",{enumerable:true,get:function(){return d.default}});var n=_interopRequireDefault(r(8628));var i=_interopRequireDefault(r(6409));var a=_interopRequireDefault(r(5122));var o=_interopRequireDefault(r(9120));var s=_interopRequireDefault(r(5332));var u=_interopRequireDefault(r(1595));var l=_interopRequireDefault(r(6900));var c=_interopRequireDefault(r(8950));var d=_interopRequireDefault(r(4848));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}},4569:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(6113));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function md5(e){if(Array.isArray(e)){e=Buffer.from(e)}else if(typeof e==="string"){e=Buffer.from(e,"utf8")}return n.default.createHash("md5").update(e).digest()}var i=md5;t["default"]=i},5332:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var r="00000000-0000-0000-0000-000000000000";t["default"]=r},4848:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(6900));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function parse(e){if(!(0,n.default)(e)){throw TypeError("Invalid UUID")}let t;const r=new Uint8Array(16);r[0]=(t=parseInt(e.slice(0,8),16))>>>24;r[1]=t>>>16&255;r[2]=t>>>8&255;r[3]=t&255;r[4]=(t=parseInt(e.slice(9,13),16))>>>8;r[5]=t&255;r[6]=(t=parseInt(e.slice(14,18),16))>>>8;r[7]=t&255;r[8]=(t=parseInt(e.slice(19,23),16))>>>8;r[9]=t&255;r[10]=(t=parseInt(e.slice(24,36),16))/1099511627776&255;r[11]=t/4294967296&255;r[12]=t>>>24&255;r[13]=t>>>16&255;r[14]=t>>>8&255;r[15]=t&255;return r}var i=parse;t["default"]=i},814:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var r=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;t["default"]=r},807:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=rng;var n=_interopRequireDefault(r(6113));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const i=new Uint8Array(256);let a=i.length;function rng(){if(a>i.length-16){n.default.randomFillSync(i);a=0}return i.slice(a,a+=16)}},5274:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(6113));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function sha1(e){if(Array.isArray(e)){e=Buffer.from(e)}else if(typeof e==="string"){e=Buffer.from(e,"utf8")}return n.default.createHash("sha1").update(e).digest()}var i=sha1;t["default"]=i},8950:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(6900));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const i=[];for(let e=0;e<256;++e){i.push((e+256).toString(16).substr(1))}function stringify(e,t=0){const r=(i[e[t+0]]+i[e[t+1]]+i[e[t+2]]+i[e[t+3]]+"-"+i[e[t+4]]+i[e[t+5]]+"-"+i[e[t+6]]+i[e[t+7]]+"-"+i[e[t+8]]+i[e[t+9]]+"-"+i[e[t+10]]+i[e[t+11]]+i[e[t+12]]+i[e[t+13]]+i[e[t+14]]+i[e[t+15]]).toLowerCase();if(!(0,n.default)(r)){throw TypeError("Stringified UUID is invalid")}return r}var a=stringify;t["default"]=a},8628:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(807));var i=_interopRequireDefault(r(8950));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}let a;let o;let s=0;let u=0;function v1(e,t,r){let l=t&&r||0;const c=t||new Array(16);e=e||{};let d=e.node||a;let h=e.clockseq!==undefined?e.clockseq:o;if(d==null||h==null){const t=e.random||(e.rng||n.default)();if(d==null){d=a=[t[0]|1,t[1],t[2],t[3],t[4],t[5]]}if(h==null){h=o=(t[6]<<8|t[7])&16383}}let p=e.msecs!==undefined?e.msecs:Date.now();let g=e.nsecs!==undefined?e.nsecs:u+1;const m=p-s+(g-u)/1e4;if(m<0&&e.clockseq===undefined){h=h+1&16383}if((m<0||p>s)&&e.nsecs===undefined){g=0}if(g>=1e4){throw new Error("uuid.v1(): Can't create more than 10M uuids/sec")}s=p;u=g;o=h;p+=122192928e5;const b=((p&268435455)*1e4+g)%4294967296;c[l++]=b>>>24&255;c[l++]=b>>>16&255;c[l++]=b>>>8&255;c[l++]=b&255;const v=p/4294967296*1e4&268435455;c[l++]=v>>>8&255;c[l++]=v&255;c[l++]=v>>>24&15|16;c[l++]=v>>>16&255;c[l++]=h>>>8|128;c[l++]=h&255;for(let e=0;e<6;++e){c[l+e]=d[e]}return t||(0,i.default)(c)}var l=v1;t["default"]=l},6409:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(5998));var i=_interopRequireDefault(r(4569));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const a=(0,n.default)("v3",48,i.default);var o=a;t["default"]=o},5998:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=_default;t.URL=t.DNS=void 0;var n=_interopRequireDefault(r(8950));var i=_interopRequireDefault(r(4848));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function stringToBytes(e){e=unescape(encodeURIComponent(e));const t=[];for(let r=0;r{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(807));var i=_interopRequireDefault(r(8950));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function v4(e,t,r){e=e||{};const a=e.random||(e.rng||n.default)();a[6]=a[6]&15|64;a[8]=a[8]&63|128;if(t){r=r||0;for(let e=0;e<16;++e){t[r+e]=a[e]}return t}return(0,i.default)(a)}var a=v4;t["default"]=a},9120:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(5998));var i=_interopRequireDefault(r(5274));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const a=(0,n.default)("v5",80,i.default);var o=a;t["default"]=o},6900:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(814));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function validate(e){return typeof e==="string"&&n.default.test(e)}var i=validate;t["default"]=i},1595:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(6900));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function version(e){if(!(0,n.default)(e)){throw TypeError("Invalid UUID")}return parseInt(e.substr(14,1),16)}var i=version;t["default"]=i},2940:e=>{e.exports=wrappy;function wrappy(e,t){if(e&&t)return wrappy(e)(t);if(typeof e!=="function")throw new TypeError("need wrapper function");Object.keys(e).forEach((function(t){wrapper[t]=e[t]}));return wrapper;function wrapper(){var t=new Array(arguments.length);for(var r=0;r{t.exports=e(import.meta.url)("assert")},4300:t=>{t.exports=e(import.meta.url)("buffer")},2057:t=>{t.exports=e(import.meta.url)("constants")},6113:t=>{t.exports=e(import.meta.url)("crypto")},2361:t=>{t.exports=e(import.meta.url)("events")},7147:t=>{t.exports=e(import.meta.url)("fs")},3685:t=>{t.exports=e(import.meta.url)("http")},5687:t=>{t.exports=e(import.meta.url)("https")},1808:t=>{t.exports=e(import.meta.url)("net")},7718:t=>{t.exports=e(import.meta.url)("node:child_process")},7561:t=>{t.exports=e(import.meta.url)("node:fs")},7742:t=>{t.exports=e(import.meta.url)("node:process")},4492:t=>{t.exports=e(import.meta.url)("node:stream")},5628:t=>{t.exports=e(import.meta.url)("node:zlib")},2037:t=>{t.exports=e(import.meta.url)("os")},1017:t=>{t.exports=e(import.meta.url)("path")},2781:t=>{t.exports=e(import.meta.url)("stream")},1576:t=>{t.exports=e(import.meta.url)("string_decoder")},4404:t=>{t.exports=e(import.meta.url)("tls")},3837:t=>{t.exports=e(import.meta.url)("util")},6955:(e,t,r)=>{r.a(e,(async e=>{var t=r(7718);var n=r(7742);var i=r(4492);var a=r(7561);var o=r(5628);var s=r(2283);var u=r(2186);const l=u.getInput("container",{required:true});const c=JSON.parse(u.getInput("error-log-paths",{required:true}));const d=u.getInput("log-tarball-prefix",{required:true});const h=u.getInput("tests-label",{required:true});const p=u.getInput("test-timeout",{required:true});const g=n.env.GITHUB_REPOSITORY.split("/")[1];try{if(t.spawnSync("docker",["run","--name","base","-v",`${n.cwd()}/build.tar.zst:/build.tar.zst`,"--workdir",`/__w/${g}/${g}`,l,"sh","-c","zstdcat /build.tar.zst | tar x"],{stdio:"inherit"}).status)throw new Error("Failed to create base container");if(t.spawnSync("docker",["commit","base","baseimage"],{stdio:"inherit"}).status)throw new Error("Failed to create base image");if(t.spawnSync("docker",["rm","base"],{stdio:"inherit"}).status)throw new Error("Failed to remove base container");const e=t.spawnSync("docker",["run","--rm","baseimage","bash","-e","-o","pipefail","-c",`cd build; ctest -L '${h}' --show-only=json-v1`]);if(e.status)throw new Error("Failed to discover tests with label");const r=JSON.parse(e.stdout).tests;let m=[];r.forEach((e=>{m.push(new Promise((r=>{t.spawn("docker",["run","--security-opt","seccomp=unconfined","-e","GITHUB_ACTIONS=True","--name",e.name,"--init","baseimage","bash","-c",`cd build; ctest --output-on-failure -R '^${e.name}$' --timeout ${p}`],{stdio:"inherit"}).on("close",(e=>r(e)))})))}));const b=await Promise.all(m);for(let e=0;e{if(!e.name.startsWith(`__w/${g}/${g}/build`)){t.on("end",(()=>r()));t.resume();return}e.name=e.name.substring(`__w/${g}/${g}/`.length);if(e.name!=="build/"&&c.filter((t=>e.name.startsWith(t))).length===0){t.on("end",(()=>r()));t.resume();return}t.pipe(l.entry(e,r))})).on("finish",(()=>{l.finalize()}));t.spawn("docker",["export",r[e].name]).stdout.pipe(n);i.promises.pipeline(l,o.createGzip(),a.createWriteStream(`${d}-${r[e].name}-logs.tar.gz`))}}catch(e){u.setFailed(`Uncaught exception ${e.message}`)}e()}),1)}};var r={};function __nccwpck_require__(e){var n=r[e];if(n!==undefined){return n.exports}var i=r[e]={exports:{}};var a=true;try{t[e].call(i.exports,i,i.exports,__nccwpck_require__);a=false}finally{if(a)delete r[e]}return i.exports}(()=>{var e=typeof Symbol==="function"?Symbol("webpack then"):"__webpack_then__";var t=typeof Symbol==="function"?Symbol("webpack exports"):"__webpack_exports__";var completeQueue=e=>{if(e){e.forEach((e=>e.r--));e.forEach((e=>e.r--?e.r++:e()))}};var completeFunction=e=>!--e.r&&e();var queueFunction=(e,t)=>e?e.push(t):completeFunction(t);var wrapDeps=r=>r.map((r=>{if(r!==null&&typeof r==="object"){if(r[e])return r;if(r.then){var n=[];r.then((e=>{i[t]=e;completeQueue(n);n=0}));var i={};i[e]=(e,t)=>(queueFunction(n,e),r["catch"](t));return i}}var a={};a[e]=e=>completeFunction(e);a[t]=r;return a}));__nccwpck_require__.a=(r,n,i)=>{var a=i&&[];var o=r.exports;var s;var u;var l;var c=true;var d=false;var whenAll=(t,r,n)=>{if(d)return;d=true;r.r+=t.length;t.map(((t,i)=>t[e](r,n)));d=false};var h=new Promise(((e,t)=>{l=t;u=()=>(e(o),completeQueue(a),a=0)}));h[t]=o;h[e]=(e,t)=>{if(c){return completeFunction(e)}if(s)whenAll(s,e,t);queueFunction(a,e);h["catch"](t)};r.exports=h;n((e=>{if(!e)return u();s=wrapDeps(e);var r,n;var i=new Promise(((e,i)=>{r=()=>e(n=s.map((e=>e[t])));r.r=0;whenAll(s,r,i)}));return r.r?i:n})).then(u,l);c=false}})();if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=new URL(".",import.meta.url).pathname.slice(import.meta.url.match(/^file:\/\/\/\w:/)?1:0,-1)+"/";var n=__nccwpck_require__(6955);n=await n; \ No newline at end of file +var n=r(4300);var i=n.Buffer;function copyProps(e,t){for(var r in e){t[r]=e[r]}}if(i.from&&i.alloc&&i.allocUnsafe&&i.allocUnsafeSlow){e.exports=n}else{copyProps(n,t);t.Buffer=SafeBuffer}function SafeBuffer(e,t,r){return i(e,t,r)}SafeBuffer.prototype=Object.create(i.prototype);copyProps(i,SafeBuffer);SafeBuffer.from=function(e,t,r){if(typeof e==="number"){throw new TypeError("Argument must not be a number")}return i(e,t,r)};SafeBuffer.alloc=function(e,t,r){if(typeof e!=="number"){throw new TypeError("Argument must be a number")}var n=i(e);if(t!==undefined){if(typeof r==="string"){n.fill(t,r)}else{n.fill(t)}}else{n.fill(0)}return n};SafeBuffer.allocUnsafe=function(e){if(typeof e!=="number"){throw new TypeError("Argument must be a number")}return i(e)};SafeBuffer.allocUnsafeSlow=function(e){if(typeof e!=="number"){throw new TypeError("Argument must be a number")}return n.SlowBuffer(e)}},4841:(e,t,r)=>{var n=r(1867).Buffer;var i=n.isEncoding||function(e){e=""+e;switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return true;default:return false}};function _normalizeEncoding(e){if(!e)return"utf8";var t;while(true){switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase();t=true}}}function normalizeEncoding(e){var t=_normalizeEncoding(e);if(typeof t!=="string"&&(n.isEncoding===i||!i(e)))throw new Error("Unknown encoding: "+e);return t||e}t.s=StringDecoder;function StringDecoder(e){this.encoding=normalizeEncoding(e);var t;switch(this.encoding){case"utf16le":this.text=utf16Text;this.end=utf16End;t=4;break;case"utf8":this.fillLast=utf8FillLast;t=4;break;case"base64":this.text=base64Text;this.end=base64End;t=3;break;default:this.write=simpleWrite;this.end=simpleEnd;return}this.lastNeed=0;this.lastTotal=0;this.lastChar=n.allocUnsafe(t)}StringDecoder.prototype.write=function(e){if(e.length===0)return"";var t;var r;if(this.lastNeed){t=this.fillLast(e);if(t===undefined)return"";r=this.lastNeed;this.lastNeed=0}else{r=0}if(r>5===6)return 2;else if(e>>4===14)return 3;else if(e>>3===30)return 4;return e>>6===2?-1:-2}function utf8CheckIncomplete(e,t,r){var n=t.length-1;if(n=0){if(i>0)e.lastNeed=i-1;return i}if(--n=0){if(i>0)e.lastNeed=i-2;return i}if(--n=0){if(i>0){if(i===2)i=0;else e.lastNeed=i-3}return i}return 0}function utf8CheckExtraBytes(e,t,r){if((t[0]&192)!==128){e.lastNeed=0;return"�"}if(e.lastNeed>1&&t.length>1){if((t[1]&192)!==128){e.lastNeed=1;return"�"}if(e.lastNeed>2&&t.length>2){if((t[2]&192)!==128){e.lastNeed=2;return"�"}}}}function utf8FillLast(e){var t=this.lastTotal-this.lastNeed;var r=utf8CheckExtraBytes(this,e,t);if(r!==undefined)return r;if(this.lastNeed<=e.length){e.copy(this.lastChar,t,0,this.lastNeed);return this.lastChar.toString(this.encoding,0,this.lastTotal)}e.copy(this.lastChar,t,0,e.length);this.lastNeed-=e.length}function utf8Text(e,t){var r=utf8CheckIncomplete(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=r;var n=e.length-(r-this.lastNeed);e.copy(this.lastChar,0,n);return e.toString("utf8",t,n)}function utf8End(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed)return t+"�";return t}function utf16Text(e,t){if((e.length-t)%2===0){var r=e.toString("utf16le",t);if(r){var n=r.charCodeAt(r.length-1);if(n>=55296&&n<=56319){this.lastNeed=2;this.lastTotal=4;this.lastChar[0]=e[e.length-2];this.lastChar[1]=e[e.length-1];return r.slice(0,-1)}}return r}this.lastNeed=1;this.lastTotal=2;this.lastChar[0]=e[e.length-1];return e.toString("utf16le",t,e.length-1)}function utf16End(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var r=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,r)}return t}function base64Text(e,t){var r=(e.length-t)%3;if(r===0)return e.toString("base64",t);this.lastNeed=3-r;this.lastTotal=3;if(r===1){this.lastChar[0]=e[e.length-1]}else{this.lastChar[0]=e[e.length-2];this.lastChar[1]=e[e.length-1]}return e.toString("base64",t,e.length-r)}function base64End(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed)return t+this.lastChar.toString("base64",0,3-this.lastNeed);return t}function simpleWrite(e){return e.toString(this.encoding)}function simpleEnd(e){return e&&e.length?this.write(e):""}},7882:(e,t,r)=>{var n=r(3837);var i=r(336);var a=r(8860);var o=r(1642).Writable;var s=r(1642).PassThrough;var noop=function(){};var overflow=function(e){e&=511;return e&&512-e};var emptyStream=function(e,t){var r=new Source(e,t);r.end();return r};var mixinPax=function(e,t){if(t.path)e.name=t.path;if(t.linkpath)e.linkname=t.linkpath;if(t.size)e.size=parseInt(t.size,10);e.pax=t;return e};var Source=function(e,t){this._parent=e;this.offset=t;s.call(this,{autoDestroy:false})};n.inherits(Source,s);Source.prototype.destroy=function(e){this._parent.destroy(e)};var Extract=function(e){if(!(this instanceof Extract))return new Extract(e);o.call(this,e);e=e||{};this._offset=0;this._buffer=i();this._missing=0;this._partial=false;this._onparse=noop;this._header=null;this._stream=null;this._overflow=null;this._cb=null;this._locked=false;this._destroyed=false;this._pax=null;this._paxGlobal=null;this._gnuLongPath=null;this._gnuLongLinkPath=null;var t=this;var r=t._buffer;var oncontinue=function(){t._continue()};var onunlock=function(e){t._locked=false;if(e)return t.destroy(e);if(!t._stream)oncontinue()};var onstreamend=function(){t._stream=null;var e=overflow(t._header.size);if(e)t._parse(e,ondrain);else t._parse(512,onheader);if(!t._locked)oncontinue()};var ondrain=function(){t._buffer.consume(overflow(t._header.size));t._parse(512,onheader);oncontinue()};var onpaxglobalheader=function(){var e=t._header.size;t._paxGlobal=a.decodePax(r.slice(0,e));r.consume(e);onstreamend()};var onpaxheader=function(){var e=t._header.size;t._pax=a.decodePax(r.slice(0,e));if(t._paxGlobal)t._pax=Object.assign({},t._paxGlobal,t._pax);r.consume(e);onstreamend()};var ongnulongpath=function(){var n=t._header.size;this._gnuLongPath=a.decodeLongPath(r.slice(0,n),e.filenameEncoding);r.consume(n);onstreamend()};var ongnulonglinkpath=function(){var n=t._header.size;this._gnuLongLinkPath=a.decodeLongPath(r.slice(0,n),e.filenameEncoding);r.consume(n);onstreamend()};var onheader=function(){var n=t._offset;var i;try{i=t._header=a.decode(r.slice(0,512),e.filenameEncoding,e.allowUnknownFormat)}catch(e){t.emit("error",e)}r.consume(512);if(!i){t._parse(512,onheader);oncontinue();return}if(i.type==="gnu-long-path"){t._parse(i.size,ongnulongpath);oncontinue();return}if(i.type==="gnu-long-link-path"){t._parse(i.size,ongnulonglinkpath);oncontinue();return}if(i.type==="pax-global-header"){t._parse(i.size,onpaxglobalheader);oncontinue();return}if(i.type==="pax-header"){t._parse(i.size,onpaxheader);oncontinue();return}if(t._gnuLongPath){i.name=t._gnuLongPath;t._gnuLongPath=null}if(t._gnuLongLinkPath){i.linkname=t._gnuLongLinkPath;t._gnuLongLinkPath=null}if(t._pax){t._header=i=mixinPax(i,t._pax);t._pax=null}t._locked=true;if(!i.size||i.type==="directory"){t._parse(512,onheader);t.emit("entry",i,emptyStream(t,n),onunlock);return}t._stream=new Source(t,n);t.emit("entry",i,t._stream,onunlock);t._parse(i.size,onstreamend);oncontinue()};this._onheader=onheader;this._parse(512,onheader)};n.inherits(Extract,o);Extract.prototype.destroy=function(e){if(this._destroyed)return;this._destroyed=true;if(e)this.emit("error",e);this.emit("close");if(this._stream)this._stream.emit("close")};Extract.prototype._parse=function(e,t){if(this._destroyed)return;this._offset+=e;this._missing=e;if(t===this._onheader)this._partial=false;this._onparse=t};Extract.prototype._continue=function(){if(this._destroyed)return;var e=this._cb;this._cb=noop;if(this._overflow)this._write(this._overflow,undefined,e);else e()};Extract.prototype._write=function(e,t,r){if(this._destroyed)return;var n=this._stream;var i=this._buffer;var a=this._missing;if(e.length)this._partial=true;if(e.lengtha){o=e.slice(a);e=e.slice(0,a)}if(n)n.end(e);else i.append(e);this._overflow=o;this._onparse()};Extract.prototype._final=function(e){if(this._partial)return this.destroy(new Error("Unexpected end of data"));e()};e.exports=Extract},8860:(e,t)=>{var r=Buffer.alloc;var n="0000000000000000000";var i="7777777777777777777";var a="0".charCodeAt(0);var o=Buffer.from("ustar\0","binary");var s=Buffer.from("00","binary");var u=Buffer.from("ustar ","binary");var l=Buffer.from(" \0","binary");var c=parseInt("7777",8);var d=257;var h=263;var clamp=function(e,t,r){if(typeof e!=="number")return r;e=~~e;if(e>=t)return t;if(e>=0)return e;e+=t;if(e>=0)return e;return 0};var toType=function(e){switch(e){case 0:return"file";case 1:return"link";case 2:return"symlink";case 3:return"character-device";case 4:return"block-device";case 5:return"directory";case 6:return"fifo";case 7:return"contiguous-file";case 72:return"pax-header";case 55:return"pax-global-header";case 27:return"gnu-long-link-path";case 28:case 30:return"gnu-long-path"}return null};var toTypeflag=function(e){switch(e){case"file":return 0;case"link":return 1;case"symlink":return 2;case"character-device":return 3;case"block-device":return 4;case"directory":return 5;case"fifo":return 6;case"contiguous-file":return 7;case"pax-header":return 72}return 0};var indexOf=function(e,t,r,n){for(;rt)return i.slice(0,t)+" ";else return n.slice(0,t-e.length)+e+" "};function parse256(e){var t;if(e[0]===128)t=true;else if(e[0]===255)t=false;else return null;var r=[];for(var n=e.length-1;n>0;n--){var i=e[n];if(t)r.push(i);else r.push(255-i)}var a=0;var o=r.length;for(n=0;n=Math.pow(10,r))r++;return t+r+e};t.decodeLongPath=function(e,t){return decodeStr(e,0,e.length,t)};t.encodePax=function(e){var t="";if(e.name)t+=addLength(" path="+e.name+"\n");if(e.linkname)t+=addLength(" linkpath="+e.linkname+"\n");var r=e.pax;if(r){for(var n in r){t+=addLength(" "+n+"="+r[n]+"\n")}}return Buffer.from(t)};t.decodePax=function(e){var t={};while(e.length){var r=0;while(r100){var u=n.indexOf("/");if(u===-1)return null;i+=i?"/"+n.slice(0,u):n.slice(0,u);n=n.slice(u+1)}if(Buffer.byteLength(n)>100||Buffer.byteLength(i)>155)return null;if(e.linkname&&Buffer.byteLength(e.linkname)>100)return null;t.write(n);t.write(encodeOct(e.mode&c,6),100);t.write(encodeOct(e.uid,6),108);t.write(encodeOct(e.gid,6),116);t.write(encodeOct(e.size,11),124);t.write(encodeOct(e.mtime.getTime()/1e3|0,11),136);t[156]=a+toTypeflag(e.type);if(e.linkname)t.write(e.linkname,157);o.copy(t,d);s.copy(t,h);if(e.uname)t.write(e.uname,265);if(e.gname)t.write(e.gname,297);t.write(encodeOct(e.devmajor||0,6),329);t.write(encodeOct(e.devminor||0,6),337);if(i)t.write(i,345);t.write(encodeOct(cksum(t),6),148);return t};t.decode=function(e,t,r){var n=e[156]===0?0:e[156]-a;var i=decodeStr(e,0,100,t);var s=decodeOct(e,100,8);var c=decodeOct(e,108,8);var p=decodeOct(e,116,8);var g=decodeOct(e,124,12);var m=decodeOct(e,136,12);var b=toType(n);var v=e[157]===0?null:decodeStr(e,157,100,t);var _=decodeStr(e,265,32);var y=decodeStr(e,297,32);var w=decodeOct(e,329,8);var R=decodeOct(e,337,8);var S=cksum(e);if(S===8*32)return null;if(S!==decodeOct(e,148,8))throw new Error("Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?");if(o.compare(e,d,d+6)===0){if(e[345])i=decodeStr(e,345,155,t)+"/"+i}else if(u.compare(e,d,d+6)===0&&l.compare(e,h,h+2)===0){}else{if(!r){throw new Error("Invalid tar header: unknown format.")}}if(n===0&&i&&i[i.length-1]==="/")n=5;return{name:i,mode:s,uid:c,gid:p,size:g,mtime:new Date(1e3*m),type:b,linkname:v,uname:_,gname:y,devmajor:w,devminor:R}}},2283:(e,t,r)=>{t.extract=r(7882);t.pack=r(4930)},4930:(e,t,r)=>{var n=r(3186);var i=r(1205);var a=r(4124);var o=Buffer.alloc;var s=r(1642).Readable;var u=r(1642).Writable;var l=r(1576).StringDecoder;var c=r(8860);var d=parseInt("755",8);var h=parseInt("644",8);var p=o(1024);var noop=function(){};var overflow=function(e,t){t&=511;if(t)e.push(p.slice(0,512-t))};function modeToType(e){switch(e&n.S_IFMT){case n.S_IFBLK:return"block-device";case n.S_IFCHR:return"character-device";case n.S_IFDIR:return"directory";case n.S_IFIFO:return"fifo";case n.S_IFLNK:return"symlink"}return"file"}var Sink=function(e){u.call(this);this.written=0;this._to=e;this._destroyed=false};a(Sink,u);Sink.prototype._write=function(e,t,r){this.written+=e.length;if(this._to.push(e))return r();this._to._drain=r};Sink.prototype.destroy=function(){if(this._destroyed)return;this._destroyed=true;this.emit("close")};var LinkSink=function(){u.call(this);this.linkname="";this._decoder=new l("utf-8");this._destroyed=false};a(LinkSink,u);LinkSink.prototype._write=function(e,t,r){this.linkname+=this._decoder.write(e);r()};LinkSink.prototype.destroy=function(){if(this._destroyed)return;this._destroyed=true;this.emit("close")};var Void=function(){u.call(this);this._destroyed=false};a(Void,u);Void.prototype._write=function(e,t,r){r(new Error("No body allowed for this entry"))};Void.prototype.destroy=function(){if(this._destroyed)return;this._destroyed=true;this.emit("close")};var Pack=function(e){if(!(this instanceof Pack))return new Pack(e);s.call(this,e);this._drain=noop;this._finalized=false;this._finalizing=false;this._destroyed=false;this._stream=null};a(Pack,s);Pack.prototype.entry=function(e,t,r){if(this._stream)throw new Error("already piping an entry");if(this._finalized||this._destroyed)return;if(typeof t==="function"){r=t;t=null}if(!r)r=noop;var n=this;if(!e.size||e.type==="symlink")e.size=0;if(!e.type)e.type=modeToType(e.mode);if(!e.mode)e.mode=e.type==="directory"?d:h;if(!e.uid)e.uid=0;if(!e.gid)e.gid=0;if(!e.mtime)e.mtime=new Date;if(typeof t==="string")t=Buffer.from(t);if(Buffer.isBuffer(t)){e.size=t.length;this._encode(e);var a=this.push(t);overflow(n,e.size);if(a)process.nextTick(r);else this._drain=r;return new Void}if(e.type==="symlink"&&!e.linkname){var o=new LinkSink;i(o,(function(t){if(t){n.destroy();return r(t)}e.linkname=o.linkname;n._encode(e);r()}));return o}this._encode(e);if(e.type!=="file"&&e.type!=="contiguous-file"){process.nextTick(r);return new Void}var s=new Sink(this);this._stream=s;i(s,(function(t){n._stream=null;if(t){n.destroy();return r(t)}if(s.written!==e.size){n.destroy();return r(new Error("size mismatch"))}overflow(n,e.size);if(n._finalizing)n.finalize();r()}));return s};Pack.prototype.finalize=function(){if(this._stream){this._finalizing=true;return}if(this._finalized)return;this._finalized=true;this.push(p);this.push(null)};Pack.prototype.destroy=function(e){if(this._destroyed)return;this._destroyed=true;if(e)this.emit("error",e);this.emit("close");if(this._stream&&this._stream.destroy)this._stream.destroy()};Pack.prototype._encode=function(e){if(!e.pax){var t=c.encode(e);if(t){this.push(t);return}}this._encodePax(e)};Pack.prototype._encodePax=function(e){var t=c.encodePax({name:e.name,linkname:e.linkname,pax:e.pax});var r={name:"PaxHeader",mode:e.mode,uid:e.uid,gid:e.gid,size:t.length,mtime:e.mtime,type:"pax-header",linkname:e.linkname&&"PaxHeader",uname:e.uname,gname:e.gname,devmajor:e.devmajor,devminor:e.devminor};this.push(c.encode(r));this.push(t);overflow(this,t.length);r.size=e.size;r.type=e.type;this.push(c.encode(r))};Pack.prototype._read=function(e){var t=this._drain;this._drain=noop;t()};e.exports=Pack},4294:(e,t,r)=>{e.exports=r(4219)},4219:(e,t,r)=>{var n=r(1808);var i=r(4404);var a=r(3685);var o=r(5687);var s=r(2361);var u=r(9491);var l=r(3837);t.httpOverHttp=httpOverHttp;t.httpsOverHttp=httpsOverHttp;t.httpOverHttps=httpOverHttps;t.httpsOverHttps=httpsOverHttps;function httpOverHttp(e){var t=new TunnelingAgent(e);t.request=a.request;return t}function httpsOverHttp(e){var t=new TunnelingAgent(e);t.request=a.request;t.createSocket=createSecureSocket;t.defaultPort=443;return t}function httpOverHttps(e){var t=new TunnelingAgent(e);t.request=o.request;return t}function httpsOverHttps(e){var t=new TunnelingAgent(e);t.request=o.request;t.createSocket=createSecureSocket;t.defaultPort=443;return t}function TunnelingAgent(e){var t=this;t.options=e||{};t.proxyOptions=t.options.proxy||{};t.maxSockets=t.options.maxSockets||a.Agent.defaultMaxSockets;t.requests=[];t.sockets=[];t.on("free",(function onFree(e,r,n,i){var a=toOptions(r,n,i);for(var o=0,s=t.requests.length;o=this.maxSockets){i.requests.push(a);return}i.createSocket(a,(function(t){t.on("free",onFree);t.on("close",onCloseOrRemove);t.on("agentRemove",onCloseOrRemove);e.onSocket(t);function onFree(){i.emit("free",t,a)}function onCloseOrRemove(e){i.removeSocket(t);t.removeListener("free",onFree);t.removeListener("close",onCloseOrRemove);t.removeListener("agentRemove",onCloseOrRemove)}}))};TunnelingAgent.prototype.createSocket=function createSocket(e,t){var r=this;var n={};r.sockets.push(n);var i=mergeOptions({},r.proxyOptions,{method:"CONNECT",path:e.host+":"+e.port,agent:false,headers:{host:e.host+":"+e.port}});if(e.localAddress){i.localAddress=e.localAddress}if(i.proxyAuth){i.headers=i.headers||{};i.headers["Proxy-Authorization"]="Basic "+new Buffer(i.proxyAuth).toString("base64")}c("making CONNECT request");var a=r.request(i);a.useChunkedEncodingByDefault=false;a.once("response",onResponse);a.once("upgrade",onUpgrade);a.once("connect",onConnect);a.once("error",onError);a.end();function onResponse(e){e.upgrade=true}function onUpgrade(e,t,r){process.nextTick((function(){onConnect(e,t,r)}))}function onConnect(i,o,s){a.removeAllListeners();o.removeAllListeners();if(i.statusCode!==200){c("tunneling socket could not be established, statusCode=%d",i.statusCode);o.destroy();var u=new Error("tunneling socket could not be established, "+"statusCode="+i.statusCode);u.code="ECONNRESET";e.request.emit("error",u);r.removeSocket(n);return}if(s.length>0){c("got illegal response body from proxy");o.destroy();var u=new Error("got illegal response body from proxy");u.code="ECONNRESET";e.request.emit("error",u);r.removeSocket(n);return}c("tunneling connection has established");r.sockets[r.sockets.indexOf(n)]=o;return t(o)}function onError(t){a.removeAllListeners();c("tunneling socket could not be established, cause=%s\n",t.message,t.stack);var i=new Error("tunneling socket could not be established, "+"cause="+t.message);i.code="ECONNRESET";e.request.emit("error",i);r.removeSocket(n)}};TunnelingAgent.prototype.removeSocket=function removeSocket(e){var t=this.sockets.indexOf(e);if(t===-1){return}this.sockets.splice(t,1);var r=this.requests.shift();if(r){this.createSocket(r,(function(e){r.request.onSocket(e)}))}};function createSecureSocket(e,t){var r=this;TunnelingAgent.prototype.createSocket.call(r,e,(function(n){var a=e.request.getHeader("host");var o=mergeOptions({},r.options,{socket:n,servername:a?a.replace(/:.*$/,""):e.host});var s=i.connect(0,o);r.sockets[r.sockets.indexOf(n)]=s;t(s)}))}function toOptions(e,t,r){if(typeof e==="string"){return{host:e,port:t,localAddress:r}}return e}function mergeOptions(e){for(var t=1,r=arguments.length;t{e.exports=r(3837).deprecate},5840:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});Object.defineProperty(t,"v1",{enumerable:true,get:function(){return n.default}});Object.defineProperty(t,"v3",{enumerable:true,get:function(){return i.default}});Object.defineProperty(t,"v4",{enumerable:true,get:function(){return a.default}});Object.defineProperty(t,"v5",{enumerable:true,get:function(){return o.default}});Object.defineProperty(t,"NIL",{enumerable:true,get:function(){return s.default}});Object.defineProperty(t,"version",{enumerable:true,get:function(){return u.default}});Object.defineProperty(t,"validate",{enumerable:true,get:function(){return l.default}});Object.defineProperty(t,"stringify",{enumerable:true,get:function(){return c.default}});Object.defineProperty(t,"parse",{enumerable:true,get:function(){return d.default}});var n=_interopRequireDefault(r(8628));var i=_interopRequireDefault(r(6409));var a=_interopRequireDefault(r(5122));var o=_interopRequireDefault(r(9120));var s=_interopRequireDefault(r(5332));var u=_interopRequireDefault(r(1595));var l=_interopRequireDefault(r(6900));var c=_interopRequireDefault(r(8950));var d=_interopRequireDefault(r(4848));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}},4569:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(6113));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function md5(e){if(Array.isArray(e)){e=Buffer.from(e)}else if(typeof e==="string"){e=Buffer.from(e,"utf8")}return n.default.createHash("md5").update(e).digest()}var i=md5;t["default"]=i},5332:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var r="00000000-0000-0000-0000-000000000000";t["default"]=r},4848:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(6900));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function parse(e){if(!(0,n.default)(e)){throw TypeError("Invalid UUID")}let t;const r=new Uint8Array(16);r[0]=(t=parseInt(e.slice(0,8),16))>>>24;r[1]=t>>>16&255;r[2]=t>>>8&255;r[3]=t&255;r[4]=(t=parseInt(e.slice(9,13),16))>>>8;r[5]=t&255;r[6]=(t=parseInt(e.slice(14,18),16))>>>8;r[7]=t&255;r[8]=(t=parseInt(e.slice(19,23),16))>>>8;r[9]=t&255;r[10]=(t=parseInt(e.slice(24,36),16))/1099511627776&255;r[11]=t/4294967296&255;r[12]=t>>>24&255;r[13]=t>>>16&255;r[14]=t>>>8&255;r[15]=t&255;return r}var i=parse;t["default"]=i},814:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var r=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;t["default"]=r},807:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=rng;var n=_interopRequireDefault(r(6113));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const i=new Uint8Array(256);let a=i.length;function rng(){if(a>i.length-16){n.default.randomFillSync(i);a=0}return i.slice(a,a+=16)}},5274:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(6113));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function sha1(e){if(Array.isArray(e)){e=Buffer.from(e)}else if(typeof e==="string"){e=Buffer.from(e,"utf8")}return n.default.createHash("sha1").update(e).digest()}var i=sha1;t["default"]=i},8950:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(6900));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const i=[];for(let e=0;e<256;++e){i.push((e+256).toString(16).substr(1))}function stringify(e,t=0){const r=(i[e[t+0]]+i[e[t+1]]+i[e[t+2]]+i[e[t+3]]+"-"+i[e[t+4]]+i[e[t+5]]+"-"+i[e[t+6]]+i[e[t+7]]+"-"+i[e[t+8]]+i[e[t+9]]+"-"+i[e[t+10]]+i[e[t+11]]+i[e[t+12]]+i[e[t+13]]+i[e[t+14]]+i[e[t+15]]).toLowerCase();if(!(0,n.default)(r)){throw TypeError("Stringified UUID is invalid")}return r}var a=stringify;t["default"]=a},8628:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(807));var i=_interopRequireDefault(r(8950));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}let a;let o;let s=0;let u=0;function v1(e,t,r){let l=t&&r||0;const c=t||new Array(16);e=e||{};let d=e.node||a;let h=e.clockseq!==undefined?e.clockseq:o;if(d==null||h==null){const t=e.random||(e.rng||n.default)();if(d==null){d=a=[t[0]|1,t[1],t[2],t[3],t[4],t[5]]}if(h==null){h=o=(t[6]<<8|t[7])&16383}}let p=e.msecs!==undefined?e.msecs:Date.now();let g=e.nsecs!==undefined?e.nsecs:u+1;const m=p-s+(g-u)/1e4;if(m<0&&e.clockseq===undefined){h=h+1&16383}if((m<0||p>s)&&e.nsecs===undefined){g=0}if(g>=1e4){throw new Error("uuid.v1(): Can't create more than 10M uuids/sec")}s=p;u=g;o=h;p+=122192928e5;const b=((p&268435455)*1e4+g)%4294967296;c[l++]=b>>>24&255;c[l++]=b>>>16&255;c[l++]=b>>>8&255;c[l++]=b&255;const v=p/4294967296*1e4&268435455;c[l++]=v>>>8&255;c[l++]=v&255;c[l++]=v>>>24&15|16;c[l++]=v>>>16&255;c[l++]=h>>>8|128;c[l++]=h&255;for(let e=0;e<6;++e){c[l+e]=d[e]}return t||(0,i.default)(c)}var l=v1;t["default"]=l},6409:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(5998));var i=_interopRequireDefault(r(4569));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const a=(0,n.default)("v3",48,i.default);var o=a;t["default"]=o},5998:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=_default;t.URL=t.DNS=void 0;var n=_interopRequireDefault(r(8950));var i=_interopRequireDefault(r(4848));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function stringToBytes(e){e=unescape(encodeURIComponent(e));const t=[];for(let r=0;r{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(807));var i=_interopRequireDefault(r(8950));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function v4(e,t,r){e=e||{};const a=e.random||(e.rng||n.default)();a[6]=a[6]&15|64;a[8]=a[8]&63|128;if(t){r=r||0;for(let e=0;e<16;++e){t[r+e]=a[e]}return t}return(0,i.default)(a)}var a=v4;t["default"]=a},9120:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(5998));var i=_interopRequireDefault(r(5274));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const a=(0,n.default)("v5",80,i.default);var o=a;t["default"]=o},6900:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(814));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function validate(e){return typeof e==="string"&&n.default.test(e)}var i=validate;t["default"]=i},1595:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(6900));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function version(e){if(!(0,n.default)(e)){throw TypeError("Invalid UUID")}return parseInt(e.substr(14,1),16)}var i=version;t["default"]=i},2940:e=>{e.exports=wrappy;function wrappy(e,t){if(e&&t)return wrappy(e)(t);if(typeof e!=="function")throw new TypeError("need wrapper function");Object.keys(e).forEach((function(t){wrapper[t]=e[t]}));return wrapper;function wrapper(){var t=new Array(arguments.length);for(var r=0;r{t.exports=e(import.meta.url)("assert")},4300:t=>{t.exports=e(import.meta.url)("buffer")},2057:t=>{t.exports=e(import.meta.url)("constants")},6113:t=>{t.exports=e(import.meta.url)("crypto")},2361:t=>{t.exports=e(import.meta.url)("events")},7147:t=>{t.exports=e(import.meta.url)("fs")},3685:t=>{t.exports=e(import.meta.url)("http")},5687:t=>{t.exports=e(import.meta.url)("https")},1808:t=>{t.exports=e(import.meta.url)("net")},7718:t=>{t.exports=e(import.meta.url)("node:child_process")},7561:t=>{t.exports=e(import.meta.url)("node:fs")},7742:t=>{t.exports=e(import.meta.url)("node:process")},4492:t=>{t.exports=e(import.meta.url)("node:stream")},5628:t=>{t.exports=e(import.meta.url)("node:zlib")},2037:t=>{t.exports=e(import.meta.url)("os")},1017:t=>{t.exports=e(import.meta.url)("path")},2781:t=>{t.exports=e(import.meta.url)("stream")},1576:t=>{t.exports=e(import.meta.url)("string_decoder")},4404:t=>{t.exports=e(import.meta.url)("tls")},3837:t=>{t.exports=e(import.meta.url)("util")},6955:(e,t,r)=>{r.a(e,(async e=>{var t=r(7718);var n=r(7742);var i=r(4492);var a=r(7561);var o=r(5628);var s=r(2283);var u=r(2186);const l=u.getInput("container",{required:true});const c=JSON.parse(u.getInput("error-log-paths",{required:true}));const d=u.getInput("log-tarball-prefix",{required:true});const h=u.getInput("tests-label",{required:true});const p=u.getInput("test-timeout",{required:true});const g=n.env.GITHUB_REPOSITORY.split("/")[1];try{t.spawnSync("docker",["rm","-f","base"],{stdio:"ignore"});if(t.spawnSync("docker",["run","--name","base","-v",`${n.cwd()}/build.tar.zst:/build.tar.zst`,"--workdir",`/__w/${g}/${g}`,l,"sh","-c","zstdcat /build.tar.zst | tar x"],{stdio:"inherit"}).status)throw new Error("Failed to create base container");if(t.spawnSync("docker",["commit","base","baseimage"],{stdio:"inherit"}).status)throw new Error("Failed to create base image");if(t.spawnSync("docker",["rm","base"],{stdio:"inherit"}).status)throw new Error("Failed to remove base container");const e=t.spawnSync("docker",["run","--rm","baseimage","bash","-e","-o","pipefail","-c",`cd build; ctest -L '${h}' --show-only=json-v1`]);if(e.status)throw new Error("Failed to discover tests with label");const r=JSON.parse(e.stdout).tests;let m=[];r.forEach((e=>{t.spawnSync("docker",["rm","-f",e.name],{stdio:"ignore"});m.push(new Promise((r=>{t.spawn("docker",["run","--security-opt","seccomp=unconfined","-e","GITHUB_ACTIONS=True","--name",e.name,"--init","baseimage","bash","-c",`cd build; ctest --output-on-failure -R '^${e.name}$' --timeout ${p}`],{stdio:"inherit"}).on("close",(e=>r(e)))})))}));const b=await Promise.all(m);for(let e=0;e{if(!e.name.startsWith(`__w/${g}/${g}/build`)){t.on("end",(()=>r()));t.resume();return}e.name=e.name.substring(`__w/${g}/${g}/`.length);if(e.name!=="build/"&&c.filter((t=>e.name.startsWith(t))).length===0){t.on("end",(()=>r()));t.resume();return}t.pipe(l.entry(e,r))})).on("finish",(()=>{l.finalize()}));t.spawn("docker",["export",r[e].name]).stdout.pipe(n);i.promises.pipeline(l,o.createGzip(),a.createWriteStream(`${d}-${r[e].name}-logs.tar.gz`))}}catch(e){u.setFailed(`Uncaught exception ${e.message}`)}e()}),1)}};var r={};function __nccwpck_require__(e){var n=r[e];if(n!==undefined){return n.exports}var i=r[e]={exports:{}};var a=true;try{t[e].call(i.exports,i,i.exports,__nccwpck_require__);a=false}finally{if(a)delete r[e]}return i.exports}(()=>{var e=typeof Symbol==="function"?Symbol("webpack then"):"__webpack_then__";var t=typeof Symbol==="function"?Symbol("webpack exports"):"__webpack_exports__";var completeQueue=e=>{if(e){e.forEach((e=>e.r--));e.forEach((e=>e.r--?e.r++:e()))}};var completeFunction=e=>!--e.r&&e();var queueFunction=(e,t)=>e?e.push(t):completeFunction(t);var wrapDeps=r=>r.map((r=>{if(r!==null&&typeof r==="object"){if(r[e])return r;if(r.then){var n=[];r.then((e=>{i[t]=e;completeQueue(n);n=0}));var i={};i[e]=(e,t)=>(queueFunction(n,e),r["catch"](t));return i}}var a={};a[e]=e=>completeFunction(e);a[t]=r;return a}));__nccwpck_require__.a=(r,n,i)=>{var a=i&&[];var o=r.exports;var s;var u;var l;var c=true;var d=false;var whenAll=(t,r,n)=>{if(d)return;d=true;r.r+=t.length;t.map(((t,i)=>t[e](r,n)));d=false};var h=new Promise(((e,t)=>{l=t;u=()=>(e(o),completeQueue(a),a=0)}));h[t]=o;h[e]=(e,t)=>{if(c){return completeFunction(e)}if(s)whenAll(s,e,t);queueFunction(a,e);h["catch"](t)};r.exports=h;n((e=>{if(!e)return u();s=wrapDeps(e);var r,n;var i=new Promise(((e,i)=>{r=()=>e(n=s.map((e=>e[t])));r.r=0;whenAll(s,r,i)}));return r.r?i:n})).then(u,l);c=false}})();if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=new URL(".",import.meta.url).pathname.slice(import.meta.url.match(/^file:\/\/\/\w:/)?1:0,-1)+"/";var n=__nccwpck_require__(6955);n=await n; \ No newline at end of file diff --git a/.github/actions/parallel-ctest-containers/main.mjs b/.github/actions/parallel-ctest-containers/main.mjs index b517fa1b0d..876b107d1a 100644 --- a/.github/actions/parallel-ctest-containers/main.mjs +++ b/.github/actions/parallel-ctest-containers/main.mjs @@ -15,6 +15,12 @@ const test_timeout = core.getInput('test-timeout', {required: true}); const repo_name = process.env.GITHUB_REPOSITORY.split('/')[1]; try { + // Defensively remove any leftover container from a prior/interrupted run. On a + // persistent self-hosted runner the Docker daemon survives between jobs, and the + // per-test containers below use fixed names with no --rm, so an orphan would block + // name reuse with "container name already in use". (ENF's ephemeral runners get a + // fresh daemon each job and never hit this.) + child_process.spawnSync("docker", ["rm", "-f", "base"], {stdio:"ignore"}); if(child_process.spawnSync("docker", ["run", "--name", "base", "-v", `${process.cwd()}/build.tar.zst:/build.tar.zst`, "--workdir", `/__w/${repo_name}/${repo_name}`, container, "sh", "-c", "zstdcat /build.tar.zst | tar x"], {stdio:"inherit"}).status) throw new Error("Failed to create base container"); if(child_process.spawnSync("docker", ["commit", "base", "baseimage"], {stdio:"inherit"}).status) @@ -29,6 +35,8 @@ try { let subprocesses = []; tests.forEach(t => { + // Clear any orphaned container of this name before reusing it (see note above). + child_process.spawnSync("docker", ["rm", "-f", t.name], {stdio:"ignore"}); subprocesses.push(new Promise(resolve => { child_process.spawn("docker", ["run", "--security-opt", "seccomp=unconfined", "-e", "GITHUB_ACTIONS=True", "--name", t.name, "--init", "baseimage", "bash", "-c", `cd build; ctest --output-on-failure -R '^${t.name}$' --timeout ${test_timeout}`], {stdio:"inherit"}).on('close', code => resolve(code)); })); From 1db66e50f514ea12b99d041d362370e8f8885d0d Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Sun, 7 Jun 2026 01:47:41 -0300 Subject: [PATCH 16/17] ci: cap parallel-ctest-containers concurrency (default 4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The action launched one docker container per test ALL AT ONCE (Promise.all over every discovered test). For the nonparallelizable_tests / long_running_tests suites those are heavy multi-nodeos integration tests, so on a modest self-hosted runner they starve CPU/RAM/ports and fail en masse (even trivial tests like get_account_test fail — starvation, not real bugs; they pass on ENF's sized runners). Replace the unbounded fan-out with a bounded worker pool: at most N containers run concurrently (N = CTEST_CONTAINER_CONCURRENCY env, default 4). results[i] stays aligned with tests[i] so failure-log extraction is unchanged. Rebuilt dist/index.mjs via ncc; verified it loads + runs. --- .../parallel-ctest-containers/dist/index.mjs | 8223 ++++++++++++++++- .../parallel-ctest-containers/main.mjs | 30 +- 2 files changed, 8242 insertions(+), 11 deletions(-) diff --git a/.github/actions/parallel-ctest-containers/dist/index.mjs b/.github/actions/parallel-ctest-containers/dist/index.mjs index 1fc088aed9..3404229173 100644 --- a/.github/actions/parallel-ctest-containers/dist/index.mjs +++ b/.github/actions/parallel-ctest-containers/dist/index.mjs @@ -1,3 +1,8222 @@ -import{createRequire as e}from"module";var t={7351:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};Object.defineProperty(t,"__esModule",{value:true});t.issue=t.issueCommand=void 0;const o=a(r(2037));const s=r(6321);function issueCommand(e,t,r){const n=new Command(e,t,r);process.stdout.write(n.toString()+o.EOL)}t.issueCommand=issueCommand;function issue(e,t=""){issueCommand(e,{},t)}t.issue=issue;const u="::";class Command{constructor(e,t,r){if(!e){e="missing.command"}this.command=e;this.properties=t;this.message=r}toString(){let e=u+this.command;if(this.properties&&Object.keys(this.properties).length>0){e+=" ";let t=true;for(const r in this.properties){if(this.properties.hasOwnProperty(r)){const n=this.properties[r];if(n){if(t){t=false}else{e+=","}e+=`${r}=${escapeProperty(n)}`}}}}e+=`${u}${escapeData(this.message)}`;return e}}function escapeData(e){return s.toCommandValue(e).replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function escapeProperty(e){return s.toCommandValue(e).replace(/%/g,"%25").replace(/\r/g,"%0D").replace(/\n/g,"%0A").replace(/:/g,"%3A").replace(/,/g,"%2C")}},2186:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};var o=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.getIDToken=t.getState=t.saveState=t.group=t.endGroup=t.startGroup=t.info=t.notice=t.warning=t.error=t.debug=t.isDebug=t.setFailed=t.setCommandEcho=t.setOutput=t.getBooleanInput=t.getMultilineInput=t.getInput=t.addPath=t.setSecret=t.exportVariable=t.ExitCode=void 0;const s=r(7351);const u=r(717);const l=r(6321);const c=a(r(2037));const d=a(r(1017));const h=r(5840);const p=r(8041);var g;(function(e){e[e["Success"]=0]="Success";e[e["Failure"]=1]="Failure"})(g=t.ExitCode||(t.ExitCode={}));function exportVariable(e,t){const r=l.toCommandValue(t);process.env[e]=r;const n=process.env["GITHUB_ENV"]||"";if(n){const t=`ghadelimiter_${h.v4()}`;if(e.includes(t)){throw new Error(`Unexpected input: name should not contain the delimiter "${t}"`)}if(r.includes(t)){throw new Error(`Unexpected input: value should not contain the delimiter "${t}"`)}const n=`${e}<<${t}${c.EOL}${r}${c.EOL}${t}`;u.issueCommand("ENV",n)}else{s.issueCommand("set-env",{name:e},r)}}t.exportVariable=exportVariable;function setSecret(e){s.issueCommand("add-mask",{},e)}t.setSecret=setSecret;function addPath(e){const t=process.env["GITHUB_PATH"]||"";if(t){u.issueCommand("PATH",e)}else{s.issueCommand("add-path",{},e)}process.env["PATH"]=`${e}${d.delimiter}${process.env["PATH"]}`}t.addPath=addPath;function getInput(e,t){const r=process.env[`INPUT_${e.replace(/ /g,"_").toUpperCase()}`]||"";if(t&&t.required&&!r){throw new Error(`Input required and not supplied: ${e}`)}if(t&&t.trimWhitespace===false){return r}return r.trim()}t.getInput=getInput;function getMultilineInput(e,t){const r=getInput(e,t).split("\n").filter((e=>e!==""));return r}t.getMultilineInput=getMultilineInput;function getBooleanInput(e,t){const r=["true","True","TRUE"];const n=["false","False","FALSE"];const i=getInput(e,t);if(r.includes(i))return true;if(n.includes(i))return false;throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${e}\n`+`Support boolean input list: \`true | True | TRUE | false | False | FALSE\``)}t.getBooleanInput=getBooleanInput;function setOutput(e,t){process.stdout.write(c.EOL);s.issueCommand("set-output",{name:e},t)}t.setOutput=setOutput;function setCommandEcho(e){s.issue("echo",e?"on":"off")}t.setCommandEcho=setCommandEcho;function setFailed(e){process.exitCode=g.Failure;error(e)}t.setFailed=setFailed;function isDebug(){return process.env["RUNNER_DEBUG"]==="1"}t.isDebug=isDebug;function debug(e){s.issueCommand("debug",{},e)}t.debug=debug;function error(e,t={}){s.issueCommand("error",l.toCommandProperties(t),e instanceof Error?e.toString():e)}t.error=error;function warning(e,t={}){s.issueCommand("warning",l.toCommandProperties(t),e instanceof Error?e.toString():e)}t.warning=warning;function notice(e,t={}){s.issueCommand("notice",l.toCommandProperties(t),e instanceof Error?e.toString():e)}t.notice=notice;function info(e){process.stdout.write(e+c.EOL)}t.info=info;function startGroup(e){s.issue("group",e)}t.startGroup=startGroup;function endGroup(){s.issue("endgroup")}t.endGroup=endGroup;function group(e,t){return o(this,void 0,void 0,(function*(){startGroup(e);let r;try{r=yield t()}finally{endGroup()}return r}))}t.group=group;function saveState(e,t){s.issueCommand("save-state",{name:e},t)}t.saveState=saveState;function getState(e){return process.env[`STATE_${e}`]||""}t.getState=getState;function getIDToken(e){return o(this,void 0,void 0,(function*(){return yield p.OidcClient.getIDToken(e)}))}t.getIDToken=getIDToken;var m=r(1327);Object.defineProperty(t,"summary",{enumerable:true,get:function(){return m.summary}});var b=r(1327);Object.defineProperty(t,"markdownSummary",{enumerable:true,get:function(){return b.markdownSummary}});var v=r(2981);Object.defineProperty(t,"toPosixPath",{enumerable:true,get:function(){return v.toPosixPath}});Object.defineProperty(t,"toWin32Path",{enumerable:true,get:function(){return v.toWin32Path}});Object.defineProperty(t,"toPlatformPath",{enumerable:true,get:function(){return v.toPlatformPath}})},717:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};Object.defineProperty(t,"__esModule",{value:true});t.issueCommand=void 0;const o=a(r(7147));const s=a(r(2037));const u=r(6321);function issueCommand(e,t){const r=process.env[`GITHUB_${e}`];if(!r){throw new Error(`Unable to find environment variable for file command ${e}`)}if(!o.existsSync(r)){throw new Error(`Missing file at path: ${r}`)}o.appendFileSync(r,`${u.toCommandValue(t)}${s.EOL}`,{encoding:"utf8"})}t.issueCommand=issueCommand},8041:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.OidcClient=void 0;const i=r(6255);const a=r(5526);const o=r(2186);class OidcClient{static createHttpClient(e=true,t=10){const r={allowRetries:e,maxRetries:t};return new i.HttpClient("actions/oidc-client",[new a.BearerCredentialHandler(OidcClient.getRequestToken())],r)}static getRequestToken(){const e=process.env["ACTIONS_ID_TOKEN_REQUEST_TOKEN"];if(!e){throw new Error("Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable")}return e}static getIDTokenUrl(){const e=process.env["ACTIONS_ID_TOKEN_REQUEST_URL"];if(!e){throw new Error("Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable")}return e}static getCall(e){var t;return n(this,void 0,void 0,(function*(){const r=OidcClient.createHttpClient();const n=yield r.getJson(e).catch((e=>{throw new Error(`Failed to get ID Token. \n \n Error Code : ${e.statusCode}\n \n Error Message: ${e.result.message}`)}));const i=(t=n.result)===null||t===void 0?void 0:t.value;if(!i){throw new Error("Response json body do not have ID Token field")}return i}))}static getIDToken(e){return n(this,void 0,void 0,(function*(){try{let t=OidcClient.getIDTokenUrl();if(e){const r=encodeURIComponent(e);t=`${t}&audience=${r}`}o.debug(`ID token url is ${t}`);const r=yield OidcClient.getCall(t);o.setSecret(r);return r}catch(e){throw new Error(`Error message: ${e.message}`)}}))}}t.OidcClient=OidcClient},2981:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};Object.defineProperty(t,"__esModule",{value:true});t.toPlatformPath=t.toWin32Path=t.toPosixPath=void 0;const o=a(r(1017));function toPosixPath(e){return e.replace(/[\\]/g,"/")}t.toPosixPath=toPosixPath;function toWin32Path(e){return e.replace(/[/]/g,"\\")}t.toWin32Path=toWin32Path;function toPlatformPath(e){return e.replace(/[/\\]/g,o.sep)}t.toPlatformPath=toPlatformPath},1327:function(e,t,r){var n=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.summary=t.markdownSummary=t.SUMMARY_DOCS_URL=t.SUMMARY_ENV_VAR=void 0;const i=r(2037);const a=r(7147);const{access:o,appendFile:s,writeFile:u}=a.promises;t.SUMMARY_ENV_VAR="GITHUB_STEP_SUMMARY";t.SUMMARY_DOCS_URL="https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary";class Summary{constructor(){this._buffer=""}filePath(){return n(this,void 0,void 0,(function*(){if(this._filePath){return this._filePath}const e=process.env[t.SUMMARY_ENV_VAR];if(!e){throw new Error(`Unable to find environment variable for $${t.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`)}try{yield o(e,a.constants.R_OK|a.constants.W_OK)}catch(t){throw new Error(`Unable to access summary file: '${e}'. Check if the file has correct read/write permissions.`)}this._filePath=e;return this._filePath}))}wrap(e,t,r={}){const n=Object.entries(r).map((([e,t])=>` ${e}="${t}"`)).join("");if(!t){return`<${e}${n}>`}return`<${e}${n}>${t}`}write(e){return n(this,void 0,void 0,(function*(){const t=!!(e===null||e===void 0?void 0:e.overwrite);const r=yield this.filePath();const n=t?u:s;yield n(r,this._buffer,{encoding:"utf8"});return this.emptyBuffer()}))}clear(){return n(this,void 0,void 0,(function*(){return this.emptyBuffer().write({overwrite:true})}))}stringify(){return this._buffer}isEmptyBuffer(){return this._buffer.length===0}emptyBuffer(){this._buffer="";return this}addRaw(e,t=false){this._buffer+=e;return t?this.addEOL():this}addEOL(){return this.addRaw(i.EOL)}addCodeBlock(e,t){const r=Object.assign({},t&&{lang:t});const n=this.wrap("pre",this.wrap("code",e),r);return this.addRaw(n).addEOL()}addList(e,t=false){const r=t?"ol":"ul";const n=e.map((e=>this.wrap("li",e))).join("");const i=this.wrap(r,n);return this.addRaw(i).addEOL()}addTable(e){const t=e.map((e=>{const t=e.map((e=>{if(typeof e==="string"){return this.wrap("td",e)}const{header:t,data:r,colspan:n,rowspan:i}=e;const a=t?"th":"td";const o=Object.assign(Object.assign({},n&&{colspan:n}),i&&{rowspan:i});return this.wrap(a,r,o)})).join("");return this.wrap("tr",t)})).join("");const r=this.wrap("table",t);return this.addRaw(r).addEOL()}addDetails(e,t){const r=this.wrap("details",this.wrap("summary",e)+t);return this.addRaw(r).addEOL()}addImage(e,t,r){const{width:n,height:i}=r||{};const a=Object.assign(Object.assign({},n&&{width:n}),i&&{height:i});const o=this.wrap("img",null,Object.assign({src:e,alt:t},a));return this.addRaw(o).addEOL()}addHeading(e,t){const r=`h${t}`;const n=["h1","h2","h3","h4","h5","h6"].includes(r)?r:"h1";const i=this.wrap(n,e);return this.addRaw(i).addEOL()}addSeparator(){const e=this.wrap("hr",null);return this.addRaw(e).addEOL()}addBreak(){const e=this.wrap("br",null);return this.addRaw(e).addEOL()}addQuote(e,t){const r=Object.assign({},t&&{cite:t});const n=this.wrap("blockquote",e,r);return this.addRaw(n).addEOL()}addLink(e,t){const r=this.wrap("a",e,{href:t});return this.addRaw(r).addEOL()}}const l=new Summary;t.markdownSummary=l;t.summary=l},6321:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true});t.toCommandProperties=t.toCommandValue=void 0;function toCommandValue(e){if(e===null||e===undefined){return""}else if(typeof e==="string"||e instanceof String){return e}return JSON.stringify(e)}t.toCommandValue=toCommandValue;function toCommandProperties(e){if(!Object.keys(e).length){return{}}return{title:e.title,file:e.file,line:e.startLine,endLine:e.endLine,col:e.startColumn,endColumn:e.endColumn}}t.toCommandProperties=toCommandProperties},5526:function(e,t){var r=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.PersonalAccessTokenCredentialHandler=t.BearerCredentialHandler=t.BasicCredentialHandler=void 0;class BasicCredentialHandler{constructor(e,t){this.username=e;this.password=t}prepareRequest(e){if(!e.headers){throw Error("The request has no headers")}e.headers["Authorization"]=`Basic ${Buffer.from(`${this.username}:${this.password}`).toString("base64")}`}canHandleAuthentication(){return false}handleAuthentication(){return r(this,void 0,void 0,(function*(){throw new Error("not implemented")}))}}t.BasicCredentialHandler=BasicCredentialHandler;class BearerCredentialHandler{constructor(e){this.token=e}prepareRequest(e){if(!e.headers){throw Error("The request has no headers")}e.headers["Authorization"]=`Bearer ${this.token}`}canHandleAuthentication(){return false}handleAuthentication(){return r(this,void 0,void 0,(function*(){throw new Error("not implemented")}))}}t.BearerCredentialHandler=BearerCredentialHandler;class PersonalAccessTokenCredentialHandler{constructor(e){this.token=e}prepareRequest(e){if(!e.headers){throw Error("The request has no headers")}e.headers["Authorization"]=`Basic ${Buffer.from(`PAT:${this.token}`).toString("base64")}`}canHandleAuthentication(){return false}handleAuthentication(){return r(this,void 0,void 0,(function*(){throw new Error("not implemented")}))}}t.PersonalAccessTokenCredentialHandler=PersonalAccessTokenCredentialHandler},6255:function(e,t,r){var n=this&&this.__createBinding||(Object.create?function(e,t,r,n){if(n===undefined)n=r;Object.defineProperty(e,n,{enumerable:true,get:function(){return t[r]}})}:function(e,t,r,n){if(n===undefined)n=r;e[n]=t[r]});var i=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.hasOwnProperty.call(e,r))n(t,e,r);i(t,e);return t};var o=this&&this.__awaiter||function(e,t,r,n){function adopt(e){return e instanceof r?e:new r((function(t){t(e)}))}return new(r||(r=Promise))((function(r,i){function fulfilled(e){try{step(n.next(e))}catch(e){i(e)}}function rejected(e){try{step(n["throw"](e))}catch(e){i(e)}}function step(e){e.done?r(e.value):adopt(e.value).then(fulfilled,rejected)}step((n=n.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:true});t.HttpClient=t.isHttps=t.HttpClientResponse=t.HttpClientError=t.getProxyUrl=t.MediaTypes=t.Headers=t.HttpCodes=void 0;const s=a(r(3685));const u=a(r(5687));const l=a(r(9835));const c=a(r(4294));var d;(function(e){e[e["OK"]=200]="OK";e[e["MultipleChoices"]=300]="MultipleChoices";e[e["MovedPermanently"]=301]="MovedPermanently";e[e["ResourceMoved"]=302]="ResourceMoved";e[e["SeeOther"]=303]="SeeOther";e[e["NotModified"]=304]="NotModified";e[e["UseProxy"]=305]="UseProxy";e[e["SwitchProxy"]=306]="SwitchProxy";e[e["TemporaryRedirect"]=307]="TemporaryRedirect";e[e["PermanentRedirect"]=308]="PermanentRedirect";e[e["BadRequest"]=400]="BadRequest";e[e["Unauthorized"]=401]="Unauthorized";e[e["PaymentRequired"]=402]="PaymentRequired";e[e["Forbidden"]=403]="Forbidden";e[e["NotFound"]=404]="NotFound";e[e["MethodNotAllowed"]=405]="MethodNotAllowed";e[e["NotAcceptable"]=406]="NotAcceptable";e[e["ProxyAuthenticationRequired"]=407]="ProxyAuthenticationRequired";e[e["RequestTimeout"]=408]="RequestTimeout";e[e["Conflict"]=409]="Conflict";e[e["Gone"]=410]="Gone";e[e["TooManyRequests"]=429]="TooManyRequests";e[e["InternalServerError"]=500]="InternalServerError";e[e["NotImplemented"]=501]="NotImplemented";e[e["BadGateway"]=502]="BadGateway";e[e["ServiceUnavailable"]=503]="ServiceUnavailable";e[e["GatewayTimeout"]=504]="GatewayTimeout"})(d=t.HttpCodes||(t.HttpCodes={}));var h;(function(e){e["Accept"]="accept";e["ContentType"]="content-type"})(h=t.Headers||(t.Headers={}));var p;(function(e){e["ApplicationJson"]="application/json"})(p=t.MediaTypes||(t.MediaTypes={}));function getProxyUrl(e){const t=l.getProxyUrl(new URL(e));return t?t.href:""}t.getProxyUrl=getProxyUrl;const g=[d.MovedPermanently,d.ResourceMoved,d.SeeOther,d.TemporaryRedirect,d.PermanentRedirect];const m=[d.BadGateway,d.ServiceUnavailable,d.GatewayTimeout];const b=["OPTIONS","GET","DELETE","HEAD"];const v=10;const _=5;class HttpClientError extends Error{constructor(e,t){super(e);this.name="HttpClientError";this.statusCode=t;Object.setPrototypeOf(this,HttpClientError.prototype)}}t.HttpClientError=HttpClientError;class HttpClientResponse{constructor(e){this.message=e}readBody(){return o(this,void 0,void 0,(function*(){return new Promise((e=>o(this,void 0,void 0,(function*(){let t=Buffer.alloc(0);this.message.on("data",(e=>{t=Buffer.concat([t,e])}));this.message.on("end",(()=>{e(t.toString())}))}))))}))}}t.HttpClientResponse=HttpClientResponse;function isHttps(e){const t=new URL(e);return t.protocol==="https:"}t.isHttps=isHttps;class HttpClient{constructor(e,t,r){this._ignoreSslError=false;this._allowRedirects=true;this._allowRedirectDowngrade=false;this._maxRedirects=50;this._allowRetries=false;this._maxRetries=1;this._keepAlive=false;this._disposed=false;this.userAgent=e;this.handlers=t||[];this.requestOptions=r;if(r){if(r.ignoreSslError!=null){this._ignoreSslError=r.ignoreSslError}this._socketTimeout=r.socketTimeout;if(r.allowRedirects!=null){this._allowRedirects=r.allowRedirects}if(r.allowRedirectDowngrade!=null){this._allowRedirectDowngrade=r.allowRedirectDowngrade}if(r.maxRedirects!=null){this._maxRedirects=Math.max(r.maxRedirects,0)}if(r.keepAlive!=null){this._keepAlive=r.keepAlive}if(r.allowRetries!=null){this._allowRetries=r.allowRetries}if(r.maxRetries!=null){this._maxRetries=r.maxRetries}}}options(e,t){return o(this,void 0,void 0,(function*(){return this.request("OPTIONS",e,null,t||{})}))}get(e,t){return o(this,void 0,void 0,(function*(){return this.request("GET",e,null,t||{})}))}del(e,t){return o(this,void 0,void 0,(function*(){return this.request("DELETE",e,null,t||{})}))}post(e,t,r){return o(this,void 0,void 0,(function*(){return this.request("POST",e,t,r||{})}))}patch(e,t,r){return o(this,void 0,void 0,(function*(){return this.request("PATCH",e,t,r||{})}))}put(e,t,r){return o(this,void 0,void 0,(function*(){return this.request("PUT",e,t,r||{})}))}head(e,t){return o(this,void 0,void 0,(function*(){return this.request("HEAD",e,null,t||{})}))}sendStream(e,t,r,n){return o(this,void 0,void 0,(function*(){return this.request(e,t,r,n)}))}getJson(e,t={}){return o(this,void 0,void 0,(function*(){t[h.Accept]=this._getExistingOrDefaultHeader(t,h.Accept,p.ApplicationJson);const r=yield this.get(e,t);return this._processResponse(r,this.requestOptions)}))}postJson(e,t,r={}){return o(this,void 0,void 0,(function*(){const n=JSON.stringify(t,null,2);r[h.Accept]=this._getExistingOrDefaultHeader(r,h.Accept,p.ApplicationJson);r[h.ContentType]=this._getExistingOrDefaultHeader(r,h.ContentType,p.ApplicationJson);const i=yield this.post(e,n,r);return this._processResponse(i,this.requestOptions)}))}putJson(e,t,r={}){return o(this,void 0,void 0,(function*(){const n=JSON.stringify(t,null,2);r[h.Accept]=this._getExistingOrDefaultHeader(r,h.Accept,p.ApplicationJson);r[h.ContentType]=this._getExistingOrDefaultHeader(r,h.ContentType,p.ApplicationJson);const i=yield this.put(e,n,r);return this._processResponse(i,this.requestOptions)}))}patchJson(e,t,r={}){return o(this,void 0,void 0,(function*(){const n=JSON.stringify(t,null,2);r[h.Accept]=this._getExistingOrDefaultHeader(r,h.Accept,p.ApplicationJson);r[h.ContentType]=this._getExistingOrDefaultHeader(r,h.ContentType,p.ApplicationJson);const i=yield this.patch(e,n,r);return this._processResponse(i,this.requestOptions)}))}request(e,t,r,n){return o(this,void 0,void 0,(function*(){if(this._disposed){throw new Error("Client has already been disposed.")}const i=new URL(t);let a=this._prepareRequest(e,i,n);const o=this._allowRetries&&b.includes(e)?this._maxRetries+1:1;let s=0;let u;do{u=yield this.requestRaw(a,r);if(u&&u.message&&u.message.statusCode===d.Unauthorized){let e;for(const t of this.handlers){if(t.canHandleAuthentication(u)){e=t;break}}if(e){return e.handleAuthentication(this,a,r)}else{return u}}let t=this._maxRedirects;while(u.message.statusCode&&g.includes(u.message.statusCode)&&this._allowRedirects&&t>0){const o=u.message.headers["location"];if(!o){break}const s=new URL(o);if(i.protocol==="https:"&&i.protocol!==s.protocol&&!this._allowRedirectDowngrade){throw new Error("Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.")}yield u.readBody();if(s.hostname!==i.hostname){for(const e in n){if(e.toLowerCase()==="authorization"){delete n[e]}}}a=this._prepareRequest(e,s,n);u=yield this.requestRaw(a,r);t--}if(!u.message.statusCode||!m.includes(u.message.statusCode)){return u}s+=1;if(s{function callbackForResult(e,t){if(e){n(e)}else if(!t){n(new Error("Unknown error"))}else{r(t)}}this.requestRawWithCallback(e,t,callbackForResult)}))}))}requestRawWithCallback(e,t,r){if(typeof t==="string"){if(!e.options.headers){e.options.headers={}}e.options.headers["Content-Length"]=Buffer.byteLength(t,"utf8")}let n=false;function handleResult(e,t){if(!n){n=true;r(e,t)}}const i=e.httpModule.request(e.options,(e=>{const t=new HttpClientResponse(e);handleResult(undefined,t)}));let a;i.on("socket",(e=>{a=e}));i.setTimeout(this._socketTimeout||3*6e4,(()=>{if(a){a.end()}handleResult(new Error(`Request timeout: ${e.options.path}`))}));i.on("error",(function(e){handleResult(e)}));if(t&&typeof t==="string"){i.write(t,"utf8")}if(t&&typeof t!=="string"){t.on("close",(function(){i.end()}));t.pipe(i)}else{i.end()}}getAgent(e){const t=new URL(e);return this._getAgent(t)}_prepareRequest(e,t,r){const n={};n.parsedUrl=t;const i=n.parsedUrl.protocol==="https:";n.httpModule=i?u:s;const a=i?443:80;n.options={};n.options.host=n.parsedUrl.hostname;n.options.port=n.parsedUrl.port?parseInt(n.parsedUrl.port):a;n.options.path=(n.parsedUrl.pathname||"")+(n.parsedUrl.search||"");n.options.method=e;n.options.headers=this._mergeHeaders(r);if(this.userAgent!=null){n.options.headers["user-agent"]=this.userAgent}n.options.agent=this._getAgent(n.parsedUrl);if(this.handlers){for(const e of this.handlers){e.prepareRequest(n.options)}}return n}_mergeHeaders(e){if(this.requestOptions&&this.requestOptions.headers){return Object.assign({},lowercaseKeys(this.requestOptions.headers),lowercaseKeys(e||{}))}return lowercaseKeys(e||{})}_getExistingOrDefaultHeader(e,t,r){let n;if(this.requestOptions&&this.requestOptions.headers){n=lowercaseKeys(this.requestOptions.headers)[t]}return e[t]||n||r}_getAgent(e){let t;const r=l.getProxyUrl(e);const n=r&&r.hostname;if(this._keepAlive&&n){t=this._proxyAgent}if(this._keepAlive&&!n){t=this._agent}if(t){return t}const i=e.protocol==="https:";let a=100;if(this.requestOptions){a=this.requestOptions.maxSockets||s.globalAgent.maxSockets}if(r&&r.hostname){const e={maxSockets:a,keepAlive:this._keepAlive,proxy:Object.assign(Object.assign({},(r.username||r.password)&&{proxyAuth:`${r.username}:${r.password}`}),{host:r.hostname,port:r.port})};let n;const o=r.protocol==="https:";if(i){n=o?c.httpsOverHttps:c.httpsOverHttp}else{n=o?c.httpOverHttps:c.httpOverHttp}t=n(e);this._proxyAgent=t}if(this._keepAlive&&!t){const e={keepAlive:this._keepAlive,maxSockets:a};t=i?new u.Agent(e):new s.Agent(e);this._agent=t}if(!t){t=i?u.globalAgent:s.globalAgent}if(i&&this._ignoreSslError){t.options=Object.assign(t.options||{},{rejectUnauthorized:false})}return t}_performExponentialBackoff(e){return o(this,void 0,void 0,(function*(){e=Math.min(v,e);const t=_*Math.pow(2,e);return new Promise((e=>setTimeout((()=>e()),t)))}))}_processResponse(e,t){return o(this,void 0,void 0,(function*(){return new Promise(((r,n)=>o(this,void 0,void 0,(function*(){const i=e.message.statusCode||0;const a={statusCode:i,result:null,headers:{}};if(i===d.NotFound){r(a)}function dateTimeDeserializer(e,t){if(typeof t==="string"){const e=new Date(t);if(!isNaN(e.valueOf())){return e}}return t}let o;let s;try{s=yield e.readBody();if(s&&s.length>0){if(t&&t.deserializeDates){o=JSON.parse(s,dateTimeDeserializer)}else{o=JSON.parse(s)}a.result=o}a.headers=e.message.headers}catch(e){}if(i>299){let e;if(o&&o.message){e=o.message}else if(s&&s.length>0){e=s}else{e=`Failed request: (${i})`}const t=new HttpClientError(e,i);t.result=a.result;n(t)}else{r(a)}}))))}))}}t.HttpClient=HttpClient;const lowercaseKeys=e=>Object.keys(e).reduce(((t,r)=>(t[r.toLowerCase()]=e[r],t)),{})},9835:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true});t.checkBypass=t.getProxyUrl=void 0;function getProxyUrl(e){const t=e.protocol==="https:";if(checkBypass(e)){return undefined}const r=(()=>{if(t){return process.env["https_proxy"]||process.env["HTTPS_PROXY"]}else{return process.env["http_proxy"]||process.env["HTTP_PROXY"]}})();if(r){return new URL(r)}else{return undefined}}t.getProxyUrl=getProxyUrl;function checkBypass(e){if(!e.hostname){return false}const t=process.env["no_proxy"]||process.env["NO_PROXY"]||"";if(!t){return false}let r;if(e.port){r=Number(e.port)}else if(e.protocol==="http:"){r=80}else if(e.protocol==="https:"){r=443}const n=[e.hostname.toUpperCase()];if(typeof r==="number"){n.push(`${n[0]}:${r}`)}for(const e of t.split(",").map((e=>e.trim().toUpperCase())).filter((e=>e))){if(n.some((t=>t===e))){return true}}return false}t.checkBypass=checkBypass},3664:(e,t,r)=>{const{Buffer:n}=r(4300);const i=Symbol.for("BufferList");function BufferList(e){if(!(this instanceof BufferList)){return new BufferList(e)}BufferList._init.call(this,e)}BufferList._init=function _init(e){Object.defineProperty(this,i,{value:true});this._bufs=[];this.length=0;if(e){this.append(e)}};BufferList.prototype._new=function _new(e){return new BufferList(e)};BufferList.prototype._offset=function _offset(e){if(e===0){return[0,0]}let t=0;for(let r=0;rthis.length||e<0){return undefined}const t=this._offset(e);return this._bufs[t[0]][t[1]]};BufferList.prototype.slice=function slice(e,t){if(typeof e==="number"&&e<0){e+=this.length}if(typeof t==="number"&&t<0){t+=this.length}return this.copy(null,0,e,t)};BufferList.prototype.copy=function copy(e,t,r,i){if(typeof r!=="number"||r<0){r=0}if(typeof i!=="number"||i>this.length){i=this.length}if(r>=this.length){return e||n.alloc(0)}if(i<=0){return e||n.alloc(0)}const copy=!!e;const a=this._offset(r);const o=i-r;let s=o;let u=copy&&t||0;let l=a[1];if(r===0&&i===this.length){if(!copy){return this._bufs.length===1?this._bufs[0]:n.concat(this._bufs,this.length)}for(let t=0;tr){this._bufs[t].copy(e,u,l);u+=r}else{this._bufs[t].copy(e,u,l,l+s);u+=r;break}s-=r;if(l){l=0}}if(e.length>u)return e.slice(0,u);return e};BufferList.prototype.shallowSlice=function shallowSlice(e,t){e=e||0;t=typeof t!=="number"?this.length:t;if(e<0){e+=this.length}if(t<0){t+=this.length}if(e===t){return this._new()}const r=this._offset(e);const n=this._offset(t);const i=this._bufs.slice(r[0],n[0]+1);if(n[1]===0){i.pop()}else{i[i.length-1]=i[i.length-1].slice(0,n[1])}if(r[1]!==0){i[0]=i[0].slice(r[1])}return this._new(i)};BufferList.prototype.toString=function toString(e,t,r){return this.slice(t,r).toString(e)};BufferList.prototype.consume=function consume(e){e=Math.trunc(e);if(Number.isNaN(e)||e<=0)return this;while(this._bufs.length){if(e>=this._bufs[0].length){e-=this._bufs[0].length;this.length-=this._bufs[0].length;this._bufs.shift()}else{this._bufs[0]=this._bufs[0].slice(e);this.length-=e;break}}return this};BufferList.prototype.duplicate=function duplicate(){const e=this._new();for(let t=0;tthis.length?this.length:t}const i=this._offset(t);let a=i[0];let o=i[1];for(;a=e.length){const r=t.indexOf(e,o);if(r!==-1){return this._reverseOffset([a,r])}o=t.length-e.length+1}else{const t=this._reverseOffset([a,o]);if(this._match(t,e)){return t}o++}}o=0}return-1};BufferList.prototype._match=function(e,t){if(this.length-e{const n=r(1642).Duplex;const i=r(4124);const a=r(3664);function BufferListStream(e){if(!(this instanceof BufferListStream)){return new BufferListStream(e)}if(typeof e==="function"){this._callback=e;const t=function piper(e){if(this._callback){this._callback(e);this._callback=null}}.bind(this);this.on("pipe",(function onPipe(e){e.on("error",t)}));this.on("unpipe",(function onUnpipe(e){e.removeListener("error",t)}));e=null}a._init.call(this,e);n.call(this)}i(BufferListStream,n);Object.assign(BufferListStream.prototype,a.prototype);BufferListStream.prototype._new=function _new(e){return new BufferListStream(e)};BufferListStream.prototype._write=function _write(e,t,r){this._appendBuffer(e);if(typeof r==="function"){r()}};BufferListStream.prototype._read=function _read(e){if(!this.length){return this.push(null)}e=Math.min(e,this.length);this.push(this.slice(0,e));this.consume(e)};BufferListStream.prototype.end=function end(e){n.prototype.end.call(this,e);if(this._callback){this._callback(null,this.slice());this._callback=null}};BufferListStream.prototype._destroy=function _destroy(e,t){this._bufs.length=0;this.length=0;t(e)};BufferListStream.prototype._isBufferList=function _isBufferList(e){return e instanceof BufferListStream||e instanceof a||BufferListStream.isBufferList(e)};BufferListStream.isBufferList=a.isBufferList;e.exports=BufferListStream;e.exports.BufferListStream=BufferListStream;e.exports.BufferList=a},1205:(e,t,r)=>{var n=r(1223);var noop=function(){};var isRequest=function(e){return e.setHeader&&typeof e.abort==="function"};var isChildProcess=function(e){return e.stdio&&Array.isArray(e.stdio)&&e.stdio.length===3};var eos=function(e,t,r){if(typeof t==="function")return eos(e,null,t);if(!t)t={};r=n(r||noop);var i=e._writableState;var a=e._readableState;var o=t.readable||t.readable!==false&&e.readable;var s=t.writable||t.writable!==false&&e.writable;var u=false;var onlegacyfinish=function(){if(!e.writable)onfinish()};var onfinish=function(){s=false;if(!o)r.call(e)};var onend=function(){o=false;if(!s)r.call(e)};var onexit=function(t){r.call(e,t?new Error("exited with error code: "+t):null)};var onerror=function(t){r.call(e,t)};var onclose=function(){process.nextTick(onclosenexttick)};var onclosenexttick=function(){if(u)return;if(o&&!(a&&(a.ended&&!a.destroyed)))return r.call(e,new Error("premature close"));if(s&&!(i&&(i.ended&&!i.destroyed)))return r.call(e,new Error("premature close"))};var onrequest=function(){e.req.on("finish",onfinish)};if(isRequest(e)){e.on("complete",onfinish);e.on("abort",onclose);if(e.req)onrequest();else e.on("request",onrequest)}else if(s&&!i){e.on("end",onlegacyfinish);e.on("close",onlegacyfinish)}if(isChildProcess(e))e.on("exit",onexit);e.on("end",onend);e.on("finish",onfinish);if(t.error!==false)e.on("error",onerror);e.on("close",onclose);return function(){u=true;e.removeListener("complete",onfinish);e.removeListener("abort",onclose);e.removeListener("request",onrequest);if(e.req)e.req.removeListener("finish",onfinish);e.removeListener("end",onlegacyfinish);e.removeListener("close",onlegacyfinish);e.removeListener("finish",onfinish);e.removeListener("exit",onexit);e.removeListener("end",onend);e.removeListener("error",onerror);e.removeListener("close",onclose)}};e.exports=eos},3186:(e,t,r)=>{e.exports=r(7147).constants||r(2057)},4124:(e,t,r)=>{try{var n=r(3837);if(typeof n.inherits!=="function")throw"";e.exports=n.inherits}catch(t){e.exports=r(8544)}},8544:e=>{if(typeof Object.create==="function"){e.exports=function inherits(e,t){if(t){e.super_=t;e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:false,writable:true,configurable:true}})}}}else{e.exports=function inherits(e,t){if(t){e.super_=t;var TempCtor=function(){};TempCtor.prototype=t.prototype;e.prototype=new TempCtor;e.prototype.constructor=e}}}},1223:(e,t,r)=>{var n=r(2940);e.exports=n(once);e.exports.strict=n(onceStrict);once.proto=once((function(){Object.defineProperty(Function.prototype,"once",{value:function(){return once(this)},configurable:true});Object.defineProperty(Function.prototype,"onceStrict",{value:function(){return onceStrict(this)},configurable:true})}));function once(e){var f=function(){if(f.called)return f.value;f.called=true;return f.value=e.apply(this,arguments)};f.called=false;return f}function onceStrict(e){var f=function(){if(f.called)throw new Error(f.onceError);f.called=true;return f.value=e.apply(this,arguments)};var t=e.name||"Function wrapped with `once`";f.onceError=t+" shouldn't be called more than once";f.called=false;return f}},7214:e=>{const t={};function createErrorType(e,r,n){if(!n){n=Error}function getMessage(e,t,n){if(typeof r==="string"){return r}else{return r(e,t,n)}}class NodeError extends n{constructor(e,t,r){super(getMessage(e,t,r))}}NodeError.prototype.name=n.name;NodeError.prototype.code=e;t[e]=NodeError}function oneOf(e,t){if(Array.isArray(e)){const r=e.length;e=e.map((e=>String(e)));if(r>2){return`one of ${t} ${e.slice(0,r-1).join(", ")}, or `+e[r-1]}else if(r===2){return`one of ${t} ${e[0]} or ${e[1]}`}else{return`of ${t} ${e[0]}`}}else{return`of ${t} ${String(e)}`}}function startsWith(e,t,r){return e.substr(!r||r<0?0:+r,t.length)===t}function endsWith(e,t,r){if(r===undefined||r>e.length){r=e.length}return e.substring(r-t.length,r)===t}function includes(e,t,r){if(typeof r!=="number"){r=0}if(r+t.length>e.length){return false}else{return e.indexOf(t,r)!==-1}}createErrorType("ERR_INVALID_OPT_VALUE",(function(e,t){return'The value "'+t+'" is invalid for option "'+e+'"'}),TypeError);createErrorType("ERR_INVALID_ARG_TYPE",(function(e,t,r){let n;if(typeof t==="string"&&startsWith(t,"not ")){n="must not be";t=t.replace(/^not /,"")}else{n="must be"}let i;if(endsWith(e," argument")){i=`The ${e} ${n} ${oneOf(t,"type")}`}else{const r=includes(e,".")?"property":"argument";i=`The "${e}" ${r} ${n} ${oneOf(t,"type")}`}i+=`. Received type ${typeof r}`;return i}),TypeError);createErrorType("ERR_STREAM_PUSH_AFTER_EOF","stream.push() after EOF");createErrorType("ERR_METHOD_NOT_IMPLEMENTED",(function(e){return"The "+e+" method is not implemented"}));createErrorType("ERR_STREAM_PREMATURE_CLOSE","Premature close");createErrorType("ERR_STREAM_DESTROYED",(function(e){return"Cannot call "+e+" after a stream was destroyed"}));createErrorType("ERR_MULTIPLE_CALLBACK","Callback called multiple times");createErrorType("ERR_STREAM_CANNOT_PIPE","Cannot pipe, not readable");createErrorType("ERR_STREAM_WRITE_AFTER_END","write after end");createErrorType("ERR_STREAM_NULL_VALUES","May not write null values to stream",TypeError);createErrorType("ERR_UNKNOWN_ENCODING",(function(e){return"Unknown encoding: "+e}),TypeError);createErrorType("ERR_STREAM_UNSHIFT_AFTER_END_EVENT","stream.unshift() after end event");e.exports.q=t},1359:(e,t,r)=>{var n=Object.keys||function(e){var t=[];for(var r in e){t.push(r)}return t};e.exports=Duplex;var i=r(1433);var a=r(6993);r(4124)(Duplex,i);{var o=n(a.prototype);for(var s=0;s{e.exports=PassThrough;var n=r(4415);r(4124)(PassThrough,n);function PassThrough(e){if(!(this instanceof PassThrough))return new PassThrough(e);n.call(this,e)}PassThrough.prototype._transform=function(e,t,r){r(null,e)}},1433:(e,t,r)=>{e.exports=Readable;var n;Readable.ReadableState=ReadableState;var i=r(2361).EventEmitter;var a=function EElistenerCount(e,t){return e.listeners(t).length};var o=r(2387);var s=r(4300).Buffer;var u=global.Uint8Array||function(){};function _uint8ArrayToBuffer(e){return s.from(e)}function _isUint8Array(e){return s.isBuffer(e)||e instanceof u}var l=r(3837);var c;if(l&&l.debuglog){c=l.debuglog("stream")}else{c=function debug(){}}var d=r(2746);var h=r(7049);var p=r(9948),g=p.getHighWaterMark;var m=r(7214).q,b=m.ERR_INVALID_ARG_TYPE,v=m.ERR_STREAM_PUSH_AFTER_EOF,_=m.ERR_METHOD_NOT_IMPLEMENTED,y=m.ERR_STREAM_UNSHIFT_AFTER_END_EVENT;var w;var R;var S;r(4124)(Readable,o);var E=h.errorOrDestroy;var O=["error","close","destroy","pause","resume"];function prependListener(e,t,r){if(typeof e.prependListener==="function")return e.prependListener(t,r);if(!e._events||!e._events[t])e.on(t,r);else if(Array.isArray(e._events[t]))e._events[t].unshift(r);else e._events[t]=[r,e._events[t]]}function ReadableState(e,t,i){n=n||r(1359);e=e||{};if(typeof i!=="boolean")i=t instanceof n;this.objectMode=!!e.objectMode;if(i)this.objectMode=this.objectMode||!!e.readableObjectMode;this.highWaterMark=g(this,e,"readableHighWaterMark",i);this.buffer=new d;this.length=0;this.pipes=null;this.pipesCount=0;this.flowing=null;this.ended=false;this.endEmitted=false;this.reading=false;this.sync=true;this.needReadable=false;this.emittedReadable=false;this.readableListening=false;this.resumeScheduled=false;this.paused=true;this.emitClose=e.emitClose!==false;this.autoDestroy=!!e.autoDestroy;this.destroyed=false;this.defaultEncoding=e.defaultEncoding||"utf8";this.awaitDrain=0;this.readingMore=false;this.decoder=null;this.encoding=null;if(e.encoding){if(!w)w=r(4841).s;this.decoder=new w(e.encoding);this.encoding=e.encoding}}function Readable(e){n=n||r(1359);if(!(this instanceof Readable))return new Readable(e);var t=this instanceof n;this._readableState=new ReadableState(e,this,t);this.readable=true;if(e){if(typeof e.read==="function")this._read=e.read;if(typeof e.destroy==="function")this._destroy=e.destroy}o.call(this)}Object.defineProperty(Readable.prototype,"destroyed",{enumerable:false,get:function get(){if(this._readableState===undefined){return false}return this._readableState.destroyed},set:function set(e){if(!this._readableState){return}this._readableState.destroyed=e}});Readable.prototype.destroy=h.destroy;Readable.prototype._undestroy=h.undestroy;Readable.prototype._destroy=function(e,t){t(e)};Readable.prototype.push=function(e,t){var r=this._readableState;var n;if(!r.objectMode){if(typeof e==="string"){t=t||r.defaultEncoding;if(t!==r.encoding){e=s.from(e,t);t=""}n=true}}else{n=true}return readableAddChunk(this,e,t,false,n)};Readable.prototype.unshift=function(e){return readableAddChunk(this,e,null,true,false)};function readableAddChunk(e,t,r,n,i){c("readableAddChunk",t);var a=e._readableState;if(t===null){a.reading=false;onEofChunk(e,a)}else{var o;if(!i)o=chunkInvalid(a,t);if(o){E(e,o)}else if(a.objectMode||t&&t.length>0){if(typeof t!=="string"&&!a.objectMode&&Object.getPrototypeOf(t)!==s.prototype){t=_uint8ArrayToBuffer(t)}if(n){if(a.endEmitted)E(e,new y);else addChunk(e,a,t,true)}else if(a.ended){E(e,new v)}else if(a.destroyed){return false}else{a.reading=false;if(a.decoder&&!r){t=a.decoder.write(t);if(a.objectMode||t.length!==0)addChunk(e,a,t,false);else maybeReadMore(e,a)}else{addChunk(e,a,t,false)}}}else if(!n){a.reading=false;maybeReadMore(e,a)}}return!a.ended&&(a.length=k){e=k}else{e--;e|=e>>>1;e|=e>>>2;e|=e>>>4;e|=e>>>8;e|=e>>>16;e++}return e}function howMuchToRead(e,t){if(e<=0||t.length===0&&t.ended)return 0;if(t.objectMode)return 1;if(e!==e){if(t.flowing&&t.length)return t.buffer.head.data.length;else return t.length}if(e>t.highWaterMark)t.highWaterMark=computeNewHighWaterMark(e);if(e<=t.length)return e;if(!t.ended){t.needReadable=true;return 0}return t.length}Readable.prototype.read=function(e){c("read",e);e=parseInt(e,10);var t=this._readableState;var r=e;if(e!==0)t.emittedReadable=false;if(e===0&&t.needReadable&&((t.highWaterMark!==0?t.length>=t.highWaterMark:t.length>0)||t.ended)){c("read: emitReadable",t.length,t.ended);if(t.length===0&&t.ended)endReadable(this);else emitReadable(this);return null}e=howMuchToRead(e,t);if(e===0&&t.ended){if(t.length===0)endReadable(this);return null}var n=t.needReadable;c("need readable",n);if(t.length===0||t.length-e0)i=fromList(e,t);else i=null;if(i===null){t.needReadable=t.length<=t.highWaterMark;e=0}else{t.length-=e;t.awaitDrain=0}if(t.length===0){if(!t.ended)t.needReadable=true;if(r!==e&&t.ended)endReadable(this)}if(i!==null)this.emit("data",i);return i};function onEofChunk(e,t){c("onEofChunk");if(t.ended)return;if(t.decoder){var r=t.decoder.end();if(r&&r.length){t.buffer.push(r);t.length+=t.objectMode?1:r.length}}t.ended=true;if(t.sync){emitReadable(e)}else{t.needReadable=false;if(!t.emittedReadable){t.emittedReadable=true;emitReadable_(e)}}}function emitReadable(e){var t=e._readableState;c("emitReadable",t.needReadable,t.emittedReadable);t.needReadable=false;if(!t.emittedReadable){c("emitReadable",t.flowing);t.emittedReadable=true;process.nextTick(emitReadable_,e)}}function emitReadable_(e){var t=e._readableState;c("emitReadable_",t.destroyed,t.length,t.ended);if(!t.destroyed&&(t.length||t.ended)){e.emit("readable");t.emittedReadable=false}t.needReadable=!t.flowing&&!t.ended&&t.length<=t.highWaterMark;flow(e)}function maybeReadMore(e,t){if(!t.readingMore){t.readingMore=true;process.nextTick(maybeReadMore_,e,t)}}function maybeReadMore_(e,t){while(!t.reading&&!t.ended&&(t.length1&&indexOf(n.pipes,e)!==-1)&&!u){c("false write response, pause",n.awaitDrain);n.awaitDrain++}r.pause()}}function onerror(t){c("onerror",t);unpipe();e.removeListener("error",onerror);if(a(e,"error")===0)E(e,t)}prependListener(e,"error",onerror);function onclose(){e.removeListener("finish",onfinish);unpipe()}e.once("close",onclose);function onfinish(){c("onfinish");e.removeListener("close",onclose);unpipe()}e.once("finish",onfinish);function unpipe(){c("unpipe");r.unpipe(e)}e.emit("pipe",r);if(!n.flowing){c("pipe resume");r.resume()}return e};function pipeOnDrain(e){return function pipeOnDrainFunctionResult(){var t=e._readableState;c("pipeOnDrain",t.awaitDrain);if(t.awaitDrain)t.awaitDrain--;if(t.awaitDrain===0&&a(e,"data")){t.flowing=true;flow(e)}}}Readable.prototype.unpipe=function(e){var t=this._readableState;var r={hasUnpiped:false};if(t.pipesCount===0)return this;if(t.pipesCount===1){if(e&&e!==t.pipes)return this;if(!e)e=t.pipes;t.pipes=null;t.pipesCount=0;t.flowing=false;if(e)e.emit("unpipe",this,r);return this}if(!e){var n=t.pipes;var i=t.pipesCount;t.pipes=null;t.pipesCount=0;t.flowing=false;for(var a=0;a0;if(n.flowing!==false)this.resume()}else if(e==="readable"){if(!n.endEmitted&&!n.readableListening){n.readableListening=n.needReadable=true;n.flowing=false;n.emittedReadable=false;c("on readable",n.length,n.reading);if(n.length){emitReadable(this)}else if(!n.reading){process.nextTick(nReadingNextTick,this)}}}return r};Readable.prototype.addListener=Readable.prototype.on;Readable.prototype.removeListener=function(e,t){var r=o.prototype.removeListener.call(this,e,t);if(e==="readable"){process.nextTick(updateReadableListening,this)}return r};Readable.prototype.removeAllListeners=function(e){var t=o.prototype.removeAllListeners.apply(this,arguments);if(e==="readable"||e===undefined){process.nextTick(updateReadableListening,this)}return t};function updateReadableListening(e){var t=e._readableState;t.readableListening=e.listenerCount("readable")>0;if(t.resumeScheduled&&!t.paused){t.flowing=true}else if(e.listenerCount("data")>0){e.resume()}}function nReadingNextTick(e){c("readable nexttick read 0");e.read(0)}Readable.prototype.resume=function(){var e=this._readableState;if(!e.flowing){c("resume");e.flowing=!e.readableListening;resume(this,e)}e.paused=false;return this};function resume(e,t){if(!t.resumeScheduled){t.resumeScheduled=true;process.nextTick(resume_,e,t)}}function resume_(e,t){c("resume",t.reading);if(!t.reading){e.read(0)}t.resumeScheduled=false;e.emit("resume");flow(e);if(t.flowing&&!t.reading)e.read(0)}Readable.prototype.pause=function(){c("call pause flowing=%j",this._readableState.flowing);if(this._readableState.flowing!==false){c("pause");this._readableState.flowing=false;this.emit("pause")}this._readableState.paused=true;return this};function flow(e){var t=e._readableState;c("flow",t.flowing);while(t.flowing&&e.read()!==null){}}Readable.prototype.wrap=function(e){var t=this;var r=this._readableState;var n=false;e.on("end",(function(){c("wrapped end");if(r.decoder&&!r.ended){var e=r.decoder.end();if(e&&e.length)t.push(e)}t.push(null)}));e.on("data",(function(i){c("wrapped data");if(r.decoder)i=r.decoder.write(i);if(r.objectMode&&(i===null||i===undefined))return;else if(!r.objectMode&&(!i||!i.length))return;var a=t.push(i);if(!a){n=true;e.pause()}}));for(var i in e){if(this[i]===undefined&&typeof e[i]==="function"){this[i]=function methodWrap(t){return function methodWrapReturnFunction(){return e[t].apply(e,arguments)}}(i)}}for(var a=0;a=t.length){if(t.decoder)r=t.buffer.join("");else if(t.buffer.length===1)r=t.buffer.first();else r=t.buffer.concat(t.length);t.buffer.clear()}else{r=t.buffer.consume(e,t.decoder)}return r}function endReadable(e){var t=e._readableState;c("endReadable",t.endEmitted);if(!t.endEmitted){t.ended=true;process.nextTick(endReadableNT,t,e)}}function endReadableNT(e,t){c("endReadableNT",e.endEmitted,e.length);if(!e.endEmitted&&e.length===0){e.endEmitted=true;t.readable=false;t.emit("end");if(e.autoDestroy){var r=t._writableState;if(!r||r.autoDestroy&&r.finished){t.destroy()}}}}if(typeof Symbol==="function"){Readable.from=function(e,t){if(S===undefined){S=r(9082)}return S(Readable,e,t)}}function indexOf(e,t){for(var r=0,n=e.length;r{e.exports=Transform;var n=r(7214).q,i=n.ERR_METHOD_NOT_IMPLEMENTED,a=n.ERR_MULTIPLE_CALLBACK,o=n.ERR_TRANSFORM_ALREADY_TRANSFORMING,s=n.ERR_TRANSFORM_WITH_LENGTH_0;var u=r(1359);r(4124)(Transform,u);function afterTransform(e,t){var r=this._transformState;r.transforming=false;var n=r.writecb;if(n===null){return this.emit("error",new a)}r.writechunk=null;r.writecb=null;if(t!=null)this.push(t);n(e);var i=this._readableState;i.reading=false;if(i.needReadable||i.length{e.exports=Writable;function WriteReq(e,t,r){this.chunk=e;this.encoding=t;this.callback=r;this.next=null}function CorkedRequest(e){var t=this;this.next=null;this.entry=null;this.finish=function(){onCorkedFinish(t,e)}}var n;Writable.WritableState=WritableState;var i={deprecate:r(5278)};var a=r(2387);var o=r(4300).Buffer;var s=global.Uint8Array||function(){};function _uint8ArrayToBuffer(e){return o.from(e)}function _isUint8Array(e){return o.isBuffer(e)||e instanceof s}var u=r(7049);var l=r(9948),c=l.getHighWaterMark;var d=r(7214).q,h=d.ERR_INVALID_ARG_TYPE,p=d.ERR_METHOD_NOT_IMPLEMENTED,g=d.ERR_MULTIPLE_CALLBACK,m=d.ERR_STREAM_CANNOT_PIPE,b=d.ERR_STREAM_DESTROYED,v=d.ERR_STREAM_NULL_VALUES,_=d.ERR_STREAM_WRITE_AFTER_END,y=d.ERR_UNKNOWN_ENCODING;var w=u.errorOrDestroy;r(4124)(Writable,a);function nop(){}function WritableState(e,t,i){n=n||r(1359);e=e||{};if(typeof i!=="boolean")i=t instanceof n;this.objectMode=!!e.objectMode;if(i)this.objectMode=this.objectMode||!!e.writableObjectMode;this.highWaterMark=c(this,e,"writableHighWaterMark",i);this.finalCalled=false;this.needDrain=false;this.ending=false;this.ended=false;this.finished=false;this.destroyed=false;var a=e.decodeStrings===false;this.decodeStrings=!a;this.defaultEncoding=e.defaultEncoding||"utf8";this.length=0;this.writing=false;this.corked=0;this.sync=true;this.bufferProcessing=false;this.onwrite=function(e){onwrite(t,e)};this.writecb=null;this.writelen=0;this.bufferedRequest=null;this.lastBufferedRequest=null;this.pendingcb=0;this.prefinished=false;this.errorEmitted=false;this.emitClose=e.emitClose!==false;this.autoDestroy=!!e.autoDestroy;this.bufferedRequestCount=0;this.corkedRequestsFree=new CorkedRequest(this)}WritableState.prototype.getBuffer=function getBuffer(){var e=this.bufferedRequest;var t=[];while(e){t.push(e);e=e.next}return t};(function(){try{Object.defineProperty(WritableState.prototype,"buffer",{get:i.deprecate((function writableStateBufferGetter(){return this.getBuffer()}),"_writableState.buffer is deprecated. Use _writableState.getBuffer "+"instead.","DEP0003")})}catch(e){}})();var R;if(typeof Symbol==="function"&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]==="function"){R=Function.prototype[Symbol.hasInstance];Object.defineProperty(Writable,Symbol.hasInstance,{value:function value(e){if(R.call(this,e))return true;if(this!==Writable)return false;return e&&e._writableState instanceof WritableState}})}else{R=function realHasInstance(e){return e instanceof this}}function Writable(e){n=n||r(1359);var t=this instanceof n;if(!t&&!R.call(Writable,this))return new Writable(e);this._writableState=new WritableState(e,this,t);this.writable=true;if(e){if(typeof e.write==="function")this._write=e.write;if(typeof e.writev==="function")this._writev=e.writev;if(typeof e.destroy==="function")this._destroy=e.destroy;if(typeof e.final==="function")this._final=e.final}a.call(this)}Writable.prototype.pipe=function(){w(this,new m)};function writeAfterEnd(e,t){var r=new _;w(e,r);process.nextTick(t,r)}function validChunk(e,t,r,n){var i;if(r===null){i=new v}else if(typeof r!=="string"&&!t.objectMode){i=new h("chunk",["string","Buffer"],r)}if(i){w(e,i);process.nextTick(n,i);return false}return true}Writable.prototype.write=function(e,t,r){var n=this._writableState;var i=false;var a=!n.objectMode&&_isUint8Array(e);if(a&&!o.isBuffer(e)){e=_uint8ArrayToBuffer(e)}if(typeof t==="function"){r=t;t=null}if(a)t="buffer";else if(!t)t=n.defaultEncoding;if(typeof r!=="function")r=nop;if(n.ending)writeAfterEnd(this,r);else if(a||validChunk(this,n,e,r)){n.pendingcb++;i=writeOrBuffer(this,n,a,e,t,r)}return i};Writable.prototype.cork=function(){this._writableState.corked++};Writable.prototype.uncork=function(){var e=this._writableState;if(e.corked){e.corked--;if(!e.writing&&!e.corked&&!e.bufferProcessing&&e.bufferedRequest)clearBuffer(this,e)}};Writable.prototype.setDefaultEncoding=function setDefaultEncoding(e){if(typeof e==="string")e=e.toLowerCase();if(!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new y(e);this._writableState.defaultEncoding=e;return this};Object.defineProperty(Writable.prototype,"writableBuffer",{enumerable:false,get:function get(){return this._writableState&&this._writableState.getBuffer()}});function decodeChunk(e,t,r){if(!e.objectMode&&e.decodeStrings!==false&&typeof t==="string"){t=o.from(t,r)}return t}Object.defineProperty(Writable.prototype,"writableHighWaterMark",{enumerable:false,get:function get(){return this._writableState.highWaterMark}});function writeOrBuffer(e,t,r,n,i,a){if(!r){var o=decodeChunk(t,n,i);if(n!==o){r=true;i="buffer";n=o}}var s=t.objectMode?1:n.length;t.length+=s;var u=t.length{var n;function _defineProperty(e,t,r){if(t in e){Object.defineProperty(e,t,{value:r,enumerable:true,configurable:true,writable:true})}else{e[t]=r}return e}var i=r(6080);var a=Symbol("lastResolve");var o=Symbol("lastReject");var s=Symbol("error");var u=Symbol("ended");var l=Symbol("lastPromise");var c=Symbol("handlePromise");var d=Symbol("stream");function createIterResult(e,t){return{value:e,done:t}}function readAndResolve(e){var t=e[a];if(t!==null){var r=e[d].read();if(r!==null){e[l]=null;e[a]=null;e[o]=null;t(createIterResult(r,false))}}}function onReadable(e){process.nextTick(readAndResolve,e)}function wrapForNext(e,t){return function(r,n){e.then((function(){if(t[u]){r(createIterResult(undefined,true));return}t[c](r,n)}),n)}}var h=Object.getPrototypeOf((function(){}));var p=Object.setPrototypeOf((n={get stream(){return this[d]},next:function next(){var e=this;var t=this[s];if(t!==null){return Promise.reject(t)}if(this[u]){return Promise.resolve(createIterResult(undefined,true))}if(this[d].destroyed){return new Promise((function(t,r){process.nextTick((function(){if(e[s]){r(e[s])}else{t(createIterResult(undefined,true))}}))}))}var r=this[l];var n;if(r){n=new Promise(wrapForNext(r,this))}else{var i=this[d].read();if(i!==null){return Promise.resolve(createIterResult(i,false))}n=new Promise(this[c])}this[l]=n;return n}},_defineProperty(n,Symbol.asyncIterator,(function(){return this})),_defineProperty(n,"return",(function _return(){var e=this;return new Promise((function(t,r){e[d].destroy(null,(function(e){if(e){r(e);return}t(createIterResult(undefined,true))}))}))})),n),h);var g=function createReadableStreamAsyncIterator(e){var t;var r=Object.create(p,(t={},_defineProperty(t,d,{value:e,writable:true}),_defineProperty(t,a,{value:null,writable:true}),_defineProperty(t,o,{value:null,writable:true}),_defineProperty(t,s,{value:null,writable:true}),_defineProperty(t,u,{value:e._readableState.endEmitted,writable:true}),_defineProperty(t,c,{value:function value(e,t){var n=r[d].read();if(n){r[l]=null;r[a]=null;r[o]=null;e(createIterResult(n,false))}else{r[a]=e;r[o]=t}},writable:true}),t));r[l]=null;i(e,(function(e){if(e&&e.code!=="ERR_STREAM_PREMATURE_CLOSE"){var t=r[o];if(t!==null){r[l]=null;r[a]=null;r[o]=null;t(e)}r[s]=e;return}var n=r[a];if(n!==null){r[l]=null;r[a]=null;r[o]=null;n(createIterResult(undefined,true))}r[u]=true}));e.on("readable",onReadable.bind(null,r));return r};e.exports=g},2746:(e,t,r)=>{function ownKeys(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);if(t)n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}));r.push.apply(r,n)}return r}function _objectSpread(e){for(var t=1;t0)this.tail.next=t;else this.head=t;this.tail=t;++this.length}},{key:"unshift",value:function unshift(e){var t={data:e,next:this.head};if(this.length===0)this.tail=t;this.head=t;++this.length}},{key:"shift",value:function shift(){if(this.length===0)return;var e=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;--this.length;return e}},{key:"clear",value:function clear(){this.head=this.tail=null;this.length=0}},{key:"join",value:function join(e){if(this.length===0)return"";var t=this.head;var r=""+t.data;while(t=t.next){r+=e+t.data}return r}},{key:"concat",value:function concat(e){if(this.length===0)return i.alloc(0);var t=i.allocUnsafe(e>>>0);var r=this.head;var n=0;while(r){copyBuffer(r.data,t,n);n+=r.data.length;r=r.next}return t}},{key:"consume",value:function consume(e,t){var r;if(ei.length?i.length:e;if(a===i.length)n+=i;else n+=i.slice(0,e);e-=a;if(e===0){if(a===i.length){++r;if(t.next)this.head=t.next;else this.head=this.tail=null}else{this.head=t;t.data=i.slice(a)}break}++r}this.length-=r;return n}},{key:"_getBuffer",value:function _getBuffer(e){var t=i.allocUnsafe(e);var r=this.head;var n=1;r.data.copy(t);e-=r.data.length;while(r=r.next){var a=r.data;var o=e>a.length?a.length:e;a.copy(t,t.length-e,0,o);e-=o;if(e===0){if(o===a.length){++n;if(r.next)this.head=r.next;else this.head=this.tail=null}else{this.head=r;r.data=a.slice(o)}break}++n}this.length-=n;return t}},{key:s,value:function value(e,t){return o(this,_objectSpread({},t,{depth:0,customInspect:false}))}}]);return BufferList}()},7049:e=>{function destroy(e,t){var r=this;var n=this._readableState&&this._readableState.destroyed;var i=this._writableState&&this._writableState.destroyed;if(n||i){if(t){t(e)}else if(e){if(!this._writableState){process.nextTick(emitErrorNT,this,e)}else if(!this._writableState.errorEmitted){this._writableState.errorEmitted=true;process.nextTick(emitErrorNT,this,e)}}return this}if(this._readableState){this._readableState.destroyed=true}if(this._writableState){this._writableState.destroyed=true}this._destroy(e||null,(function(e){if(!t&&e){if(!r._writableState){process.nextTick(emitErrorAndCloseNT,r,e)}else if(!r._writableState.errorEmitted){r._writableState.errorEmitted=true;process.nextTick(emitErrorAndCloseNT,r,e)}else{process.nextTick(emitCloseNT,r)}}else if(t){process.nextTick(emitCloseNT,r);t(e)}else{process.nextTick(emitCloseNT,r)}}));return this}function emitErrorAndCloseNT(e,t){emitErrorNT(e,t);emitCloseNT(e)}function emitCloseNT(e){if(e._writableState&&!e._writableState.emitClose)return;if(e._readableState&&!e._readableState.emitClose)return;e.emit("close")}function undestroy(){if(this._readableState){this._readableState.destroyed=false;this._readableState.reading=false;this._readableState.ended=false;this._readableState.endEmitted=false}if(this._writableState){this._writableState.destroyed=false;this._writableState.ended=false;this._writableState.ending=false;this._writableState.finalCalled=false;this._writableState.prefinished=false;this._writableState.finished=false;this._writableState.errorEmitted=false}}function emitErrorNT(e,t){e.emit("error",t)}function errorOrDestroy(e,t){var r=e._readableState;var n=e._writableState;if(r&&r.autoDestroy||n&&n.autoDestroy)e.destroy(t);else e.emit("error",t)}e.exports={destroy:destroy,undestroy:undestroy,errorOrDestroy:errorOrDestroy}},6080:(e,t,r)=>{var n=r(7214).q.ERR_STREAM_PREMATURE_CLOSE;function once(e){var t=false;return function(){if(t)return;t=true;for(var r=arguments.length,n=new Array(r),i=0;i{function asyncGeneratorStep(e,t,r,n,i,a,o){try{var s=e[a](o);var u=s.value}catch(e){r(e);return}if(s.done){t(u)}else{Promise.resolve(u).then(n,i)}}function _asyncToGenerator(e){return function(){var t=this,r=arguments;return new Promise((function(n,i){var a=e.apply(t,r);function _next(e){asyncGeneratorStep(a,n,i,_next,_throw,"next",e)}function _throw(e){asyncGeneratorStep(a,n,i,_next,_throw,"throw",e)}_next(undefined)}))}}function ownKeys(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);if(t)n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}));r.push.apply(r,n)}return r}function _objectSpread(e){for(var t=1;t{var n;function once(e){var t=false;return function(){if(t)return;t=true;e.apply(void 0,arguments)}}var i=r(7214).q,a=i.ERR_MISSING_ARGS,o=i.ERR_STREAM_DESTROYED;function noop(e){if(e)throw e}function isRequest(e){return e.setHeader&&typeof e.abort==="function"}function destroyer(e,t,i,a){a=once(a);var s=false;e.on("close",(function(){s=true}));if(n===undefined)n=r(6080);n(e,{readable:t,writable:i},(function(e){if(e)return a(e);s=true;a()}));var u=false;return function(t){if(s)return;if(u)return;u=true;if(isRequest(e))return e.abort();if(typeof e.destroy==="function")return e.destroy();a(t||new o("pipe"))}}function call(e){e()}function pipe(e,t){return e.pipe(t)}function popCallback(e){if(!e.length)return noop;if(typeof e[e.length-1]!=="function")return noop;return e.pop()}function pipeline(){for(var e=arguments.length,t=new Array(e),r=0;r0;return destroyer(e,a,s,(function(e){if(!i)i=e;if(e)o.forEach(call);if(a)return;o.forEach(call);n(i)}))}));return t.reduce(pipe)}e.exports=pipeline},9948:(e,t,r)=>{var n=r(7214).q.ERR_INVALID_OPT_VALUE;function highWaterMarkFrom(e,t,r){return e.highWaterMark!=null?e.highWaterMark:t?e[r]:null}function getHighWaterMark(e,t,r,i){var a=highWaterMarkFrom(t,i,r);if(a!=null){if(!(isFinite(a)&&Math.floor(a)===a)||a<0){var o=i?r:"highWaterMark";throw new n(o,a)}return Math.floor(a)}return e.objectMode?16:16*1024}e.exports={getHighWaterMark:getHighWaterMark}},2387:(e,t,r)=>{e.exports=r(2781)},1642:(e,t,r)=>{var n=r(2781);if(process.env.READABLE_STREAM==="disable"&&n){e.exports=n.Readable;Object.assign(e.exports,n);e.exports.Stream=n}else{t=e.exports=r(1433);t.Stream=n||t;t.Readable=t;t.Writable=r(6993);t.Duplex=r(1359);t.Transform=r(4415);t.PassThrough=r(1542);t.finished=r(6080);t.pipeline=r(6989)}},1867:(e,t,r)=>{ +import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "module"; +/******/ var __webpack_modules__ = ({ + +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(6321); +/** + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value + */ +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; + } + this.command = command; + this.properties = properties; + this.message = message; + } + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } + } + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; + } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map + +/***/ }), + +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = __nccwpck_require__(7351); +const file_command_1 = __nccwpck_require__(717); +const utils_1 = __nccwpck_require__(6321); +const os = __importStar(__nccwpck_require__(2037)); +const path = __importStar(__nccwpck_require__(1017)); +const uuid_1 = __nccwpck_require__(5840); +const oidc_utils_1 = __nccwpck_require__(8041); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { + /** + * A code indicating that the action was successful + */ + ExitCode[ExitCode["Success"] = 0] = "Success"; + /** + * A code indicating that the action was a failure + */ + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + const delimiter = `ghadelimiter_${uuid_1.v4()}`; + // These should realistically never happen, but just in case someone finds a way to exploit uuid generation let's not allow keys or values that contain the delimiter. + if (name.includes(delimiter)) { + throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); + } + if (convertedVal.includes(delimiter)) { + throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); + } + const commandValue = `${name}<<${delimiter}${os.EOL}${convertedVal}${os.EOL}${delimiter}`; + file_command_1.issueCommand('ENV', commandValue); + } + else { + command_1.issueCommand('set-env', { name }, convertedVal); + } +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueCommand('PATH', inputPath); + } + else { + command_1.issueCommand('add-path', {}, inputPath); + } + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); + } + if (options && options.trimWhitespace === false) { + return val; + } + return val.trim(); +} +exports.getInput = getInput; +/** + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] + * + */ +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + return inputs; +} +exports.getMultilineInput = getMultilineInput; +/** + * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. + * Support boolean input list: `true | True | TRUE | false | False | FALSE` . + * The return value is also in boolean type. + * ref: https://yaml.org/spec/1.2/spec.html#id2804923 + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns boolean + */ +function getBooleanInput(name, options) { + const trueValue = ['true', 'True', 'TRUE']; + const falseValue = ['false', 'False', 'FALSE']; + const val = getInput(name, options); + if (trueValue.includes(val)) + return true; + if (falseValue.includes(val)) + return false; + throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + + `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); +} +exports.getBooleanInput = getBooleanInput; +/** + * Sets the value of an output. + * + * @param name name of the output to set + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function setOutput(name, value) { + process.stdout.write(os.EOL); + command_1.issueCommand('set-output', { name }, value); +} +exports.setOutput = setOutput; +/** + * Enables or disables the echoing of commands into stdout for the rest of the step. + * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. + * + */ +function setCommandEcho(enabled) { + command_1.issue('echo', enabled ? 'on' : 'off'); +} +exports.setCommandEcho = setCommandEcho; +//----------------------------------------------------------------------- +// Results +//----------------------------------------------------------------------- +/** + * Sets the action status to failed. + * When the action exits it will be with an exit code of 1 + * @param message add error issue message + */ +function setFailed(message) { + process.exitCode = ExitCode.Failure; + error(message); +} +exports.setFailed = setFailed; +//----------------------------------------------------------------------- +// Logging Commands +//----------------------------------------------------------------------- +/** + * Gets whether Actions Step Debug is on or not + */ +function isDebug() { + return process.env['RUNNER_DEBUG'] === '1'; +} +exports.isDebug = isDebug; +/** + * Writes debug message to user log + * @param message debug message + */ +function debug(message) { + command_1.issueCommand('debug', {}, message); +} +exports.debug = debug; +/** + * Adds an error issue + * @param message error issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function error(message, properties = {}) { + command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.error = error; +/** + * Adds a warning issue + * @param message warning issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function warning(message, properties = {}) { + command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.warning = warning; +/** + * Adds a notice issue + * @param message notice issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function notice(message, properties = {}) { + command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.notice = notice; +/** + * Writes info to log with console.log. + * @param message info message + */ +function info(message) { + process.stdout.write(message + os.EOL); +} +exports.info = info; +/** + * Begin an output group. + * + * Output until the next `groupEnd` will be foldable in this group + * + * @param name The name of the output group + */ +function startGroup(name) { + command_1.issue('group', name); +} +exports.startGroup = startGroup; +/** + * End an output group. + */ +function endGroup() { + command_1.issue('endgroup'); +} +exports.endGroup = endGroup; +/** + * Wrap an asynchronous function call in a group. + * + * Returns the same type as the function itself. + * + * @param name The name of the group + * @param fn The function to wrap in the group + */ +function group(name, fn) { + return __awaiter(this, void 0, void 0, function* () { + startGroup(name); + let result; + try { + result = yield fn(); + } + finally { + endGroup(); + } + return result; + }); +} +exports.group = group; +//----------------------------------------------------------------------- +// Wrapper action state +//----------------------------------------------------------------------- +/** + * Saves state for current action, the state can only be retrieved by this action's post job execution. + * + * @param name name of the state to store + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function saveState(name, value) { + command_1.issueCommand('save-state', { name }, value); +} +exports.saveState = saveState; +/** + * Gets the value of an state set by this action's main execution. + * + * @param name name of the state to get + * @returns string + */ +function getState(name) { + return process.env[`STATE_${name}`] || ''; +} +exports.getState = getState; +function getIDToken(aud) { + return __awaiter(this, void 0, void 0, function* () { + return yield oidc_utils_1.OidcClient.getIDToken(aud); + }); +} +exports.getIDToken = getIDToken; +/** + * Summary exports + */ +var summary_1 = __nccwpck_require__(1327); +Object.defineProperty(exports, "summary", ({ enumerable: true, get: function () { return summary_1.summary; } })); +/** + * @deprecated use core.summary + */ +var summary_2 = __nccwpck_require__(1327); +Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } })); +/** + * Path exports + */ +var path_utils_1 = __nccwpck_require__(2981); +Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } })); +Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } })); +Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } })); +//# sourceMappingURL=core.js.map + +/***/ }), + +/***/ 717: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +// For internal use, subject to change. +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issueCommand = void 0; +// We use any as a valid input type +/* eslint-disable @typescript-eslint/no-explicit-any */ +const fs = __importStar(__nccwpck_require__(7147)); +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(6321); +function issueCommand(command, message) { + const filePath = process.env[`GITHUB_${command}`]; + if (!filePath) { + throw new Error(`Unable to find environment variable for file command ${command}`); + } + if (!fs.existsSync(filePath)) { + throw new Error(`Missing file at path: ${filePath}`); + } + fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { + encoding: 'utf8' + }); +} +exports.issueCommand = issueCommand; +//# sourceMappingURL=file-command.js.map + +/***/ }), + +/***/ 8041: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.OidcClient = void 0; +const http_client_1 = __nccwpck_require__(6255); +const auth_1 = __nccwpck_require__(5526); +const core_1 = __nccwpck_require__(2186); +class OidcClient { + static createHttpClient(allowRetry = true, maxRetry = 10) { + const requestOptions = { + allowRetries: allowRetry, + maxRetries: maxRetry + }; + return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions); + } + static getRequestToken() { + const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']; + if (!token) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'); + } + return token; + } + static getIDTokenUrl() { + const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']; + if (!runtimeUrl) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable'); + } + return runtimeUrl; + } + static getCall(id_token_url) { + var _a; + return __awaiter(this, void 0, void 0, function* () { + const httpclient = OidcClient.createHttpClient(); + const res = yield httpclient + .getJson(id_token_url) + .catch(error => { + throw new Error(`Failed to get ID Token. \n + Error Code : ${error.statusCode}\n + Error Message: ${error.result.message}`); + }); + const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; + if (!id_token) { + throw new Error('Response json body do not have ID Token field'); + } + return id_token; + }); + } + static getIDToken(audience) { + return __awaiter(this, void 0, void 0, function* () { + try { + // New ID Token is requested from action service + let id_token_url = OidcClient.getIDTokenUrl(); + if (audience) { + const encodedAudience = encodeURIComponent(audience); + id_token_url = `${id_token_url}&audience=${encodedAudience}`; + } + core_1.debug(`ID token url is ${id_token_url}`); + const id_token = yield OidcClient.getCall(id_token_url); + core_1.setSecret(id_token); + return id_token; + } + catch (error) { + throw new Error(`Error message: ${error.message}`); + } + }); + } +} +exports.OidcClient = OidcClient; +//# sourceMappingURL=oidc-utils.js.map + +/***/ }), + +/***/ 2981: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0; +const path = __importStar(__nccwpck_require__(1017)); +/** + * toPosixPath converts the given path to the posix form. On Windows, \\ will be + * replaced with /. + * + * @param pth. Path to transform. + * @return string Posix path. + */ +function toPosixPath(pth) { + return pth.replace(/[\\]/g, '/'); +} +exports.toPosixPath = toPosixPath; +/** + * toWin32Path converts the given path to the win32 form. On Linux, / will be + * replaced with \\. + * + * @param pth. Path to transform. + * @return string Win32 path. + */ +function toWin32Path(pth) { + return pth.replace(/[/]/g, '\\'); +} +exports.toWin32Path = toWin32Path; +/** + * toPlatformPath converts the given path to a platform-specific path. It does + * this by replacing instances of / and \ with the platform-specific path + * separator. + * + * @param pth The path to platformize. + * @return string The platform-specific path. + */ +function toPlatformPath(pth) { + return pth.replace(/[/\\]/g, path.sep); +} +exports.toPlatformPath = toPlatformPath; +//# sourceMappingURL=path-utils.js.map + +/***/ }), + +/***/ 1327: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; +const os_1 = __nccwpck_require__(2037); +const fs_1 = __nccwpck_require__(7147); +const { access, appendFile, writeFile } = fs_1.promises; +exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY'; +exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary'; +class Summary { + constructor() { + this._buffer = ''; + } + /** + * Finds the summary file path from the environment, rejects if env var is not found or file does not exist + * Also checks r/w permissions. + * + * @returns step summary file path + */ + filePath() { + return __awaiter(this, void 0, void 0, function* () { + if (this._filePath) { + return this._filePath; + } + const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR]; + if (!pathFromEnv) { + throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`); + } + try { + yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK); + } + catch (_a) { + throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`); + } + this._filePath = pathFromEnv; + return this._filePath; + }); + } + /** + * Wraps content in an HTML tag, adding any HTML attributes + * + * @param {string} tag HTML tag to wrap + * @param {string | null} content content within the tag + * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add + * + * @returns {string} content wrapped in HTML element + */ + wrap(tag, content, attrs = {}) { + const htmlAttrs = Object.entries(attrs) + .map(([key, value]) => ` ${key}="${value}"`) + .join(''); + if (!content) { + return `<${tag}${htmlAttrs}>`; + } + return `<${tag}${htmlAttrs}>${content}`; + } + /** + * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. + * + * @param {SummaryWriteOptions} [options] (optional) options for write operation + * + * @returns {Promise} summary instance + */ + write(options) { + return __awaiter(this, void 0, void 0, function* () { + const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite); + const filePath = yield this.filePath(); + const writeFunc = overwrite ? writeFile : appendFile; + yield writeFunc(filePath, this._buffer, { encoding: 'utf8' }); + return this.emptyBuffer(); + }); + } + /** + * Clears the summary buffer and wipes the summary file + * + * @returns {Summary} summary instance + */ + clear() { + return __awaiter(this, void 0, void 0, function* () { + return this.emptyBuffer().write({ overwrite: true }); + }); + } + /** + * Returns the current summary buffer as a string + * + * @returns {string} string of summary buffer + */ + stringify() { + return this._buffer; + } + /** + * If the summary buffer is empty + * + * @returns {boolen} true if the buffer is empty + */ + isEmptyBuffer() { + return this._buffer.length === 0; + } + /** + * Resets the summary buffer without writing to summary file + * + * @returns {Summary} summary instance + */ + emptyBuffer() { + this._buffer = ''; + return this; + } + /** + * Adds raw text to the summary buffer + * + * @param {string} text content to add + * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) + * + * @returns {Summary} summary instance + */ + addRaw(text, addEOL = false) { + this._buffer += text; + return addEOL ? this.addEOL() : this; + } + /** + * Adds the operating system-specific end-of-line marker to the buffer + * + * @returns {Summary} summary instance + */ + addEOL() { + return this.addRaw(os_1.EOL); + } + /** + * Adds an HTML codeblock to the summary buffer + * + * @param {string} code content to render within fenced code block + * @param {string} lang (optional) language to syntax highlight code + * + * @returns {Summary} summary instance + */ + addCodeBlock(code, lang) { + const attrs = Object.assign({}, (lang && { lang })); + const element = this.wrap('pre', this.wrap('code', code), attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML list to the summary buffer + * + * @param {string[]} items list of items to render + * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) + * + * @returns {Summary} summary instance + */ + addList(items, ordered = false) { + const tag = ordered ? 'ol' : 'ul'; + const listItems = items.map(item => this.wrap('li', item)).join(''); + const element = this.wrap(tag, listItems); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML table to the summary buffer + * + * @param {SummaryTableCell[]} rows table rows + * + * @returns {Summary} summary instance + */ + addTable(rows) { + const tableBody = rows + .map(row => { + const cells = row + .map(cell => { + if (typeof cell === 'string') { + return this.wrap('td', cell); + } + const { header, data, colspan, rowspan } = cell; + const tag = header ? 'th' : 'td'; + const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan })); + return this.wrap(tag, data, attrs); + }) + .join(''); + return this.wrap('tr', cells); + }) + .join(''); + const element = this.wrap('table', tableBody); + return this.addRaw(element).addEOL(); + } + /** + * Adds a collapsable HTML details element to the summary buffer + * + * @param {string} label text for the closed state + * @param {string} content collapsable content + * + * @returns {Summary} summary instance + */ + addDetails(label, content) { + const element = this.wrap('details', this.wrap('summary', label) + content); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML image tag to the summary buffer + * + * @param {string} src path to the image you to embed + * @param {string} alt text description of the image + * @param {SummaryImageOptions} options (optional) addition image attributes + * + * @returns {Summary} summary instance + */ + addImage(src, alt, options) { + const { width, height } = options || {}; + const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height })); + const element = this.wrap('img', null, Object.assign({ src, alt }, attrs)); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML section heading element + * + * @param {string} text heading text + * @param {number | string} [level=1] (optional) the heading level, default: 1 + * + * @returns {Summary} summary instance + */ + addHeading(text, level) { + const tag = `h${level}`; + const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) + ? tag + : 'h1'; + const element = this.wrap(allowedTag, text); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML thematic break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addSeparator() { + const element = this.wrap('hr', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML line break (
) to the summary buffer + * + * @returns {Summary} summary instance + */ + addBreak() { + const element = this.wrap('br', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML blockquote to the summary buffer + * + * @param {string} text quote text + * @param {string} cite (optional) citation url + * + * @returns {Summary} summary instance + */ + addQuote(text, cite) { + const attrs = Object.assign({}, (cite && { cite })); + const element = this.wrap('blockquote', text, attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML anchor tag to the summary buffer + * + * @param {string} text link text/content + * @param {string} href hyperlink + * + * @returns {Summary} summary instance + */ + addLink(text, href) { + const element = this.wrap('a', text, { href }); + return this.addRaw(element).addEOL(); + } +} +const _summary = new Summary(); +/** + * @deprecated use `core.summary` + */ +exports.markdownSummary = _summary; +exports.summary = _summary; +//# sourceMappingURL=summary.js.map + +/***/ }), + +/***/ 6321: +/***/ ((__unused_webpack_module, exports) => { + + +// We use any as a valid input type +/* eslint-disable @typescript-eslint/no-explicit-any */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toCommandProperties = exports.toCommandValue = void 0; +/** + * Sanitizes an input into a string so it can be passed into issueCommand safely + * @param input input to sanitize into a string + */ +function toCommandValue(input) { + if (input === null || input === undefined) { + return ''; + } + else if (typeof input === 'string' || input instanceof String) { + return input; + } + return JSON.stringify(input); +} +exports.toCommandValue = toCommandValue; +/** + * + * @param annotationProperties + * @returns The command properties to send with the actual annotation command + * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 + */ +function toCommandProperties(annotationProperties) { + if (!Object.keys(annotationProperties).length) { + return {}; + } + return { + title: annotationProperties.title, + file: annotationProperties.file, + line: annotationProperties.startLine, + endLine: annotationProperties.endLine, + col: annotationProperties.startColumn, + endColumn: annotationProperties.endColumn + }; +} +exports.toCommandProperties = toCommandProperties; +//# sourceMappingURL=utils.js.map + +/***/ }), + +/***/ 5526: +/***/ (function(__unused_webpack_module, exports) { + + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.PersonalAccessTokenCredentialHandler = exports.BearerCredentialHandler = exports.BasicCredentialHandler = void 0; +class BasicCredentialHandler { + constructor(username, password) { + this.username = username; + this.password = password; + } + prepareRequest(options) { + if (!options.headers) { + throw Error('The request has no headers'); + } + options.headers['Authorization'] = `Basic ${Buffer.from(`${this.username}:${this.password}`).toString('base64')}`; + } + // This handler cannot handle 401 + canHandleAuthentication() { + return false; + } + handleAuthentication() { + return __awaiter(this, void 0, void 0, function* () { + throw new Error('not implemented'); + }); + } +} +exports.BasicCredentialHandler = BasicCredentialHandler; +class BearerCredentialHandler { + constructor(token) { + this.token = token; + } + // currently implements pre-authorization + // TODO: support preAuth = false where it hooks on 401 + prepareRequest(options) { + if (!options.headers) { + throw Error('The request has no headers'); + } + options.headers['Authorization'] = `Bearer ${this.token}`; + } + // This handler cannot handle 401 + canHandleAuthentication() { + return false; + } + handleAuthentication() { + return __awaiter(this, void 0, void 0, function* () { + throw new Error('not implemented'); + }); + } +} +exports.BearerCredentialHandler = BearerCredentialHandler; +class PersonalAccessTokenCredentialHandler { + constructor(token) { + this.token = token; + } + // currently implements pre-authorization + // TODO: support preAuth = false where it hooks on 401 + prepareRequest(options) { + if (!options.headers) { + throw Error('The request has no headers'); + } + options.headers['Authorization'] = `Basic ${Buffer.from(`PAT:${this.token}`).toString('base64')}`; + } + // This handler cannot handle 401 + canHandleAuthentication() { + return false; + } + handleAuthentication() { + return __awaiter(this, void 0, void 0, function* () { + throw new Error('not implemented'); + }); + } +} +exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler; +//# sourceMappingURL=auth.js.map + +/***/ }), + +/***/ 6255: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +/* eslint-disable @typescript-eslint/no-explicit-any */ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.HttpClient = exports.isHttps = exports.HttpClientResponse = exports.HttpClientError = exports.getProxyUrl = exports.MediaTypes = exports.Headers = exports.HttpCodes = void 0; +const http = __importStar(__nccwpck_require__(3685)); +const https = __importStar(__nccwpck_require__(5687)); +const pm = __importStar(__nccwpck_require__(9835)); +const tunnel = __importStar(__nccwpck_require__(4294)); +var HttpCodes; +(function (HttpCodes) { + HttpCodes[HttpCodes["OK"] = 200] = "OK"; + HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices"; + HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently"; + HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved"; + HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther"; + HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified"; + HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy"; + HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy"; + HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect"; + HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect"; + HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest"; + HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized"; + HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired"; + HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden"; + HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound"; + HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed"; + HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable"; + HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired"; + HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout"; + HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict"; + HttpCodes[HttpCodes["Gone"] = 410] = "Gone"; + HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests"; + HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError"; + HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented"; + HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway"; + HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable"; + HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout"; +})(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {})); +var Headers; +(function (Headers) { + Headers["Accept"] = "accept"; + Headers["ContentType"] = "content-type"; +})(Headers = exports.Headers || (exports.Headers = {})); +var MediaTypes; +(function (MediaTypes) { + MediaTypes["ApplicationJson"] = "application/json"; +})(MediaTypes = exports.MediaTypes || (exports.MediaTypes = {})); +/** + * Returns the proxy URL, depending upon the supplied url and proxy environment variables. + * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com + */ +function getProxyUrl(serverUrl) { + const proxyUrl = pm.getProxyUrl(new URL(serverUrl)); + return proxyUrl ? proxyUrl.href : ''; +} +exports.getProxyUrl = getProxyUrl; +const HttpRedirectCodes = [ + HttpCodes.MovedPermanently, + HttpCodes.ResourceMoved, + HttpCodes.SeeOther, + HttpCodes.TemporaryRedirect, + HttpCodes.PermanentRedirect +]; +const HttpResponseRetryCodes = [ + HttpCodes.BadGateway, + HttpCodes.ServiceUnavailable, + HttpCodes.GatewayTimeout +]; +const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD']; +const ExponentialBackoffCeiling = 10; +const ExponentialBackoffTimeSlice = 5; +class HttpClientError extends Error { + constructor(message, statusCode) { + super(message); + this.name = 'HttpClientError'; + this.statusCode = statusCode; + Object.setPrototypeOf(this, HttpClientError.prototype); + } +} +exports.HttpClientError = HttpClientError; +class HttpClientResponse { + constructor(message) { + this.message = message; + } + readBody() { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + let output = Buffer.alloc(0); + this.message.on('data', (chunk) => { + output = Buffer.concat([output, chunk]); + }); + this.message.on('end', () => { + resolve(output.toString()); + }); + })); + }); + } +} +exports.HttpClientResponse = HttpClientResponse; +function isHttps(requestUrl) { + const parsedUrl = new URL(requestUrl); + return parsedUrl.protocol === 'https:'; +} +exports.isHttps = isHttps; +class HttpClient { + constructor(userAgent, handlers, requestOptions) { + this._ignoreSslError = false; + this._allowRedirects = true; + this._allowRedirectDowngrade = false; + this._maxRedirects = 50; + this._allowRetries = false; + this._maxRetries = 1; + this._keepAlive = false; + this._disposed = false; + this.userAgent = userAgent; + this.handlers = handlers || []; + this.requestOptions = requestOptions; + if (requestOptions) { + if (requestOptions.ignoreSslError != null) { + this._ignoreSslError = requestOptions.ignoreSslError; + } + this._socketTimeout = requestOptions.socketTimeout; + if (requestOptions.allowRedirects != null) { + this._allowRedirects = requestOptions.allowRedirects; + } + if (requestOptions.allowRedirectDowngrade != null) { + this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade; + } + if (requestOptions.maxRedirects != null) { + this._maxRedirects = Math.max(requestOptions.maxRedirects, 0); + } + if (requestOptions.keepAlive != null) { + this._keepAlive = requestOptions.keepAlive; + } + if (requestOptions.allowRetries != null) { + this._allowRetries = requestOptions.allowRetries; + } + if (requestOptions.maxRetries != null) { + this._maxRetries = requestOptions.maxRetries; + } + } + } + options(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('OPTIONS', requestUrl, null, additionalHeaders || {}); + }); + } + get(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('GET', requestUrl, null, additionalHeaders || {}); + }); + } + del(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('DELETE', requestUrl, null, additionalHeaders || {}); + }); + } + post(requestUrl, data, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('POST', requestUrl, data, additionalHeaders || {}); + }); + } + patch(requestUrl, data, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('PATCH', requestUrl, data, additionalHeaders || {}); + }); + } + put(requestUrl, data, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('PUT', requestUrl, data, additionalHeaders || {}); + }); + } + head(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('HEAD', requestUrl, null, additionalHeaders || {}); + }); + } + sendStream(verb, requestUrl, stream, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request(verb, requestUrl, stream, additionalHeaders); + }); + } + /** + * Gets a typed object from an endpoint + * Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise + */ + getJson(requestUrl, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + const res = yield this.get(requestUrl, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + postJson(requestUrl, obj, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + const data = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); + const res = yield this.post(requestUrl, data, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + putJson(requestUrl, obj, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + const data = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); + const res = yield this.put(requestUrl, data, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + patchJson(requestUrl, obj, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + const data = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); + const res = yield this.patch(requestUrl, data, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + /** + * Makes a raw http request. + * All other methods such as get, post, patch, and request ultimately call this. + * Prefer get, del, post and patch + */ + request(verb, requestUrl, data, headers) { + return __awaiter(this, void 0, void 0, function* () { + if (this._disposed) { + throw new Error('Client has already been disposed.'); + } + const parsedUrl = new URL(requestUrl); + let info = this._prepareRequest(verb, parsedUrl, headers); + // Only perform retries on reads since writes may not be idempotent. + const maxTries = this._allowRetries && RetryableHttpVerbs.includes(verb) + ? this._maxRetries + 1 + : 1; + let numTries = 0; + let response; + do { + response = yield this.requestRaw(info, data); + // Check if it's an authentication challenge + if (response && + response.message && + response.message.statusCode === HttpCodes.Unauthorized) { + let authenticationHandler; + for (const handler of this.handlers) { + if (handler.canHandleAuthentication(response)) { + authenticationHandler = handler; + break; + } + } + if (authenticationHandler) { + return authenticationHandler.handleAuthentication(this, info, data); + } + else { + // We have received an unauthorized response but have no handlers to handle it. + // Let the response return to the caller. + return response; + } + } + let redirectsRemaining = this._maxRedirects; + while (response.message.statusCode && + HttpRedirectCodes.includes(response.message.statusCode) && + this._allowRedirects && + redirectsRemaining > 0) { + const redirectUrl = response.message.headers['location']; + if (!redirectUrl) { + // if there's no location to redirect to, we won't + break; + } + const parsedRedirectUrl = new URL(redirectUrl); + if (parsedUrl.protocol === 'https:' && + parsedUrl.protocol !== parsedRedirectUrl.protocol && + !this._allowRedirectDowngrade) { + throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.'); + } + // we need to finish reading the response before reassigning response + // which will leak the open socket. + yield response.readBody(); + // strip authorization header if redirected to a different hostname + if (parsedRedirectUrl.hostname !== parsedUrl.hostname) { + for (const header in headers) { + // header names are case insensitive + if (header.toLowerCase() === 'authorization') { + delete headers[header]; + } + } + } + // let's make the request with the new redirectUrl + info = this._prepareRequest(verb, parsedRedirectUrl, headers); + response = yield this.requestRaw(info, data); + redirectsRemaining--; + } + if (!response.message.statusCode || + !HttpResponseRetryCodes.includes(response.message.statusCode)) { + // If not a retry code, return immediately instead of retrying + return response; + } + numTries += 1; + if (numTries < maxTries) { + yield response.readBody(); + yield this._performExponentialBackoff(numTries); + } + } while (numTries < maxTries); + return response; + }); + } + /** + * Needs to be called if keepAlive is set to true in request options. + */ + dispose() { + if (this._agent) { + this._agent.destroy(); + } + this._disposed = true; + } + /** + * Raw request. + * @param info + * @param data + */ + requestRaw(info, data) { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve, reject) => { + function callbackForResult(err, res) { + if (err) { + reject(err); + } + else if (!res) { + // If `err` is not passed, then `res` must be passed. + reject(new Error('Unknown error')); + } + else { + resolve(res); + } + } + this.requestRawWithCallback(info, data, callbackForResult); + }); + }); + } + /** + * Raw request with callback. + * @param info + * @param data + * @param onResult + */ + requestRawWithCallback(info, data, onResult) { + if (typeof data === 'string') { + if (!info.options.headers) { + info.options.headers = {}; + } + info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); + } + let callbackCalled = false; + function handleResult(err, res) { + if (!callbackCalled) { + callbackCalled = true; + onResult(err, res); + } + } + const req = info.httpModule.request(info.options, (msg) => { + const res = new HttpClientResponse(msg); + handleResult(undefined, res); + }); + let socket; + req.on('socket', sock => { + socket = sock; + }); + // If we ever get disconnected, we want the socket to timeout eventually + req.setTimeout(this._socketTimeout || 3 * 60000, () => { + if (socket) { + socket.end(); + } + handleResult(new Error(`Request timeout: ${info.options.path}`)); + }); + req.on('error', function (err) { + // err has statusCode property + // res should have headers + handleResult(err); + }); + if (data && typeof data === 'string') { + req.write(data, 'utf8'); + } + if (data && typeof data !== 'string') { + data.on('close', function () { + req.end(); + }); + data.pipe(req); + } + else { + req.end(); + } + } + /** + * Gets an http agent. This function is useful when you need an http agent that handles + * routing through a proxy server - depending upon the url and proxy environment variables. + * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com + */ + getAgent(serverUrl) { + const parsedUrl = new URL(serverUrl); + return this._getAgent(parsedUrl); + } + _prepareRequest(method, requestUrl, headers) { + const info = {}; + info.parsedUrl = requestUrl; + const usingSsl = info.parsedUrl.protocol === 'https:'; + info.httpModule = usingSsl ? https : http; + const defaultPort = usingSsl ? 443 : 80; + info.options = {}; + info.options.host = info.parsedUrl.hostname; + info.options.port = info.parsedUrl.port + ? parseInt(info.parsedUrl.port) + : defaultPort; + info.options.path = + (info.parsedUrl.pathname || '') + (info.parsedUrl.search || ''); + info.options.method = method; + info.options.headers = this._mergeHeaders(headers); + if (this.userAgent != null) { + info.options.headers['user-agent'] = this.userAgent; + } + info.options.agent = this._getAgent(info.parsedUrl); + // gives handlers an opportunity to participate + if (this.handlers) { + for (const handler of this.handlers) { + handler.prepareRequest(info.options); + } + } + return info; + } + _mergeHeaders(headers) { + if (this.requestOptions && this.requestOptions.headers) { + return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers || {})); + } + return lowercaseKeys(headers || {}); + } + _getExistingOrDefaultHeader(additionalHeaders, header, _default) { + let clientHeader; + if (this.requestOptions && this.requestOptions.headers) { + clientHeader = lowercaseKeys(this.requestOptions.headers)[header]; + } + return additionalHeaders[header] || clientHeader || _default; + } + _getAgent(parsedUrl) { + let agent; + const proxyUrl = pm.getProxyUrl(parsedUrl); + const useProxy = proxyUrl && proxyUrl.hostname; + if (this._keepAlive && useProxy) { + agent = this._proxyAgent; + } + if (this._keepAlive && !useProxy) { + agent = this._agent; + } + // if agent is already assigned use that agent. + if (agent) { + return agent; + } + const usingSsl = parsedUrl.protocol === 'https:'; + let maxSockets = 100; + if (this.requestOptions) { + maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets; + } + // This is `useProxy` again, but we need to check `proxyURl` directly for TypeScripts's flow analysis. + if (proxyUrl && proxyUrl.hostname) { + const agentOptions = { + maxSockets, + keepAlive: this._keepAlive, + proxy: Object.assign(Object.assign({}, ((proxyUrl.username || proxyUrl.password) && { + proxyAuth: `${proxyUrl.username}:${proxyUrl.password}` + })), { host: proxyUrl.hostname, port: proxyUrl.port }) + }; + let tunnelAgent; + const overHttps = proxyUrl.protocol === 'https:'; + if (usingSsl) { + tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp; + } + else { + tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp; + } + agent = tunnelAgent(agentOptions); + this._proxyAgent = agent; + } + // if reusing agent across request and tunneling agent isn't assigned create a new agent + if (this._keepAlive && !agent) { + const options = { keepAlive: this._keepAlive, maxSockets }; + agent = usingSsl ? new https.Agent(options) : new http.Agent(options); + this._agent = agent; + } + // if not using private agent and tunnel agent isn't setup then use global agent + if (!agent) { + agent = usingSsl ? https.globalAgent : http.globalAgent; + } + if (usingSsl && this._ignoreSslError) { + // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process + // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options + // we have to cast it to any and change it directly + agent.options = Object.assign(agent.options || {}, { + rejectUnauthorized: false + }); + } + return agent; + } + _performExponentialBackoff(retryNumber) { + return __awaiter(this, void 0, void 0, function* () { + retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); + const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); + return new Promise(resolve => setTimeout(() => resolve(), ms)); + }); + } + _processResponse(res, options) { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { + const statusCode = res.message.statusCode || 0; + const response = { + statusCode, + result: null, + headers: {} + }; + // not found leads to null obj returned + if (statusCode === HttpCodes.NotFound) { + resolve(response); + } + // get the result from the body + function dateTimeDeserializer(key, value) { + if (typeof value === 'string') { + const a = new Date(value); + if (!isNaN(a.valueOf())) { + return a; + } + } + return value; + } + let obj; + let contents; + try { + contents = yield res.readBody(); + if (contents && contents.length > 0) { + if (options && options.deserializeDates) { + obj = JSON.parse(contents, dateTimeDeserializer); + } + else { + obj = JSON.parse(contents); + } + response.result = obj; + } + response.headers = res.message.headers; + } + catch (err) { + // Invalid resource (contents not json); leaving result obj null + } + // note that 3xx redirects are handled by the http layer. + if (statusCode > 299) { + let msg; + // if exception/error in body, attempt to get better error + if (obj && obj.message) { + msg = obj.message; + } + else if (contents && contents.length > 0) { + // it may be the case that the exception is in the body message as string + msg = contents; + } + else { + msg = `Failed request: (${statusCode})`; + } + const err = new HttpClientError(msg, statusCode); + err.result = response.result; + reject(err); + } + else { + resolve(response); + } + })); + }); + } +} +exports.HttpClient = HttpClient; +const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {}); +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 9835: +/***/ ((__unused_webpack_module, exports) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.checkBypass = exports.getProxyUrl = void 0; +function getProxyUrl(reqUrl) { + const usingSsl = reqUrl.protocol === 'https:'; + if (checkBypass(reqUrl)) { + return undefined; + } + const proxyVar = (() => { + if (usingSsl) { + return process.env['https_proxy'] || process.env['HTTPS_PROXY']; + } + else { + return process.env['http_proxy'] || process.env['HTTP_PROXY']; + } + })(); + if (proxyVar) { + return new URL(proxyVar); + } + else { + return undefined; + } +} +exports.getProxyUrl = getProxyUrl; +function checkBypass(reqUrl) { + if (!reqUrl.hostname) { + return false; + } + const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || ''; + if (!noProxy) { + return false; + } + // Determine the request port + let reqPort; + if (reqUrl.port) { + reqPort = Number(reqUrl.port); + } + else if (reqUrl.protocol === 'http:') { + reqPort = 80; + } + else if (reqUrl.protocol === 'https:') { + reqPort = 443; + } + // Format the request hostname and hostname with port + const upperReqHosts = [reqUrl.hostname.toUpperCase()]; + if (typeof reqPort === 'number') { + upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`); + } + // Compare request host against noproxy + for (const upperNoProxyItem of noProxy + .split(',') + .map(x => x.trim().toUpperCase()) + .filter(x => x)) { + if (upperReqHosts.some(x => x === upperNoProxyItem)) { + return true; + } + } + return false; +} +exports.checkBypass = checkBypass; +//# sourceMappingURL=proxy.js.map + +/***/ }), + +/***/ 3664: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + + +const { Buffer } = __nccwpck_require__(4300) +const symbol = Symbol.for('BufferList') + +function BufferList (buf) { + if (!(this instanceof BufferList)) { + return new BufferList(buf) + } + + BufferList._init.call(this, buf) +} + +BufferList._init = function _init (buf) { + Object.defineProperty(this, symbol, { value: true }) + + this._bufs = [] + this.length = 0 + + if (buf) { + this.append(buf) + } +} + +BufferList.prototype._new = function _new (buf) { + return new BufferList(buf) +} + +BufferList.prototype._offset = function _offset (offset) { + if (offset === 0) { + return [0, 0] + } + + let tot = 0 + + for (let i = 0; i < this._bufs.length; i++) { + const _t = tot + this._bufs[i].length + if (offset < _t || i === this._bufs.length - 1) { + return [i, offset - tot] + } + tot = _t + } +} + +BufferList.prototype._reverseOffset = function (blOffset) { + const bufferId = blOffset[0] + let offset = blOffset[1] + + for (let i = 0; i < bufferId; i++) { + offset += this._bufs[i].length + } + + return offset +} + +BufferList.prototype.get = function get (index) { + if (index > this.length || index < 0) { + return undefined + } + + const offset = this._offset(index) + + return this._bufs[offset[0]][offset[1]] +} + +BufferList.prototype.slice = function slice (start, end) { + if (typeof start === 'number' && start < 0) { + start += this.length + } + + if (typeof end === 'number' && end < 0) { + end += this.length + } + + return this.copy(null, 0, start, end) +} + +BufferList.prototype.copy = function copy (dst, dstStart, srcStart, srcEnd) { + if (typeof srcStart !== 'number' || srcStart < 0) { + srcStart = 0 + } + + if (typeof srcEnd !== 'number' || srcEnd > this.length) { + srcEnd = this.length + } + + if (srcStart >= this.length) { + return dst || Buffer.alloc(0) + } + + if (srcEnd <= 0) { + return dst || Buffer.alloc(0) + } + + const copy = !!dst + const off = this._offset(srcStart) + const len = srcEnd - srcStart + let bytes = len + let bufoff = (copy && dstStart) || 0 + let start = off[1] + + // copy/slice everything + if (srcStart === 0 && srcEnd === this.length) { + if (!copy) { + // slice, but full concat if multiple buffers + return this._bufs.length === 1 + ? this._bufs[0] + : Buffer.concat(this._bufs, this.length) + } + + // copy, need to copy individual buffers + for (let i = 0; i < this._bufs.length; i++) { + this._bufs[i].copy(dst, bufoff) + bufoff += this._bufs[i].length + } + + return dst + } + + // easy, cheap case where it's a subset of one of the buffers + if (bytes <= this._bufs[off[0]].length - start) { + return copy + ? this._bufs[off[0]].copy(dst, dstStart, start, start + bytes) + : this._bufs[off[0]].slice(start, start + bytes) + } + + if (!copy) { + // a slice, we need something to copy in to + dst = Buffer.allocUnsafe(len) + } + + for (let i = off[0]; i < this._bufs.length; i++) { + const l = this._bufs[i].length - start + + if (bytes > l) { + this._bufs[i].copy(dst, bufoff, start) + bufoff += l + } else { + this._bufs[i].copy(dst, bufoff, start, start + bytes) + bufoff += l + break + } + + bytes -= l + + if (start) { + start = 0 + } + } + + // safeguard so that we don't return uninitialized memory + if (dst.length > bufoff) return dst.slice(0, bufoff) + + return dst +} + +BufferList.prototype.shallowSlice = function shallowSlice (start, end) { + start = start || 0 + end = typeof end !== 'number' ? this.length : end + + if (start < 0) { + start += this.length + } + + if (end < 0) { + end += this.length + } + + if (start === end) { + return this._new() + } + + const startOffset = this._offset(start) + const endOffset = this._offset(end) + const buffers = this._bufs.slice(startOffset[0], endOffset[0] + 1) + + if (endOffset[1] === 0) { + buffers.pop() + } else { + buffers[buffers.length - 1] = buffers[buffers.length - 1].slice(0, endOffset[1]) + } + + if (startOffset[1] !== 0) { + buffers[0] = buffers[0].slice(startOffset[1]) + } + + return this._new(buffers) +} + +BufferList.prototype.toString = function toString (encoding, start, end) { + return this.slice(start, end).toString(encoding) +} + +BufferList.prototype.consume = function consume (bytes) { + // first, normalize the argument, in accordance with how Buffer does it + bytes = Math.trunc(bytes) + // do nothing if not a positive number + if (Number.isNaN(bytes) || bytes <= 0) return this + + while (this._bufs.length) { + if (bytes >= this._bufs[0].length) { + bytes -= this._bufs[0].length + this.length -= this._bufs[0].length + this._bufs.shift() + } else { + this._bufs[0] = this._bufs[0].slice(bytes) + this.length -= bytes + break + } + } + + return this +} + +BufferList.prototype.duplicate = function duplicate () { + const copy = this._new() + + for (let i = 0; i < this._bufs.length; i++) { + copy.append(this._bufs[i]) + } + + return copy +} + +BufferList.prototype.append = function append (buf) { + if (buf == null) { + return this + } + + if (buf.buffer) { + // append a view of the underlying ArrayBuffer + this._appendBuffer(Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength)) + } else if (Array.isArray(buf)) { + for (let i = 0; i < buf.length; i++) { + this.append(buf[i]) + } + } else if (this._isBufferList(buf)) { + // unwrap argument into individual BufferLists + for (let i = 0; i < buf._bufs.length; i++) { + this.append(buf._bufs[i]) + } + } else { + // coerce number arguments to strings, since Buffer(number) does + // uninitialized memory allocation + if (typeof buf === 'number') { + buf = buf.toString() + } + + this._appendBuffer(Buffer.from(buf)) + } + + return this +} + +BufferList.prototype._appendBuffer = function appendBuffer (buf) { + this._bufs.push(buf) + this.length += buf.length +} + +BufferList.prototype.indexOf = function (search, offset, encoding) { + if (encoding === undefined && typeof offset === 'string') { + encoding = offset + offset = undefined + } + + if (typeof search === 'function' || Array.isArray(search)) { + throw new TypeError('The "value" argument must be one of type string, Buffer, BufferList, or Uint8Array.') + } else if (typeof search === 'number') { + search = Buffer.from([search]) + } else if (typeof search === 'string') { + search = Buffer.from(search, encoding) + } else if (this._isBufferList(search)) { + search = search.slice() + } else if (Array.isArray(search.buffer)) { + search = Buffer.from(search.buffer, search.byteOffset, search.byteLength) + } else if (!Buffer.isBuffer(search)) { + search = Buffer.from(search) + } + + offset = Number(offset || 0) + + if (isNaN(offset)) { + offset = 0 + } + + if (offset < 0) { + offset = this.length + offset + } + + if (offset < 0) { + offset = 0 + } + + if (search.length === 0) { + return offset > this.length ? this.length : offset + } + + const blOffset = this._offset(offset) + let blIndex = blOffset[0] // index of which internal buffer we're working on + let buffOffset = blOffset[1] // offset of the internal buffer we're working on + + // scan over each buffer + for (; blIndex < this._bufs.length; blIndex++) { + const buff = this._bufs[blIndex] + + while (buffOffset < buff.length) { + const availableWindow = buff.length - buffOffset + + if (availableWindow >= search.length) { + const nativeSearchResult = buff.indexOf(search, buffOffset) + + if (nativeSearchResult !== -1) { + return this._reverseOffset([blIndex, nativeSearchResult]) + } + + buffOffset = buff.length - search.length + 1 // end of native search window + } else { + const revOffset = this._reverseOffset([blIndex, buffOffset]) + + if (this._match(revOffset, search)) { + return revOffset + } + + buffOffset++ + } + } + + buffOffset = 0 + } + + return -1 +} + +BufferList.prototype._match = function (offset, search) { + if (this.length - offset < search.length) { + return false + } + + for (let searchOffset = 0; searchOffset < search.length; searchOffset++) { + if (this.get(offset + searchOffset) !== search[searchOffset]) { + return false + } + } + return true +} + +;(function () { + const methods = { + readDoubleBE: 8, + readDoubleLE: 8, + readFloatBE: 4, + readFloatLE: 4, + readInt32BE: 4, + readInt32LE: 4, + readUInt32BE: 4, + readUInt32LE: 4, + readInt16BE: 2, + readInt16LE: 2, + readUInt16BE: 2, + readUInt16LE: 2, + readInt8: 1, + readUInt8: 1, + readIntBE: null, + readIntLE: null, + readUIntBE: null, + readUIntLE: null + } + + for (const m in methods) { + (function (m) { + if (methods[m] === null) { + BufferList.prototype[m] = function (offset, byteLength) { + return this.slice(offset, offset + byteLength)[m](0, byteLength) + } + } else { + BufferList.prototype[m] = function (offset = 0) { + return this.slice(offset, offset + methods[m])[m](0) + } + } + }(m)) + } +}()) + +// Used internally by the class and also as an indicator of this object being +// a `BufferList`. It's not possible to use `instanceof BufferList` in a browser +// environment because there could be multiple different copies of the +// BufferList class and some `BufferList`s might be `BufferList`s. +BufferList.prototype._isBufferList = function _isBufferList (b) { + return b instanceof BufferList || BufferList.isBufferList(b) +} + +BufferList.isBufferList = function isBufferList (b) { + return b != null && b[symbol] +} + +module.exports = BufferList + + +/***/ }), + +/***/ 336: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + + +const DuplexStream = (__nccwpck_require__(1642).Duplex) +const inherits = __nccwpck_require__(4124) +const BufferList = __nccwpck_require__(3664) + +function BufferListStream (callback) { + if (!(this instanceof BufferListStream)) { + return new BufferListStream(callback) + } + + if (typeof callback === 'function') { + this._callback = callback + + const piper = function piper (err) { + if (this._callback) { + this._callback(err) + this._callback = null + } + }.bind(this) + + this.on('pipe', function onPipe (src) { + src.on('error', piper) + }) + this.on('unpipe', function onUnpipe (src) { + src.removeListener('error', piper) + }) + + callback = null + } + + BufferList._init.call(this, callback) + DuplexStream.call(this) +} + +inherits(BufferListStream, DuplexStream) +Object.assign(BufferListStream.prototype, BufferList.prototype) + +BufferListStream.prototype._new = function _new (callback) { + return new BufferListStream(callback) +} + +BufferListStream.prototype._write = function _write (buf, encoding, callback) { + this._appendBuffer(buf) + + if (typeof callback === 'function') { + callback() + } +} + +BufferListStream.prototype._read = function _read (size) { + if (!this.length) { + return this.push(null) + } + + size = Math.min(size, this.length) + this.push(this.slice(0, size)) + this.consume(size) +} + +BufferListStream.prototype.end = function end (chunk) { + DuplexStream.prototype.end.call(this, chunk) + + if (this._callback) { + this._callback(null, this.slice()) + this._callback = null + } +} + +BufferListStream.prototype._destroy = function _destroy (err, cb) { + this._bufs.length = 0 + this.length = 0 + cb(err) +} + +BufferListStream.prototype._isBufferList = function _isBufferList (b) { + return b instanceof BufferListStream || b instanceof BufferList || BufferListStream.isBufferList(b) +} + +BufferListStream.isBufferList = BufferList.isBufferList + +module.exports = BufferListStream +module.exports.BufferListStream = BufferListStream +module.exports.BufferList = BufferList + + +/***/ }), + +/***/ 1205: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +var once = __nccwpck_require__(1223); + +var noop = function() {}; + +var isRequest = function(stream) { + return stream.setHeader && typeof stream.abort === 'function'; +}; + +var isChildProcess = function(stream) { + return stream.stdio && Array.isArray(stream.stdio) && stream.stdio.length === 3 +}; + +var eos = function(stream, opts, callback) { + if (typeof opts === 'function') return eos(stream, null, opts); + if (!opts) opts = {}; + + callback = once(callback || noop); + + var ws = stream._writableState; + var rs = stream._readableState; + var readable = opts.readable || (opts.readable !== false && stream.readable); + var writable = opts.writable || (opts.writable !== false && stream.writable); + var cancelled = false; + + var onlegacyfinish = function() { + if (!stream.writable) onfinish(); + }; + + var onfinish = function() { + writable = false; + if (!readable) callback.call(stream); + }; + + var onend = function() { + readable = false; + if (!writable) callback.call(stream); + }; + + var onexit = function(exitCode) { + callback.call(stream, exitCode ? new Error('exited with error code: ' + exitCode) : null); + }; + + var onerror = function(err) { + callback.call(stream, err); + }; + + var onclose = function() { + process.nextTick(onclosenexttick); + }; + + var onclosenexttick = function() { + if (cancelled) return; + if (readable && !(rs && (rs.ended && !rs.destroyed))) return callback.call(stream, new Error('premature close')); + if (writable && !(ws && (ws.ended && !ws.destroyed))) return callback.call(stream, new Error('premature close')); + }; + + var onrequest = function() { + stream.req.on('finish', onfinish); + }; + + if (isRequest(stream)) { + stream.on('complete', onfinish); + stream.on('abort', onclose); + if (stream.req) onrequest(); + else stream.on('request', onrequest); + } else if (writable && !ws) { // legacy streams + stream.on('end', onlegacyfinish); + stream.on('close', onlegacyfinish); + } + + if (isChildProcess(stream)) stream.on('exit', onexit); + + stream.on('end', onend); + stream.on('finish', onfinish); + if (opts.error !== false) stream.on('error', onerror); + stream.on('close', onclose); + + return function() { + cancelled = true; + stream.removeListener('complete', onfinish); + stream.removeListener('abort', onclose); + stream.removeListener('request', onrequest); + if (stream.req) stream.req.removeListener('finish', onfinish); + stream.removeListener('end', onlegacyfinish); + stream.removeListener('close', onlegacyfinish); + stream.removeListener('finish', onfinish); + stream.removeListener('exit', onexit); + stream.removeListener('end', onend); + stream.removeListener('error', onerror); + stream.removeListener('close', onclose); + }; +}; + +module.exports = eos; + + +/***/ }), + +/***/ 3186: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +module.exports = (__nccwpck_require__(7147).constants) || __nccwpck_require__(2057) + + +/***/ }), + +/***/ 4124: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +try { + var util = __nccwpck_require__(3837); + /* istanbul ignore next */ + if (typeof util.inherits !== 'function') throw ''; + module.exports = util.inherits; +} catch (e) { + /* istanbul ignore next */ + module.exports = __nccwpck_require__(8544); +} + + +/***/ }), + +/***/ 8544: +/***/ ((module) => { + +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }) + } + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } + } +} + + +/***/ }), + +/***/ 1223: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +var wrappy = __nccwpck_require__(2940) +module.exports = wrappy(once) +module.exports.strict = wrappy(onceStrict) + +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) + }, + configurable: true + }) + + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this) + }, + configurable: true + }) +}) + +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) + } + f.called = false + return f +} + +function onceStrict (fn) { + var f = function () { + if (f.called) + throw new Error(f.onceError) + f.called = true + return f.value = fn.apply(this, arguments) + } + var name = fn.name || 'Function wrapped with `once`' + f.onceError = name + " shouldn't be called more than once" + f.called = false + return f +} + + +/***/ }), + +/***/ 7214: +/***/ ((module) => { + + + +const codes = {}; + +function createErrorType(code, message, Base) { + if (!Base) { + Base = Error + } + + function getMessage (arg1, arg2, arg3) { + if (typeof message === 'string') { + return message + } else { + return message(arg1, arg2, arg3) + } + } + + class NodeError extends Base { + constructor (arg1, arg2, arg3) { + super(getMessage(arg1, arg2, arg3)); + } + } + + NodeError.prototype.name = Base.name; + NodeError.prototype.code = code; + + codes[code] = NodeError; +} + +// https://github.com/nodejs/node/blob/v10.8.0/lib/internal/errors.js +function oneOf(expected, thing) { + if (Array.isArray(expected)) { + const len = expected.length; + expected = expected.map((i) => String(i)); + if (len > 2) { + return `one of ${thing} ${expected.slice(0, len - 1).join(', ')}, or ` + + expected[len - 1]; + } else if (len === 2) { + return `one of ${thing} ${expected[0]} or ${expected[1]}`; + } else { + return `of ${thing} ${expected[0]}`; + } + } else { + return `of ${thing} ${String(expected)}`; + } +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith +function startsWith(str, search, pos) { + return str.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith +function endsWith(str, search, this_len) { + if (this_len === undefined || this_len > str.length) { + this_len = str.length; + } + return str.substring(this_len - search.length, this_len) === search; +} + +// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes +function includes(str, search, start) { + if (typeof start !== 'number') { + start = 0; + } + + if (start + search.length > str.length) { + return false; + } else { + return str.indexOf(search, start) !== -1; + } +} + +createErrorType('ERR_INVALID_OPT_VALUE', function (name, value) { + return 'The value "' + value + '" is invalid for option "' + name + '"' +}, TypeError); +createErrorType('ERR_INVALID_ARG_TYPE', function (name, expected, actual) { + // determiner: 'must be' or 'must not be' + let determiner; + if (typeof expected === 'string' && startsWith(expected, 'not ')) { + determiner = 'must not be'; + expected = expected.replace(/^not /, ''); + } else { + determiner = 'must be'; + } + + let msg; + if (endsWith(name, ' argument')) { + // For cases like 'first argument' + msg = `The ${name} ${determiner} ${oneOf(expected, 'type')}`; + } else { + const type = includes(name, '.') ? 'property' : 'argument'; + msg = `The "${name}" ${type} ${determiner} ${oneOf(expected, 'type')}`; + } + + msg += `. Received type ${typeof actual}`; + return msg; +}, TypeError); +createErrorType('ERR_STREAM_PUSH_AFTER_EOF', 'stream.push() after EOF'); +createErrorType('ERR_METHOD_NOT_IMPLEMENTED', function (name) { + return 'The ' + name + ' method is not implemented' +}); +createErrorType('ERR_STREAM_PREMATURE_CLOSE', 'Premature close'); +createErrorType('ERR_STREAM_DESTROYED', function (name) { + return 'Cannot call ' + name + ' after a stream was destroyed'; +}); +createErrorType('ERR_MULTIPLE_CALLBACK', 'Callback called multiple times'); +createErrorType('ERR_STREAM_CANNOT_PIPE', 'Cannot pipe, not readable'); +createErrorType('ERR_STREAM_WRITE_AFTER_END', 'write after end'); +createErrorType('ERR_STREAM_NULL_VALUES', 'May not write null values to stream', TypeError); +createErrorType('ERR_UNKNOWN_ENCODING', function (arg) { + return 'Unknown encoding: ' + arg +}, TypeError); +createErrorType('ERR_STREAM_UNSHIFT_AFTER_END_EVENT', 'stream.unshift() after end event'); + +module.exports.q = codes; + + +/***/ }), + +/***/ 1359: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. +// a duplex stream is just a stream that is both readable and writable. +// Since JS doesn't have multiple prototypal inheritance, this class +// prototypally inherits from Readable, and then parasitically from +// Writable. + +/**/ + +var objectKeys = Object.keys || function (obj) { + var keys = []; + + for (var key in obj) { + keys.push(key); + } + + return keys; +}; +/**/ + + +module.exports = Duplex; + +var Readable = __nccwpck_require__(1433); + +var Writable = __nccwpck_require__(6993); + +__nccwpck_require__(4124)(Duplex, Readable); + +{ + // Allow the keys array to be GC'ed. + var keys = objectKeys(Writable.prototype); + + for (var v = 0; v < keys.length; v++) { + var method = keys[v]; + if (!Duplex.prototype[method]) Duplex.prototype[method] = Writable.prototype[method]; + } +} + +function Duplex(options) { + if (!(this instanceof Duplex)) return new Duplex(options); + Readable.call(this, options); + Writable.call(this, options); + this.allowHalfOpen = true; + + if (options) { + if (options.readable === false) this.readable = false; + if (options.writable === false) this.writable = false; + + if (options.allowHalfOpen === false) { + this.allowHalfOpen = false; + this.once('end', onend); + } + } +} + +Object.defineProperty(Duplex.prototype, 'writableHighWaterMark', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState.highWaterMark; + } +}); +Object.defineProperty(Duplex.prototype, 'writableBuffer', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState && this._writableState.getBuffer(); + } +}); +Object.defineProperty(Duplex.prototype, 'writableLength', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState.length; + } +}); // the no-half-open enforcer + +function onend() { + // If the writable side ended, then we're ok. + if (this._writableState.ended) return; // no more data can be written. + // But allow more writes to happen in this tick. + + process.nextTick(onEndNT, this); +} + +function onEndNT(self) { + self.end(); +} + +Object.defineProperty(Duplex.prototype, 'destroyed', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + if (this._readableState === undefined || this._writableState === undefined) { + return false; + } + + return this._readableState.destroyed && this._writableState.destroyed; + }, + set: function set(value) { + // we ignore the value if the stream + // has not been initialized yet + if (this._readableState === undefined || this._writableState === undefined) { + return; + } // backward compatibility, the user is explicitly + // managing destroyed + + + this._readableState.destroyed = value; + this._writableState.destroyed = value; + } +}); + +/***/ }), + +/***/ 1542: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. +// a passthrough stream. +// basically just the most minimal sort of Transform stream. +// Every written chunk gets output as-is. + + +module.exports = PassThrough; + +var Transform = __nccwpck_require__(4415); + +__nccwpck_require__(4124)(PassThrough, Transform); + +function PassThrough(options) { + if (!(this instanceof PassThrough)) return new PassThrough(options); + Transform.call(this, options); +} + +PassThrough.prototype._transform = function (chunk, encoding, cb) { + cb(null, chunk); +}; + +/***/ }), + +/***/ 1433: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + + +module.exports = Readable; +/**/ + +var Duplex; +/**/ + +Readable.ReadableState = ReadableState; +/**/ + +var EE = (__nccwpck_require__(2361).EventEmitter); + +var EElistenerCount = function EElistenerCount(emitter, type) { + return emitter.listeners(type).length; +}; +/**/ + +/**/ + + +var Stream = __nccwpck_require__(2387); +/**/ + + +var Buffer = (__nccwpck_require__(4300).Buffer); + +var OurUint8Array = global.Uint8Array || function () {}; + +function _uint8ArrayToBuffer(chunk) { + return Buffer.from(chunk); +} + +function _isUint8Array(obj) { + return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; +} +/**/ + + +var debugUtil = __nccwpck_require__(3837); + +var debug; + +if (debugUtil && debugUtil.debuglog) { + debug = debugUtil.debuglog('stream'); +} else { + debug = function debug() {}; +} +/**/ + + +var BufferList = __nccwpck_require__(2746); + +var destroyImpl = __nccwpck_require__(7049); + +var _require = __nccwpck_require__(9948), + getHighWaterMark = _require.getHighWaterMark; + +var _require$codes = (__nccwpck_require__(7214)/* .codes */ .q), + ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE, + ERR_STREAM_PUSH_AFTER_EOF = _require$codes.ERR_STREAM_PUSH_AFTER_EOF, + ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, + ERR_STREAM_UNSHIFT_AFTER_END_EVENT = _require$codes.ERR_STREAM_UNSHIFT_AFTER_END_EVENT; // Lazy loaded to improve the startup performance. + + +var StringDecoder; +var createReadableStreamAsyncIterator; +var from; + +__nccwpck_require__(4124)(Readable, Stream); + +var errorOrDestroy = destroyImpl.errorOrDestroy; +var kProxyEvents = ['error', 'close', 'destroy', 'pause', 'resume']; + +function prependListener(emitter, event, fn) { + // Sadly this is not cacheable as some libraries bundle their own + // event emitter implementation with them. + if (typeof emitter.prependListener === 'function') return emitter.prependListener(event, fn); // This is a hack to make sure that our error handler is attached before any + // userland ones. NEVER DO THIS. This is here only because this code needs + // to continue to work with older versions of Node.js that do not include + // the prependListener() method. The goal is to eventually remove this hack. + + if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (Array.isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; +} + +function ReadableState(options, stream, isDuplex) { + Duplex = Duplex || __nccwpck_require__(1359); + options = options || {}; // Duplex streams are both readable and writable, but share + // the same options object. + // However, some cases require setting options to different + // values for the readable and the writable sides of the duplex stream. + // These options can be provided separately as readableXXX and writableXXX. + + if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex; // object stream flag. Used to make read(n) ignore n and to + // make all the buffer merging and length checks go away + + this.objectMode = !!options.objectMode; + if (isDuplex) this.objectMode = this.objectMode || !!options.readableObjectMode; // the point at which it stops calling _read() to fill the buffer + // Note: 0 is a valid value, means "don't call _read preemptively ever" + + this.highWaterMark = getHighWaterMark(this, options, 'readableHighWaterMark', isDuplex); // A linked list is used to store data chunks instead of an array because the + // linked list can remove elements from the beginning faster than + // array.shift() + + this.buffer = new BufferList(); + this.length = 0; + this.pipes = null; + this.pipesCount = 0; + this.flowing = null; + this.ended = false; + this.endEmitted = false; + this.reading = false; // a flag to be able to tell if the event 'readable'/'data' is emitted + // immediately, or on a later tick. We set this to true at first, because + // any actions that shouldn't happen until "later" should generally also + // not happen before the first read call. + + this.sync = true; // whenever we return null, then we set a flag to say + // that we're awaiting a 'readable' event emission. + + this.needReadable = false; + this.emittedReadable = false; + this.readableListening = false; + this.resumeScheduled = false; + this.paused = true; // Should close be emitted on destroy. Defaults to true. + + this.emitClose = options.emitClose !== false; // Should .destroy() be called after 'end' (and potentially 'finish') + + this.autoDestroy = !!options.autoDestroy; // has it been destroyed + + this.destroyed = false; // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + + this.defaultEncoding = options.defaultEncoding || 'utf8'; // the number of writers that are awaiting a drain event in .pipe()s + + this.awaitDrain = 0; // if true, a maybeReadMore has been scheduled + + this.readingMore = false; + this.decoder = null; + this.encoding = null; + + if (options.encoding) { + if (!StringDecoder) StringDecoder = (__nccwpck_require__(4841)/* .StringDecoder */ .s); + this.decoder = new StringDecoder(options.encoding); + this.encoding = options.encoding; + } +} + +function Readable(options) { + Duplex = Duplex || __nccwpck_require__(1359); + if (!(this instanceof Readable)) return new Readable(options); // Checking for a Stream.Duplex instance is faster here instead of inside + // the ReadableState constructor, at least with V8 6.5 + + var isDuplex = this instanceof Duplex; + this._readableState = new ReadableState(options, this, isDuplex); // legacy + + this.readable = true; + + if (options) { + if (typeof options.read === 'function') this._read = options.read; + if (typeof options.destroy === 'function') this._destroy = options.destroy; + } + + Stream.call(this); +} + +Object.defineProperty(Readable.prototype, 'destroyed', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + if (this._readableState === undefined) { + return false; + } + + return this._readableState.destroyed; + }, + set: function set(value) { + // we ignore the value if the stream + // has not been initialized yet + if (!this._readableState) { + return; + } // backward compatibility, the user is explicitly + // managing destroyed + + + this._readableState.destroyed = value; + } +}); +Readable.prototype.destroy = destroyImpl.destroy; +Readable.prototype._undestroy = destroyImpl.undestroy; + +Readable.prototype._destroy = function (err, cb) { + cb(err); +}; // Manually shove something into the read() buffer. +// This returns true if the highWaterMark has not been hit yet, +// similar to how Writable.write() returns true if you should +// write() some more. + + +Readable.prototype.push = function (chunk, encoding) { + var state = this._readableState; + var skipChunkCheck; + + if (!state.objectMode) { + if (typeof chunk === 'string') { + encoding = encoding || state.defaultEncoding; + + if (encoding !== state.encoding) { + chunk = Buffer.from(chunk, encoding); + encoding = ''; + } + + skipChunkCheck = true; + } + } else { + skipChunkCheck = true; + } + + return readableAddChunk(this, chunk, encoding, false, skipChunkCheck); +}; // Unshift should *always* be something directly out of read() + + +Readable.prototype.unshift = function (chunk) { + return readableAddChunk(this, chunk, null, true, false); +}; + +function readableAddChunk(stream, chunk, encoding, addToFront, skipChunkCheck) { + debug('readableAddChunk', chunk); + var state = stream._readableState; + + if (chunk === null) { + state.reading = false; + onEofChunk(stream, state); + } else { + var er; + if (!skipChunkCheck) er = chunkInvalid(state, chunk); + + if (er) { + errorOrDestroy(stream, er); + } else if (state.objectMode || chunk && chunk.length > 0) { + if (typeof chunk !== 'string' && !state.objectMode && Object.getPrototypeOf(chunk) !== Buffer.prototype) { + chunk = _uint8ArrayToBuffer(chunk); + } + + if (addToFront) { + if (state.endEmitted) errorOrDestroy(stream, new ERR_STREAM_UNSHIFT_AFTER_END_EVENT());else addChunk(stream, state, chunk, true); + } else if (state.ended) { + errorOrDestroy(stream, new ERR_STREAM_PUSH_AFTER_EOF()); + } else if (state.destroyed) { + return false; + } else { + state.reading = false; + + if (state.decoder && !encoding) { + chunk = state.decoder.write(chunk); + if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state); + } else { + addChunk(stream, state, chunk, false); + } + } + } else if (!addToFront) { + state.reading = false; + maybeReadMore(stream, state); + } + } // We can push more data if we are below the highWaterMark. + // Also, if we have no data yet, we can stand some more bytes. + // This is to work around cases where hwm=0, such as the repl. + + + return !state.ended && (state.length < state.highWaterMark || state.length === 0); +} + +function addChunk(stream, state, chunk, addToFront) { + if (state.flowing && state.length === 0 && !state.sync) { + state.awaitDrain = 0; + stream.emit('data', chunk); + } else { + // update the buffer info. + state.length += state.objectMode ? 1 : chunk.length; + if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); + if (state.needReadable) emitReadable(stream); + } + + maybeReadMore(stream, state); +} + +function chunkInvalid(state, chunk) { + var er; + + if (!_isUint8Array(chunk) && typeof chunk !== 'string' && chunk !== undefined && !state.objectMode) { + er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer', 'Uint8Array'], chunk); + } + + return er; +} + +Readable.prototype.isPaused = function () { + return this._readableState.flowing === false; +}; // backwards compatibility. + + +Readable.prototype.setEncoding = function (enc) { + if (!StringDecoder) StringDecoder = (__nccwpck_require__(4841)/* .StringDecoder */ .s); + var decoder = new StringDecoder(enc); + this._readableState.decoder = decoder; // If setEncoding(null), decoder.encoding equals utf8 + + this._readableState.encoding = this._readableState.decoder.encoding; // Iterate over current buffer to convert already stored Buffers: + + var p = this._readableState.buffer.head; + var content = ''; + + while (p !== null) { + content += decoder.write(p.data); + p = p.next; + } + + this._readableState.buffer.clear(); + + if (content !== '') this._readableState.buffer.push(content); + this._readableState.length = content.length; + return this; +}; // Don't raise the hwm > 1GB + + +var MAX_HWM = 0x40000000; + +function computeNewHighWaterMark(n) { + if (n >= MAX_HWM) { + // TODO(ronag): Throw ERR_VALUE_OUT_OF_RANGE. + n = MAX_HWM; + } else { + // Get the next highest power of 2 to prevent increasing hwm excessively in + // tiny amounts + n--; + n |= n >>> 1; + n |= n >>> 2; + n |= n >>> 4; + n |= n >>> 8; + n |= n >>> 16; + n++; + } + + return n; +} // This function is designed to be inlinable, so please take care when making +// changes to the function body. + + +function howMuchToRead(n, state) { + if (n <= 0 || state.length === 0 && state.ended) return 0; + if (state.objectMode) return 1; + + if (n !== n) { + // Only flow one buffer at a time + if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; + } // If we're asking for more than the current hwm, then raise the hwm. + + + if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); + if (n <= state.length) return n; // Don't have enough + + if (!state.ended) { + state.needReadable = true; + return 0; + } + + return state.length; +} // you can override either this method, or the async _read(n) below. + + +Readable.prototype.read = function (n) { + debug('read', n); + n = parseInt(n, 10); + var state = this._readableState; + var nOrig = n; + if (n !== 0) state.emittedReadable = false; // if we're doing read(0) to trigger a readable event, but we + // already have a bunch of data in the buffer, then just trigger + // the 'readable' event and move on. + + if (n === 0 && state.needReadable && ((state.highWaterMark !== 0 ? state.length >= state.highWaterMark : state.length > 0) || state.ended)) { + debug('read: emitReadable', state.length, state.ended); + if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); + return null; + } + + n = howMuchToRead(n, state); // if we've ended, and we're now clear, then finish it up. + + if (n === 0 && state.ended) { + if (state.length === 0) endReadable(this); + return null; + } // All the actual chunk generation logic needs to be + // *below* the call to _read. The reason is that in certain + // synthetic stream cases, such as passthrough streams, _read + // may be a completely synchronous operation which may change + // the state of the read buffer, providing enough data when + // before there was *not* enough. + // + // So, the steps are: + // 1. Figure out what the state of things will be after we do + // a read from the buffer. + // + // 2. If that resulting state will trigger a _read, then call _read. + // Note that this may be asynchronous, or synchronous. Yes, it is + // deeply ugly to write APIs this way, but that still doesn't mean + // that the Readable class should behave improperly, as streams are + // designed to be sync/async agnostic. + // Take note if the _read call is sync or async (ie, if the read call + // has returned yet), so that we know whether or not it's safe to emit + // 'readable' etc. + // + // 3. Actually pull the requested chunks out of the buffer and return. + // if we need a readable event, then we need to do some reading. + + + var doRead = state.needReadable; + debug('need readable', doRead); // if we currently have less than the highWaterMark, then also read some + + if (state.length === 0 || state.length - n < state.highWaterMark) { + doRead = true; + debug('length less than watermark', doRead); + } // however, if we've ended, then there's no point, and if we're already + // reading, then it's unnecessary. + + + if (state.ended || state.reading) { + doRead = false; + debug('reading or ended', doRead); + } else if (doRead) { + debug('do read'); + state.reading = true; + state.sync = true; // if the length is currently zero, then we *need* a readable event. + + if (state.length === 0) state.needReadable = true; // call internal read method + + this._read(state.highWaterMark); + + state.sync = false; // If _read pushed data synchronously, then `reading` will be false, + // and we need to re-evaluate how much data we can return to the user. + + if (!state.reading) n = howMuchToRead(nOrig, state); + } + + var ret; + if (n > 0) ret = fromList(n, state);else ret = null; + + if (ret === null) { + state.needReadable = state.length <= state.highWaterMark; + n = 0; + } else { + state.length -= n; + state.awaitDrain = 0; + } + + if (state.length === 0) { + // If we have nothing in the buffer, then we want to know + // as soon as we *do* get something into the buffer. + if (!state.ended) state.needReadable = true; // If we tried to read() past the EOF, then emit end on the next tick. + + if (nOrig !== n && state.ended) endReadable(this); + } + + if (ret !== null) this.emit('data', ret); + return ret; +}; + +function onEofChunk(stream, state) { + debug('onEofChunk'); + if (state.ended) return; + + if (state.decoder) { + var chunk = state.decoder.end(); + + if (chunk && chunk.length) { + state.buffer.push(chunk); + state.length += state.objectMode ? 1 : chunk.length; + } + } + + state.ended = true; + + if (state.sync) { + // if we are sync, wait until next tick to emit the data. + // Otherwise we risk emitting data in the flow() + // the readable code triggers during a read() call + emitReadable(stream); + } else { + // emit 'readable' now to make sure it gets picked up. + state.needReadable = false; + + if (!state.emittedReadable) { + state.emittedReadable = true; + emitReadable_(stream); + } + } +} // Don't emit readable right away in sync mode, because this can trigger +// another read() call => stack overflow. This way, it might trigger +// a nextTick recursion warning, but that's not so bad. + + +function emitReadable(stream) { + var state = stream._readableState; + debug('emitReadable', state.needReadable, state.emittedReadable); + state.needReadable = false; + + if (!state.emittedReadable) { + debug('emitReadable', state.flowing); + state.emittedReadable = true; + process.nextTick(emitReadable_, stream); + } +} + +function emitReadable_(stream) { + var state = stream._readableState; + debug('emitReadable_', state.destroyed, state.length, state.ended); + + if (!state.destroyed && (state.length || state.ended)) { + stream.emit('readable'); + state.emittedReadable = false; + } // The stream needs another readable event if + // 1. It is not flowing, as the flow mechanism will take + // care of it. + // 2. It is not ended. + // 3. It is below the highWaterMark, so we can schedule + // another readable later. + + + state.needReadable = !state.flowing && !state.ended && state.length <= state.highWaterMark; + flow(stream); +} // at this point, the user has presumably seen the 'readable' event, +// and called read() to consume some data. that may have triggered +// in turn another _read(n) call, in which case reading = true if +// it's in progress. +// However, if we're not ended, or reading, and the length < hwm, +// then go ahead and try to read some more preemptively. + + +function maybeReadMore(stream, state) { + if (!state.readingMore) { + state.readingMore = true; + process.nextTick(maybeReadMore_, stream, state); + } +} + +function maybeReadMore_(stream, state) { + // Attempt to read more data if we should. + // + // The conditions for reading more data are (one of): + // - Not enough data buffered (state.length < state.highWaterMark). The loop + // is responsible for filling the buffer with enough data if such data + // is available. If highWaterMark is 0 and we are not in the flowing mode + // we should _not_ attempt to buffer any extra data. We'll get more data + // when the stream consumer calls read() instead. + // - No data in the buffer, and the stream is in flowing mode. In this mode + // the loop below is responsible for ensuring read() is called. Failing to + // call read here would abort the flow and there's no other mechanism for + // continuing the flow if the stream consumer has just subscribed to the + // 'data' event. + // + // In addition to the above conditions to keep reading data, the following + // conditions prevent the data from being read: + // - The stream has ended (state.ended). + // - There is already a pending 'read' operation (state.reading). This is a + // case where the the stream has called the implementation defined _read() + // method, but they are processing the call asynchronously and have _not_ + // called push() with new data. In this case we skip performing more + // read()s. The execution ends in this method again after the _read() ends + // up calling push() with more data. + while (!state.reading && !state.ended && (state.length < state.highWaterMark || state.flowing && state.length === 0)) { + var len = state.length; + debug('maybeReadMore read 0'); + stream.read(0); + if (len === state.length) // didn't get any data, stop spinning. + break; + } + + state.readingMore = false; +} // abstract method. to be overridden in specific implementation classes. +// call cb(er, data) where data is <= n in length. +// for virtual (non-string, non-buffer) streams, "length" is somewhat +// arbitrary, and perhaps not very meaningful. + + +Readable.prototype._read = function (n) { + errorOrDestroy(this, new ERR_METHOD_NOT_IMPLEMENTED('_read()')); +}; + +Readable.prototype.pipe = function (dest, pipeOpts) { + var src = this; + var state = this._readableState; + + switch (state.pipesCount) { + case 0: + state.pipes = dest; + break; + + case 1: + state.pipes = [state.pipes, dest]; + break; + + default: + state.pipes.push(dest); + break; + } + + state.pipesCount += 1; + debug('pipe count=%d opts=%j', state.pipesCount, pipeOpts); + var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; + var endFn = doEnd ? onend : unpipe; + if (state.endEmitted) process.nextTick(endFn);else src.once('end', endFn); + dest.on('unpipe', onunpipe); + + function onunpipe(readable, unpipeInfo) { + debug('onunpipe'); + + if (readable === src) { + if (unpipeInfo && unpipeInfo.hasUnpiped === false) { + unpipeInfo.hasUnpiped = true; + cleanup(); + } + } + } + + function onend() { + debug('onend'); + dest.end(); + } // when the dest drains, it reduces the awaitDrain counter + // on the source. This would be more elegant with a .once() + // handler in flow(), but adding and removing repeatedly is + // too slow. + + + var ondrain = pipeOnDrain(src); + dest.on('drain', ondrain); + var cleanedUp = false; + + function cleanup() { + debug('cleanup'); // cleanup event handlers once the pipe is broken + + dest.removeListener('close', onclose); + dest.removeListener('finish', onfinish); + dest.removeListener('drain', ondrain); + dest.removeListener('error', onerror); + dest.removeListener('unpipe', onunpipe); + src.removeListener('end', onend); + src.removeListener('end', unpipe); + src.removeListener('data', ondata); + cleanedUp = true; // if the reader is waiting for a drain event from this + // specific writer, then it would cause it to never start + // flowing again. + // So, if this is awaiting a drain, then we just call it now. + // If we don't know, then assume that we are waiting for one. + + if (state.awaitDrain && (!dest._writableState || dest._writableState.needDrain)) ondrain(); + } + + src.on('data', ondata); + + function ondata(chunk) { + debug('ondata'); + var ret = dest.write(chunk); + debug('dest.write', ret); + + if (ret === false) { + // If the user unpiped during `dest.write()`, it is possible + // to get stuck in a permanently paused state if that write + // also returned false. + // => Check whether `dest` is still a piping destination. + if ((state.pipesCount === 1 && state.pipes === dest || state.pipesCount > 1 && indexOf(state.pipes, dest) !== -1) && !cleanedUp) { + debug('false write response, pause', state.awaitDrain); + state.awaitDrain++; + } + + src.pause(); + } + } // if the dest has an error, then stop piping into it. + // however, don't suppress the throwing behavior for this. + + + function onerror(er) { + debug('onerror', er); + unpipe(); + dest.removeListener('error', onerror); + if (EElistenerCount(dest, 'error') === 0) errorOrDestroy(dest, er); + } // Make sure our error handler is attached before userland ones. + + + prependListener(dest, 'error', onerror); // Both close and finish should trigger unpipe, but only once. + + function onclose() { + dest.removeListener('finish', onfinish); + unpipe(); + } + + dest.once('close', onclose); + + function onfinish() { + debug('onfinish'); + dest.removeListener('close', onclose); + unpipe(); + } + + dest.once('finish', onfinish); + + function unpipe() { + debug('unpipe'); + src.unpipe(dest); + } // tell the dest that it's being piped to + + + dest.emit('pipe', src); // start the flow if it hasn't been started already. + + if (!state.flowing) { + debug('pipe resume'); + src.resume(); + } + + return dest; +}; + +function pipeOnDrain(src) { + return function pipeOnDrainFunctionResult() { + var state = src._readableState; + debug('pipeOnDrain', state.awaitDrain); + if (state.awaitDrain) state.awaitDrain--; + + if (state.awaitDrain === 0 && EElistenerCount(src, 'data')) { + state.flowing = true; + flow(src); + } + }; +} + +Readable.prototype.unpipe = function (dest) { + var state = this._readableState; + var unpipeInfo = { + hasUnpiped: false + }; // if we're not piping anywhere, then do nothing. + + if (state.pipesCount === 0) return this; // just one destination. most common case. + + if (state.pipesCount === 1) { + // passed in one, but it's not the right one. + if (dest && dest !== state.pipes) return this; + if (!dest) dest = state.pipes; // got a match. + + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + if (dest) dest.emit('unpipe', this, unpipeInfo); + return this; + } // slow case. multiple pipe destinations. + + + if (!dest) { + // remove all. + var dests = state.pipes; + var len = state.pipesCount; + state.pipes = null; + state.pipesCount = 0; + state.flowing = false; + + for (var i = 0; i < len; i++) { + dests[i].emit('unpipe', this, { + hasUnpiped: false + }); + } + + return this; + } // try to find the right one. + + + var index = indexOf(state.pipes, dest); + if (index === -1) return this; + state.pipes.splice(index, 1); + state.pipesCount -= 1; + if (state.pipesCount === 1) state.pipes = state.pipes[0]; + dest.emit('unpipe', this, unpipeInfo); + return this; +}; // set up data events if they are asked for +// Ensure readable listeners eventually get something + + +Readable.prototype.on = function (ev, fn) { + var res = Stream.prototype.on.call(this, ev, fn); + var state = this._readableState; + + if (ev === 'data') { + // update readableListening so that resume() may be a no-op + // a few lines down. This is needed to support once('readable'). + state.readableListening = this.listenerCount('readable') > 0; // Try start flowing on next tick if stream isn't explicitly paused + + if (state.flowing !== false) this.resume(); + } else if (ev === 'readable') { + if (!state.endEmitted && !state.readableListening) { + state.readableListening = state.needReadable = true; + state.flowing = false; + state.emittedReadable = false; + debug('on readable', state.length, state.reading); + + if (state.length) { + emitReadable(this); + } else if (!state.reading) { + process.nextTick(nReadingNextTick, this); + } + } + } + + return res; +}; + +Readable.prototype.addListener = Readable.prototype.on; + +Readable.prototype.removeListener = function (ev, fn) { + var res = Stream.prototype.removeListener.call(this, ev, fn); + + if (ev === 'readable') { + // We need to check if there is someone still listening to + // readable and reset the state. However this needs to happen + // after readable has been emitted but before I/O (nextTick) to + // support once('readable', fn) cycles. This means that calling + // resume within the same tick will have no + // effect. + process.nextTick(updateReadableListening, this); + } + + return res; +}; + +Readable.prototype.removeAllListeners = function (ev) { + var res = Stream.prototype.removeAllListeners.apply(this, arguments); + + if (ev === 'readable' || ev === undefined) { + // We need to check if there is someone still listening to + // readable and reset the state. However this needs to happen + // after readable has been emitted but before I/O (nextTick) to + // support once('readable', fn) cycles. This means that calling + // resume within the same tick will have no + // effect. + process.nextTick(updateReadableListening, this); + } + + return res; +}; + +function updateReadableListening(self) { + var state = self._readableState; + state.readableListening = self.listenerCount('readable') > 0; + + if (state.resumeScheduled && !state.paused) { + // flowing needs to be set to true now, otherwise + // the upcoming resume will not flow. + state.flowing = true; // crude way to check if we should resume + } else if (self.listenerCount('data') > 0) { + self.resume(); + } +} + +function nReadingNextTick(self) { + debug('readable nexttick read 0'); + self.read(0); +} // pause() and resume() are remnants of the legacy readable stream API +// If the user uses them, then switch into old mode. + + +Readable.prototype.resume = function () { + var state = this._readableState; + + if (!state.flowing) { + debug('resume'); // we flow only if there is no one listening + // for readable, but we still have to call + // resume() + + state.flowing = !state.readableListening; + resume(this, state); + } + + state.paused = false; + return this; +}; + +function resume(stream, state) { + if (!state.resumeScheduled) { + state.resumeScheduled = true; + process.nextTick(resume_, stream, state); + } +} + +function resume_(stream, state) { + debug('resume', state.reading); + + if (!state.reading) { + stream.read(0); + } + + state.resumeScheduled = false; + stream.emit('resume'); + flow(stream); + if (state.flowing && !state.reading) stream.read(0); +} + +Readable.prototype.pause = function () { + debug('call pause flowing=%j', this._readableState.flowing); + + if (this._readableState.flowing !== false) { + debug('pause'); + this._readableState.flowing = false; + this.emit('pause'); + } + + this._readableState.paused = true; + return this; +}; + +function flow(stream) { + var state = stream._readableState; + debug('flow', state.flowing); + + while (state.flowing && stream.read() !== null) { + ; + } +} // wrap an old-style stream as the async data source. +// This is *not* part of the readable stream interface. +// It is an ugly unfortunate mess of history. + + +Readable.prototype.wrap = function (stream) { + var _this = this; + + var state = this._readableState; + var paused = false; + stream.on('end', function () { + debug('wrapped end'); + + if (state.decoder && !state.ended) { + var chunk = state.decoder.end(); + if (chunk && chunk.length) _this.push(chunk); + } + + _this.push(null); + }); + stream.on('data', function (chunk) { + debug('wrapped data'); + if (state.decoder) chunk = state.decoder.write(chunk); // don't skip over falsy values in objectMode + + if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; + + var ret = _this.push(chunk); + + if (!ret) { + paused = true; + stream.pause(); + } + }); // proxy all the other methods. + // important when wrapping filters and duplexes. + + for (var i in stream) { + if (this[i] === undefined && typeof stream[i] === 'function') { + this[i] = function methodWrap(method) { + return function methodWrapReturnFunction() { + return stream[method].apply(stream, arguments); + }; + }(i); + } + } // proxy certain important events. + + + for (var n = 0; n < kProxyEvents.length; n++) { + stream.on(kProxyEvents[n], this.emit.bind(this, kProxyEvents[n])); + } // when we try to consume some more bytes, simply unpause the + // underlying stream. + + + this._read = function (n) { + debug('wrapped _read', n); + + if (paused) { + paused = false; + stream.resume(); + } + }; + + return this; +}; + +if (typeof Symbol === 'function') { + Readable.prototype[Symbol.asyncIterator] = function () { + if (createReadableStreamAsyncIterator === undefined) { + createReadableStreamAsyncIterator = __nccwpck_require__(3306); + } + + return createReadableStreamAsyncIterator(this); + }; +} + +Object.defineProperty(Readable.prototype, 'readableHighWaterMark', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._readableState.highWaterMark; + } +}); +Object.defineProperty(Readable.prototype, 'readableBuffer', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._readableState && this._readableState.buffer; + } +}); +Object.defineProperty(Readable.prototype, 'readableFlowing', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._readableState.flowing; + }, + set: function set(state) { + if (this._readableState) { + this._readableState.flowing = state; + } + } +}); // exposed for testing purposes only. + +Readable._fromList = fromList; +Object.defineProperty(Readable.prototype, 'readableLength', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._readableState.length; + } +}); // Pluck off n bytes from an array of buffers. +// Length is the combined lengths of all the buffers in the list. +// This function is designed to be inlinable, so please take care when making +// changes to the function body. + +function fromList(n, state) { + // nothing buffered + if (state.length === 0) return null; + var ret; + if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { + // read it all, truncate the list + if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.first();else ret = state.buffer.concat(state.length); + state.buffer.clear(); + } else { + // read part of list + ret = state.buffer.consume(n, state.decoder); + } + return ret; +} + +function endReadable(stream) { + var state = stream._readableState; + debug('endReadable', state.endEmitted); + + if (!state.endEmitted) { + state.ended = true; + process.nextTick(endReadableNT, state, stream); + } +} + +function endReadableNT(state, stream) { + debug('endReadableNT', state.endEmitted, state.length); // Check that we didn't get one last unshift. + + if (!state.endEmitted && state.length === 0) { + state.endEmitted = true; + stream.readable = false; + stream.emit('end'); + + if (state.autoDestroy) { + // In case of duplex streams we need a way to detect + // if the writable side is ready for autoDestroy as well + var wState = stream._writableState; + + if (!wState || wState.autoDestroy && wState.finished) { + stream.destroy(); + } + } + } +} + +if (typeof Symbol === 'function') { + Readable.from = function (iterable, opts) { + if (from === undefined) { + from = __nccwpck_require__(9082); + } + + return from(Readable, iterable, opts); + }; +} + +function indexOf(xs, x) { + for (var i = 0, l = xs.length; i < l; i++) { + if (xs[i] === x) return i; + } + + return -1; +} + +/***/ }), + +/***/ 4415: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. +// a transform stream is a readable/writable stream where you do +// something with the data. Sometimes it's called a "filter", +// but that's not a great name for it, since that implies a thing where +// some bits pass through, and others are simply ignored. (That would +// be a valid example of a transform, of course.) +// +// While the output is causally related to the input, it's not a +// necessarily symmetric or synchronous transformation. For example, +// a zlib stream might take multiple plain-text writes(), and then +// emit a single compressed chunk some time in the future. +// +// Here's how this works: +// +// The Transform stream has all the aspects of the readable and writable +// stream classes. When you write(chunk), that calls _write(chunk,cb) +// internally, and returns false if there's a lot of pending writes +// buffered up. When you call read(), that calls _read(n) until +// there's enough pending readable data buffered up. +// +// In a transform stream, the written data is placed in a buffer. When +// _read(n) is called, it transforms the queued up data, calling the +// buffered _write cb's as it consumes chunks. If consuming a single +// written chunk would result in multiple output chunks, then the first +// outputted bit calls the readcb, and subsequent chunks just go into +// the read buffer, and will cause it to emit 'readable' if necessary. +// +// This way, back-pressure is actually determined by the reading side, +// since _read has to be called to start processing a new chunk. However, +// a pathological inflate type of transform can cause excessive buffering +// here. For example, imagine a stream where every byte of input is +// interpreted as an integer from 0-255, and then results in that many +// bytes of output. Writing the 4 bytes {ff,ff,ff,ff} would result in +// 1kb of data being output. In this case, you could write a very small +// amount of input, and end up with a very large amount of output. In +// such a pathological inflating mechanism, there'd be no way to tell +// the system to stop doing the transform. A single 4MB write could +// cause the system to run out of memory. +// +// However, even in such a pathological case, only a single written chunk +// would be consumed, and then the rest would wait (un-transformed) until +// the results of the previous transformed chunk were consumed. + + +module.exports = Transform; + +var _require$codes = (__nccwpck_require__(7214)/* .codes */ .q), + ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, + ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK, + ERR_TRANSFORM_ALREADY_TRANSFORMING = _require$codes.ERR_TRANSFORM_ALREADY_TRANSFORMING, + ERR_TRANSFORM_WITH_LENGTH_0 = _require$codes.ERR_TRANSFORM_WITH_LENGTH_0; + +var Duplex = __nccwpck_require__(1359); + +__nccwpck_require__(4124)(Transform, Duplex); + +function afterTransform(er, data) { + var ts = this._transformState; + ts.transforming = false; + var cb = ts.writecb; + + if (cb === null) { + return this.emit('error', new ERR_MULTIPLE_CALLBACK()); + } + + ts.writechunk = null; + ts.writecb = null; + if (data != null) // single equals check for both `null` and `undefined` + this.push(data); + cb(er); + var rs = this._readableState; + rs.reading = false; + + if (rs.needReadable || rs.length < rs.highWaterMark) { + this._read(rs.highWaterMark); + } +} + +function Transform(options) { + if (!(this instanceof Transform)) return new Transform(options); + Duplex.call(this, options); + this._transformState = { + afterTransform: afterTransform.bind(this), + needTransform: false, + transforming: false, + writecb: null, + writechunk: null, + writeencoding: null + }; // start out asking for a readable event once data is transformed. + + this._readableState.needReadable = true; // we have implemented the _read method, and done the other things + // that Readable wants before the first _read call, so unset the + // sync guard flag. + + this._readableState.sync = false; + + if (options) { + if (typeof options.transform === 'function') this._transform = options.transform; + if (typeof options.flush === 'function') this._flush = options.flush; + } // When the writable side finishes, then flush out anything remaining. + + + this.on('prefinish', prefinish); +} + +function prefinish() { + var _this = this; + + if (typeof this._flush === 'function' && !this._readableState.destroyed) { + this._flush(function (er, data) { + done(_this, er, data); + }); + } else { + done(this, null, null); + } +} + +Transform.prototype.push = function (chunk, encoding) { + this._transformState.needTransform = false; + return Duplex.prototype.push.call(this, chunk, encoding); +}; // This is the part where you do stuff! +// override this function in implementation classes. +// 'chunk' is an input chunk. +// +// Call `push(newChunk)` to pass along transformed output +// to the readable side. You may call 'push' zero or more times. +// +// Call `cb(err)` when you are done with this chunk. If you pass +// an error, then that'll put the hurt on the whole operation. If you +// never call cb(), then you'll never get another chunk. + + +Transform.prototype._transform = function (chunk, encoding, cb) { + cb(new ERR_METHOD_NOT_IMPLEMENTED('_transform()')); +}; + +Transform.prototype._write = function (chunk, encoding, cb) { + var ts = this._transformState; + ts.writecb = cb; + ts.writechunk = chunk; + ts.writeencoding = encoding; + + if (!ts.transforming) { + var rs = this._readableState; + if (ts.needTransform || rs.needReadable || rs.length < rs.highWaterMark) this._read(rs.highWaterMark); + } +}; // Doesn't matter what the args are here. +// _transform does all the work. +// That we got here means that the readable side wants more data. + + +Transform.prototype._read = function (n) { + var ts = this._transformState; + + if (ts.writechunk !== null && !ts.transforming) { + ts.transforming = true; + + this._transform(ts.writechunk, ts.writeencoding, ts.afterTransform); + } else { + // mark that we need a transform, so that any data that comes in + // will get processed, now that we've asked for it. + ts.needTransform = true; + } +}; + +Transform.prototype._destroy = function (err, cb) { + Duplex.prototype._destroy.call(this, err, function (err2) { + cb(err2); + }); +}; + +function done(stream, er, data) { + if (er) return stream.emit('error', er); + if (data != null) // single equals check for both `null` and `undefined` + stream.push(data); // TODO(BridgeAR): Write a test for these two error cases + // if there's nothing in the write buffer, then that means + // that nothing more will ever be provided + + if (stream._writableState.length) throw new ERR_TRANSFORM_WITH_LENGTH_0(); + if (stream._transformState.transforming) throw new ERR_TRANSFORM_ALREADY_TRANSFORMING(); + return stream.push(null); +} + +/***/ }), + +/***/ 6993: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. +// A bit simpler than readable streams. +// Implement an async ._write(chunk, encoding, cb), and it'll handle all +// the drain event emission and buffering. + + +module.exports = Writable; +/* */ + +function WriteReq(chunk, encoding, cb) { + this.chunk = chunk; + this.encoding = encoding; + this.callback = cb; + this.next = null; +} // It seems a linked list but it is not +// there will be only 2 of these for each stream + + +function CorkedRequest(state) { + var _this = this; + + this.next = null; + this.entry = null; + + this.finish = function () { + onCorkedFinish(_this, state); + }; +} +/* */ + +/**/ + + +var Duplex; +/**/ + +Writable.WritableState = WritableState; +/**/ + +var internalUtil = { + deprecate: __nccwpck_require__(5278) +}; +/**/ + +/**/ + +var Stream = __nccwpck_require__(2387); +/**/ + + +var Buffer = (__nccwpck_require__(4300).Buffer); + +var OurUint8Array = global.Uint8Array || function () {}; + +function _uint8ArrayToBuffer(chunk) { + return Buffer.from(chunk); +} + +function _isUint8Array(obj) { + return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; +} + +var destroyImpl = __nccwpck_require__(7049); + +var _require = __nccwpck_require__(9948), + getHighWaterMark = _require.getHighWaterMark; + +var _require$codes = (__nccwpck_require__(7214)/* .codes */ .q), + ERR_INVALID_ARG_TYPE = _require$codes.ERR_INVALID_ARG_TYPE, + ERR_METHOD_NOT_IMPLEMENTED = _require$codes.ERR_METHOD_NOT_IMPLEMENTED, + ERR_MULTIPLE_CALLBACK = _require$codes.ERR_MULTIPLE_CALLBACK, + ERR_STREAM_CANNOT_PIPE = _require$codes.ERR_STREAM_CANNOT_PIPE, + ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED, + ERR_STREAM_NULL_VALUES = _require$codes.ERR_STREAM_NULL_VALUES, + ERR_STREAM_WRITE_AFTER_END = _require$codes.ERR_STREAM_WRITE_AFTER_END, + ERR_UNKNOWN_ENCODING = _require$codes.ERR_UNKNOWN_ENCODING; + +var errorOrDestroy = destroyImpl.errorOrDestroy; + +__nccwpck_require__(4124)(Writable, Stream); + +function nop() {} + +function WritableState(options, stream, isDuplex) { + Duplex = Duplex || __nccwpck_require__(1359); + options = options || {}; // Duplex streams are both readable and writable, but share + // the same options object. + // However, some cases require setting options to different + // values for the readable and the writable sides of the duplex stream, + // e.g. options.readableObjectMode vs. options.writableObjectMode, etc. + + if (typeof isDuplex !== 'boolean') isDuplex = stream instanceof Duplex; // object stream flag to indicate whether or not this stream + // contains buffers or objects. + + this.objectMode = !!options.objectMode; + if (isDuplex) this.objectMode = this.objectMode || !!options.writableObjectMode; // the point at which write() starts returning false + // Note: 0 is a valid value, means that we always return false if + // the entire buffer is not flushed immediately on write() + + this.highWaterMark = getHighWaterMark(this, options, 'writableHighWaterMark', isDuplex); // if _final has been called + + this.finalCalled = false; // drain event flag. + + this.needDrain = false; // at the start of calling end() + + this.ending = false; // when end() has been called, and returned + + this.ended = false; // when 'finish' is emitted + + this.finished = false; // has it been destroyed + + this.destroyed = false; // should we decode strings into buffers before passing to _write? + // this is here so that some node-core streams can optimize string + // handling at a lower level. + + var noDecode = options.decodeStrings === false; + this.decodeStrings = !noDecode; // Crypto is kind of old and crusty. Historically, its default string + // encoding is 'binary' so we have to make this configurable. + // Everything else in the universe uses 'utf8', though. + + this.defaultEncoding = options.defaultEncoding || 'utf8'; // not an actual buffer we keep track of, but a measurement + // of how much we're waiting to get pushed to some underlying + // socket or file. + + this.length = 0; // a flag to see when we're in the middle of a write. + + this.writing = false; // when true all writes will be buffered until .uncork() call + + this.corked = 0; // a flag to be able to tell if the onwrite cb is called immediately, + // or on a later tick. We set this to true at first, because any + // actions that shouldn't happen until "later" should generally also + // not happen before the first write call. + + this.sync = true; // a flag to know if we're processing previously buffered items, which + // may call the _write() callback in the same tick, so that we don't + // end up in an overlapped onwrite situation. + + this.bufferProcessing = false; // the callback that's passed to _write(chunk,cb) + + this.onwrite = function (er) { + onwrite(stream, er); + }; // the callback that the user supplies to write(chunk,encoding,cb) + + + this.writecb = null; // the amount that is being written when _write is called. + + this.writelen = 0; + this.bufferedRequest = null; + this.lastBufferedRequest = null; // number of pending user-supplied write callbacks + // this must be 0 before 'finish' can be emitted + + this.pendingcb = 0; // emit prefinish if the only thing we're waiting for is _write cbs + // This is relevant for synchronous Transform streams + + this.prefinished = false; // True if the error was already emitted and should not be thrown again + + this.errorEmitted = false; // Should close be emitted on destroy. Defaults to true. + + this.emitClose = options.emitClose !== false; // Should .destroy() be called after 'finish' (and potentially 'end') + + this.autoDestroy = !!options.autoDestroy; // count buffered requests + + this.bufferedRequestCount = 0; // allocate the first CorkedRequest, there is always + // one allocated and free to use, and we maintain at most two + + this.corkedRequestsFree = new CorkedRequest(this); +} + +WritableState.prototype.getBuffer = function getBuffer() { + var current = this.bufferedRequest; + var out = []; + + while (current) { + out.push(current); + current = current.next; + } + + return out; +}; + +(function () { + try { + Object.defineProperty(WritableState.prototype, 'buffer', { + get: internalUtil.deprecate(function writableStateBufferGetter() { + return this.getBuffer(); + }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003') + }); + } catch (_) {} +})(); // Test _writableState for inheritance to account for Duplex streams, +// whose prototype chain only points to Readable. + + +var realHasInstance; + +if (typeof Symbol === 'function' && Symbol.hasInstance && typeof Function.prototype[Symbol.hasInstance] === 'function') { + realHasInstance = Function.prototype[Symbol.hasInstance]; + Object.defineProperty(Writable, Symbol.hasInstance, { + value: function value(object) { + if (realHasInstance.call(this, object)) return true; + if (this !== Writable) return false; + return object && object._writableState instanceof WritableState; + } + }); +} else { + realHasInstance = function realHasInstance(object) { + return object instanceof this; + }; +} + +function Writable(options) { + Duplex = Duplex || __nccwpck_require__(1359); // Writable ctor is applied to Duplexes, too. + // `realHasInstance` is necessary because using plain `instanceof` + // would return false, as no `_writableState` property is attached. + // Trying to use the custom `instanceof` for Writable here will also break the + // Node.js LazyTransform implementation, which has a non-trivial getter for + // `_writableState` that would lead to infinite recursion. + // Checking for a Stream.Duplex instance is faster here instead of inside + // the WritableState constructor, at least with V8 6.5 + + var isDuplex = this instanceof Duplex; + if (!isDuplex && !realHasInstance.call(Writable, this)) return new Writable(options); + this._writableState = new WritableState(options, this, isDuplex); // legacy. + + this.writable = true; + + if (options) { + if (typeof options.write === 'function') this._write = options.write; + if (typeof options.writev === 'function') this._writev = options.writev; + if (typeof options.destroy === 'function') this._destroy = options.destroy; + if (typeof options.final === 'function') this._final = options.final; + } + + Stream.call(this); +} // Otherwise people can pipe Writable streams, which is just wrong. + + +Writable.prototype.pipe = function () { + errorOrDestroy(this, new ERR_STREAM_CANNOT_PIPE()); +}; + +function writeAfterEnd(stream, cb) { + var er = new ERR_STREAM_WRITE_AFTER_END(); // TODO: defer error events consistently everywhere, not just the cb + + errorOrDestroy(stream, er); + process.nextTick(cb, er); +} // Checks that a user-supplied chunk is valid, especially for the particular +// mode the stream is in. Currently this means that `null` is never accepted +// and undefined/non-string values are only allowed in object mode. + + +function validChunk(stream, state, chunk, cb) { + var er; + + if (chunk === null) { + er = new ERR_STREAM_NULL_VALUES(); + } else if (typeof chunk !== 'string' && !state.objectMode) { + er = new ERR_INVALID_ARG_TYPE('chunk', ['string', 'Buffer'], chunk); + } + + if (er) { + errorOrDestroy(stream, er); + process.nextTick(cb, er); + return false; + } + + return true; +} + +Writable.prototype.write = function (chunk, encoding, cb) { + var state = this._writableState; + var ret = false; + + var isBuf = !state.objectMode && _isUint8Array(chunk); + + if (isBuf && !Buffer.isBuffer(chunk)) { + chunk = _uint8ArrayToBuffer(chunk); + } + + if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; + if (typeof cb !== 'function') cb = nop; + if (state.ending) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { + state.pendingcb++; + ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); + } + return ret; +}; + +Writable.prototype.cork = function () { + this._writableState.corked++; +}; + +Writable.prototype.uncork = function () { + var state = this._writableState; + + if (state.corked) { + state.corked--; + if (!state.writing && !state.corked && !state.bufferProcessing && state.bufferedRequest) clearBuffer(this, state); + } +}; + +Writable.prototype.setDefaultEncoding = function setDefaultEncoding(encoding) { + // node::ParseEncoding() requires lower case. + if (typeof encoding === 'string') encoding = encoding.toLowerCase(); + if (!(['hex', 'utf8', 'utf-8', 'ascii', 'binary', 'base64', 'ucs2', 'ucs-2', 'utf16le', 'utf-16le', 'raw'].indexOf((encoding + '').toLowerCase()) > -1)) throw new ERR_UNKNOWN_ENCODING(encoding); + this._writableState.defaultEncoding = encoding; + return this; +}; + +Object.defineProperty(Writable.prototype, 'writableBuffer', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState && this._writableState.getBuffer(); + } +}); + +function decodeChunk(state, chunk, encoding) { + if (!state.objectMode && state.decodeStrings !== false && typeof chunk === 'string') { + chunk = Buffer.from(chunk, encoding); + } + + return chunk; +} + +Object.defineProperty(Writable.prototype, 'writableHighWaterMark', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState.highWaterMark; + } +}); // if we're already writing something, then just put this +// in the queue, and wait our turn. Otherwise, call _write +// If we return false, then we need a drain event, so set that flag. + +function writeOrBuffer(stream, state, isBuf, chunk, encoding, cb) { + if (!isBuf) { + var newChunk = decodeChunk(state, chunk, encoding); + + if (chunk !== newChunk) { + isBuf = true; + encoding = 'buffer'; + chunk = newChunk; + } + } + + var len = state.objectMode ? 1 : chunk.length; + state.length += len; + var ret = state.length < state.highWaterMark; // we must ensure that previous needDrain will not be reset to false. + + if (!ret) state.needDrain = true; + + if (state.writing || state.corked) { + var last = state.lastBufferedRequest; + state.lastBufferedRequest = { + chunk: chunk, + encoding: encoding, + isBuf: isBuf, + callback: cb, + next: null + }; + + if (last) { + last.next = state.lastBufferedRequest; + } else { + state.bufferedRequest = state.lastBufferedRequest; + } + + state.bufferedRequestCount += 1; + } else { + doWrite(stream, state, false, len, chunk, encoding, cb); + } + + return ret; +} + +function doWrite(stream, state, writev, len, chunk, encoding, cb) { + state.writelen = len; + state.writecb = cb; + state.writing = true; + state.sync = true; + if (state.destroyed) state.onwrite(new ERR_STREAM_DESTROYED('write'));else if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); + state.sync = false; +} + +function onwriteError(stream, state, sync, er, cb) { + --state.pendingcb; + + if (sync) { + // defer the callback if we are being called synchronously + // to avoid piling up things on the stack + process.nextTick(cb, er); // this can emit finish, and it will always happen + // after error + + process.nextTick(finishMaybe, stream, state); + stream._writableState.errorEmitted = true; + errorOrDestroy(stream, er); + } else { + // the caller expect this to happen before if + // it is async + cb(er); + stream._writableState.errorEmitted = true; + errorOrDestroy(stream, er); // this can emit finish, but finish must + // always follow error + + finishMaybe(stream, state); + } +} + +function onwriteStateUpdate(state) { + state.writing = false; + state.writecb = null; + state.length -= state.writelen; + state.writelen = 0; +} + +function onwrite(stream, er) { + var state = stream._writableState; + var sync = state.sync; + var cb = state.writecb; + if (typeof cb !== 'function') throw new ERR_MULTIPLE_CALLBACK(); + onwriteStateUpdate(state); + if (er) onwriteError(stream, state, sync, er, cb);else { + // Check if we're actually ready to finish, but don't emit yet + var finished = needFinish(state) || stream.destroyed; + + if (!finished && !state.corked && !state.bufferProcessing && state.bufferedRequest) { + clearBuffer(stream, state); + } + + if (sync) { + process.nextTick(afterWrite, stream, state, finished, cb); + } else { + afterWrite(stream, state, finished, cb); + } + } +} + +function afterWrite(stream, state, finished, cb) { + if (!finished) onwriteDrain(stream, state); + state.pendingcb--; + cb(); + finishMaybe(stream, state); +} // Must force callback to be called on nextTick, so that we don't +// emit 'drain' before the write() consumer gets the 'false' return +// value, and has a chance to attach a 'drain' listener. + + +function onwriteDrain(stream, state) { + if (state.length === 0 && state.needDrain) { + state.needDrain = false; + stream.emit('drain'); + } +} // if there's something in the buffer waiting, then process it + + +function clearBuffer(stream, state) { + state.bufferProcessing = true; + var entry = state.bufferedRequest; + + if (stream._writev && entry && entry.next) { + // Fast case, write everything using _writev() + var l = state.bufferedRequestCount; + var buffer = new Array(l); + var holder = state.corkedRequestsFree; + holder.entry = entry; + var count = 0; + var allBuffers = true; + + while (entry) { + buffer[count] = entry; + if (!entry.isBuf) allBuffers = false; + entry = entry.next; + count += 1; + } + + buffer.allBuffers = allBuffers; + doWrite(stream, state, true, state.length, buffer, '', holder.finish); // doWrite is almost always async, defer these to save a bit of time + // as the hot path ends with doWrite + + state.pendingcb++; + state.lastBufferedRequest = null; + + if (holder.next) { + state.corkedRequestsFree = holder.next; + holder.next = null; + } else { + state.corkedRequestsFree = new CorkedRequest(state); + } + + state.bufferedRequestCount = 0; + } else { + // Slow case, write chunks one-by-one + while (entry) { + var chunk = entry.chunk; + var encoding = entry.encoding; + var cb = entry.callback; + var len = state.objectMode ? 1 : chunk.length; + doWrite(stream, state, false, len, chunk, encoding, cb); + entry = entry.next; + state.bufferedRequestCount--; // if we didn't call the onwrite immediately, then + // it means that we need to wait until it does. + // also, that means that the chunk and cb are currently + // being processed, so move the buffer counter past them. + + if (state.writing) { + break; + } + } + + if (entry === null) state.lastBufferedRequest = null; + } + + state.bufferedRequest = entry; + state.bufferProcessing = false; +} + +Writable.prototype._write = function (chunk, encoding, cb) { + cb(new ERR_METHOD_NOT_IMPLEMENTED('_write()')); +}; + +Writable.prototype._writev = null; + +Writable.prototype.end = function (chunk, encoding, cb) { + var state = this._writableState; + + if (typeof chunk === 'function') { + cb = chunk; + chunk = null; + encoding = null; + } else if (typeof encoding === 'function') { + cb = encoding; + encoding = null; + } + + if (chunk !== null && chunk !== undefined) this.write(chunk, encoding); // .end() fully uncorks + + if (state.corked) { + state.corked = 1; + this.uncork(); + } // ignore unnecessary end() calls. + + + if (!state.ending) endWritable(this, state, cb); + return this; +}; + +Object.defineProperty(Writable.prototype, 'writableLength', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + return this._writableState.length; + } +}); + +function needFinish(state) { + return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; +} + +function callFinal(stream, state) { + stream._final(function (err) { + state.pendingcb--; + + if (err) { + errorOrDestroy(stream, err); + } + + state.prefinished = true; + stream.emit('prefinish'); + finishMaybe(stream, state); + }); +} + +function prefinish(stream, state) { + if (!state.prefinished && !state.finalCalled) { + if (typeof stream._final === 'function' && !state.destroyed) { + state.pendingcb++; + state.finalCalled = true; + process.nextTick(callFinal, stream, state); + } else { + state.prefinished = true; + stream.emit('prefinish'); + } + } +} + +function finishMaybe(stream, state) { + var need = needFinish(state); + + if (need) { + prefinish(stream, state); + + if (state.pendingcb === 0) { + state.finished = true; + stream.emit('finish'); + + if (state.autoDestroy) { + // In case of duplex streams we need a way to detect + // if the readable side is ready for autoDestroy as well + var rState = stream._readableState; + + if (!rState || rState.autoDestroy && rState.endEmitted) { + stream.destroy(); + } + } + } + } + + return need; +} + +function endWritable(stream, state, cb) { + state.ending = true; + finishMaybe(stream, state); + + if (cb) { + if (state.finished) process.nextTick(cb);else stream.once('finish', cb); + } + + state.ended = true; + stream.writable = false; +} + +function onCorkedFinish(corkReq, state, err) { + var entry = corkReq.entry; + corkReq.entry = null; + + while (entry) { + var cb = entry.callback; + state.pendingcb--; + cb(err); + entry = entry.next; + } // reuse the free corkReq. + + + state.corkedRequestsFree.next = corkReq; +} + +Object.defineProperty(Writable.prototype, 'destroyed', { + // making it explicit this property is not enumerable + // because otherwise some prototype manipulation in + // userland will fail + enumerable: false, + get: function get() { + if (this._writableState === undefined) { + return false; + } + + return this._writableState.destroyed; + }, + set: function set(value) { + // we ignore the value if the stream + // has not been initialized yet + if (!this._writableState) { + return; + } // backward compatibility, the user is explicitly + // managing destroyed + + + this._writableState.destroyed = value; + } +}); +Writable.prototype.destroy = destroyImpl.destroy; +Writable.prototype._undestroy = destroyImpl.undestroy; + +Writable.prototype._destroy = function (err, cb) { + cb(err); +}; + +/***/ }), + +/***/ 3306: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + + +var _Object$setPrototypeO; + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var finished = __nccwpck_require__(6080); + +var kLastResolve = Symbol('lastResolve'); +var kLastReject = Symbol('lastReject'); +var kError = Symbol('error'); +var kEnded = Symbol('ended'); +var kLastPromise = Symbol('lastPromise'); +var kHandlePromise = Symbol('handlePromise'); +var kStream = Symbol('stream'); + +function createIterResult(value, done) { + return { + value: value, + done: done + }; +} + +function readAndResolve(iter) { + var resolve = iter[kLastResolve]; + + if (resolve !== null) { + var data = iter[kStream].read(); // we defer if data is null + // we can be expecting either 'end' or + // 'error' + + if (data !== null) { + iter[kLastPromise] = null; + iter[kLastResolve] = null; + iter[kLastReject] = null; + resolve(createIterResult(data, false)); + } + } +} + +function onReadable(iter) { + // we wait for the next tick, because it might + // emit an error with process.nextTick + process.nextTick(readAndResolve, iter); +} + +function wrapForNext(lastPromise, iter) { + return function (resolve, reject) { + lastPromise.then(function () { + if (iter[kEnded]) { + resolve(createIterResult(undefined, true)); + return; + } + + iter[kHandlePromise](resolve, reject); + }, reject); + }; +} + +var AsyncIteratorPrototype = Object.getPrototypeOf(function () {}); +var ReadableStreamAsyncIteratorPrototype = Object.setPrototypeOf((_Object$setPrototypeO = { + get stream() { + return this[kStream]; + }, + + next: function next() { + var _this = this; + + // if we have detected an error in the meanwhile + // reject straight away + var error = this[kError]; + + if (error !== null) { + return Promise.reject(error); + } + + if (this[kEnded]) { + return Promise.resolve(createIterResult(undefined, true)); + } + + if (this[kStream].destroyed) { + // We need to defer via nextTick because if .destroy(err) is + // called, the error will be emitted via nextTick, and + // we cannot guarantee that there is no error lingering around + // waiting to be emitted. + return new Promise(function (resolve, reject) { + process.nextTick(function () { + if (_this[kError]) { + reject(_this[kError]); + } else { + resolve(createIterResult(undefined, true)); + } + }); + }); + } // if we have multiple next() calls + // we will wait for the previous Promise to finish + // this logic is optimized to support for await loops, + // where next() is only called once at a time + + + var lastPromise = this[kLastPromise]; + var promise; + + if (lastPromise) { + promise = new Promise(wrapForNext(lastPromise, this)); + } else { + // fast path needed to support multiple this.push() + // without triggering the next() queue + var data = this[kStream].read(); + + if (data !== null) { + return Promise.resolve(createIterResult(data, false)); + } + + promise = new Promise(this[kHandlePromise]); + } + + this[kLastPromise] = promise; + return promise; + } +}, _defineProperty(_Object$setPrototypeO, Symbol.asyncIterator, function () { + return this; +}), _defineProperty(_Object$setPrototypeO, "return", function _return() { + var _this2 = this; + + // destroy(err, cb) is a private API + // we can guarantee we have that here, because we control the + // Readable class this is attached to + return new Promise(function (resolve, reject) { + _this2[kStream].destroy(null, function (err) { + if (err) { + reject(err); + return; + } + + resolve(createIterResult(undefined, true)); + }); + }); +}), _Object$setPrototypeO), AsyncIteratorPrototype); + +var createReadableStreamAsyncIterator = function createReadableStreamAsyncIterator(stream) { + var _Object$create; + + var iterator = Object.create(ReadableStreamAsyncIteratorPrototype, (_Object$create = {}, _defineProperty(_Object$create, kStream, { + value: stream, + writable: true + }), _defineProperty(_Object$create, kLastResolve, { + value: null, + writable: true + }), _defineProperty(_Object$create, kLastReject, { + value: null, + writable: true + }), _defineProperty(_Object$create, kError, { + value: null, + writable: true + }), _defineProperty(_Object$create, kEnded, { + value: stream._readableState.endEmitted, + writable: true + }), _defineProperty(_Object$create, kHandlePromise, { + value: function value(resolve, reject) { + var data = iterator[kStream].read(); + + if (data) { + iterator[kLastPromise] = null; + iterator[kLastResolve] = null; + iterator[kLastReject] = null; + resolve(createIterResult(data, false)); + } else { + iterator[kLastResolve] = resolve; + iterator[kLastReject] = reject; + } + }, + writable: true + }), _Object$create)); + iterator[kLastPromise] = null; + finished(stream, function (err) { + if (err && err.code !== 'ERR_STREAM_PREMATURE_CLOSE') { + var reject = iterator[kLastReject]; // reject if we are waiting for data in the Promise + // returned by next() and store the error + + if (reject !== null) { + iterator[kLastPromise] = null; + iterator[kLastResolve] = null; + iterator[kLastReject] = null; + reject(err); + } + + iterator[kError] = err; + return; + } + + var resolve = iterator[kLastResolve]; + + if (resolve !== null) { + iterator[kLastPromise] = null; + iterator[kLastResolve] = null; + iterator[kLastReject] = null; + resolve(createIterResult(undefined, true)); + } + + iterator[kEnded] = true; + }); + stream.on('readable', onReadable.bind(null, iterator)); + return iterator; +}; + +module.exports = createReadableStreamAsyncIterator; + +/***/ }), + +/***/ 2746: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +var _require = __nccwpck_require__(4300), + Buffer = _require.Buffer; + +var _require2 = __nccwpck_require__(3837), + inspect = _require2.inspect; + +var custom = inspect && inspect.custom || 'inspect'; + +function copyBuffer(src, target, offset) { + Buffer.prototype.copy.call(src, target, offset); +} + +module.exports = +/*#__PURE__*/ +function () { + function BufferList() { + _classCallCheck(this, BufferList); + + this.head = null; + this.tail = null; + this.length = 0; + } + + _createClass(BufferList, [{ + key: "push", + value: function push(v) { + var entry = { + data: v, + next: null + }; + if (this.length > 0) this.tail.next = entry;else this.head = entry; + this.tail = entry; + ++this.length; + } + }, { + key: "unshift", + value: function unshift(v) { + var entry = { + data: v, + next: this.head + }; + if (this.length === 0) this.tail = entry; + this.head = entry; + ++this.length; + } + }, { + key: "shift", + value: function shift() { + if (this.length === 0) return; + var ret = this.head.data; + if (this.length === 1) this.head = this.tail = null;else this.head = this.head.next; + --this.length; + return ret; + } + }, { + key: "clear", + value: function clear() { + this.head = this.tail = null; + this.length = 0; + } + }, { + key: "join", + value: function join(s) { + if (this.length === 0) return ''; + var p = this.head; + var ret = '' + p.data; + + while (p = p.next) { + ret += s + p.data; + } + + return ret; + } + }, { + key: "concat", + value: function concat(n) { + if (this.length === 0) return Buffer.alloc(0); + var ret = Buffer.allocUnsafe(n >>> 0); + var p = this.head; + var i = 0; + + while (p) { + copyBuffer(p.data, ret, i); + i += p.data.length; + p = p.next; + } + + return ret; + } // Consumes a specified amount of bytes or characters from the buffered data. + + }, { + key: "consume", + value: function consume(n, hasStrings) { + var ret; + + if (n < this.head.data.length) { + // `slice` is the same for buffers and strings. + ret = this.head.data.slice(0, n); + this.head.data = this.head.data.slice(n); + } else if (n === this.head.data.length) { + // First chunk is a perfect match. + ret = this.shift(); + } else { + // Result spans more than one buffer. + ret = hasStrings ? this._getString(n) : this._getBuffer(n); + } + + return ret; + } + }, { + key: "first", + value: function first() { + return this.head.data; + } // Consumes a specified amount of characters from the buffered data. + + }, { + key: "_getString", + value: function _getString(n) { + var p = this.head; + var c = 1; + var ret = p.data; + n -= ret.length; + + while (p = p.next) { + var str = p.data; + var nb = n > str.length ? str.length : n; + if (nb === str.length) ret += str;else ret += str.slice(0, n); + n -= nb; + + if (n === 0) { + if (nb === str.length) { + ++c; + if (p.next) this.head = p.next;else this.head = this.tail = null; + } else { + this.head = p; + p.data = str.slice(nb); + } + + break; + } + + ++c; + } + + this.length -= c; + return ret; + } // Consumes a specified amount of bytes from the buffered data. + + }, { + key: "_getBuffer", + value: function _getBuffer(n) { + var ret = Buffer.allocUnsafe(n); + var p = this.head; + var c = 1; + p.data.copy(ret); + n -= p.data.length; + + while (p = p.next) { + var buf = p.data; + var nb = n > buf.length ? buf.length : n; + buf.copy(ret, ret.length - n, 0, nb); + n -= nb; + + if (n === 0) { + if (nb === buf.length) { + ++c; + if (p.next) this.head = p.next;else this.head = this.tail = null; + } else { + this.head = p; + p.data = buf.slice(nb); + } + + break; + } + + ++c; + } + + this.length -= c; + return ret; + } // Make sure the linked list only shows the minimal necessary information. + + }, { + key: custom, + value: function value(_, options) { + return inspect(this, _objectSpread({}, options, { + // Only inspect one level. + depth: 0, + // It should not recurse. + customInspect: false + })); + } + }]); + + return BufferList; +}(); + +/***/ }), + +/***/ 7049: +/***/ ((module) => { + + // undocumented cb() API, needed for core, not for public API + +function destroy(err, cb) { + var _this = this; + + var readableDestroyed = this._readableState && this._readableState.destroyed; + var writableDestroyed = this._writableState && this._writableState.destroyed; + + if (readableDestroyed || writableDestroyed) { + if (cb) { + cb(err); + } else if (err) { + if (!this._writableState) { + process.nextTick(emitErrorNT, this, err); + } else if (!this._writableState.errorEmitted) { + this._writableState.errorEmitted = true; + process.nextTick(emitErrorNT, this, err); + } + } + + return this; + } // we set destroyed to true before firing error callbacks in order + // to make it re-entrance safe in case destroy() is called within callbacks + + + if (this._readableState) { + this._readableState.destroyed = true; + } // if this is a duplex stream mark the writable part as destroyed as well + + + if (this._writableState) { + this._writableState.destroyed = true; + } + + this._destroy(err || null, function (err) { + if (!cb && err) { + if (!_this._writableState) { + process.nextTick(emitErrorAndCloseNT, _this, err); + } else if (!_this._writableState.errorEmitted) { + _this._writableState.errorEmitted = true; + process.nextTick(emitErrorAndCloseNT, _this, err); + } else { + process.nextTick(emitCloseNT, _this); + } + } else if (cb) { + process.nextTick(emitCloseNT, _this); + cb(err); + } else { + process.nextTick(emitCloseNT, _this); + } + }); + + return this; +} + +function emitErrorAndCloseNT(self, err) { + emitErrorNT(self, err); + emitCloseNT(self); +} + +function emitCloseNT(self) { + if (self._writableState && !self._writableState.emitClose) return; + if (self._readableState && !self._readableState.emitClose) return; + self.emit('close'); +} + +function undestroy() { + if (this._readableState) { + this._readableState.destroyed = false; + this._readableState.reading = false; + this._readableState.ended = false; + this._readableState.endEmitted = false; + } + + if (this._writableState) { + this._writableState.destroyed = false; + this._writableState.ended = false; + this._writableState.ending = false; + this._writableState.finalCalled = false; + this._writableState.prefinished = false; + this._writableState.finished = false; + this._writableState.errorEmitted = false; + } +} + +function emitErrorNT(self, err) { + self.emit('error', err); +} + +function errorOrDestroy(stream, err) { + // We have tests that rely on errors being emitted + // in the same tick, so changing this is semver major. + // For now when you opt-in to autoDestroy we allow + // the error to be emitted nextTick. In a future + // semver major update we should change the default to this. + var rState = stream._readableState; + var wState = stream._writableState; + if (rState && rState.autoDestroy || wState && wState.autoDestroy) stream.destroy(err);else stream.emit('error', err); +} + +module.exports = { + destroy: destroy, + undestroy: undestroy, + errorOrDestroy: errorOrDestroy +}; + +/***/ }), + +/***/ 6080: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +// Ported from https://github.com/mafintosh/end-of-stream with +// permission from the author, Mathias Buus (@mafintosh). + + +var ERR_STREAM_PREMATURE_CLOSE = (__nccwpck_require__(7214)/* .codes.ERR_STREAM_PREMATURE_CLOSE */ .q.ERR_STREAM_PREMATURE_CLOSE); + +function once(callback) { + var called = false; + return function () { + if (called) return; + called = true; + + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + callback.apply(this, args); + }; +} + +function noop() {} + +function isRequest(stream) { + return stream.setHeader && typeof stream.abort === 'function'; +} + +function eos(stream, opts, callback) { + if (typeof opts === 'function') return eos(stream, null, opts); + if (!opts) opts = {}; + callback = once(callback || noop); + var readable = opts.readable || opts.readable !== false && stream.readable; + var writable = opts.writable || opts.writable !== false && stream.writable; + + var onlegacyfinish = function onlegacyfinish() { + if (!stream.writable) onfinish(); + }; + + var writableEnded = stream._writableState && stream._writableState.finished; + + var onfinish = function onfinish() { + writable = false; + writableEnded = true; + if (!readable) callback.call(stream); + }; + + var readableEnded = stream._readableState && stream._readableState.endEmitted; + + var onend = function onend() { + readable = false; + readableEnded = true; + if (!writable) callback.call(stream); + }; + + var onerror = function onerror(err) { + callback.call(stream, err); + }; + + var onclose = function onclose() { + var err; + + if (readable && !readableEnded) { + if (!stream._readableState || !stream._readableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE(); + return callback.call(stream, err); + } + + if (writable && !writableEnded) { + if (!stream._writableState || !stream._writableState.ended) err = new ERR_STREAM_PREMATURE_CLOSE(); + return callback.call(stream, err); + } + }; + + var onrequest = function onrequest() { + stream.req.on('finish', onfinish); + }; + + if (isRequest(stream)) { + stream.on('complete', onfinish); + stream.on('abort', onclose); + if (stream.req) onrequest();else stream.on('request', onrequest); + } else if (writable && !stream._writableState) { + // legacy streams + stream.on('end', onlegacyfinish); + stream.on('close', onlegacyfinish); + } + + stream.on('end', onend); + stream.on('finish', onfinish); + if (opts.error !== false) stream.on('error', onerror); + stream.on('close', onclose); + return function () { + stream.removeListener('complete', onfinish); + stream.removeListener('abort', onclose); + stream.removeListener('request', onrequest); + if (stream.req) stream.req.removeListener('finish', onfinish); + stream.removeListener('end', onlegacyfinish); + stream.removeListener('close', onlegacyfinish); + stream.removeListener('finish', onfinish); + stream.removeListener('end', onend); + stream.removeListener('error', onerror); + stream.removeListener('close', onclose); + }; +} + +module.exports = eos; + +/***/ }), + +/***/ 9082: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + + +function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } + +function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } + +function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } + +function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } + +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } + +var ERR_INVALID_ARG_TYPE = (__nccwpck_require__(7214)/* .codes.ERR_INVALID_ARG_TYPE */ .q.ERR_INVALID_ARG_TYPE); + +function from(Readable, iterable, opts) { + var iterator; + + if (iterable && typeof iterable.next === 'function') { + iterator = iterable; + } else if (iterable && iterable[Symbol.asyncIterator]) iterator = iterable[Symbol.asyncIterator]();else if (iterable && iterable[Symbol.iterator]) iterator = iterable[Symbol.iterator]();else throw new ERR_INVALID_ARG_TYPE('iterable', ['Iterable'], iterable); + + var readable = new Readable(_objectSpread({ + objectMode: true + }, opts)); // Reading boolean to protect against _read + // being called before last iteration completion. + + var reading = false; + + readable._read = function () { + if (!reading) { + reading = true; + next(); + } + }; + + function next() { + return _next2.apply(this, arguments); + } + + function _next2() { + _next2 = _asyncToGenerator(function* () { + try { + var _ref = yield iterator.next(), + value = _ref.value, + done = _ref.done; + + if (done) { + readable.push(null); + } else if (readable.push((yield value))) { + next(); + } else { + reading = false; + } + } catch (err) { + readable.destroy(err); + } + }); + return _next2.apply(this, arguments); + } + + return readable; +} + +module.exports = from; + +/***/ }), + +/***/ 6989: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +// Ported from https://github.com/mafintosh/pump with +// permission from the author, Mathias Buus (@mafintosh). + + +var eos; + +function once(callback) { + var called = false; + return function () { + if (called) return; + called = true; + callback.apply(void 0, arguments); + }; +} + +var _require$codes = (__nccwpck_require__(7214)/* .codes */ .q), + ERR_MISSING_ARGS = _require$codes.ERR_MISSING_ARGS, + ERR_STREAM_DESTROYED = _require$codes.ERR_STREAM_DESTROYED; + +function noop(err) { + // Rethrow the error if it exists to avoid swallowing it + if (err) throw err; +} + +function isRequest(stream) { + return stream.setHeader && typeof stream.abort === 'function'; +} + +function destroyer(stream, reading, writing, callback) { + callback = once(callback); + var closed = false; + stream.on('close', function () { + closed = true; + }); + if (eos === undefined) eos = __nccwpck_require__(6080); + eos(stream, { + readable: reading, + writable: writing + }, function (err) { + if (err) return callback(err); + closed = true; + callback(); + }); + var destroyed = false; + return function (err) { + if (closed) return; + if (destroyed) return; + destroyed = true; // request.destroy just do .end - .abort is what we want + + if (isRequest(stream)) return stream.abort(); + if (typeof stream.destroy === 'function') return stream.destroy(); + callback(err || new ERR_STREAM_DESTROYED('pipe')); + }; +} + +function call(fn) { + fn(); +} + +function pipe(from, to) { + return from.pipe(to); +} + +function popCallback(streams) { + if (!streams.length) return noop; + if (typeof streams[streams.length - 1] !== 'function') return noop; + return streams.pop(); +} + +function pipeline() { + for (var _len = arguments.length, streams = new Array(_len), _key = 0; _key < _len; _key++) { + streams[_key] = arguments[_key]; + } + + var callback = popCallback(streams); + if (Array.isArray(streams[0])) streams = streams[0]; + + if (streams.length < 2) { + throw new ERR_MISSING_ARGS('streams'); + } + + var error; + var destroys = streams.map(function (stream, i) { + var reading = i < streams.length - 1; + var writing = i > 0; + return destroyer(stream, reading, writing, function (err) { + if (!error) error = err; + if (err) destroys.forEach(call); + if (reading) return; + destroys.forEach(call); + callback(error); + }); + }); + return streams.reduce(pipe); +} + +module.exports = pipeline; + +/***/ }), + +/***/ 9948: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + + +var ERR_INVALID_OPT_VALUE = (__nccwpck_require__(7214)/* .codes.ERR_INVALID_OPT_VALUE */ .q.ERR_INVALID_OPT_VALUE); + +function highWaterMarkFrom(options, isDuplex, duplexKey) { + return options.highWaterMark != null ? options.highWaterMark : isDuplex ? options[duplexKey] : null; +} + +function getHighWaterMark(state, options, duplexKey, isDuplex) { + var hwm = highWaterMarkFrom(options, isDuplex, duplexKey); + + if (hwm != null) { + if (!(isFinite(hwm) && Math.floor(hwm) === hwm) || hwm < 0) { + var name = isDuplex ? duplexKey : 'highWaterMark'; + throw new ERR_INVALID_OPT_VALUE(name, hwm); + } + + return Math.floor(hwm); + } // Default value + + + return state.objectMode ? 16 : 16 * 1024; +} + +module.exports = { + getHighWaterMark: getHighWaterMark +}; + +/***/ }), + +/***/ 2387: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +module.exports = __nccwpck_require__(2781); + + +/***/ }), + +/***/ 1642: +/***/ ((module, exports, __nccwpck_require__) => { + +var Stream = __nccwpck_require__(2781); +if (process.env.READABLE_STREAM === 'disable' && Stream) { + module.exports = Stream.Readable; + Object.assign(module.exports, Stream); + module.exports.Stream = Stream; +} else { + exports = module.exports = __nccwpck_require__(1433); + exports.Stream = Stream || exports; + exports.Readable = exports; + exports.Writable = __nccwpck_require__(6993); + exports.Duplex = __nccwpck_require__(1359); + exports.Transform = __nccwpck_require__(4415); + exports.PassThrough = __nccwpck_require__(1542); + exports.finished = __nccwpck_require__(6080); + exports.pipeline = __nccwpck_require__(6989); +} + + +/***/ }), + +/***/ 1867: +/***/ ((module, exports, __nccwpck_require__) => { + /*! safe-buffer. MIT License. Feross Aboukhadijeh */ -var n=r(4300);var i=n.Buffer;function copyProps(e,t){for(var r in e){t[r]=e[r]}}if(i.from&&i.alloc&&i.allocUnsafe&&i.allocUnsafeSlow){e.exports=n}else{copyProps(n,t);t.Buffer=SafeBuffer}function SafeBuffer(e,t,r){return i(e,t,r)}SafeBuffer.prototype=Object.create(i.prototype);copyProps(i,SafeBuffer);SafeBuffer.from=function(e,t,r){if(typeof e==="number"){throw new TypeError("Argument must not be a number")}return i(e,t,r)};SafeBuffer.alloc=function(e,t,r){if(typeof e!=="number"){throw new TypeError("Argument must be a number")}var n=i(e);if(t!==undefined){if(typeof r==="string"){n.fill(t,r)}else{n.fill(t)}}else{n.fill(0)}return n};SafeBuffer.allocUnsafe=function(e){if(typeof e!=="number"){throw new TypeError("Argument must be a number")}return i(e)};SafeBuffer.allocUnsafeSlow=function(e){if(typeof e!=="number"){throw new TypeError("Argument must be a number")}return n.SlowBuffer(e)}},4841:(e,t,r)=>{var n=r(1867).Buffer;var i=n.isEncoding||function(e){e=""+e;switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return true;default:return false}};function _normalizeEncoding(e){if(!e)return"utf8";var t;while(true){switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase();t=true}}}function normalizeEncoding(e){var t=_normalizeEncoding(e);if(typeof t!=="string"&&(n.isEncoding===i||!i(e)))throw new Error("Unknown encoding: "+e);return t||e}t.s=StringDecoder;function StringDecoder(e){this.encoding=normalizeEncoding(e);var t;switch(this.encoding){case"utf16le":this.text=utf16Text;this.end=utf16End;t=4;break;case"utf8":this.fillLast=utf8FillLast;t=4;break;case"base64":this.text=base64Text;this.end=base64End;t=3;break;default:this.write=simpleWrite;this.end=simpleEnd;return}this.lastNeed=0;this.lastTotal=0;this.lastChar=n.allocUnsafe(t)}StringDecoder.prototype.write=function(e){if(e.length===0)return"";var t;var r;if(this.lastNeed){t=this.fillLast(e);if(t===undefined)return"";r=this.lastNeed;this.lastNeed=0}else{r=0}if(r>5===6)return 2;else if(e>>4===14)return 3;else if(e>>3===30)return 4;return e>>6===2?-1:-2}function utf8CheckIncomplete(e,t,r){var n=t.length-1;if(n=0){if(i>0)e.lastNeed=i-1;return i}if(--n=0){if(i>0)e.lastNeed=i-2;return i}if(--n=0){if(i>0){if(i===2)i=0;else e.lastNeed=i-3}return i}return 0}function utf8CheckExtraBytes(e,t,r){if((t[0]&192)!==128){e.lastNeed=0;return"�"}if(e.lastNeed>1&&t.length>1){if((t[1]&192)!==128){e.lastNeed=1;return"�"}if(e.lastNeed>2&&t.length>2){if((t[2]&192)!==128){e.lastNeed=2;return"�"}}}}function utf8FillLast(e){var t=this.lastTotal-this.lastNeed;var r=utf8CheckExtraBytes(this,e,t);if(r!==undefined)return r;if(this.lastNeed<=e.length){e.copy(this.lastChar,t,0,this.lastNeed);return this.lastChar.toString(this.encoding,0,this.lastTotal)}e.copy(this.lastChar,t,0,e.length);this.lastNeed-=e.length}function utf8Text(e,t){var r=utf8CheckIncomplete(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=r;var n=e.length-(r-this.lastNeed);e.copy(this.lastChar,0,n);return e.toString("utf8",t,n)}function utf8End(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed)return t+"�";return t}function utf16Text(e,t){if((e.length-t)%2===0){var r=e.toString("utf16le",t);if(r){var n=r.charCodeAt(r.length-1);if(n>=55296&&n<=56319){this.lastNeed=2;this.lastTotal=4;this.lastChar[0]=e[e.length-2];this.lastChar[1]=e[e.length-1];return r.slice(0,-1)}}return r}this.lastNeed=1;this.lastTotal=2;this.lastChar[0]=e[e.length-1];return e.toString("utf16le",t,e.length-1)}function utf16End(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var r=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,r)}return t}function base64Text(e,t){var r=(e.length-t)%3;if(r===0)return e.toString("base64",t);this.lastNeed=3-r;this.lastTotal=3;if(r===1){this.lastChar[0]=e[e.length-1]}else{this.lastChar[0]=e[e.length-2];this.lastChar[1]=e[e.length-1]}return e.toString("base64",t,e.length-r)}function base64End(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed)return t+this.lastChar.toString("base64",0,3-this.lastNeed);return t}function simpleWrite(e){return e.toString(this.encoding)}function simpleEnd(e){return e&&e.length?this.write(e):""}},7882:(e,t,r)=>{var n=r(3837);var i=r(336);var a=r(8860);var o=r(1642).Writable;var s=r(1642).PassThrough;var noop=function(){};var overflow=function(e){e&=511;return e&&512-e};var emptyStream=function(e,t){var r=new Source(e,t);r.end();return r};var mixinPax=function(e,t){if(t.path)e.name=t.path;if(t.linkpath)e.linkname=t.linkpath;if(t.size)e.size=parseInt(t.size,10);e.pax=t;return e};var Source=function(e,t){this._parent=e;this.offset=t;s.call(this,{autoDestroy:false})};n.inherits(Source,s);Source.prototype.destroy=function(e){this._parent.destroy(e)};var Extract=function(e){if(!(this instanceof Extract))return new Extract(e);o.call(this,e);e=e||{};this._offset=0;this._buffer=i();this._missing=0;this._partial=false;this._onparse=noop;this._header=null;this._stream=null;this._overflow=null;this._cb=null;this._locked=false;this._destroyed=false;this._pax=null;this._paxGlobal=null;this._gnuLongPath=null;this._gnuLongLinkPath=null;var t=this;var r=t._buffer;var oncontinue=function(){t._continue()};var onunlock=function(e){t._locked=false;if(e)return t.destroy(e);if(!t._stream)oncontinue()};var onstreamend=function(){t._stream=null;var e=overflow(t._header.size);if(e)t._parse(e,ondrain);else t._parse(512,onheader);if(!t._locked)oncontinue()};var ondrain=function(){t._buffer.consume(overflow(t._header.size));t._parse(512,onheader);oncontinue()};var onpaxglobalheader=function(){var e=t._header.size;t._paxGlobal=a.decodePax(r.slice(0,e));r.consume(e);onstreamend()};var onpaxheader=function(){var e=t._header.size;t._pax=a.decodePax(r.slice(0,e));if(t._paxGlobal)t._pax=Object.assign({},t._paxGlobal,t._pax);r.consume(e);onstreamend()};var ongnulongpath=function(){var n=t._header.size;this._gnuLongPath=a.decodeLongPath(r.slice(0,n),e.filenameEncoding);r.consume(n);onstreamend()};var ongnulonglinkpath=function(){var n=t._header.size;this._gnuLongLinkPath=a.decodeLongPath(r.slice(0,n),e.filenameEncoding);r.consume(n);onstreamend()};var onheader=function(){var n=t._offset;var i;try{i=t._header=a.decode(r.slice(0,512),e.filenameEncoding,e.allowUnknownFormat)}catch(e){t.emit("error",e)}r.consume(512);if(!i){t._parse(512,onheader);oncontinue();return}if(i.type==="gnu-long-path"){t._parse(i.size,ongnulongpath);oncontinue();return}if(i.type==="gnu-long-link-path"){t._parse(i.size,ongnulonglinkpath);oncontinue();return}if(i.type==="pax-global-header"){t._parse(i.size,onpaxglobalheader);oncontinue();return}if(i.type==="pax-header"){t._parse(i.size,onpaxheader);oncontinue();return}if(t._gnuLongPath){i.name=t._gnuLongPath;t._gnuLongPath=null}if(t._gnuLongLinkPath){i.linkname=t._gnuLongLinkPath;t._gnuLongLinkPath=null}if(t._pax){t._header=i=mixinPax(i,t._pax);t._pax=null}t._locked=true;if(!i.size||i.type==="directory"){t._parse(512,onheader);t.emit("entry",i,emptyStream(t,n),onunlock);return}t._stream=new Source(t,n);t.emit("entry",i,t._stream,onunlock);t._parse(i.size,onstreamend);oncontinue()};this._onheader=onheader;this._parse(512,onheader)};n.inherits(Extract,o);Extract.prototype.destroy=function(e){if(this._destroyed)return;this._destroyed=true;if(e)this.emit("error",e);this.emit("close");if(this._stream)this._stream.emit("close")};Extract.prototype._parse=function(e,t){if(this._destroyed)return;this._offset+=e;this._missing=e;if(t===this._onheader)this._partial=false;this._onparse=t};Extract.prototype._continue=function(){if(this._destroyed)return;var e=this._cb;this._cb=noop;if(this._overflow)this._write(this._overflow,undefined,e);else e()};Extract.prototype._write=function(e,t,r){if(this._destroyed)return;var n=this._stream;var i=this._buffer;var a=this._missing;if(e.length)this._partial=true;if(e.lengtha){o=e.slice(a);e=e.slice(0,a)}if(n)n.end(e);else i.append(e);this._overflow=o;this._onparse()};Extract.prototype._final=function(e){if(this._partial)return this.destroy(new Error("Unexpected end of data"));e()};e.exports=Extract},8860:(e,t)=>{var r=Buffer.alloc;var n="0000000000000000000";var i="7777777777777777777";var a="0".charCodeAt(0);var o=Buffer.from("ustar\0","binary");var s=Buffer.from("00","binary");var u=Buffer.from("ustar ","binary");var l=Buffer.from(" \0","binary");var c=parseInt("7777",8);var d=257;var h=263;var clamp=function(e,t,r){if(typeof e!=="number")return r;e=~~e;if(e>=t)return t;if(e>=0)return e;e+=t;if(e>=0)return e;return 0};var toType=function(e){switch(e){case 0:return"file";case 1:return"link";case 2:return"symlink";case 3:return"character-device";case 4:return"block-device";case 5:return"directory";case 6:return"fifo";case 7:return"contiguous-file";case 72:return"pax-header";case 55:return"pax-global-header";case 27:return"gnu-long-link-path";case 28:case 30:return"gnu-long-path"}return null};var toTypeflag=function(e){switch(e){case"file":return 0;case"link":return 1;case"symlink":return 2;case"character-device":return 3;case"block-device":return 4;case"directory":return 5;case"fifo":return 6;case"contiguous-file":return 7;case"pax-header":return 72}return 0};var indexOf=function(e,t,r,n){for(;rt)return i.slice(0,t)+" ";else return n.slice(0,t-e.length)+e+" "};function parse256(e){var t;if(e[0]===128)t=true;else if(e[0]===255)t=false;else return null;var r=[];for(var n=e.length-1;n>0;n--){var i=e[n];if(t)r.push(i);else r.push(255-i)}var a=0;var o=r.length;for(n=0;n=Math.pow(10,r))r++;return t+r+e};t.decodeLongPath=function(e,t){return decodeStr(e,0,e.length,t)};t.encodePax=function(e){var t="";if(e.name)t+=addLength(" path="+e.name+"\n");if(e.linkname)t+=addLength(" linkpath="+e.linkname+"\n");var r=e.pax;if(r){for(var n in r){t+=addLength(" "+n+"="+r[n]+"\n")}}return Buffer.from(t)};t.decodePax=function(e){var t={};while(e.length){var r=0;while(r100){var u=n.indexOf("/");if(u===-1)return null;i+=i?"/"+n.slice(0,u):n.slice(0,u);n=n.slice(u+1)}if(Buffer.byteLength(n)>100||Buffer.byteLength(i)>155)return null;if(e.linkname&&Buffer.byteLength(e.linkname)>100)return null;t.write(n);t.write(encodeOct(e.mode&c,6),100);t.write(encodeOct(e.uid,6),108);t.write(encodeOct(e.gid,6),116);t.write(encodeOct(e.size,11),124);t.write(encodeOct(e.mtime.getTime()/1e3|0,11),136);t[156]=a+toTypeflag(e.type);if(e.linkname)t.write(e.linkname,157);o.copy(t,d);s.copy(t,h);if(e.uname)t.write(e.uname,265);if(e.gname)t.write(e.gname,297);t.write(encodeOct(e.devmajor||0,6),329);t.write(encodeOct(e.devminor||0,6),337);if(i)t.write(i,345);t.write(encodeOct(cksum(t),6),148);return t};t.decode=function(e,t,r){var n=e[156]===0?0:e[156]-a;var i=decodeStr(e,0,100,t);var s=decodeOct(e,100,8);var c=decodeOct(e,108,8);var p=decodeOct(e,116,8);var g=decodeOct(e,124,12);var m=decodeOct(e,136,12);var b=toType(n);var v=e[157]===0?null:decodeStr(e,157,100,t);var _=decodeStr(e,265,32);var y=decodeStr(e,297,32);var w=decodeOct(e,329,8);var R=decodeOct(e,337,8);var S=cksum(e);if(S===8*32)return null;if(S!==decodeOct(e,148,8))throw new Error("Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?");if(o.compare(e,d,d+6)===0){if(e[345])i=decodeStr(e,345,155,t)+"/"+i}else if(u.compare(e,d,d+6)===0&&l.compare(e,h,h+2)===0){}else{if(!r){throw new Error("Invalid tar header: unknown format.")}}if(n===0&&i&&i[i.length-1]==="/")n=5;return{name:i,mode:s,uid:c,gid:p,size:g,mtime:new Date(1e3*m),type:b,linkname:v,uname:_,gname:y,devmajor:w,devminor:R}}},2283:(e,t,r)=>{t.extract=r(7882);t.pack=r(4930)},4930:(e,t,r)=>{var n=r(3186);var i=r(1205);var a=r(4124);var o=Buffer.alloc;var s=r(1642).Readable;var u=r(1642).Writable;var l=r(1576).StringDecoder;var c=r(8860);var d=parseInt("755",8);var h=parseInt("644",8);var p=o(1024);var noop=function(){};var overflow=function(e,t){t&=511;if(t)e.push(p.slice(0,512-t))};function modeToType(e){switch(e&n.S_IFMT){case n.S_IFBLK:return"block-device";case n.S_IFCHR:return"character-device";case n.S_IFDIR:return"directory";case n.S_IFIFO:return"fifo";case n.S_IFLNK:return"symlink"}return"file"}var Sink=function(e){u.call(this);this.written=0;this._to=e;this._destroyed=false};a(Sink,u);Sink.prototype._write=function(e,t,r){this.written+=e.length;if(this._to.push(e))return r();this._to._drain=r};Sink.prototype.destroy=function(){if(this._destroyed)return;this._destroyed=true;this.emit("close")};var LinkSink=function(){u.call(this);this.linkname="";this._decoder=new l("utf-8");this._destroyed=false};a(LinkSink,u);LinkSink.prototype._write=function(e,t,r){this.linkname+=this._decoder.write(e);r()};LinkSink.prototype.destroy=function(){if(this._destroyed)return;this._destroyed=true;this.emit("close")};var Void=function(){u.call(this);this._destroyed=false};a(Void,u);Void.prototype._write=function(e,t,r){r(new Error("No body allowed for this entry"))};Void.prototype.destroy=function(){if(this._destroyed)return;this._destroyed=true;this.emit("close")};var Pack=function(e){if(!(this instanceof Pack))return new Pack(e);s.call(this,e);this._drain=noop;this._finalized=false;this._finalizing=false;this._destroyed=false;this._stream=null};a(Pack,s);Pack.prototype.entry=function(e,t,r){if(this._stream)throw new Error("already piping an entry");if(this._finalized||this._destroyed)return;if(typeof t==="function"){r=t;t=null}if(!r)r=noop;var n=this;if(!e.size||e.type==="symlink")e.size=0;if(!e.type)e.type=modeToType(e.mode);if(!e.mode)e.mode=e.type==="directory"?d:h;if(!e.uid)e.uid=0;if(!e.gid)e.gid=0;if(!e.mtime)e.mtime=new Date;if(typeof t==="string")t=Buffer.from(t);if(Buffer.isBuffer(t)){e.size=t.length;this._encode(e);var a=this.push(t);overflow(n,e.size);if(a)process.nextTick(r);else this._drain=r;return new Void}if(e.type==="symlink"&&!e.linkname){var o=new LinkSink;i(o,(function(t){if(t){n.destroy();return r(t)}e.linkname=o.linkname;n._encode(e);r()}));return o}this._encode(e);if(e.type!=="file"&&e.type!=="contiguous-file"){process.nextTick(r);return new Void}var s=new Sink(this);this._stream=s;i(s,(function(t){n._stream=null;if(t){n.destroy();return r(t)}if(s.written!==e.size){n.destroy();return r(new Error("size mismatch"))}overflow(n,e.size);if(n._finalizing)n.finalize();r()}));return s};Pack.prototype.finalize=function(){if(this._stream){this._finalizing=true;return}if(this._finalized)return;this._finalized=true;this.push(p);this.push(null)};Pack.prototype.destroy=function(e){if(this._destroyed)return;this._destroyed=true;if(e)this.emit("error",e);this.emit("close");if(this._stream&&this._stream.destroy)this._stream.destroy()};Pack.prototype._encode=function(e){if(!e.pax){var t=c.encode(e);if(t){this.push(t);return}}this._encodePax(e)};Pack.prototype._encodePax=function(e){var t=c.encodePax({name:e.name,linkname:e.linkname,pax:e.pax});var r={name:"PaxHeader",mode:e.mode,uid:e.uid,gid:e.gid,size:t.length,mtime:e.mtime,type:"pax-header",linkname:e.linkname&&"PaxHeader",uname:e.uname,gname:e.gname,devmajor:e.devmajor,devminor:e.devminor};this.push(c.encode(r));this.push(t);overflow(this,t.length);r.size=e.size;r.type=e.type;this.push(c.encode(r))};Pack.prototype._read=function(e){var t=this._drain;this._drain=noop;t()};e.exports=Pack},4294:(e,t,r)=>{e.exports=r(4219)},4219:(e,t,r)=>{var n=r(1808);var i=r(4404);var a=r(3685);var o=r(5687);var s=r(2361);var u=r(9491);var l=r(3837);t.httpOverHttp=httpOverHttp;t.httpsOverHttp=httpsOverHttp;t.httpOverHttps=httpOverHttps;t.httpsOverHttps=httpsOverHttps;function httpOverHttp(e){var t=new TunnelingAgent(e);t.request=a.request;return t}function httpsOverHttp(e){var t=new TunnelingAgent(e);t.request=a.request;t.createSocket=createSecureSocket;t.defaultPort=443;return t}function httpOverHttps(e){var t=new TunnelingAgent(e);t.request=o.request;return t}function httpsOverHttps(e){var t=new TunnelingAgent(e);t.request=o.request;t.createSocket=createSecureSocket;t.defaultPort=443;return t}function TunnelingAgent(e){var t=this;t.options=e||{};t.proxyOptions=t.options.proxy||{};t.maxSockets=t.options.maxSockets||a.Agent.defaultMaxSockets;t.requests=[];t.sockets=[];t.on("free",(function onFree(e,r,n,i){var a=toOptions(r,n,i);for(var o=0,s=t.requests.length;o=this.maxSockets){i.requests.push(a);return}i.createSocket(a,(function(t){t.on("free",onFree);t.on("close",onCloseOrRemove);t.on("agentRemove",onCloseOrRemove);e.onSocket(t);function onFree(){i.emit("free",t,a)}function onCloseOrRemove(e){i.removeSocket(t);t.removeListener("free",onFree);t.removeListener("close",onCloseOrRemove);t.removeListener("agentRemove",onCloseOrRemove)}}))};TunnelingAgent.prototype.createSocket=function createSocket(e,t){var r=this;var n={};r.sockets.push(n);var i=mergeOptions({},r.proxyOptions,{method:"CONNECT",path:e.host+":"+e.port,agent:false,headers:{host:e.host+":"+e.port}});if(e.localAddress){i.localAddress=e.localAddress}if(i.proxyAuth){i.headers=i.headers||{};i.headers["Proxy-Authorization"]="Basic "+new Buffer(i.proxyAuth).toString("base64")}c("making CONNECT request");var a=r.request(i);a.useChunkedEncodingByDefault=false;a.once("response",onResponse);a.once("upgrade",onUpgrade);a.once("connect",onConnect);a.once("error",onError);a.end();function onResponse(e){e.upgrade=true}function onUpgrade(e,t,r){process.nextTick((function(){onConnect(e,t,r)}))}function onConnect(i,o,s){a.removeAllListeners();o.removeAllListeners();if(i.statusCode!==200){c("tunneling socket could not be established, statusCode=%d",i.statusCode);o.destroy();var u=new Error("tunneling socket could not be established, "+"statusCode="+i.statusCode);u.code="ECONNRESET";e.request.emit("error",u);r.removeSocket(n);return}if(s.length>0){c("got illegal response body from proxy");o.destroy();var u=new Error("got illegal response body from proxy");u.code="ECONNRESET";e.request.emit("error",u);r.removeSocket(n);return}c("tunneling connection has established");r.sockets[r.sockets.indexOf(n)]=o;return t(o)}function onError(t){a.removeAllListeners();c("tunneling socket could not be established, cause=%s\n",t.message,t.stack);var i=new Error("tunneling socket could not be established, "+"cause="+t.message);i.code="ECONNRESET";e.request.emit("error",i);r.removeSocket(n)}};TunnelingAgent.prototype.removeSocket=function removeSocket(e){var t=this.sockets.indexOf(e);if(t===-1){return}this.sockets.splice(t,1);var r=this.requests.shift();if(r){this.createSocket(r,(function(e){r.request.onSocket(e)}))}};function createSecureSocket(e,t){var r=this;TunnelingAgent.prototype.createSocket.call(r,e,(function(n){var a=e.request.getHeader("host");var o=mergeOptions({},r.options,{socket:n,servername:a?a.replace(/:.*$/,""):e.host});var s=i.connect(0,o);r.sockets[r.sockets.indexOf(n)]=s;t(s)}))}function toOptions(e,t,r){if(typeof e==="string"){return{host:e,port:t,localAddress:r}}return e}function mergeOptions(e){for(var t=1,r=arguments.length;t{e.exports=r(3837).deprecate},5840:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});Object.defineProperty(t,"v1",{enumerable:true,get:function(){return n.default}});Object.defineProperty(t,"v3",{enumerable:true,get:function(){return i.default}});Object.defineProperty(t,"v4",{enumerable:true,get:function(){return a.default}});Object.defineProperty(t,"v5",{enumerable:true,get:function(){return o.default}});Object.defineProperty(t,"NIL",{enumerable:true,get:function(){return s.default}});Object.defineProperty(t,"version",{enumerable:true,get:function(){return u.default}});Object.defineProperty(t,"validate",{enumerable:true,get:function(){return l.default}});Object.defineProperty(t,"stringify",{enumerable:true,get:function(){return c.default}});Object.defineProperty(t,"parse",{enumerable:true,get:function(){return d.default}});var n=_interopRequireDefault(r(8628));var i=_interopRequireDefault(r(6409));var a=_interopRequireDefault(r(5122));var o=_interopRequireDefault(r(9120));var s=_interopRequireDefault(r(5332));var u=_interopRequireDefault(r(1595));var l=_interopRequireDefault(r(6900));var c=_interopRequireDefault(r(8950));var d=_interopRequireDefault(r(4848));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}},4569:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(6113));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function md5(e){if(Array.isArray(e)){e=Buffer.from(e)}else if(typeof e==="string"){e=Buffer.from(e,"utf8")}return n.default.createHash("md5").update(e).digest()}var i=md5;t["default"]=i},5332:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var r="00000000-0000-0000-0000-000000000000";t["default"]=r},4848:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(6900));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function parse(e){if(!(0,n.default)(e)){throw TypeError("Invalid UUID")}let t;const r=new Uint8Array(16);r[0]=(t=parseInt(e.slice(0,8),16))>>>24;r[1]=t>>>16&255;r[2]=t>>>8&255;r[3]=t&255;r[4]=(t=parseInt(e.slice(9,13),16))>>>8;r[5]=t&255;r[6]=(t=parseInt(e.slice(14,18),16))>>>8;r[7]=t&255;r[8]=(t=parseInt(e.slice(19,23),16))>>>8;r[9]=t&255;r[10]=(t=parseInt(e.slice(24,36),16))/1099511627776&255;r[11]=t/4294967296&255;r[12]=t>>>24&255;r[13]=t>>>16&255;r[14]=t>>>8&255;r[15]=t&255;return r}var i=parse;t["default"]=i},814:(e,t)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var r=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;t["default"]=r},807:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=rng;var n=_interopRequireDefault(r(6113));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const i=new Uint8Array(256);let a=i.length;function rng(){if(a>i.length-16){n.default.randomFillSync(i);a=0}return i.slice(a,a+=16)}},5274:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(6113));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function sha1(e){if(Array.isArray(e)){e=Buffer.from(e)}else if(typeof e==="string"){e=Buffer.from(e,"utf8")}return n.default.createHash("sha1").update(e).digest()}var i=sha1;t["default"]=i},8950:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(6900));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const i=[];for(let e=0;e<256;++e){i.push((e+256).toString(16).substr(1))}function stringify(e,t=0){const r=(i[e[t+0]]+i[e[t+1]]+i[e[t+2]]+i[e[t+3]]+"-"+i[e[t+4]]+i[e[t+5]]+"-"+i[e[t+6]]+i[e[t+7]]+"-"+i[e[t+8]]+i[e[t+9]]+"-"+i[e[t+10]]+i[e[t+11]]+i[e[t+12]]+i[e[t+13]]+i[e[t+14]]+i[e[t+15]]).toLowerCase();if(!(0,n.default)(r)){throw TypeError("Stringified UUID is invalid")}return r}var a=stringify;t["default"]=a},8628:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(807));var i=_interopRequireDefault(r(8950));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}let a;let o;let s=0;let u=0;function v1(e,t,r){let l=t&&r||0;const c=t||new Array(16);e=e||{};let d=e.node||a;let h=e.clockseq!==undefined?e.clockseq:o;if(d==null||h==null){const t=e.random||(e.rng||n.default)();if(d==null){d=a=[t[0]|1,t[1],t[2],t[3],t[4],t[5]]}if(h==null){h=o=(t[6]<<8|t[7])&16383}}let p=e.msecs!==undefined?e.msecs:Date.now();let g=e.nsecs!==undefined?e.nsecs:u+1;const m=p-s+(g-u)/1e4;if(m<0&&e.clockseq===undefined){h=h+1&16383}if((m<0||p>s)&&e.nsecs===undefined){g=0}if(g>=1e4){throw new Error("uuid.v1(): Can't create more than 10M uuids/sec")}s=p;u=g;o=h;p+=122192928e5;const b=((p&268435455)*1e4+g)%4294967296;c[l++]=b>>>24&255;c[l++]=b>>>16&255;c[l++]=b>>>8&255;c[l++]=b&255;const v=p/4294967296*1e4&268435455;c[l++]=v>>>8&255;c[l++]=v&255;c[l++]=v>>>24&15|16;c[l++]=v>>>16&255;c[l++]=h>>>8|128;c[l++]=h&255;for(let e=0;e<6;++e){c[l+e]=d[e]}return t||(0,i.default)(c)}var l=v1;t["default"]=l},6409:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(5998));var i=_interopRequireDefault(r(4569));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const a=(0,n.default)("v3",48,i.default);var o=a;t["default"]=o},5998:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=_default;t.URL=t.DNS=void 0;var n=_interopRequireDefault(r(8950));var i=_interopRequireDefault(r(4848));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function stringToBytes(e){e=unescape(encodeURIComponent(e));const t=[];for(let r=0;r{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(807));var i=_interopRequireDefault(r(8950));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function v4(e,t,r){e=e||{};const a=e.random||(e.rng||n.default)();a[6]=a[6]&15|64;a[8]=a[8]&63|128;if(t){r=r||0;for(let e=0;e<16;++e){t[r+e]=a[e]}return t}return(0,i.default)(a)}var a=v4;t["default"]=a},9120:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(5998));var i=_interopRequireDefault(r(5274));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}const a=(0,n.default)("v5",80,i.default);var o=a;t["default"]=o},6900:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(814));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function validate(e){return typeof e==="string"&&n.default.test(e)}var i=validate;t["default"]=i},1595:(e,t,r)=>{Object.defineProperty(t,"__esModule",{value:true});t["default"]=void 0;var n=_interopRequireDefault(r(6900));function _interopRequireDefault(e){return e&&e.__esModule?e:{default:e}}function version(e){if(!(0,n.default)(e)){throw TypeError("Invalid UUID")}return parseInt(e.substr(14,1),16)}var i=version;t["default"]=i},2940:e=>{e.exports=wrappy;function wrappy(e,t){if(e&&t)return wrappy(e)(t);if(typeof e!=="function")throw new TypeError("need wrapper function");Object.keys(e).forEach((function(t){wrapper[t]=e[t]}));return wrapper;function wrapper(){var t=new Array(arguments.length);for(var r=0;r{t.exports=e(import.meta.url)("assert")},4300:t=>{t.exports=e(import.meta.url)("buffer")},2057:t=>{t.exports=e(import.meta.url)("constants")},6113:t=>{t.exports=e(import.meta.url)("crypto")},2361:t=>{t.exports=e(import.meta.url)("events")},7147:t=>{t.exports=e(import.meta.url)("fs")},3685:t=>{t.exports=e(import.meta.url)("http")},5687:t=>{t.exports=e(import.meta.url)("https")},1808:t=>{t.exports=e(import.meta.url)("net")},7718:t=>{t.exports=e(import.meta.url)("node:child_process")},7561:t=>{t.exports=e(import.meta.url)("node:fs")},7742:t=>{t.exports=e(import.meta.url)("node:process")},4492:t=>{t.exports=e(import.meta.url)("node:stream")},5628:t=>{t.exports=e(import.meta.url)("node:zlib")},2037:t=>{t.exports=e(import.meta.url)("os")},1017:t=>{t.exports=e(import.meta.url)("path")},2781:t=>{t.exports=e(import.meta.url)("stream")},1576:t=>{t.exports=e(import.meta.url)("string_decoder")},4404:t=>{t.exports=e(import.meta.url)("tls")},3837:t=>{t.exports=e(import.meta.url)("util")},6955:(e,t,r)=>{r.a(e,(async e=>{var t=r(7718);var n=r(7742);var i=r(4492);var a=r(7561);var o=r(5628);var s=r(2283);var u=r(2186);const l=u.getInput("container",{required:true});const c=JSON.parse(u.getInput("error-log-paths",{required:true}));const d=u.getInput("log-tarball-prefix",{required:true});const h=u.getInput("tests-label",{required:true});const p=u.getInput("test-timeout",{required:true});const g=n.env.GITHUB_REPOSITORY.split("/")[1];try{t.spawnSync("docker",["rm","-f","base"],{stdio:"ignore"});if(t.spawnSync("docker",["run","--name","base","-v",`${n.cwd()}/build.tar.zst:/build.tar.zst`,"--workdir",`/__w/${g}/${g}`,l,"sh","-c","zstdcat /build.tar.zst | tar x"],{stdio:"inherit"}).status)throw new Error("Failed to create base container");if(t.spawnSync("docker",["commit","base","baseimage"],{stdio:"inherit"}).status)throw new Error("Failed to create base image");if(t.spawnSync("docker",["rm","base"],{stdio:"inherit"}).status)throw new Error("Failed to remove base container");const e=t.spawnSync("docker",["run","--rm","baseimage","bash","-e","-o","pipefail","-c",`cd build; ctest -L '${h}' --show-only=json-v1`]);if(e.status)throw new Error("Failed to discover tests with label");const r=JSON.parse(e.stdout).tests;let m=[];r.forEach((e=>{t.spawnSync("docker",["rm","-f",e.name],{stdio:"ignore"});m.push(new Promise((r=>{t.spawn("docker",["run","--security-opt","seccomp=unconfined","-e","GITHUB_ACTIONS=True","--name",e.name,"--init","baseimage","bash","-c",`cd build; ctest --output-on-failure -R '^${e.name}$' --timeout ${p}`],{stdio:"inherit"}).on("close",(e=>r(e)))})))}));const b=await Promise.all(m);for(let e=0;e{if(!e.name.startsWith(`__w/${g}/${g}/build`)){t.on("end",(()=>r()));t.resume();return}e.name=e.name.substring(`__w/${g}/${g}/`.length);if(e.name!=="build/"&&c.filter((t=>e.name.startsWith(t))).length===0){t.on("end",(()=>r()));t.resume();return}t.pipe(l.entry(e,r))})).on("finish",(()=>{l.finalize()}));t.spawn("docker",["export",r[e].name]).stdout.pipe(n);i.promises.pipeline(l,o.createGzip(),a.createWriteStream(`${d}-${r[e].name}-logs.tar.gz`))}}catch(e){u.setFailed(`Uncaught exception ${e.message}`)}e()}),1)}};var r={};function __nccwpck_require__(e){var n=r[e];if(n!==undefined){return n.exports}var i=r[e]={exports:{}};var a=true;try{t[e].call(i.exports,i,i.exports,__nccwpck_require__);a=false}finally{if(a)delete r[e]}return i.exports}(()=>{var e=typeof Symbol==="function"?Symbol("webpack then"):"__webpack_then__";var t=typeof Symbol==="function"?Symbol("webpack exports"):"__webpack_exports__";var completeQueue=e=>{if(e){e.forEach((e=>e.r--));e.forEach((e=>e.r--?e.r++:e()))}};var completeFunction=e=>!--e.r&&e();var queueFunction=(e,t)=>e?e.push(t):completeFunction(t);var wrapDeps=r=>r.map((r=>{if(r!==null&&typeof r==="object"){if(r[e])return r;if(r.then){var n=[];r.then((e=>{i[t]=e;completeQueue(n);n=0}));var i={};i[e]=(e,t)=>(queueFunction(n,e),r["catch"](t));return i}}var a={};a[e]=e=>completeFunction(e);a[t]=r;return a}));__nccwpck_require__.a=(r,n,i)=>{var a=i&&[];var o=r.exports;var s;var u;var l;var c=true;var d=false;var whenAll=(t,r,n)=>{if(d)return;d=true;r.r+=t.length;t.map(((t,i)=>t[e](r,n)));d=false};var h=new Promise(((e,t)=>{l=t;u=()=>(e(o),completeQueue(a),a=0)}));h[t]=o;h[e]=(e,t)=>{if(c){return completeFunction(e)}if(s)whenAll(s,e,t);queueFunction(a,e);h["catch"](t)};r.exports=h;n((e=>{if(!e)return u();s=wrapDeps(e);var r,n;var i=new Promise(((e,i)=>{r=()=>e(n=s.map((e=>e[t])));r.r=0;whenAll(s,r,i)}));return r.r?i:n})).then(u,l);c=false}})();if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=new URL(".",import.meta.url).pathname.slice(import.meta.url.match(/^file:\/\/\/\w:/)?1:0,-1)+"/";var n=__nccwpck_require__(6955);n=await n; \ No newline at end of file +/* eslint-disable node/no-deprecated-api */ +var buffer = __nccwpck_require__(4300) +var Buffer = buffer.Buffer + +// alternative to using Object.keys for old browsers +function copyProps (src, dst) { + for (var key in src) { + dst[key] = src[key] + } +} +if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { + module.exports = buffer +} else { + // Copy properties from require('buffer') + copyProps(buffer, exports) + exports.Buffer = SafeBuffer +} + +function SafeBuffer (arg, encodingOrOffset, length) { + return Buffer(arg, encodingOrOffset, length) +} + +SafeBuffer.prototype = Object.create(Buffer.prototype) + +// Copy static methods from Buffer +copyProps(Buffer, SafeBuffer) + +SafeBuffer.from = function (arg, encodingOrOffset, length) { + if (typeof arg === 'number') { + throw new TypeError('Argument must not be a number') + } + return Buffer(arg, encodingOrOffset, length) +} + +SafeBuffer.alloc = function (size, fill, encoding) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + var buf = Buffer(size) + if (fill !== undefined) { + if (typeof encoding === 'string') { + buf.fill(fill, encoding) + } else { + buf.fill(fill) + } + } else { + buf.fill(0) + } + return buf +} + +SafeBuffer.allocUnsafe = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return Buffer(size) +} + +SafeBuffer.allocUnsafeSlow = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return buffer.SlowBuffer(size) +} + + +/***/ }), + +/***/ 4841: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + + + +/**/ + +var Buffer = (__nccwpck_require__(1867).Buffer); +/**/ + +var isEncoding = Buffer.isEncoding || function (encoding) { + encoding = '' + encoding; + switch (encoding && encoding.toLowerCase()) { + case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw': + return true; + default: + return false; + } +}; + +function _normalizeEncoding(enc) { + if (!enc) return 'utf8'; + var retried; + while (true) { + switch (enc) { + case 'utf8': + case 'utf-8': + return 'utf8'; + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return 'utf16le'; + case 'latin1': + case 'binary': + return 'latin1'; + case 'base64': + case 'ascii': + case 'hex': + return enc; + default: + if (retried) return; // undefined + enc = ('' + enc).toLowerCase(); + retried = true; + } + } +}; + +// Do not cache `Buffer.isEncoding` when checking encoding names as some +// modules monkey-patch it to support additional encodings +function normalizeEncoding(enc) { + var nenc = _normalizeEncoding(enc); + if (typeof nenc !== 'string' && (Buffer.isEncoding === isEncoding || !isEncoding(enc))) throw new Error('Unknown encoding: ' + enc); + return nenc || enc; +} + +// StringDecoder provides an interface for efficiently splitting a series of +// buffers into a series of JS strings without breaking apart multi-byte +// characters. +exports.s = StringDecoder; +function StringDecoder(encoding) { + this.encoding = normalizeEncoding(encoding); + var nb; + switch (this.encoding) { + case 'utf16le': + this.text = utf16Text; + this.end = utf16End; + nb = 4; + break; + case 'utf8': + this.fillLast = utf8FillLast; + nb = 4; + break; + case 'base64': + this.text = base64Text; + this.end = base64End; + nb = 3; + break; + default: + this.write = simpleWrite; + this.end = simpleEnd; + return; + } + this.lastNeed = 0; + this.lastTotal = 0; + this.lastChar = Buffer.allocUnsafe(nb); +} + +StringDecoder.prototype.write = function (buf) { + if (buf.length === 0) return ''; + var r; + var i; + if (this.lastNeed) { + r = this.fillLast(buf); + if (r === undefined) return ''; + i = this.lastNeed; + this.lastNeed = 0; + } else { + i = 0; + } + if (i < buf.length) return r ? r + this.text(buf, i) : this.text(buf, i); + return r || ''; +}; + +StringDecoder.prototype.end = utf8End; + +// Returns only complete characters in a Buffer +StringDecoder.prototype.text = utf8Text; + +// Attempts to complete a partial non-UTF-8 character using bytes from a Buffer +StringDecoder.prototype.fillLast = function (buf) { + if (this.lastNeed <= buf.length) { + buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, this.lastNeed); + return this.lastChar.toString(this.encoding, 0, this.lastTotal); + } + buf.copy(this.lastChar, this.lastTotal - this.lastNeed, 0, buf.length); + this.lastNeed -= buf.length; +}; + +// Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a +// continuation byte. If an invalid byte is detected, -2 is returned. +function utf8CheckByte(byte) { + if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4; + return byte >> 6 === 0x02 ? -1 : -2; +} + +// Checks at most 3 bytes at the end of a Buffer in order to detect an +// incomplete multi-byte UTF-8 character. The total number of bytes (2, 3, or 4) +// needed to complete the UTF-8 character (if applicable) are returned. +function utf8CheckIncomplete(self, buf, i) { + var j = buf.length - 1; + if (j < i) return 0; + var nb = utf8CheckByte(buf[j]); + if (nb >= 0) { + if (nb > 0) self.lastNeed = nb - 1; + return nb; + } + if (--j < i || nb === -2) return 0; + nb = utf8CheckByte(buf[j]); + if (nb >= 0) { + if (nb > 0) self.lastNeed = nb - 2; + return nb; + } + if (--j < i || nb === -2) return 0; + nb = utf8CheckByte(buf[j]); + if (nb >= 0) { + if (nb > 0) { + if (nb === 2) nb = 0;else self.lastNeed = nb - 3; + } + return nb; + } + return 0; +} + +// Validates as many continuation bytes for a multi-byte UTF-8 character as +// needed or are available. If we see a non-continuation byte where we expect +// one, we "replace" the validated continuation bytes we've seen so far with +// a single UTF-8 replacement character ('\ufffd'), to match v8's UTF-8 decoding +// behavior. The continuation byte check is included three times in the case +// where all of the continuation bytes for a character exist in the same buffer. +// It is also done this way as a slight performance increase instead of using a +// loop. +function utf8CheckExtraBytes(self, buf, p) { + if ((buf[0] & 0xC0) !== 0x80) { + self.lastNeed = 0; + return '\ufffd'; + } + if (self.lastNeed > 1 && buf.length > 1) { + if ((buf[1] & 0xC0) !== 0x80) { + self.lastNeed = 1; + return '\ufffd'; + } + if (self.lastNeed > 2 && buf.length > 2) { + if ((buf[2] & 0xC0) !== 0x80) { + self.lastNeed = 2; + return '\ufffd'; + } + } + } +} + +// Attempts to complete a multi-byte UTF-8 character using bytes from a Buffer. +function utf8FillLast(buf) { + var p = this.lastTotal - this.lastNeed; + var r = utf8CheckExtraBytes(this, buf, p); + if (r !== undefined) return r; + if (this.lastNeed <= buf.length) { + buf.copy(this.lastChar, p, 0, this.lastNeed); + return this.lastChar.toString(this.encoding, 0, this.lastTotal); + } + buf.copy(this.lastChar, p, 0, buf.length); + this.lastNeed -= buf.length; +} + +// Returns all complete UTF-8 characters in a Buffer. If the Buffer ended on a +// partial character, the character's bytes are buffered until the required +// number of bytes are available. +function utf8Text(buf, i) { + var total = utf8CheckIncomplete(this, buf, i); + if (!this.lastNeed) return buf.toString('utf8', i); + this.lastTotal = total; + var end = buf.length - (total - this.lastNeed); + buf.copy(this.lastChar, 0, end); + return buf.toString('utf8', i, end); +} + +// For UTF-8, a replacement character is added when ending on a partial +// character. +function utf8End(buf) { + var r = buf && buf.length ? this.write(buf) : ''; + if (this.lastNeed) return r + '\ufffd'; + return r; +} + +// UTF-16LE typically needs two bytes per character, but even if we have an even +// number of bytes available, we need to check if we end on a leading/high +// surrogate. In that case, we need to wait for the next two bytes in order to +// decode the last character properly. +function utf16Text(buf, i) { + if ((buf.length - i) % 2 === 0) { + var r = buf.toString('utf16le', i); + if (r) { + var c = r.charCodeAt(r.length - 1); + if (c >= 0xD800 && c <= 0xDBFF) { + this.lastNeed = 2; + this.lastTotal = 4; + this.lastChar[0] = buf[buf.length - 2]; + this.lastChar[1] = buf[buf.length - 1]; + return r.slice(0, -1); + } + } + return r; + } + this.lastNeed = 1; + this.lastTotal = 2; + this.lastChar[0] = buf[buf.length - 1]; + return buf.toString('utf16le', i, buf.length - 1); +} + +// For UTF-16LE we do not explicitly append special replacement characters if we +// end on a partial character, we simply let v8 handle that. +function utf16End(buf) { + var r = buf && buf.length ? this.write(buf) : ''; + if (this.lastNeed) { + var end = this.lastTotal - this.lastNeed; + return r + this.lastChar.toString('utf16le', 0, end); + } + return r; +} + +function base64Text(buf, i) { + var n = (buf.length - i) % 3; + if (n === 0) return buf.toString('base64', i); + this.lastNeed = 3 - n; + this.lastTotal = 3; + if (n === 1) { + this.lastChar[0] = buf[buf.length - 1]; + } else { + this.lastChar[0] = buf[buf.length - 2]; + this.lastChar[1] = buf[buf.length - 1]; + } + return buf.toString('base64', i, buf.length - n); +} + +function base64End(buf) { + var r = buf && buf.length ? this.write(buf) : ''; + if (this.lastNeed) return r + this.lastChar.toString('base64', 0, 3 - this.lastNeed); + return r; +} + +// Pass bytes on through for single-byte encodings (e.g. ascii, latin1, hex) +function simpleWrite(buf) { + return buf.toString(this.encoding); +} + +function simpleEnd(buf) { + return buf && buf.length ? this.write(buf) : ''; +} + +/***/ }), + +/***/ 7882: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +var util = __nccwpck_require__(3837) +var bl = __nccwpck_require__(336) +var headers = __nccwpck_require__(8860) + +var Writable = (__nccwpck_require__(1642).Writable) +var PassThrough = (__nccwpck_require__(1642).PassThrough) + +var noop = function () {} + +var overflow = function (size) { + size &= 511 + return size && 512 - size +} + +var emptyStream = function (self, offset) { + var s = new Source(self, offset) + s.end() + return s +} + +var mixinPax = function (header, pax) { + if (pax.path) header.name = pax.path + if (pax.linkpath) header.linkname = pax.linkpath + if (pax.size) header.size = parseInt(pax.size, 10) + header.pax = pax + return header +} + +var Source = function (self, offset) { + this._parent = self + this.offset = offset + PassThrough.call(this, { autoDestroy: false }) +} + +util.inherits(Source, PassThrough) + +Source.prototype.destroy = function (err) { + this._parent.destroy(err) +} + +var Extract = function (opts) { + if (!(this instanceof Extract)) return new Extract(opts) + Writable.call(this, opts) + + opts = opts || {} + + this._offset = 0 + this._buffer = bl() + this._missing = 0 + this._partial = false + this._onparse = noop + this._header = null + this._stream = null + this._overflow = null + this._cb = null + this._locked = false + this._destroyed = false + this._pax = null + this._paxGlobal = null + this._gnuLongPath = null + this._gnuLongLinkPath = null + + var self = this + var b = self._buffer + + var oncontinue = function () { + self._continue() + } + + var onunlock = function (err) { + self._locked = false + if (err) return self.destroy(err) + if (!self._stream) oncontinue() + } + + var onstreamend = function () { + self._stream = null + var drain = overflow(self._header.size) + if (drain) self._parse(drain, ondrain) + else self._parse(512, onheader) + if (!self._locked) oncontinue() + } + + var ondrain = function () { + self._buffer.consume(overflow(self._header.size)) + self._parse(512, onheader) + oncontinue() + } + + var onpaxglobalheader = function () { + var size = self._header.size + self._paxGlobal = headers.decodePax(b.slice(0, size)) + b.consume(size) + onstreamend() + } + + var onpaxheader = function () { + var size = self._header.size + self._pax = headers.decodePax(b.slice(0, size)) + if (self._paxGlobal) self._pax = Object.assign({}, self._paxGlobal, self._pax) + b.consume(size) + onstreamend() + } + + var ongnulongpath = function () { + var size = self._header.size + this._gnuLongPath = headers.decodeLongPath(b.slice(0, size), opts.filenameEncoding) + b.consume(size) + onstreamend() + } + + var ongnulonglinkpath = function () { + var size = self._header.size + this._gnuLongLinkPath = headers.decodeLongPath(b.slice(0, size), opts.filenameEncoding) + b.consume(size) + onstreamend() + } + + var onheader = function () { + var offset = self._offset + var header + try { + header = self._header = headers.decode(b.slice(0, 512), opts.filenameEncoding, opts.allowUnknownFormat) + } catch (err) { + self.emit('error', err) + } + b.consume(512) + + if (!header) { + self._parse(512, onheader) + oncontinue() + return + } + if (header.type === 'gnu-long-path') { + self._parse(header.size, ongnulongpath) + oncontinue() + return + } + if (header.type === 'gnu-long-link-path') { + self._parse(header.size, ongnulonglinkpath) + oncontinue() + return + } + if (header.type === 'pax-global-header') { + self._parse(header.size, onpaxglobalheader) + oncontinue() + return + } + if (header.type === 'pax-header') { + self._parse(header.size, onpaxheader) + oncontinue() + return + } + + if (self._gnuLongPath) { + header.name = self._gnuLongPath + self._gnuLongPath = null + } + + if (self._gnuLongLinkPath) { + header.linkname = self._gnuLongLinkPath + self._gnuLongLinkPath = null + } + + if (self._pax) { + self._header = header = mixinPax(header, self._pax) + self._pax = null + } + + self._locked = true + + if (!header.size || header.type === 'directory') { + self._parse(512, onheader) + self.emit('entry', header, emptyStream(self, offset), onunlock) + return + } + + self._stream = new Source(self, offset) + + self.emit('entry', header, self._stream, onunlock) + self._parse(header.size, onstreamend) + oncontinue() + } + + this._onheader = onheader + this._parse(512, onheader) +} + +util.inherits(Extract, Writable) + +Extract.prototype.destroy = function (err) { + if (this._destroyed) return + this._destroyed = true + + if (err) this.emit('error', err) + this.emit('close') + if (this._stream) this._stream.emit('close') +} + +Extract.prototype._parse = function (size, onparse) { + if (this._destroyed) return + this._offset += size + this._missing = size + if (onparse === this._onheader) this._partial = false + this._onparse = onparse +} + +Extract.prototype._continue = function () { + if (this._destroyed) return + var cb = this._cb + this._cb = noop + if (this._overflow) this._write(this._overflow, undefined, cb) + else cb() +} + +Extract.prototype._write = function (data, enc, cb) { + if (this._destroyed) return + + var s = this._stream + var b = this._buffer + var missing = this._missing + if (data.length) this._partial = true + + // we do not reach end-of-chunk now. just forward it + + if (data.length < missing) { + this._missing -= data.length + this._overflow = null + if (s) return s.write(data, cb) + b.append(data) + return cb() + } + + // end-of-chunk. the parser should call cb. + + this._cb = cb + this._missing = 0 + + var overflow = null + if (data.length > missing) { + overflow = data.slice(missing) + data = data.slice(0, missing) + } + + if (s) s.end(data) + else b.append(data) + + this._overflow = overflow + this._onparse() +} + +Extract.prototype._final = function (cb) { + if (this._partial) return this.destroy(new Error('Unexpected end of data')) + cb() +} + +module.exports = Extract + + +/***/ }), + +/***/ 8860: +/***/ ((__unused_webpack_module, exports) => { + +var alloc = Buffer.alloc + +var ZEROS = '0000000000000000000' +var SEVENS = '7777777777777777777' +var ZERO_OFFSET = '0'.charCodeAt(0) +var USTAR_MAGIC = Buffer.from('ustar\x00', 'binary') +var USTAR_VER = Buffer.from('00', 'binary') +var GNU_MAGIC = Buffer.from('ustar\x20', 'binary') +var GNU_VER = Buffer.from('\x20\x00', 'binary') +var MASK = parseInt('7777', 8) +var MAGIC_OFFSET = 257 +var VERSION_OFFSET = 263 + +var clamp = function (index, len, defaultValue) { + if (typeof index !== 'number') return defaultValue + index = ~~index // Coerce to integer. + if (index >= len) return len + if (index >= 0) return index + index += len + if (index >= 0) return index + return 0 +} + +var toType = function (flag) { + switch (flag) { + case 0: + return 'file' + case 1: + return 'link' + case 2: + return 'symlink' + case 3: + return 'character-device' + case 4: + return 'block-device' + case 5: + return 'directory' + case 6: + return 'fifo' + case 7: + return 'contiguous-file' + case 72: + return 'pax-header' + case 55: + return 'pax-global-header' + case 27: + return 'gnu-long-link-path' + case 28: + case 30: + return 'gnu-long-path' + } + + return null +} + +var toTypeflag = function (flag) { + switch (flag) { + case 'file': + return 0 + case 'link': + return 1 + case 'symlink': + return 2 + case 'character-device': + return 3 + case 'block-device': + return 4 + case 'directory': + return 5 + case 'fifo': + return 6 + case 'contiguous-file': + return 7 + case 'pax-header': + return 72 + } + + return 0 +} + +var indexOf = function (block, num, offset, end) { + for (; offset < end; offset++) { + if (block[offset] === num) return offset + } + return end +} + +var cksum = function (block) { + var sum = 8 * 32 + for (var i = 0; i < 148; i++) sum += block[i] + for (var j = 156; j < 512; j++) sum += block[j] + return sum +} + +var encodeOct = function (val, n) { + val = val.toString(8) + if (val.length > n) return SEVENS.slice(0, n) + ' ' + else return ZEROS.slice(0, n - val.length) + val + ' ' +} + +/* Copied from the node-tar repo and modified to meet + * tar-stream coding standard. + * + * Source: https://github.com/npm/node-tar/blob/51b6627a1f357d2eb433e7378e5f05e83b7aa6cd/lib/header.js#L349 + */ +function parse256 (buf) { + // first byte MUST be either 80 or FF + // 80 for positive, FF for 2's comp + var positive + if (buf[0] === 0x80) positive = true + else if (buf[0] === 0xFF) positive = false + else return null + + // build up a base-256 tuple from the least sig to the highest + var tuple = [] + for (var i = buf.length - 1; i > 0; i--) { + var byte = buf[i] + if (positive) tuple.push(byte) + else tuple.push(0xFF - byte) + } + + var sum = 0 + var l = tuple.length + for (i = 0; i < l; i++) { + sum += tuple[i] * Math.pow(256, i) + } + + return positive ? sum : -1 * sum +} + +var decodeOct = function (val, offset, length) { + val = val.slice(offset, offset + length) + offset = 0 + + // If prefixed with 0x80 then parse as a base-256 integer + if (val[offset] & 0x80) { + return parse256(val) + } else { + // Older versions of tar can prefix with spaces + while (offset < val.length && val[offset] === 32) offset++ + var end = clamp(indexOf(val, 32, offset, val.length), val.length, val.length) + while (offset < end && val[offset] === 0) offset++ + if (end === offset) return 0 + return parseInt(val.slice(offset, end).toString(), 8) + } +} + +var decodeStr = function (val, offset, length, encoding) { + return val.slice(offset, indexOf(val, 0, offset, offset + length)).toString(encoding) +} + +var addLength = function (str) { + var len = Buffer.byteLength(str) + var digits = Math.floor(Math.log(len) / Math.log(10)) + 1 + if (len + digits >= Math.pow(10, digits)) digits++ + + return (len + digits) + str +} + +exports.decodeLongPath = function (buf, encoding) { + return decodeStr(buf, 0, buf.length, encoding) +} + +exports.encodePax = function (opts) { // TODO: encode more stuff in pax + var result = '' + if (opts.name) result += addLength(' path=' + opts.name + '\n') + if (opts.linkname) result += addLength(' linkpath=' + opts.linkname + '\n') + var pax = opts.pax + if (pax) { + for (var key in pax) { + result += addLength(' ' + key + '=' + pax[key] + '\n') + } + } + return Buffer.from(result) +} + +exports.decodePax = function (buf) { + var result = {} + + while (buf.length) { + var i = 0 + while (i < buf.length && buf[i] !== 32) i++ + var len = parseInt(buf.slice(0, i).toString(), 10) + if (!len) return result + + var b = buf.slice(i + 1, len - 1).toString() + var keyIndex = b.indexOf('=') + if (keyIndex === -1) return result + result[b.slice(0, keyIndex)] = b.slice(keyIndex + 1) + + buf = buf.slice(len) + } + + return result +} + +exports.encode = function (opts) { + var buf = alloc(512) + var name = opts.name + var prefix = '' + + if (opts.typeflag === 5 && name[name.length - 1] !== '/') name += '/' + if (Buffer.byteLength(name) !== name.length) return null // utf-8 + + while (Buffer.byteLength(name) > 100) { + var i = name.indexOf('/') + if (i === -1) return null + prefix += prefix ? '/' + name.slice(0, i) : name.slice(0, i) + name = name.slice(i + 1) + } + + if (Buffer.byteLength(name) > 100 || Buffer.byteLength(prefix) > 155) return null + if (opts.linkname && Buffer.byteLength(opts.linkname) > 100) return null + + buf.write(name) + buf.write(encodeOct(opts.mode & MASK, 6), 100) + buf.write(encodeOct(opts.uid, 6), 108) + buf.write(encodeOct(opts.gid, 6), 116) + buf.write(encodeOct(opts.size, 11), 124) + buf.write(encodeOct((opts.mtime.getTime() / 1000) | 0, 11), 136) + + buf[156] = ZERO_OFFSET + toTypeflag(opts.type) + + if (opts.linkname) buf.write(opts.linkname, 157) + + USTAR_MAGIC.copy(buf, MAGIC_OFFSET) + USTAR_VER.copy(buf, VERSION_OFFSET) + if (opts.uname) buf.write(opts.uname, 265) + if (opts.gname) buf.write(opts.gname, 297) + buf.write(encodeOct(opts.devmajor || 0, 6), 329) + buf.write(encodeOct(opts.devminor || 0, 6), 337) + + if (prefix) buf.write(prefix, 345) + + buf.write(encodeOct(cksum(buf), 6), 148) + + return buf +} + +exports.decode = function (buf, filenameEncoding, allowUnknownFormat) { + var typeflag = buf[156] === 0 ? 0 : buf[156] - ZERO_OFFSET + + var name = decodeStr(buf, 0, 100, filenameEncoding) + var mode = decodeOct(buf, 100, 8) + var uid = decodeOct(buf, 108, 8) + var gid = decodeOct(buf, 116, 8) + var size = decodeOct(buf, 124, 12) + var mtime = decodeOct(buf, 136, 12) + var type = toType(typeflag) + var linkname = buf[157] === 0 ? null : decodeStr(buf, 157, 100, filenameEncoding) + var uname = decodeStr(buf, 265, 32) + var gname = decodeStr(buf, 297, 32) + var devmajor = decodeOct(buf, 329, 8) + var devminor = decodeOct(buf, 337, 8) + + var c = cksum(buf) + + // checksum is still initial value if header was null. + if (c === 8 * 32) return null + + // valid checksum + if (c !== decodeOct(buf, 148, 8)) throw new Error('Invalid tar header. Maybe the tar is corrupted or it needs to be gunzipped?') + + if (USTAR_MAGIC.compare(buf, MAGIC_OFFSET, MAGIC_OFFSET + 6) === 0) { + // ustar (posix) format. + // prepend prefix, if present. + if (buf[345]) name = decodeStr(buf, 345, 155, filenameEncoding) + '/' + name + } else if (GNU_MAGIC.compare(buf, MAGIC_OFFSET, MAGIC_OFFSET + 6) === 0 && + GNU_VER.compare(buf, VERSION_OFFSET, VERSION_OFFSET + 2) === 0) { + // 'gnu'/'oldgnu' format. Similar to ustar, but has support for incremental and + // multi-volume tarballs. + } else { + if (!allowUnknownFormat) { + throw new Error('Invalid tar header: unknown format.') + } + } + + // to support old tar versions that use trailing / to indicate dirs + if (typeflag === 0 && name && name[name.length - 1] === '/') typeflag = 5 + + return { + name, + mode, + uid, + gid, + size, + mtime: new Date(1000 * mtime), + type, + linkname, + uname, + gname, + devmajor, + devminor + } +} + + +/***/ }), + +/***/ 2283: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +exports.extract = __nccwpck_require__(7882) +exports.pack = __nccwpck_require__(4930) + + +/***/ }), + +/***/ 4930: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +var constants = __nccwpck_require__(3186) +var eos = __nccwpck_require__(1205) +var inherits = __nccwpck_require__(4124) +var alloc = Buffer.alloc + +var Readable = (__nccwpck_require__(1642).Readable) +var Writable = (__nccwpck_require__(1642).Writable) +var StringDecoder = (__nccwpck_require__(1576).StringDecoder) + +var headers = __nccwpck_require__(8860) + +var DMODE = parseInt('755', 8) +var FMODE = parseInt('644', 8) + +var END_OF_TAR = alloc(1024) + +var noop = function () {} + +var overflow = function (self, size) { + size &= 511 + if (size) self.push(END_OF_TAR.slice(0, 512 - size)) +} + +function modeToType (mode) { + switch (mode & constants.S_IFMT) { + case constants.S_IFBLK: return 'block-device' + case constants.S_IFCHR: return 'character-device' + case constants.S_IFDIR: return 'directory' + case constants.S_IFIFO: return 'fifo' + case constants.S_IFLNK: return 'symlink' + } + + return 'file' +} + +var Sink = function (to) { + Writable.call(this) + this.written = 0 + this._to = to + this._destroyed = false +} + +inherits(Sink, Writable) + +Sink.prototype._write = function (data, enc, cb) { + this.written += data.length + if (this._to.push(data)) return cb() + this._to._drain = cb +} + +Sink.prototype.destroy = function () { + if (this._destroyed) return + this._destroyed = true + this.emit('close') +} + +var LinkSink = function () { + Writable.call(this) + this.linkname = '' + this._decoder = new StringDecoder('utf-8') + this._destroyed = false +} + +inherits(LinkSink, Writable) + +LinkSink.prototype._write = function (data, enc, cb) { + this.linkname += this._decoder.write(data) + cb() +} + +LinkSink.prototype.destroy = function () { + if (this._destroyed) return + this._destroyed = true + this.emit('close') +} + +var Void = function () { + Writable.call(this) + this._destroyed = false +} + +inherits(Void, Writable) + +Void.prototype._write = function (data, enc, cb) { + cb(new Error('No body allowed for this entry')) +} + +Void.prototype.destroy = function () { + if (this._destroyed) return + this._destroyed = true + this.emit('close') +} + +var Pack = function (opts) { + if (!(this instanceof Pack)) return new Pack(opts) + Readable.call(this, opts) + + this._drain = noop + this._finalized = false + this._finalizing = false + this._destroyed = false + this._stream = null +} + +inherits(Pack, Readable) + +Pack.prototype.entry = function (header, buffer, callback) { + if (this._stream) throw new Error('already piping an entry') + if (this._finalized || this._destroyed) return + + if (typeof buffer === 'function') { + callback = buffer + buffer = null + } + + if (!callback) callback = noop + + var self = this + + if (!header.size || header.type === 'symlink') header.size = 0 + if (!header.type) header.type = modeToType(header.mode) + if (!header.mode) header.mode = header.type === 'directory' ? DMODE : FMODE + if (!header.uid) header.uid = 0 + if (!header.gid) header.gid = 0 + if (!header.mtime) header.mtime = new Date() + + if (typeof buffer === 'string') buffer = Buffer.from(buffer) + if (Buffer.isBuffer(buffer)) { + header.size = buffer.length + this._encode(header) + var ok = this.push(buffer) + overflow(self, header.size) + if (ok) process.nextTick(callback) + else this._drain = callback + return new Void() + } + + if (header.type === 'symlink' && !header.linkname) { + var linkSink = new LinkSink() + eos(linkSink, function (err) { + if (err) { // stream was closed + self.destroy() + return callback(err) + } + + header.linkname = linkSink.linkname + self._encode(header) + callback() + }) + + return linkSink + } + + this._encode(header) + + if (header.type !== 'file' && header.type !== 'contiguous-file') { + process.nextTick(callback) + return new Void() + } + + var sink = new Sink(this) + + this._stream = sink + + eos(sink, function (err) { + self._stream = null + + if (err) { // stream was closed + self.destroy() + return callback(err) + } + + if (sink.written !== header.size) { // corrupting tar + self.destroy() + return callback(new Error('size mismatch')) + } + + overflow(self, header.size) + if (self._finalizing) self.finalize() + callback() + }) + + return sink +} + +Pack.prototype.finalize = function () { + if (this._stream) { + this._finalizing = true + return + } + + if (this._finalized) return + this._finalized = true + this.push(END_OF_TAR) + this.push(null) +} + +Pack.prototype.destroy = function (err) { + if (this._destroyed) return + this._destroyed = true + + if (err) this.emit('error', err) + this.emit('close') + if (this._stream && this._stream.destroy) this._stream.destroy() +} + +Pack.prototype._encode = function (header) { + if (!header.pax) { + var buf = headers.encode(header) + if (buf) { + this.push(buf) + return + } + } + this._encodePax(header) +} + +Pack.prototype._encodePax = function (header) { + var paxHeader = headers.encodePax({ + name: header.name, + linkname: header.linkname, + pax: header.pax + }) + + var newHeader = { + name: 'PaxHeader', + mode: header.mode, + uid: header.uid, + gid: header.gid, + size: paxHeader.length, + mtime: header.mtime, + type: 'pax-header', + linkname: header.linkname && 'PaxHeader', + uname: header.uname, + gname: header.gname, + devmajor: header.devmajor, + devminor: header.devminor + } + + this.push(headers.encode(newHeader)) + this.push(paxHeader) + overflow(this, paxHeader.length) + + newHeader.size = header.size + newHeader.type = header.type + this.push(headers.encode(newHeader)) +} + +Pack.prototype._read = function (n) { + var drain = this._drain + this._drain = noop + drain() +} + +module.exports = Pack + + +/***/ }), + +/***/ 4294: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +module.exports = __nccwpck_require__(4219); + + +/***/ }), + +/***/ 4219: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +var net = __nccwpck_require__(1808); +var tls = __nccwpck_require__(4404); +var http = __nccwpck_require__(3685); +var https = __nccwpck_require__(5687); +var events = __nccwpck_require__(2361); +var assert = __nccwpck_require__(9491); +var util = __nccwpck_require__(3837); + + +exports.httpOverHttp = httpOverHttp; +exports.httpsOverHttp = httpsOverHttp; +exports.httpOverHttps = httpOverHttps; +exports.httpsOverHttps = httpsOverHttps; + + +function httpOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + return agent; +} + +function httpsOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + +function httpOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + return agent; +} + +function httpsOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + + +function TunnelingAgent(options) { + var self = this; + self.options = options || {}; + self.proxyOptions = self.options.proxy || {}; + self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; + self.requests = []; + self.sockets = []; + + self.on('free', function onFree(socket, host, port, localAddress) { + var options = toOptions(host, port, localAddress); + for (var i = 0, len = self.requests.length; i < len; ++i) { + var pending = self.requests[i]; + if (pending.host === options.host && pending.port === options.port) { + // Detect the request to connect same origin server, + // reuse the connection. + self.requests.splice(i, 1); + pending.request.onSocket(socket); + return; + } + } + socket.destroy(); + self.removeSocket(socket); + }); +} +util.inherits(TunnelingAgent, events.EventEmitter); + +TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { + var self = this; + var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); + + if (self.sockets.length >= this.maxSockets) { + // We are over limit so we'll add it to the queue. + self.requests.push(options); + return; + } + + // If we are under maxSockets create a new one. + self.createSocket(options, function(socket) { + socket.on('free', onFree); + socket.on('close', onCloseOrRemove); + socket.on('agentRemove', onCloseOrRemove); + req.onSocket(socket); + + function onFree() { + self.emit('free', socket, options); + } + + function onCloseOrRemove(err) { + self.removeSocket(socket); + socket.removeListener('free', onFree); + socket.removeListener('close', onCloseOrRemove); + socket.removeListener('agentRemove', onCloseOrRemove); + } + }); +}; + +TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { + var self = this; + var placeholder = {}; + self.sockets.push(placeholder); + + var connectOptions = mergeOptions({}, self.proxyOptions, { + method: 'CONNECT', + path: options.host + ':' + options.port, + agent: false, + headers: { + host: options.host + ':' + options.port + } + }); + if (options.localAddress) { + connectOptions.localAddress = options.localAddress; + } + if (connectOptions.proxyAuth) { + connectOptions.headers = connectOptions.headers || {}; + connectOptions.headers['Proxy-Authorization'] = 'Basic ' + + new Buffer(connectOptions.proxyAuth).toString('base64'); + } + + debug('making CONNECT request'); + var connectReq = self.request(connectOptions); + connectReq.useChunkedEncodingByDefault = false; // for v0.6 + connectReq.once('response', onResponse); // for v0.6 + connectReq.once('upgrade', onUpgrade); // for v0.6 + connectReq.once('connect', onConnect); // for v0.7 or later + connectReq.once('error', onError); + connectReq.end(); + + function onResponse(res) { + // Very hacky. This is necessary to avoid http-parser leaks. + res.upgrade = true; + } + + function onUpgrade(res, socket, head) { + // Hacky. + process.nextTick(function() { + onConnect(res, socket, head); + }); + } + + function onConnect(res, socket, head) { + connectReq.removeAllListeners(); + socket.removeAllListeners(); + + if (res.statusCode !== 200) { + debug('tunneling socket could not be established, statusCode=%d', + res.statusCode); + socket.destroy(); + var error = new Error('tunneling socket could not be established, ' + + 'statusCode=' + res.statusCode); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + if (head.length > 0) { + debug('got illegal response body from proxy'); + socket.destroy(); + var error = new Error('got illegal response body from proxy'); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + debug('tunneling connection has established'); + self.sockets[self.sockets.indexOf(placeholder)] = socket; + return cb(socket); + } + + function onError(cause) { + connectReq.removeAllListeners(); + + debug('tunneling socket could not be established, cause=%s\n', + cause.message, cause.stack); + var error = new Error('tunneling socket could not be established, ' + + 'cause=' + cause.message); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + } +}; + +TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { + var pos = this.sockets.indexOf(socket) + if (pos === -1) { + return; + } + this.sockets.splice(pos, 1); + + var pending = this.requests.shift(); + if (pending) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(pending, function(socket) { + pending.request.onSocket(socket); + }); + } +}; + +function createSecureSocket(options, cb) { + var self = this; + TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { + var hostHeader = options.request.getHeader('host'); + var tlsOptions = mergeOptions({}, self.options, { + socket: socket, + servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host + }); + + // 0 is dummy port for v0.6 + var secureSocket = tls.connect(0, tlsOptions); + self.sockets[self.sockets.indexOf(socket)] = secureSocket; + cb(secureSocket); + }); +} + + +function toOptions(host, port, localAddress) { + if (typeof host === 'string') { // since v0.10 + return { + host: host, + port: port, + localAddress: localAddress + }; + } + return host; // for v0.11 or later +} + +function mergeOptions(target) { + for (var i = 1, len = arguments.length; i < len; ++i) { + var overrides = arguments[i]; + if (typeof overrides === 'object') { + var keys = Object.keys(overrides); + for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { + var k = keys[j]; + if (overrides[k] !== undefined) { + target[k] = overrides[k]; + } + } + } + } + return target; +} + + +var debug; +if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { + debug = function() { + var args = Array.prototype.slice.call(arguments); + if (typeof args[0] === 'string') { + args[0] = 'TUNNEL: ' + args[0]; + } else { + args.unshift('TUNNEL:'); + } + console.error.apply(console, args); + } +} else { + debug = function() {}; +} +exports.debug = debug; // for test + + +/***/ }), + +/***/ 5278: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + +/** + * For Node.js, simply re-export the core `util.deprecate` function. + */ + +module.exports = __nccwpck_require__(3837).deprecate; + + +/***/ }), + +/***/ 5840: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "v1", ({ + enumerable: true, + get: function () { + return _v.default; + } +})); +Object.defineProperty(exports, "v3", ({ + enumerable: true, + get: function () { + return _v2.default; + } +})); +Object.defineProperty(exports, "v4", ({ + enumerable: true, + get: function () { + return _v3.default; + } +})); +Object.defineProperty(exports, "v5", ({ + enumerable: true, + get: function () { + return _v4.default; + } +})); +Object.defineProperty(exports, "NIL", ({ + enumerable: true, + get: function () { + return _nil.default; + } +})); +Object.defineProperty(exports, "version", ({ + enumerable: true, + get: function () { + return _version.default; + } +})); +Object.defineProperty(exports, "validate", ({ + enumerable: true, + get: function () { + return _validate.default; + } +})); +Object.defineProperty(exports, "stringify", ({ + enumerable: true, + get: function () { + return _stringify.default; + } +})); +Object.defineProperty(exports, "parse", ({ + enumerable: true, + get: function () { + return _parse.default; + } +})); + +var _v = _interopRequireDefault(__nccwpck_require__(8628)); + +var _v2 = _interopRequireDefault(__nccwpck_require__(6409)); + +var _v3 = _interopRequireDefault(__nccwpck_require__(5122)); + +var _v4 = _interopRequireDefault(__nccwpck_require__(9120)); + +var _nil = _interopRequireDefault(__nccwpck_require__(5332)); + +var _version = _interopRequireDefault(__nccwpck_require__(1595)); + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +var _parse = _interopRequireDefault(__nccwpck_require__(4848)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/***/ }), + +/***/ 4569: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function md5(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } + + return _crypto.default.createHash('md5').update(bytes).digest(); +} + +var _default = md5; +exports["default"] = _default; + +/***/ }), + +/***/ 5332: +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = '00000000-0000-0000-0000-000000000000'; +exports["default"] = _default; + +/***/ }), + +/***/ 4848: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function parse(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + let v; + const arr = new Uint8Array(16); // Parse ########-....-....-....-............ + + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 0xff; + arr[2] = v >>> 8 & 0xff; + arr[3] = v & 0xff; // Parse ........-####-....-....-............ + + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 0xff; // Parse ........-....-####-....-............ + + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 0xff; // Parse ........-....-....-####-............ + + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 0xff; // Parse ........-....-....-....-############ + // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; + arr[11] = v / 0x100000000 & 0xff; + arr[12] = v >>> 24 & 0xff; + arr[13] = v >>> 16 & 0xff; + arr[14] = v >>> 8 & 0xff; + arr[15] = v & 0xff; + return arr; +} + +var _default = parse; +exports["default"] = _default; + +/***/ }), + +/***/ 814: +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; +exports["default"] = _default; + +/***/ }), + +/***/ 807: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = rng; + +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate + +let poolPtr = rnds8Pool.length; + +function rng() { + if (poolPtr > rnds8Pool.length - 16) { + _crypto.default.randomFillSync(rnds8Pool); + + poolPtr = 0; + } + + return rnds8Pool.slice(poolPtr, poolPtr += 16); +} + +/***/ }), + +/***/ 5274: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function sha1(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } + + return _crypto.default.createHash('sha1').update(bytes).digest(); +} + +var _default = sha1; +exports["default"] = _default; + +/***/ }), + +/***/ 8950: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +const byteToHex = []; + +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 0x100).toString(16).substr(1)); +} + +function stringify(arr, offset = 0) { + // Note: Be careful editing this code! It's been tuned for performance + // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 + const uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one + // of the following: + // - One or more input array values don't map to a hex octet (leading to + // "undefined" in the uuid) + // - Invalid input values for the RFC `version` or `variant` fields + + if (!(0, _validate.default)(uuid)) { + throw TypeError('Stringified UUID is invalid'); + } + + return uuid; +} + +var _default = stringify; +exports["default"] = _default; + +/***/ }), + +/***/ 8628: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _rng = _interopRequireDefault(__nccwpck_require__(807)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html +let _nodeId; + +let _clockseq; // Previous uuid creation time + + +let _lastMSecs = 0; +let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details + +function v1(options, buf, offset) { + let i = buf && offset || 0; + const b = buf || new Array(16); + options = options || {}; + let node = options.node || _nodeId; + let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || _rng.default)(); + + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; + } + + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + + + let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + + let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) + + const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression + + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + + + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } // Per 4.2.1.2 Throw error if too many uuids are requested + + + if (nsecs >= 10000) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + + msecs += 12219292800000; // `time_low` + + const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; // `time_mid` + + const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; // `time_high_and_version` + + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + + b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + + b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` + + b[i++] = clockseq & 0xff; // `node` + + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf || (0, _stringify.default)(b); +} + +var _default = v1; +exports["default"] = _default; + +/***/ }), + +/***/ 6409: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _v = _interopRequireDefault(__nccwpck_require__(5998)); + +var _md = _interopRequireDefault(__nccwpck_require__(4569)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v3 = (0, _v.default)('v3', 0x30, _md.default); +var _default = v3; +exports["default"] = _default; + +/***/ }), + +/***/ 5998: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = _default; +exports.URL = exports.DNS = void 0; + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +var _parse = _interopRequireDefault(__nccwpck_require__(4848)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; + +function _default(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } + + if (namespace.length !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return (0, _stringify.default)(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} + +/***/ }), + +/***/ 5122: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _rng = _interopRequireDefault(__nccwpck_require__(807)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function v4(options, buf, offset) { + options = options || {}; + + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + + + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; + } + + return (0, _stringify.default)(rnds); +} + +var _default = v4; +exports["default"] = _default; + +/***/ }), + +/***/ 9120: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _v = _interopRequireDefault(__nccwpck_require__(5998)); + +var _sha = _interopRequireDefault(__nccwpck_require__(5274)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; +exports["default"] = _default; + +/***/ }), + +/***/ 6900: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _regex = _interopRequireDefault(__nccwpck_require__(814)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); +} + +var _default = validate; +exports["default"] = _default; + +/***/ }), + +/***/ 1595: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.substr(14, 1), 16); +} + +var _default = version; +exports["default"] = _default; + +/***/ }), + +/***/ 2940: +/***/ ((module) => { + +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') + + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + + return wrapper + + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } +} + + +/***/ }), + +/***/ 9491: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("assert"); + +/***/ }), + +/***/ 4300: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("buffer"); + +/***/ }), + +/***/ 2057: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("constants"); + +/***/ }), + +/***/ 6113: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("crypto"); + +/***/ }), + +/***/ 2361: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("events"); + +/***/ }), + +/***/ 7147: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("fs"); + +/***/ }), + +/***/ 3685: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("http"); + +/***/ }), + +/***/ 5687: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("https"); + +/***/ }), + +/***/ 1808: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("net"); + +/***/ }), + +/***/ 7718: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:child_process"); + +/***/ }), + +/***/ 7561: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:fs"); + +/***/ }), + +/***/ 7742: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:process"); + +/***/ }), + +/***/ 4492: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:stream"); + +/***/ }), + +/***/ 5628: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:zlib"); + +/***/ }), + +/***/ 2037: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("os"); + +/***/ }), + +/***/ 1017: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("path"); + +/***/ }), + +/***/ 2781: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("stream"); + +/***/ }), + +/***/ 1576: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("string_decoder"); + +/***/ }), + +/***/ 4404: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("tls"); + +/***/ }), + +/***/ 3837: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("util"); + +/***/ }), + +/***/ 6955: +/***/ ((__webpack_module__, __unused_webpack___webpack_exports__, __nccwpck_require__) => { + +__nccwpck_require__.a(__webpack_module__, async (__webpack_handle_async_dependencies__) => { +/* harmony import */ var node_child_process__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(7718); +/* harmony import */ var node_process__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(7742); +/* harmony import */ var node_stream__WEBPACK_IMPORTED_MODULE_2__ = __nccwpck_require__(4492); +/* harmony import */ var node_fs__WEBPACK_IMPORTED_MODULE_3__ = __nccwpck_require__(7561); +/* harmony import */ var node_zlib__WEBPACK_IMPORTED_MODULE_4__ = __nccwpck_require__(5628); +/* harmony import */ var tar_stream__WEBPACK_IMPORTED_MODULE_5__ = __nccwpck_require__(2283); +/* harmony import */ var _actions_core__WEBPACK_IMPORTED_MODULE_6__ = __nccwpck_require__(2186); + + + + + + + + +const container = _actions_core__WEBPACK_IMPORTED_MODULE_6__.getInput('container', {required: true}); +const error_log_paths = JSON.parse(_actions_core__WEBPACK_IMPORTED_MODULE_6__.getInput('error-log-paths', {required: true})); +const log_tarball_prefix = _actions_core__WEBPACK_IMPORTED_MODULE_6__.getInput('log-tarball-prefix', {required: true}); +const tests_label = _actions_core__WEBPACK_IMPORTED_MODULE_6__.getInput('tests-label', {required: true}); +const test_timeout = _actions_core__WEBPACK_IMPORTED_MODULE_6__.getInput('test-timeout', {required: true}); + +const repo_name = node_process__WEBPACK_IMPORTED_MODULE_1__.env.GITHUB_REPOSITORY.split('/')[1]; + +try { + // Defensively remove any leftover container from a prior/interrupted run. On a + // persistent self-hosted runner the Docker daemon survives between jobs, and the + // per-test containers below use fixed names with no --rm, so an orphan would block + // name reuse with "container name already in use". (ENF's ephemeral runners get a + // fresh daemon each job and never hit this.) + node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync("docker", ["rm", "-f", "base"], {stdio:"ignore"}); + if(node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync("docker", ["run", "--name", "base", "-v", `${node_process__WEBPACK_IMPORTED_MODULE_1__.cwd()}/build.tar.zst:/build.tar.zst`, "--workdir", `/__w/${repo_name}/${repo_name}`, container, "sh", "-c", "zstdcat /build.tar.zst | tar x"], {stdio:"inherit"}).status) + throw new Error("Failed to create base container"); + if(node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync("docker", ["commit", "base", "baseimage"], {stdio:"inherit"}).status) + throw new Error("Failed to create base image"); + if(node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync("docker", ["rm", "base"], {stdio:"inherit"}).status) + throw new Error("Failed to remove base container"); + + const test_query_result = node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync("docker", ["run", "--rm", "baseimage", "bash", "-e", "-o", "pipefail", "-c", `cd build; ctest -L '${tests_label}' --show-only=json-v1`]); + if(test_query_result.status) + throw new Error("Failed to discover tests with label") + const tests = JSON.parse(test_query_result.stdout).tests; + + // Run the test containers with BOUNDED concurrency. The nonparallelizable_tests and + // long_running_tests suites are heavy multi-nodeos integration tests; launching one + // container per test all at once (the original behaviour) starves CPU/RAM/ports on a + // modest self-hosted runner and makes them fail en masse. Cap how many run at a time + // (override with the CTEST_CONTAINER_CONCURRENCY env var; default 4). results[i] stays + // aligned with tests[i] so the failure-log extraction below is unchanged. + const max_concurrency = Math.max(1, parseInt(node_process__WEBPACK_IMPORTED_MODULE_1__.env.CTEST_CONTAINER_CONCURRENCY, 10) || 4); + console.log(`Running ${tests.length} '${tests_label}' test(s), up to ${max_concurrency} container(s) at a time`); + + const results = new Array(tests.length); + let next_test = 0; + async function run_worker() { + for(let i = next_test++; i < tests.length; i = next_test++) { + const t = tests[i]; + // Clear any orphaned container of this name before reusing it (see note above). + node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync("docker", ["rm", "-f", t.name], {stdio:"ignore"}); + results[i] = await new Promise(resolve => { + node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawn("docker", ["run", "--security-opt", "seccomp=unconfined", "-e", "GITHUB_ACTIONS=True", "--name", t.name, "--init", "baseimage", "bash", "-c", `cd build; ctest --output-on-failure -R '^${t.name}$' --timeout ${test_timeout}`], {stdio:"inherit"}).on('close', code => resolve(code)); + }); + } + } + await Promise.all(Array.from({length: Math.min(max_concurrency, tests.length)}, run_worker)); + + for(let i = 0; i < results.length; ++i) { + if(results[i] === 0) + continue; + + //failing test + _actions_core__WEBPACK_IMPORTED_MODULE_6__.setFailed("Some tests failed"); + + let extractor = tar_stream__WEBPACK_IMPORTED_MODULE_5__.extract(); + let packer = tar_stream__WEBPACK_IMPORTED_MODULE_5__.pack(); + + extractor.on('entry', (header, stream, next) => { + if(!header.name.startsWith(`__w/${repo_name}/${repo_name}/build`)) { + stream.on('end', () => next()); + stream.resume(); + return; + } + + header.name = header.name.substring(`__w/${repo_name}/${repo_name}/`.length); + if(header.name !== "build/" && error_log_paths.filter(p => header.name.startsWith(p)).length === 0) { + stream.on('end', () => next()); + stream.resume(); + return; + } + + stream.pipe(packer.entry(header, next)); + }).on('finish', () => {packer.finalize()}); + + node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawn("docker", ["export", tests[i].name]).stdout.pipe(extractor); + node_stream__WEBPACK_IMPORTED_MODULE_2__.promises.pipeline(packer, node_zlib__WEBPACK_IMPORTED_MODULE_4__.createGzip(), node_fs__WEBPACK_IMPORTED_MODULE_3__.createWriteStream(`${log_tarball_prefix}-${tests[i].name}-logs.tar.gz`)); + } +} catch(e) { + _actions_core__WEBPACK_IMPORTED_MODULE_6__.setFailed(`Uncaught exception ${e.message}`); +} + +__webpack_handle_async_dependencies__(); +}, 1); + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __nccwpck_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ var threw = true; +/******/ try { +/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __nccwpck_require__); +/******/ threw = false; +/******/ } finally { +/******/ if(threw) delete __webpack_module_cache__[moduleId]; +/******/ } +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/async module */ +/******/ (() => { +/******/ var webpackThen = typeof Symbol === "function" ? Symbol("webpack then") : "__webpack_then__"; +/******/ var webpackExports = typeof Symbol === "function" ? Symbol("webpack exports") : "__webpack_exports__"; +/******/ var completeQueue = (queue) => { +/******/ if(queue) { +/******/ queue.forEach((fn) => (fn.r--)); +/******/ queue.forEach((fn) => (fn.r-- ? fn.r++ : fn())); +/******/ } +/******/ } +/******/ var completeFunction = (fn) => (!--fn.r && fn()); +/******/ var queueFunction = (queue, fn) => (queue ? queue.push(fn) : completeFunction(fn)); +/******/ var wrapDeps = (deps) => (deps.map((dep) => { +/******/ if(dep !== null && typeof dep === "object") { +/******/ if(dep[webpackThen]) return dep; +/******/ if(dep.then) { +/******/ var queue = []; +/******/ dep.then((r) => { +/******/ obj[webpackExports] = r; +/******/ completeQueue(queue); +/******/ queue = 0; +/******/ }); +/******/ var obj = {}; +/******/ obj[webpackThen] = (fn, reject) => (queueFunction(queue, fn), dep['catch'](reject)); +/******/ return obj; +/******/ } +/******/ } +/******/ var ret = {}; +/******/ ret[webpackThen] = (fn) => (completeFunction(fn)); +/******/ ret[webpackExports] = dep; +/******/ return ret; +/******/ })); +/******/ __nccwpck_require__.a = (module, body, hasAwait) => { +/******/ var queue = hasAwait && []; +/******/ var exports = module.exports; +/******/ var currentDeps; +/******/ var outerResolve; +/******/ var reject; +/******/ var isEvaluating = true; +/******/ var nested = false; +/******/ var whenAll = (deps, onResolve, onReject) => { +/******/ if (nested) return; +/******/ nested = true; +/******/ onResolve.r += deps.length; +/******/ deps.map((dep, i) => (dep[webpackThen](onResolve, onReject))); +/******/ nested = false; +/******/ }; +/******/ var promise = new Promise((resolve, rej) => { +/******/ reject = rej; +/******/ outerResolve = () => (resolve(exports), completeQueue(queue), queue = 0); +/******/ }); +/******/ promise[webpackExports] = exports; +/******/ promise[webpackThen] = (fn, rejectFn) => { +/******/ if (isEvaluating) { return completeFunction(fn); } +/******/ if (currentDeps) whenAll(currentDeps, fn, rejectFn); +/******/ queueFunction(queue, fn); +/******/ promise['catch'](rejectFn); +/******/ }; +/******/ module.exports = promise; +/******/ body((deps) => { +/******/ if(!deps) return outerResolve(); +/******/ currentDeps = wrapDeps(deps); +/******/ var fn, result; +/******/ var promise = new Promise((resolve, reject) => { +/******/ fn = () => (resolve(result = currentDeps.map((d) => (d[webpackExports])))); +/******/ fn.r = 0; +/******/ whenAll(currentDeps, fn, reject); +/******/ }); +/******/ return fn.r ? promise : result; +/******/ }).then(outerResolve, reject); +/******/ isEvaluating = false; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/compat */ +/******/ +/******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = new URL('.', import.meta.url).pathname.slice(import.meta.url.match(/^file:\/\/\/\w:/) ? 1 : 0, -1) + "/"; +/******/ +/************************************************************************/ +/******/ +/******/ // startup +/******/ // Load entry module and return exports +/******/ // This entry module used 'module' so it can't be inlined +/******/ var __webpack_exports__ = __nccwpck_require__(6955); +/******/ __webpack_exports__ = await __webpack_exports__; +/******/ diff --git a/.github/actions/parallel-ctest-containers/main.mjs b/.github/actions/parallel-ctest-containers/main.mjs index 876b107d1a..63d9538a14 100644 --- a/.github/actions/parallel-ctest-containers/main.mjs +++ b/.github/actions/parallel-ctest-containers/main.mjs @@ -33,16 +33,28 @@ try { throw new Error("Failed to discover tests with label") const tests = JSON.parse(test_query_result.stdout).tests; - let subprocesses = []; - tests.forEach(t => { - // Clear any orphaned container of this name before reusing it (see note above). - child_process.spawnSync("docker", ["rm", "-f", t.name], {stdio:"ignore"}); - subprocesses.push(new Promise(resolve => { - child_process.spawn("docker", ["run", "--security-opt", "seccomp=unconfined", "-e", "GITHUB_ACTIONS=True", "--name", t.name, "--init", "baseimage", "bash", "-c", `cd build; ctest --output-on-failure -R '^${t.name}$' --timeout ${test_timeout}`], {stdio:"inherit"}).on('close', code => resolve(code)); - })); - }); + // Run the test containers with BOUNDED concurrency. The nonparallelizable_tests and + // long_running_tests suites are heavy multi-nodeos integration tests; launching one + // container per test all at once (the original behaviour) starves CPU/RAM/ports on a + // modest self-hosted runner and makes them fail en masse. Cap how many run at a time + // (override with the CTEST_CONTAINER_CONCURRENCY env var; default 4). results[i] stays + // aligned with tests[i] so the failure-log extraction below is unchanged. + const max_concurrency = Math.max(1, parseInt(process.env.CTEST_CONTAINER_CONCURRENCY, 10) || 4); + console.log(`Running ${tests.length} '${tests_label}' test(s), up to ${max_concurrency} container(s) at a time`); - const results = await Promise.all(subprocesses); + const results = new Array(tests.length); + let next_test = 0; + async function run_worker() { + for(let i = next_test++; i < tests.length; i = next_test++) { + const t = tests[i]; + // Clear any orphaned container of this name before reusing it (see note above). + child_process.spawnSync("docker", ["rm", "-f", t.name], {stdio:"ignore"}); + results[i] = await new Promise(resolve => { + child_process.spawn("docker", ["run", "--security-opt", "seccomp=unconfined", "-e", "GITHUB_ACTIONS=True", "--name", t.name, "--init", "baseimage", "bash", "-c", `cd build; ctest --output-on-failure -R '^${t.name}$' --timeout ${test_timeout}`], {stdio:"inherit"}).on('close', code => resolve(code)); + }); + } + } + await Promise.all(Array.from({length: Math.min(max_concurrency, tests.length)}, run_worker)); for(let i = 0; i < results.length; ++i) { if(results[i] === 0) From bd8471d6a65411863fb591c425b22f18d853f07a Mon Sep 17 00:00:00 2001 From: igorls <4753812+igorls@users.noreply.github.com> Date: Sun, 7 Jun 2026 19:52:05 -0300 Subject: [PATCH 17/17] ci: address review feedback on ctest concurrency pool - use a plain while loop instead of the unconventional for(;;) with next_test++ in both clauses (readability; Gemini) - parse CTEST_CONTAINER_CONCURRENCY with an explicit NaN check so a configured 0 clamps to 1 instead of silently falling back to 4 (Copilot) - add an 'error' handler to the docker spawn so a spawn failure resolves the worker as failed instead of hanging the pool (Copilot) Rebuilt dist/index.mjs; behaviour on the happy path is unchanged. --- .../actions/parallel-ctest-containers/dist/index.mjs | 12 +++++++++--- .github/actions/parallel-ctest-containers/main.mjs | 12 +++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/.github/actions/parallel-ctest-containers/dist/index.mjs b/.github/actions/parallel-ctest-containers/dist/index.mjs index 3404229173..17de5883b4 100644 --- a/.github/actions/parallel-ctest-containers/dist/index.mjs +++ b/.github/actions/parallel-ctest-containers/dist/index.mjs @@ -8045,18 +8045,24 @@ try { // modest self-hosted runner and makes them fail en masse. Cap how many run at a time // (override with the CTEST_CONTAINER_CONCURRENCY env var; default 4). results[i] stays // aligned with tests[i] so the failure-log extraction below is unchanged. - const max_concurrency = Math.max(1, parseInt(node_process__WEBPACK_IMPORTED_MODULE_1__.env.CTEST_CONTAINER_CONCURRENCY, 10) || 4); + const parsed_concurrency = parseInt(node_process__WEBPACK_IMPORTED_MODULE_1__.env.CTEST_CONTAINER_CONCURRENCY, 10); + const max_concurrency = Number.isNaN(parsed_concurrency) ? 4 : Math.max(1, parsed_concurrency); console.log(`Running ${tests.length} '${tests_label}' test(s), up to ${max_concurrency} container(s) at a time`); const results = new Array(tests.length); let next_test = 0; async function run_worker() { - for(let i = next_test++; i < tests.length; i = next_test++) { + while(next_test < tests.length) { + const i = next_test++; const t = tests[i]; // Clear any orphaned container of this name before reusing it (see note above). node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawnSync("docker", ["rm", "-f", t.name], {stdio:"ignore"}); results[i] = await new Promise(resolve => { - node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawn("docker", ["run", "--security-opt", "seccomp=unconfined", "-e", "GITHUB_ACTIONS=True", "--name", t.name, "--init", "baseimage", "bash", "-c", `cd build; ctest --output-on-failure -R '^${t.name}$' --timeout ${test_timeout}`], {stdio:"inherit"}).on('close', code => resolve(code)); + node_child_process__WEBPACK_IMPORTED_MODULE_0__.spawn("docker", ["run", "--security-opt", "seccomp=unconfined", "-e", "GITHUB_ACTIONS=True", "--name", t.name, "--init", "baseimage", "bash", "-c", `cd build; ctest --output-on-failure -R '^${t.name}$' --timeout ${test_timeout}`], {stdio:"inherit"}) + .on('close', code => resolve(code)) + // If docker can't even be spawned, 'close' may never fire — resolve as a + // failure so the pool doesn't hang and the test is reported as failed. + .on('error', err => { console.error(`Failed to spawn docker for ${t.name}: ${err.message}`); resolve(1); }); }); } } diff --git a/.github/actions/parallel-ctest-containers/main.mjs b/.github/actions/parallel-ctest-containers/main.mjs index 63d9538a14..d73c6d89b5 100644 --- a/.github/actions/parallel-ctest-containers/main.mjs +++ b/.github/actions/parallel-ctest-containers/main.mjs @@ -39,18 +39,24 @@ try { // modest self-hosted runner and makes them fail en masse. Cap how many run at a time // (override with the CTEST_CONTAINER_CONCURRENCY env var; default 4). results[i] stays // aligned with tests[i] so the failure-log extraction below is unchanged. - const max_concurrency = Math.max(1, parseInt(process.env.CTEST_CONTAINER_CONCURRENCY, 10) || 4); + const parsed_concurrency = parseInt(process.env.CTEST_CONTAINER_CONCURRENCY, 10); + const max_concurrency = Number.isNaN(parsed_concurrency) ? 4 : Math.max(1, parsed_concurrency); console.log(`Running ${tests.length} '${tests_label}' test(s), up to ${max_concurrency} container(s) at a time`); const results = new Array(tests.length); let next_test = 0; async function run_worker() { - for(let i = next_test++; i < tests.length; i = next_test++) { + while(next_test < tests.length) { + const i = next_test++; const t = tests[i]; // Clear any orphaned container of this name before reusing it (see note above). child_process.spawnSync("docker", ["rm", "-f", t.name], {stdio:"ignore"}); results[i] = await new Promise(resolve => { - child_process.spawn("docker", ["run", "--security-opt", "seccomp=unconfined", "-e", "GITHUB_ACTIONS=True", "--name", t.name, "--init", "baseimage", "bash", "-c", `cd build; ctest --output-on-failure -R '^${t.name}$' --timeout ${test_timeout}`], {stdio:"inherit"}).on('close', code => resolve(code)); + child_process.spawn("docker", ["run", "--security-opt", "seccomp=unconfined", "-e", "GITHUB_ACTIONS=True", "--name", t.name, "--init", "baseimage", "bash", "-c", `cd build; ctest --output-on-failure -R '^${t.name}$' --timeout ${test_timeout}`], {stdio:"inherit"}) + .on('close', code => resolve(code)) + // If docker can't even be spawned, 'close' may never fire — resolve as a + // failure so the pool doesn't hang and the test is reported as failed. + .on('error', err => { console.error(`Failed to spawn docker for ${t.name}: ${err.message}`); resolve(1); }); }); } }