From 4f1c27af8c09c45ac7dcb7c48146aa9392cebde8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Mon, 26 Aug 2024 19:20:09 +0200 Subject: [PATCH 1/5] src: handle errors correctly in webstorage PR-URL: https://github.com/nodejs/node/pull/54544 Reviewed-By: Benjamin Gruenbaum Reviewed-By: Anna Henningsen Reviewed-By: James M Snell Reviewed-By: Mohammed Keyvanzadeh --- src/node_webstorage.cc | 178 +++++++++++++++++++++-------------------- src/node_webstorage.h | 16 ++-- 2 files changed, 99 insertions(+), 95 deletions(-) diff --git a/src/node_webstorage.cc b/src/node_webstorage.cc index ee6a00a9ec2324..c6c1c902749bfe 100644 --- a/src/node_webstorage.cc +++ b/src/node_webstorage.cc @@ -24,12 +24,16 @@ using v8::IndexedPropertyHandlerConfiguration; using v8::Integer; using v8::Intercepted; using v8::Isolate; +using v8::JustVoid; using v8::Local; using v8::Map; using v8::Maybe; using v8::MaybeLocal; using v8::Name; using v8::NamedPropertyHandlerConfiguration; +using v8::NewStringType; +using v8::Nothing; +using v8::Null; using v8::Object; using v8::PropertyAttribute; using v8::PropertyCallbackInfo; @@ -96,7 +100,7 @@ void Storage::MemoryInfo(MemoryTracker* tracker) const { tracker->TrackField("location", location_); } -bool Storage::Open() { +Maybe Storage::Open() { static const int kCurrentSchemaVersion = 1; static constexpr std::string_view get_schema_version_sql = "SELECT schema_version FROM nodejs_webstorage_state"; @@ -161,22 +165,23 @@ bool Storage::Open() { sqlite3* db = db_.get(); if (db != nullptr) { - return true; + return JustVoid(); } int r = sqlite3_open(location_.c_str(), &db); - CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, false); + CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Nothing()); r = sqlite3_exec(db, init_sql_v0.data(), 0, 0, nullptr); - CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, false); + CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Nothing()); // Get the current schema version, used to determine schema migrations. sqlite3_stmt* s = nullptr; r = sqlite3_prepare_v2( db, get_schema_version_sql.data(), get_schema_version_sql.size(), &s, 0); r = sqlite3_exec(db, init_sql_v0.data(), 0, 0, nullptr); - CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, false); + CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Nothing()); auto stmt = stmt_unique_ptr(s); - CHECK_ERROR_OR_THROW(env(), sqlite3_step(stmt.get()), SQLITE_ROW, false); + CHECK_ERROR_OR_THROW( + env(), sqlite3_step(stmt.get()), SQLITE_ROW, Nothing()); CHECK(sqlite3_column_type(stmt.get(), 0) == SQLITE_INTEGER); int schema_version = sqlite3_column_int(stmt.get(), 0); stmt = nullptr; // Force finalization. @@ -184,7 +189,7 @@ bool Storage::Open() { if (schema_version > kCurrentSchemaVersion) { THROW_ERR_INVALID_STATE( env(), "localStorage was created with a newer version of Node.js"); - return false; + return Nothing(); } if (schema_version < kCurrentSchemaVersion) { @@ -193,11 +198,11 @@ bool Storage::Open() { "UPDATE nodejs_webstorage_state SET schema_version = " + std::to_string(kCurrentSchemaVersion) + ";"; r = sqlite3_exec(db, set_user_version_sql.c_str(), 0, 0, nullptr); - CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, false); + CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Nothing()); } db_ = conn_unique_ptr(db); - return true; + return JustVoid(); } void Storage::New(const FunctionCallbackInfo& args) { @@ -222,9 +227,9 @@ void Storage::New(const FunctionCallbackInfo& args) { new Storage(env, args.This(), location.ToStringView()); } -void Storage::Clear() { - if (!Open()) { - return; +Maybe Storage::Clear() { + if (!Open().IsJust()) { + return Nothing(); } static constexpr std::string_view sql = "DELETE FROM nodejs_webstorage"; @@ -233,13 +238,15 @@ void Storage::Clear() { env(), sqlite3_prepare_v2(db_.get(), sql.data(), sql.size(), &s, 0), SQLITE_OK, - void()); + Nothing()); auto stmt = stmt_unique_ptr(s); - CHECK_ERROR_OR_THROW(env(), sqlite3_step(stmt.get()), SQLITE_DONE, void()); + CHECK_ERROR_OR_THROW( + env(), sqlite3_step(stmt.get()), SQLITE_DONE, Nothing()); + return JustVoid(); } -Local Storage::Enumerate() { - if (!Open()) { +MaybeLocal Storage::Enumerate() { + if (!Open().IsJust()) { return Local(); } @@ -256,7 +263,7 @@ Local Storage::Enumerate() { if (!String::NewFromTwoByte(env()->isolate(), reinterpret_cast( sqlite3_column_blob(stmt.get(), 0)), - v8::NewStringType::kNormal, + NewStringType::kNormal, size) .ToLocal(&value)) { return Local(); @@ -267,8 +274,8 @@ Local Storage::Enumerate() { return Array::New(env()->isolate(), values.data(), values.size()); } -Local Storage::Length() { - if (!Open()) { +MaybeLocal Storage::Length() { + if (!Open().IsJust()) { return {}; } @@ -285,14 +292,13 @@ Local Storage::Length() { return Integer::New(env()->isolate(), result); } -Local Storage::Load(Local key) { +MaybeLocal Storage::Load(Local key) { if (key->IsSymbol()) { auto symbol_map = symbols_.Get(env()->isolate()); - MaybeLocal result = symbol_map->Get(env()->context(), key); - return result.FromMaybe(Local()); + return symbol_map->Get(env()->context(), key); } - if (!Open()) { + if (!Open().IsJust()) { return {}; } @@ -306,28 +312,26 @@ Local Storage::Load(Local key) { auto key_size = utf16key.length() * sizeof(uint16_t); r = sqlite3_bind_blob(stmt.get(), 1, utf16key.out(), key_size, SQLITE_STATIC); CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Local()); - auto value = Local(); r = sqlite3_step(stmt.get()); if (r == SQLITE_ROW) { CHECK(sqlite3_column_type(stmt.get(), 0) == SQLITE_BLOB); auto size = sqlite3_column_bytes(stmt.get(), 0) / sizeof(uint16_t); - if (!String::NewFromTwoByte(env()->isolate(), - reinterpret_cast( - sqlite3_column_blob(stmt.get(), 0)), - v8::NewStringType::kNormal, - size) - .ToLocal(&value)) { - return {}; - } + return String::NewFromTwoByte(env()->isolate(), + reinterpret_cast( + sqlite3_column_blob(stmt.get(), 0)), + NewStringType::kNormal, + size) + .As(); } else if (r != SQLITE_DONE) { THROW_SQLITE_ERROR(env(), r); + return {}; + } else { + return Null(env()->isolate()); } - - return value; } -Local Storage::LoadKey(const int index) { - if (!Open()) { +MaybeLocal Storage::LoadKey(const int index) { + if (!Open().IsJust()) { return {}; } @@ -340,65 +344,64 @@ Local Storage::LoadKey(const int index) { r = sqlite3_bind_int(stmt.get(), 1, index); CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Local()); - auto value = Local(); r = sqlite3_step(stmt.get()); if (r == SQLITE_ROW) { CHECK(sqlite3_column_type(stmt.get(), 0) == SQLITE_BLOB); auto size = sqlite3_column_bytes(stmt.get(), 0) / sizeof(uint16_t); - if (!String::NewFromTwoByte(env()->isolate(), - reinterpret_cast( - sqlite3_column_blob(stmt.get(), 0)), - v8::NewStringType::kNormal, - size) - .ToLocal(&value)) { - return {}; - } + return String::NewFromTwoByte(env()->isolate(), + reinterpret_cast( + sqlite3_column_blob(stmt.get(), 0)), + NewStringType::kNormal, + size) + .As(); } else if (r != SQLITE_DONE) { THROW_SQLITE_ERROR(env(), r); + return {}; + } else { + return Null(env()->isolate()); } - - return value; } -bool Storage::Remove(Local key) { +Maybe Storage::Remove(Local key) { if (key->IsSymbol()) { auto symbol_map = symbols_.Get(env()->isolate()); Maybe result = symbol_map->Delete(env()->context(), key); - return !result.IsNothing(); + return result.IsNothing() ? Nothing() : JustVoid(); } - if (!Open()) { - return false; + if (!Open().IsJust()) { + return Nothing(); } static constexpr std::string_view sql = "DELETE FROM nodejs_webstorage WHERE key = ?"; sqlite3_stmt* s = nullptr; int r = sqlite3_prepare_v2(db_.get(), sql.data(), sql.size(), &s, 0); - CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, false); + CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Nothing()); auto stmt = stmt_unique_ptr(s); TwoByteValue utf16key(env()->isolate(), key); auto key_size = utf16key.length() * sizeof(uint16_t); r = sqlite3_bind_blob(stmt.get(), 1, utf16key.out(), key_size, SQLITE_STATIC); - CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, false); - CHECK_ERROR_OR_THROW(env(), sqlite3_step(stmt.get()), SQLITE_DONE, false); - return true; + CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Nothing()); + CHECK_ERROR_OR_THROW( + env(), sqlite3_step(stmt.get()), SQLITE_DONE, Nothing()); + return JustVoid(); } -bool Storage::Store(Local key, Local value) { +Maybe Storage::Store(Local key, Local value) { if (key->IsSymbol()) { auto symbol_map = symbols_.Get(env()->isolate()); MaybeLocal result = symbol_map->Set(env()->context(), key, value); - return !result.IsEmpty(); + return result.IsEmpty() ? Nothing() : JustVoid(); } Local val; if (!value->ToString(env()->context()).ToLocal(&val)) { - return false; + return Nothing(); } - if (!Open()) { - return false; + if (!Open().IsJust()) { + return Nothing(); } static constexpr std::string_view sql = @@ -409,23 +412,23 @@ bool Storage::Store(Local key, Local value) { TwoByteValue utf16key(env()->isolate(), key); TwoByteValue utf16val(env()->isolate(), val); int r = sqlite3_prepare_v2(db_.get(), sql.data(), sql.size(), &s, 0); - CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, false); + CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Nothing()); auto stmt = stmt_unique_ptr(s); auto key_size = utf16key.length() * sizeof(uint16_t); r = sqlite3_bind_blob(stmt.get(), 1, utf16key.out(), key_size, SQLITE_STATIC); - CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, false); + CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Nothing()); auto val_size = utf16val.length() * sizeof(uint16_t); r = sqlite3_bind_blob(stmt.get(), 2, utf16val.out(), val_size, SQLITE_STATIC); - CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, false); + CHECK_ERROR_OR_THROW(env(), r, SQLITE_OK, Nothing()); r = sqlite3_step(stmt.get()); if (r == SQLITE_CONSTRAINT) { ThrowQuotaExceededException(env()->context()); - return false; + return Nothing(); } - CHECK_ERROR_OR_THROW(env(), r, SQLITE_DONE, false); - return true; + CHECK_ERROR_OR_THROW(env(), r, SQLITE_DONE, Nothing()); + return JustVoid(); } static MaybeLocal Uint32ToName(Local context, uint32_t index) { @@ -453,12 +456,11 @@ static void GetItem(const FunctionCallbackInfo& info) { return; } - Local result = storage->Load(prop); - if (result.IsEmpty()) { - info.GetReturnValue().SetNull(); - } else { - info.GetReturnValue().Set(result); + Local result; + if (!storage->Load(prop).ToLocal(&result)) { + return; } + info.GetReturnValue().Set(result); } static void Key(const FunctionCallbackInfo& info) { @@ -481,10 +483,8 @@ static void Key(const FunctionCallbackInfo& info) { return; } - Local result = storage->LoadKey(index); - if (result.IsEmpty()) { - info.GetReturnValue().SetNull(); - } else { + Local result; + if (storage->LoadKey(index).ToLocal(&result)) { info.GetReturnValue().Set(result); } } @@ -555,11 +555,9 @@ static Intercepted StorageGetter(Local property, Storage* storage; ASSIGN_OR_RETURN_UNWRAP(&storage, info.This(), Intercepted::kNo); - Local result = storage->Load(property); + Local result; - if (result.IsEmpty()) { - info.GetReturnValue().SetUndefined(); - } else { + if (storage->Load(property).ToLocal(&result) && !result->IsNull()) { info.GetReturnValue().Set(result); } @@ -572,7 +570,7 @@ static Intercepted StorageSetter(Local property, Storage* storage; ASSIGN_OR_RETURN_UNWRAP(&storage, info.This(), Intercepted::kNo); - if (!storage->Store(property, value)) { + if (storage->Store(property, value).IsNothing()) { info.GetReturnValue().SetFalse(); } @@ -587,8 +585,8 @@ static Intercepted StorageQuery(Local property, Storage* storage; ASSIGN_OR_RETURN_UNWRAP(&storage, info.This(), Intercepted::kNo); - Local result = storage->Load(property); - if (result.IsEmpty()) { + Local result; + if (!storage->Load(property).ToLocal(&result) || result->IsNull()) { return Intercepted::kNo; } @@ -601,9 +599,7 @@ static Intercepted StorageDeleter(Local property, Storage* storage; ASSIGN_OR_RETURN_UNWRAP(&storage, info.This(), Intercepted::kNo); - if (storage->Remove(property)) { - info.GetReturnValue().Set(true); - } + info.GetReturnValue().Set(storage->Remove(property).IsJust()); return Intercepted::kYes; } @@ -611,7 +607,11 @@ static Intercepted StorageDeleter(Local property, static void StorageEnumerator(const PropertyCallbackInfo& info) { Storage* storage; ASSIGN_OR_RETURN_UNWRAP(&storage, info.This()); - info.GetReturnValue().Set(storage->Enumerate()); + Local result; + if (!storage->Enumerate().ToLocal(&result)) { + return; + } + info.GetReturnValue().Set(result); } static Intercepted StorageDefiner(Local property, @@ -697,7 +697,11 @@ static Intercepted IndexedDefiner(uint32_t index, static void StorageLengthGetter(const FunctionCallbackInfo& info) { Storage* storage; ASSIGN_OR_RETURN_UNWRAP(&storage, info.This()); - info.GetReturnValue().Set(storage->Length()); + Local result; + if (!storage->Length().ToLocal(&result)) { + return; + } + info.GetReturnValue().Set(result); } static void Initialize(Local target, diff --git a/src/node_webstorage.h b/src/node_webstorage.h index 2c0c3ab688cae5..c2548d32e993fd 100644 --- a/src/node_webstorage.h +++ b/src/node_webstorage.h @@ -33,19 +33,19 @@ class Storage : public BaseObject { void MemoryInfo(MemoryTracker* tracker) const override; static void New(const v8::FunctionCallbackInfo& args); - void Clear(); - v8::Local Enumerate(); - v8::Local Length(); - v8::Local Load(v8::Local key); - v8::Local LoadKey(const int index); - bool Remove(v8::Local key); - bool Store(v8::Local key, v8::Local value); + v8::Maybe Clear(); + v8::MaybeLocal Enumerate(); + v8::MaybeLocal Length(); + v8::MaybeLocal Load(v8::Local key); + v8::MaybeLocal LoadKey(const int index); + v8::Maybe Remove(v8::Local key); + v8::Maybe Store(v8::Local key, v8::Local value); SET_MEMORY_INFO_NAME(Storage) SET_SELF_SIZE(Storage) private: - bool Open(); + v8::Maybe Open(); ~Storage() override; std::string location_; From 3a71ccf6c473357e89be61b26739fd9139dce4db Mon Sep 17 00:00:00 2001 From: Aviv Keller <38299977+RedYetiDev@users.noreply.github.com> Date: Mon, 26 Aug 2024 16:43:19 -0400 Subject: [PATCH 2/5] tools: remove unused python files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/53928 Reviewed-By: Moshe Atlow Reviewed-By: Luigi Pinca Reviewed-By: James M Snell Reviewed-By: Ulises Gascón --- tools/getarch.py | 10 ---------- tools/getendian.py | 4 ---- tools/getmachine.py | 3 --- 3 files changed, 17 deletions(-) delete mode 100644 tools/getarch.py delete mode 100644 tools/getendian.py delete mode 100644 tools/getmachine.py diff --git a/tools/getarch.py b/tools/getarch.py deleted file mode 100644 index 3c366525463340..00000000000000 --- a/tools/getarch.py +++ /dev/null @@ -1,10 +0,0 @@ -from __future__ import print_function -from utils import GuessArchitecture -arch = GuessArchitecture() - -# assume 64 bit unless set specifically -print(GuessArchitecture() \ - .replace('ia32', 'x64') \ - .replace('ppc', 'ppc64') \ - .replace('arm', 'arm64') \ - .replace('s390', 's390x')) diff --git a/tools/getendian.py b/tools/getendian.py deleted file mode 100644 index 0f9fcc1c860584..00000000000000 --- a/tools/getendian.py +++ /dev/null @@ -1,4 +0,0 @@ -from __future__ import print_function -import sys -# "little" or "big" -print(sys.byteorder) diff --git a/tools/getmachine.py b/tools/getmachine.py deleted file mode 100644 index 046d8b17a797fd..00000000000000 --- a/tools/getmachine.py +++ /dev/null @@ -1,3 +0,0 @@ -from __future__ import print_function -import platform -print(platform.machine()) From 3d5357a2f454429615669e2dff35bde82502452b Mon Sep 17 00:00:00 2001 From: Colin Ihrig Date: Mon, 26 Aug 2024 20:54:22 -0400 Subject: [PATCH 3/5] test: refactor test_runner tests to change default reporter This commit updates the test runner tests in order to switch the default reporter from tap to spec. This commit can be backported, while changing the default reporter cannot. Refs: https://github.com/nodejs/node/issues/54540 PR-URL: https://github.com/nodejs/node/pull/54547 Reviewed-By: Matteo Collina Reviewed-By: Benjamin Gruenbaum Reviewed-By: James M Snell Reviewed-By: Moshe Atlow Reviewed-By: Jake Yuesong Li --- test/common/assertSnapshot.js | 6 +- test/parallel/test-runner-cli.js | 24 ++- test/parallel/test-runner-exit-code.js | 10 +- .../test-runner-extraneous-async-activity.js | 44 ++--- .../test-runner-force-exit-failure.js | 3 +- test/parallel/test-runner-inspect.mjs | 7 +- test/parallel/test-runner-misc.js | 6 +- test/parallel/test-runner-module-mocking.js | 2 +- .../test-runner-no-isolation-filtering.js | 3 + test/parallel/test-runner-output.mjs | 184 ++++++++++++++---- test/parallel/test-runner-root-duration.js | 1 + test/parallel/test-runner-snapshot-tests.js | 12 +- .../test-runner-watch-mode-complex.mjs | 18 +- 13 files changed, 220 insertions(+), 100 deletions(-) diff --git a/test/common/assertSnapshot.js b/test/common/assertSnapshot.js index a22455160bd9f7..e0793ce5394cda 100644 --- a/test/common/assertSnapshot.js +++ b/test/common/assertSnapshot.js @@ -77,7 +77,11 @@ async function spawnAndAssert(filename, transform = (x) => x, { tty = false, ... test({ skip: 'Skipping pseudo-tty tests, as pseudo terminals are not available on Windows.' }); return; } - const flags = common.parseTestFlags(filename); + let flags = common.parseTestFlags(filename); + if (options.flags) { + flags = [...options.flags, ...flags]; + } + const executable = tty ? (process.env.PYTHON || 'python3') : process.execPath; const args = tty ? diff --git a/test/parallel/test-runner-cli.js b/test/parallel/test-runner-cli.js index d2d2eea8809404..8610d512561dff 100644 --- a/test/parallel/test-runner-cli.js +++ b/test/parallel/test-runner-cli.js @@ -26,7 +26,8 @@ for (const isolation of ['none', 'process']) { { // Default behavior. node_modules is ignored. Files that don't match the // pattern are ignored except in test/ directories. - const args = ['--test', `--experimental-test-isolation=${isolation}`]; + const args = ['--test', '--test-reporter=tap', + `--experimental-test-isolation=${isolation}`]; const child = spawnSync(process.execPath, args, { cwd: join(testFixtures, 'default-behavior') }); assert.strictEqual(child.status, 1); @@ -47,6 +48,7 @@ for (const isolation of ['none', 'process']) { const args = [ '--require', join(testFixtures, 'protoMutation.js'), '--test', + '--test-reporter=tap', `--experimental-test-isolation=${isolation}`, ]; const child = spawnSync(process.execPath, args, { cwd: join(testFixtures, 'default-behavior') }); @@ -67,6 +69,7 @@ for (const isolation of ['none', 'process']) { // User specified files that don't match the pattern are still run. const args = [ '--test', + '--test-reporter=tap', `--experimental-test-isolation=${isolation}`, join(testFixtures, 'index.js'), ]; @@ -83,6 +86,7 @@ for (const isolation of ['none', 'process']) { // Searches node_modules if specified. const args = [ '--test', + '--test-reporter=tap', `--experimental-test-isolation=${isolation}`, join(testFixtures, 'default-behavior/node_modules/*.js'), ]; @@ -105,18 +109,19 @@ for (const isolation of ['none', 'process']) { assert.strictEqual(child.signal, null); assert.strictEqual(child.stderr.toString(), ''); const stdout = child.stdout.toString(); - assert.match(stdout, /ok 1 - this should pass/); - assert.match(stdout, /not ok 2 - this should fail/); - assert.match(stdout, /ok 3 - subdir.+subdir_test\.js/); - assert.match(stdout, /ok 4 - this should pass/); - assert.match(stdout, /ok 5 - this should be skipped/); - assert.match(stdout, /ok 6 - this should be executed/); + assert.match(stdout, /this should pass/); + assert.match(stdout, /this should fail/); + assert.match(stdout, /subdir.+subdir_test\.js/); + assert.match(stdout, /this should pass/); + assert.match(stdout, /this should be skipped/); + assert.match(stdout, /this should be executed/); } { // Test combined stream outputs const args = [ '--test', + '--test-reporter=tap', `--experimental-test-isolation=${isolation}`, 'test/fixtures/test-runner/default-behavior/index.test.js', 'test/fixtures/test-runner/nested.js', @@ -189,6 +194,7 @@ for (const isolation of ['none', 'process']) { // Test user logging in tests. const args = [ '--test', + '--test-reporter=tap', 'test/fixtures/test-runner/user-logs.js', ]; const child = spawnSync(process.execPath, args); @@ -223,7 +229,7 @@ for (const isolation of ['none', 'process']) { assert.strictEqual(child.status, 0); assert.strictEqual(child.signal, null); const stdout = child.stdout.toString(); - assert.match(stdout, /ok 1 - this should pass/); + assert.match(stdout, /this should pass/); } { @@ -290,6 +296,7 @@ for (const isolation of ['none', 'process']) { // --test-shard option, first shard const args = [ '--test', + '--test-reporter=tap', '--test-shard=1/2', join(testFixtures, 'shards/*.cjs'), ]; @@ -324,6 +331,7 @@ for (const isolation of ['none', 'process']) { // --test-shard option, last shard const args = [ '--test', + '--test-reporter=tap', '--test-shard=2/2', join(testFixtures, 'shards/*.cjs'), ]; diff --git a/test/parallel/test-runner-exit-code.js b/test/parallel/test-runner-exit-code.js index 700480386d5b4a..d2f0251e5fb30c 100644 --- a/test/parallel/test-runner-exit-code.js +++ b/test/parallel/test-runner-exit-code.js @@ -12,7 +12,7 @@ async function runAndKill(file) { return; } let stdout = ''; - const child = spawn(process.execPath, ['--test', file]); + const child = spawn(process.execPath, ['--test', '--test-reporter=tap', file]); child.stdout.setEncoding('utf8'); child.stdout.on('data', (chunk) => { if (!stdout.length) child.kill('SIGINT'); @@ -58,10 +58,10 @@ if (process.argv[2] === 'child') { assert.strictEqual(child.status, 0); assert.strictEqual(child.signal, null); const stdout = child.stdout.toString(); - assert.match(stdout, /# tests 3/); - assert.match(stdout, /# pass 0/); - assert.match(stdout, /# fail 0/); - assert.match(stdout, /# todo 3/); + assert.match(stdout, /tests 3/); + assert.match(stdout, /pass 0/); + assert.match(stdout, /fail 0/); + assert.match(stdout, /todo 3/); child = spawnSync(process.execPath, [__filename, 'child', 'fail']); assert.strictEqual(child.status, 1); diff --git a/test/parallel/test-runner-extraneous-async-activity.js b/test/parallel/test-runner-extraneous-async-activity.js index 23f3194e02f106..58593fe70bbe10 100644 --- a/test/parallel/test-runner-extraneous-async-activity.js +++ b/test/parallel/test-runner-extraneous-async-activity.js @@ -10,10 +10,10 @@ const { spawnSync } = require('child_process'); fixtures.path('test-runner', 'extraneous_set_immediate_async.mjs'), ]); const stdout = child.stdout.toString(); - assert.match(stdout, /^# Error: Test "extraneous async activity test" at .+extraneous_set_immediate_async\.mjs:3:1 generated asynchronous activity after the test ended/m); - assert.match(stdout, /^# pass 1/m); - assert.match(stdout, /^# fail 1$/m); - assert.match(stdout, /^# cancelled 0$/m); + assert.match(stdout, /Error: Test "extraneous async activity test" at .+extraneous_set_immediate_async\.mjs:3:1 generated asynchronous activity after the test ended/m); + assert.match(stdout, /pass 1/m); + assert.match(stdout, /fail 1$/m); + assert.match(stdout, /cancelled 0$/m); assert.strictEqual(child.status, 1); assert.strictEqual(child.signal, null); } @@ -24,10 +24,10 @@ const { spawnSync } = require('child_process'); fixtures.path('test-runner', 'extraneous_set_timeout_async.mjs'), ]); const stdout = child.stdout.toString(); - assert.match(stdout, /^# Error: Test "extraneous async activity test" at .+extraneous_set_timeout_async\.mjs:3:1 generated asynchronous activity after the test ended/m); - assert.match(stdout, /^# pass 1$/m); - assert.match(stdout, /^# fail 1$/m); - assert.match(stdout, /^# cancelled 0$/m); + assert.match(stdout, /Error: Test "extraneous async activity test" at .+extraneous_set_timeout_async\.mjs:3:1 generated asynchronous activity after the test ended/m); + assert.match(stdout, /pass 1$/m); + assert.match(stdout, /fail 1$/m); + assert.match(stdout, /cancelled 0$/m); assert.strictEqual(child.status, 1); assert.strictEqual(child.signal, null); } @@ -38,13 +38,13 @@ const { spawnSync } = require('child_process'); fixtures.path('test-runner', 'async-error-in-test-hook.mjs'), ]); const stdout = child.stdout.toString(); - assert.match(stdout, /^# Error: Test hook "before" at .+async-error-in-test-hook\.mjs:3:1 generated asynchronous activity after the test ended/m); - assert.match(stdout, /^# Error: Test hook "beforeEach" at .+async-error-in-test-hook\.mjs:9:1 generated asynchronous activity after the test ended/m); - assert.match(stdout, /^# Error: Test hook "after" at .+async-error-in-test-hook\.mjs:15:1 generated asynchronous activity after the test ended/m); - assert.match(stdout, /^# Error: Test hook "afterEach" at .+async-error-in-test-hook\.mjs:21:1 generated asynchronous activity after the test ended/m); - assert.match(stdout, /^# pass 1$/m); - assert.match(stdout, /^# fail 1$/m); - assert.match(stdout, /^# cancelled 0$/m); + assert.match(stdout, /Error: Test hook "before" at .+async-error-in-test-hook\.mjs:3:1 generated asynchronous activity after the test ended/m); + assert.match(stdout, /Error: Test hook "beforeEach" at .+async-error-in-test-hook\.mjs:9:1 generated asynchronous activity after the test ended/m); + assert.match(stdout, /Error: Test hook "after" at .+async-error-in-test-hook\.mjs:15:1 generated asynchronous activity after the test ended/m); + assert.match(stdout, /Error: Test hook "afterEach" at .+async-error-in-test-hook\.mjs:21:1 generated asynchronous activity after the test ended/m); + assert.match(stdout, /pass 1$/m); + assert.match(stdout, /fail 1$/m); + assert.match(stdout, /cancelled 0$/m); assert.strictEqual(child.status, 1); assert.strictEqual(child.signal, null); } @@ -56,13 +56,13 @@ const { spawnSync } = require('child_process'); fixtures.path('test-runner', 'async-error-in-test-hook.mjs'), ]); const stdout = child.stdout.toString(); - assert.match(stdout, /^# Error: Test hook "before" at .+async-error-in-test-hook\.mjs:3:1 generated asynchronous activity after the test ended/m); - assert.match(stdout, /^# Error: Test hook "beforeEach" at .+async-error-in-test-hook\.mjs:9:1 generated asynchronous activity after the test ended/m); - assert.match(stdout, /^# Error: Test hook "after" at .+async-error-in-test-hook\.mjs:15:1 generated asynchronous activity after the test ended/m); - assert.match(stdout, /^# Error: Test hook "afterEach" at .+async-error-in-test-hook\.mjs:21:1 generated asynchronous activity after the test ended/m); - assert.match(stdout, /^# pass 1$/m); - assert.match(stdout, /^# fail 0$/m); - assert.match(stdout, /^# cancelled 0$/m); + assert.match(stdout, /Error: Test hook "before" at .+async-error-in-test-hook\.mjs:3:1 generated asynchronous activity after the test ended/m); + assert.match(stdout, /Error: Test hook "beforeEach" at .+async-error-in-test-hook\.mjs:9:1 generated asynchronous activity after the test ended/m); + assert.match(stdout, /Error: Test hook "after" at .+async-error-in-test-hook\.mjs:15:1 generated asynchronous activity after the test ended/m); + assert.match(stdout, /Error: Test hook "afterEach" at .+async-error-in-test-hook\.mjs:21:1 generated asynchronous activity after the test ended/m); + assert.match(stdout, /pass 1$/m); + assert.match(stdout, /fail 0$/m); + assert.match(stdout, /cancelled 0$/m); assert.strictEqual(child.status, 1); assert.strictEqual(child.signal, null); } diff --git a/test/parallel/test-runner-force-exit-failure.js b/test/parallel/test-runner-force-exit-failure.js index ce1f3208c5b4e6..ae2b21d7c61dc0 100644 --- a/test/parallel/test-runner-force-exit-failure.js +++ b/test/parallel/test-runner-force-exit-failure.js @@ -8,6 +8,7 @@ const fixture = fixtures.path('test-runner/throws_sync_and_async.js'); for (const isolation of ['none', 'process']) { const args = [ '--test', + '--test-reporter=spec', '--test-force-exit', `--experimental-test-isolation=${isolation}`, fixture, @@ -19,6 +20,6 @@ for (const isolation of ['none', 'process']) { strictEqual(r.stderr.toString(), ''); const stdout = r.stdout.toString(); - match(stdout, /error: 'fails'/); + match(stdout, /Error: fails/); doesNotMatch(stdout, /this should not have a chance to be thrown/); } diff --git a/test/parallel/test-runner-inspect.mjs b/test/parallel/test-runner-inspect.mjs index e4e6a7d35f4810..2161959498f15c 100644 --- a/test/parallel/test-runner-inspect.mjs +++ b/test/parallel/test-runner-inspect.mjs @@ -12,7 +12,7 @@ tmpdir.refresh(); { const child = new NodeInstance( - ['--test', '--inspect-brk=0'], + ['--test', '--test-reporter=tap', '--inspect-brk=0'], undefined, fixtures.path('test-runner/default-behavior/index.test.js') ); @@ -38,7 +38,10 @@ tmpdir.refresh(); { - const args = ['--test', '--inspect=0', fixtures.path('test-runner/index.js')]; + const args = [ + '--test', '--test-reporter=tap', '--inspect=0', + fixtures.path('test-runner/index.js'), + ]; const { stderr, stdout, code, signal } = await common.spawnPromisified(process.execPath, args); assert.match(stderr, diff --git a/test/parallel/test-runner-misc.js b/test/parallel/test-runner-misc.js index abc2715dcfba48..cea115493249a1 100644 --- a/test/parallel/test-runner-misc.js +++ b/test/parallel/test-runner-misc.js @@ -33,9 +33,9 @@ if (process.argv[2] === 'child') { } else { const child = spawnSync(process.execPath, [__filename, 'child', 'abortSignal']); const stdout = child.stdout.toString(); - assert.match(stdout, /^# pass 2$/m); - assert.match(stdout, /^# fail 0$/m); - assert.match(stdout, /^# cancelled 1$/m); + assert.match(stdout, /pass 2$/m); + assert.match(stdout, /fail 0$/m); + assert.match(stdout, /cancelled 1$/m); assert.strictEqual(child.status, 1); assert.strictEqual(child.signal, null); } diff --git a/test/parallel/test-runner-module-mocking.js b/test/parallel/test-runner-module-mocking.js index 45345815c69db4..f36dc13915b51a 100644 --- a/test/parallel/test-runner-module-mocking.js +++ b/test/parallel/test-runner-module-mocking.js @@ -571,7 +571,7 @@ test('node_modules can be used by both module systems', async (t) => { assert.strictEqual(code, 0); assert.strictEqual(signal, null); - assert.match(stdout, /# pass 1/); + assert.match(stdout, /pass 1/); }); test('file:// imports are supported in ESM only', async (t) => { diff --git a/test/parallel/test-runner-no-isolation-filtering.js b/test/parallel/test-runner-no-isolation-filtering.js index f8fba1cbfffbef..21db267d5323c6 100644 --- a/test/parallel/test-runner-no-isolation-filtering.js +++ b/test/parallel/test-runner-no-isolation-filtering.js @@ -11,6 +11,7 @@ const fixture2 = fixtures.path('test-runner', 'no-isolation', 'two.test.js'); test('works with --test-only', () => { const args = [ '--test', + '--test-reporter=tap', '--experimental-test-isolation=none', '--test-only', fixture1, @@ -33,6 +34,7 @@ test('works with --test-only', () => { test('works with --test-name-pattern', () => { const args = [ '--test', + '--test-reporter=tap', '--experimental-test-isolation=none', '--test-name-pattern=/test one/', fixture1, @@ -52,6 +54,7 @@ test('works with --test-name-pattern', () => { test('works with --test-skip-pattern', () => { const args = [ '--test', + '--test-reporter=tap', '--experimental-test-isolation=none', '--test-skip-pattern=/one/', fixture1, diff --git a/test/parallel/test-runner-output.mjs b/test/parallel/test-runner-output.mjs index 47e0f211f34a0d..6de1c2eeafce98 100644 --- a/test/parallel/test-runner-output.mjs +++ b/test/parallel/test-runner-output.mjs @@ -92,50 +92,116 @@ const lcovTransform = snapshot.transform( const tests = [ - { name: 'test-runner/output/abort.js' }, - { name: 'test-runner/output/abort-runs-after-hook.js' }, - { name: 'test-runner/output/abort_suite.js' }, - { name: 'test-runner/output/abort_hooks.js' }, - { name: 'test-runner/output/describe_it.js' }, - { name: 'test-runner/output/describe_nested.js' }, + { name: 'test-runner/output/abort.js', flags: ['--test-reporter=tap'] }, + { + name: 'test-runner/output/abort-runs-after-hook.js', + flags: ['--test-reporter=tap'], + }, + { name: 'test-runner/output/abort_suite.js', flags: ['--test-reporter=tap'] }, + { name: 'test-runner/output/abort_hooks.js', flags: ['--test-reporter=tap'] }, + { name: 'test-runner/output/describe_it.js', flags: ['--test-reporter=tap'] }, + { + name: 'test-runner/output/describe_nested.js', + flags: ['--test-reporter=tap'], + }, { name: 'test-runner/output/eval_dot.js', transform: specTransform }, { name: 'test-runner/output/eval_spec.js', transform: specTransform }, { name: 'test-runner/output/eval_tap.js' }, - { name: 'test-runner/output/filtered-suite-delayed-build.js' }, - { name: 'test-runner/output/filtered-suite-order.mjs' }, - { name: 'test-runner/output/filtered-suite-throws.js' }, - { name: 'test-runner/output/hooks.js' }, + { + name: 'test-runner/output/filtered-suite-delayed-build.js', + flags: ['--test-reporter=tap'], + }, + { + name: 'test-runner/output/filtered-suite-order.mjs', + flags: ['--test-reporter=tap'], + }, + { + name: 'test-runner/output/filtered-suite-throws.js', + flags: ['--test-reporter=tap'], + }, + { name: 'test-runner/output/hooks.js', flags: ['--test-reporter=tap'] }, { name: 'test-runner/output/hooks_spec_reporter.js', transform: specTransform }, { name: 'test-runner/output/skip-each-hooks.js', transform: specTransform }, { name: 'test-runner/output/suite-skip-hooks.js', transform: specTransform }, - { name: 'test-runner/output/timeout_in_before_each_should_not_affect_further_tests.js' }, - { name: 'test-runner/output/hooks-with-no-global-test.js' }, - { name: 'test-runner/output/global-hooks-with-no-tests.js' }, - { name: 'test-runner/output/before-and-after-each-too-many-listeners.js' }, - { name: 'test-runner/output/before-and-after-each-with-timeout-too-many-listeners.js' }, + { + name: 'test-runner/output/timeout_in_before_each_should_not_affect_further_tests.js', + flags: ['--test-reporter=tap'], + }, + { + name: 'test-runner/output/hooks-with-no-global-test.js', + flags: ['--test-reporter=tap'], + }, + { + name: 'test-runner/output/global-hooks-with-no-tests.js', + flags: ['--test-reporter=tap'], + }, + { + name: 'test-runner/output/before-and-after-each-too-many-listeners.js', + flags: ['--test-reporter=tap'], + }, + { + name: 'test-runner/output/before-and-after-each-with-timeout-too-many-listeners.js', + flags: ['--test-reporter=tap'], + }, { name: 'test-runner/output/force_exit.js', transform: specTransform }, - { name: 'test-runner/output/global_after_should_fail_the_test.js' }, - { name: 'test-runner/output/no_refs.js' }, - { name: 'test-runner/output/no_tests.js' }, - { name: 'test-runner/output/only_tests.js' }, + { + name: 'test-runner/output/global_after_should_fail_the_test.js', + flags: ['--test-reporter=tap'], + }, + { + name: 'test-runner/output/no_refs.js', + flags: ['--test-reporter=tap'], + }, + { + name: 'test-runner/output/no_tests.js', + flags: ['--test-reporter=tap'], + }, + { name: 'test-runner/output/only_tests.js', flags: ['--test-reporter=tap'] }, { name: 'test-runner/output/dot_reporter.js', transform: specTransform }, { name: 'test-runner/output/junit_reporter.js', transform: junitTransform }, { name: 'test-runner/output/spec_reporter_successful.js', transform: specTransform }, { name: 'test-runner/output/spec_reporter.js', transform: specTransform }, { name: 'test-runner/output/spec_reporter_cli.js', transform: specTransform }, - { name: 'test-runner/output/source_mapped_locations.mjs' }, + { + name: 'test-runner/output/source_mapped_locations.mjs', + flags: ['--test-reporter=tap'], + }, process.features.inspector ? { name: 'test-runner/output/lcov_reporter.js', transform: lcovTransform } : false, - { name: 'test-runner/output/output.js' }, + { name: 'test-runner/output/output.js', flags: ['--test-reporter=tap'] }, { name: 'test-runner/output/output_cli.js' }, - { name: 'test-runner/output/name_and_skip_patterns.js' }, - { name: 'test-runner/output/name_pattern.js' }, - { name: 'test-runner/output/name_pattern_with_only.js' }, - { name: 'test-runner/output/skip_pattern.js' }, - { name: 'test-runner/output/unfinished-suite-async-error.js' }, - { name: 'test-runner/output/unresolved_promise.js' }, + { + name: 'test-runner/output/name_and_skip_patterns.js', + flags: ['--test-reporter=tap'], + }, + { + name: 'test-runner/output/name_pattern.js', + flags: ['--test-reporter=tap'], + }, + { + name: 'test-runner/output/name_pattern_with_only.js', + flags: ['--test-reporter=tap'], + }, + { + name: 'test-runner/output/skip_pattern.js', + flags: ['--test-reporter=tap'], + }, + { + name: 'test-runner/output/unfinished-suite-async-error.js', + flags: ['--test-reporter=tap'], + }, + { + name: 'test-runner/output/unresolved_promise.js', + flags: ['--test-reporter=tap'], + }, { name: 'test-runner/output/default_output.js', transform: specTransform, tty: true }, - { name: 'test-runner/output/arbitrary-output.js' }, - { name: 'test-runner/output/async-test-scheduling.mjs' }, + { + name: 'test-runner/output/arbitrary-output.js', + flags: ['--test-reporter=tap'], + }, + { + name: 'test-runner/output/async-test-scheduling.mjs', + flags: ['--test-reporter=tap'], + }, !skipForceColors ? { name: 'test-runner/output/arbitrary-output-colored.js', transform: snapshot.transform(specTransform, replaceTestDuration), tty: true @@ -147,24 +213,58 @@ const tests = [ snapshot.replaceWindowsLineEndings, replaceTestDuration, ), + flags: ['--test-reporter=tap'], + }, + { + name: 'test-runner/output/test-runner-plan.js', + flags: ['--test-reporter=tap'], }, - { name: 'test-runner/output/test-runner-plan.js' }, - process.features.inspector ? { name: 'test-runner/output/coverage_failure.js' } : false, - { name: 'test-runner/output/test-diagnostic-warning-without-test-only-flag.js' }, - process.features.inspector ? { name: 'test-runner/output/coverage-width-80.mjs' } : false, - process.features.inspector ? { name: 'test-runner/output/coverage-width-100.mjs' } : false, - process.features.inspector ? { name: 'test-runner/output/coverage-width-150.mjs' } : false, - process.features.inspector ? { name: 'test-runner/output/coverage-width-infinity.mjs' } : false, - process.features.inspector ? { name: 'test-runner/output/coverage-width-80-uncovered-lines.mjs' } : false, - process.features.inspector ? { name: 'test-runner/output/coverage-width-100-uncovered-lines.mjs' } : false, - process.features.inspector ? { name: 'test-runner/output/coverage-width-150-uncovered-lines.mjs' } : false, - process.features.inspector ? { name: 'test-runner/output/coverage-width-infinity-uncovered-lines.mjs' } : false, + process.features.inspector ? { + name: 'test-runner/output/coverage_failure.js', + flags: ['--test-reporter=tap'], + } : false, + { + name: 'test-runner/output/test-diagnostic-warning-without-test-only-flag.js', + flags: ['--test-reporter=tap'], + }, + process.features.inspector ? { + name: 'test-runner/output/coverage-width-80.mjs', + flags: ['--test-reporter=tap'], + } : false, + process.features.inspector ? { + name: 'test-runner/output/coverage-width-100.mjs', + flags: ['--test-reporter=tap'], + } : false, + process.features.inspector ? { + name: 'test-runner/output/coverage-width-150.mjs', + flags: ['--test-reporter=tap'], + } : false, + process.features.inspector ? { + name: 'test-runner/output/coverage-width-infinity.mjs', + flags: ['--test-reporter=tap'], + } : false, + process.features.inspector ? { + name: 'test-runner/output/coverage-width-80-uncovered-lines.mjs', + flags: ['--test-reporter=tap'], + } : false, + process.features.inspector ? { + name: 'test-runner/output/coverage-width-100-uncovered-lines.mjs', + flags: ['--test-reporter=tap'], + } : false, + process.features.inspector ? { + name: 'test-runner/output/coverage-width-150-uncovered-lines.mjs', + flags: ['--test-reporter=tap'], + } : false, + process.features.inspector ? { + name: 'test-runner/output/coverage-width-infinity-uncovered-lines.mjs', + flags: ['--test-reporter=tap'], + } : false, ] .filter(Boolean) -.map(({ name, tty, transform }) => ({ +.map(({ flags, name, tty, transform }) => ({ name, fn: common.mustCall(async () => { - await snapshot.spawnAndAssert(fixtures.path(name), transform ?? defaultTransform, { tty }); + await snapshot.spawnAndAssert(fixtures.path(name), transform ?? defaultTransform, { tty, flags }); }), })); diff --git a/test/parallel/test-runner-root-duration.js b/test/parallel/test-runner-root-duration.js index 0c1b69359cc497..73718a8bf00be0 100644 --- a/test/parallel/test-runner-root-duration.js +++ b/test/parallel/test-runner-root-duration.js @@ -10,6 +10,7 @@ test('root duration is longer than test duration', async () => { stderr, stdout, } = await spawnPromisified(process.execPath, [ + '--test-reporter=tap', fixtures.path('test-runner/root-duration.mjs'), ]); diff --git a/test/parallel/test-runner-snapshot-tests.js b/test/parallel/test-runner-snapshot-tests.js index 62ebdd3cade2fb..bad3645f5fa183 100644 --- a/test/parallel/test-runner-snapshot-tests.js +++ b/test/parallel/test-runner-snapshot-tests.js @@ -305,9 +305,9 @@ test('t.assert.snapshot()', async (t) => { t.assert.strictEqual(child.code, 1); t.assert.strictEqual(child.signal, null); - t.assert.match(child.stdout, /# tests 5/); - t.assert.match(child.stdout, /# pass 0/); - t.assert.match(child.stdout, /# fail 5/); + t.assert.match(child.stdout, /tests 5/); + t.assert.match(child.stdout, /pass 0/); + t.assert.match(child.stdout, /fail 5/); t.assert.match(child.stdout, /Missing snapshots/); }); @@ -362,9 +362,9 @@ test('snapshots from multiple files (isolation=none)', async (t) => { t.assert.strictEqual(child.code, 1); t.assert.strictEqual(child.signal, null); - t.assert.match(child.stdout, /# tests 6/); - t.assert.match(child.stdout, /# pass 0/); - t.assert.match(child.stdout, /# fail 6/); + t.assert.match(child.stdout, /tests 6/); + t.assert.match(child.stdout, /pass 0/); + t.assert.match(child.stdout, /fail 6/); t.assert.match(child.stdout, /Missing snapshots/); }); diff --git a/test/parallel/test-runner-watch-mode-complex.mjs b/test/parallel/test-runner-watch-mode-complex.mjs index 62966d57964276..0ec9a225c3501c 100644 --- a/test/parallel/test-runner-watch-mode-complex.mjs +++ b/test/parallel/test-runner-watch-mode-complex.mjs @@ -63,7 +63,7 @@ describe('test runner watch mode with more complex setup', () => { child.stdout.on('data', (data) => { stdout += data.toString(); currentRun += data.toString(); - const testRuns = stdout.match(/# duration_ms\s\d+/g); + const testRuns = stdout.match(/duration_ms\s\d+/g); if (testRuns?.length >= 2) { ran2.resolve(); @@ -91,14 +91,14 @@ describe('test runner watch mode with more complex setup', () => { const [firstRun, secondRun] = runs; - assert.match(firstRun, /# tests 3/); - assert.match(firstRun, /# pass 3/); - assert.match(firstRun, /# fail 0/); - assert.match(firstRun, /# cancelled 0/); + assert.match(firstRun, /tests 3/); + assert.match(firstRun, /pass 3/); + assert.match(firstRun, /fail 0/); + assert.match(firstRun, /cancelled 0/); - assert.match(secondRun, /# tests 2/); - assert.match(secondRun, /# pass 2/); - assert.match(secondRun, /# fail 0/); - assert.match(secondRun, /# cancelled 0/); + assert.match(secondRun, /tests 2/); + assert.match(secondRun, /pass 2/); + assert.match(secondRun, /fail 0/); + assert.match(secondRun, /cancelled 0/); }); }); From b39fad6052b17b5c211c675111da0a6846134c3a Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Mon, 26 Aug 2024 20:54:35 -0400 Subject: [PATCH 4/5] deps: update c-ares to v1.33.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/54549 Reviewed-By: Luigi Pinca Reviewed-By: Michaël Zasso Reviewed-By: Mohammed Keyvanzadeh Reviewed-By: James M Snell Reviewed-By: Marco Ippolito Reviewed-By: Rafael Gonzaga --- deps/cares/CMakeLists.txt | 15 +- deps/cares/Makefile.in | 2 + deps/cares/RELEASE-NOTES.md | 32 + deps/cares/aminclude_static.am | 2 +- deps/cares/configure | 562 ++++++++++-------- deps/cares/configure.ac | 12 +- deps/cares/docs/Makefile.in | 2 + deps/cares/include/Makefile.in | 2 + deps/cares/include/ares_version.h | 4 +- deps/cares/libcares.pc.cmake | 7 +- deps/cares/src/Makefile.in | 2 + deps/cares/src/lib/Makefile.in | 4 +- deps/cares/src/lib/ares__close_sockets.c | 2 +- deps/cares/src/lib/ares__socket.c | 2 +- deps/cares/src/lib/ares_android.c | 3 +- deps/cares/src/lib/ares_cookie.c | 3 +- deps/cares/src/lib/ares_getaddrinfo.c | 7 + deps/cares/src/lib/ares_metrics.c | 2 +- deps/cares/src/lib/ares_private.h | 12 +- deps/cares/src/lib/ares_process.c | 21 +- deps/cares/src/lib/ares_qcache.c | 12 +- deps/cares/src/lib/ares_search.c | 72 ++- deps/cares/src/lib/ares_send.c | 6 +- deps/cares/src/lib/ares_sysconfig.c | 3 +- deps/cares/src/lib/dsa/ares__htable.c | 2 +- .../src/lib/event/ares_event_configchg.c | 5 +- deps/cares/src/lib/str/ares__buf.c | 6 +- deps/cares/src/tools/Makefile.in | 2 + 28 files changed, 495 insertions(+), 311 deletions(-) diff --git a/deps/cares/CMakeLists.txt b/deps/cares/CMakeLists.txt index d3f6907564868e..9862406495f4fa 100644 --- a/deps/cares/CMakeLists.txt +++ b/deps/cares/CMakeLists.txt @@ -12,7 +12,7 @@ INCLUDE (CheckCSourceCompiles) INCLUDE (CheckStructHasMember) INCLUDE (CheckLibraryExists) -PROJECT (c-ares LANGUAGES C VERSION "1.33.0" ) +PROJECT (c-ares LANGUAGES C VERSION "1.33.1" ) # Set this version before release SET (CARES_VERSION "${PROJECT_VERSION}") @@ -30,7 +30,7 @@ INCLUDE (GNUInstallDirs) # include this *AFTER* PROJECT(), otherwise paths are w # For example, a version of 4:0:2 would generate output such as: # libname.so -> libname.so.2 # libname.so.2 -> libname.so.2.2.0 -SET (CARES_LIB_VERSIONINFO "20:0:18") +SET (CARES_LIB_VERSIONINFO "20:1:18") OPTION (CARES_STATIC "Build as a static library" OFF) @@ -772,12 +772,11 @@ IF (CARES_INSTALL) INSTALL (EXPORT ${PROJECT_NAME}-targets COMPONENT Devel DESTINATION ${CMAKECONFIG_INSTALL_DIR} NAMESPACE ${PROJECT_NAME}::) INSTALL (FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" COMPONENT Devel DESTINATION ${CMAKECONFIG_INSTALL_DIR}) - # pkgconfig support - IF (NOT CARES_SHARED) - FOREACH (LIB ${CARES_DEPENDENT_LIBS}) - SET (CARES_PRIVATE_LIBS "${CARES_PRIVATE_LIBS} -l${LIB}") - ENDFOREACH () - ENDIF () + # pkgconfig support for static builds + FOREACH (LIB ${CARES_DEPENDENT_LIBS}) + SET (CARES_PRIVATE_LIBS "${CARES_PRIVATE_LIBS} -l${LIB}") + ENDFOREACH () + CONFIGURE_FILE("libcares.pc.cmake" "libcares.pc" @ONLY) INSTALL (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcares.pc" COMPONENT Devel DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") ENDIF () diff --git a/deps/cares/Makefile.in b/deps/cares/Makefile.in index 4feaae7267c0fc..706dafdbdfc5fa 100644 --- a/deps/cares/Makefile.in +++ b/deps/cares/Makefile.in @@ -328,6 +328,8 @@ FGREP = @FGREP@ FILECMD = @FILECMD@ GCOV = @GCOV@ GENHTML = @GENHTML@ +GMOCK112_CFLAGS = @GMOCK112_CFLAGS@ +GMOCK112_LIBS = @GMOCK112_LIBS@ GMOCK_CFLAGS = @GMOCK_CFLAGS@ GMOCK_LIBS = @GMOCK_LIBS@ GREP = @GREP@ diff --git a/deps/cares/RELEASE-NOTES.md b/deps/cares/RELEASE-NOTES.md index b072feb29fdebe..e9c04953dc6022 100644 --- a/deps/cares/RELEASE-NOTES.md +++ b/deps/cares/RELEASE-NOTES.md @@ -1,3 +1,35 @@ +## c-ares version 1.33.1 - August 23 2024 + +This is a bugfix release. + +Bugfixes: +* Work around systemd-resolved quirk that returns unexpected codes for single + label names. Also adds test cases to validate the work around works and + will continue to work in future releases. + [PR #863](https://github.com/c-ares/c-ares/pull/863), + See Also https://github.com/systemd/systemd/issues/34101 +* Fix sysconfig ndots default value, also adds containerized test case to + prevent future regressions. + [PR #862](https://github.com/c-ares/c-ares/pull/862) +* Fix blank DNS name returning error code rather than valid record for + commands like: `adig -t SOA .`. Also adds test case to prevent future + regressions. + [9e574af](https://github.com/c-ares/c-ares/commit/9e574af) +* Fix calculation of query times > 1s. + [2b2eae7](https://github.com/c-ares/c-ares/commit/2b2eae7) +* Fix building on old Linux releases that don't have `TCP_FASTOPEN_CONNECT`. + [b7a89b9](https://github.com/c-ares/c-ares/commit/b7a89b9) +* Fix minor Android build warnings. + [PR #848](https://github.com/c-ares/c-ares/pull/848) + +Thanks go to these friendly people for their efforts and contributions for this +release: +* Brad House (@bradh352) +* Erik Lax (@eriklax) +* Hans-Christian Egtvedt (@egtvedt) +* Mikael Lindemann (@mikaellindemann) +* Nodar Chkuaselidze (@nodech) + ## c-ares version 1.33.0 - August 2 2024 This is a feature and bugfix release. diff --git a/deps/cares/aminclude_static.am b/deps/cares/aminclude_static.am index 436bfe5a5be5d1..538a810c9eb0ee 100644 --- a/deps/cares/aminclude_static.am +++ b/deps/cares/aminclude_static.am @@ -1,6 +1,6 @@ # aminclude_static.am generated automatically by Autoconf -# from AX_AM_MACROS_STATIC on Fri Aug 2 08:48:39 EDT 2024 +# from AX_AM_MACROS_STATIC on Fri Aug 23 09:37:25 EDT 2024 # Code coverage diff --git a/deps/cares/configure b/deps/cares/configure index d9dad13dd30287..74e9741fe6ee7a 100755 --- a/deps/cares/configure +++ b/deps/cares/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.72 for c-ares 1.33.0. +# Generated by GNU Autoconf 2.72 for c-ares 1.33.1. # # Report bugs to . # @@ -614,8 +614,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='c-ares' PACKAGE_TARNAME='c-ares' -PACKAGE_VERSION='1.33.0' -PACKAGE_STRING='c-ares 1.33.0' +PACKAGE_VERSION='1.33.1' +PACKAGE_STRING='c-ares 1.33.1' PACKAGE_BUGREPORT='c-ares mailing list: http://lists.haxx.se/listinfo/c-ares' PACKAGE_URL='' @@ -663,6 +663,8 @@ AM_CPPFLAGS AM_CFLAGS BUILD_TESTS_FALSE BUILD_TESTS_TRUE +GMOCK112_LIBS +GMOCK112_CFLAGS GMOCK_LIBS GMOCK_CFLAGS PKG_CONFIG_LIBDIR @@ -868,7 +870,9 @@ PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR GMOCK_CFLAGS -GMOCK_LIBS' +GMOCK_LIBS +GMOCK112_CFLAGS +GMOCK112_LIBS' # Initialize some variables set by options. @@ -1417,7 +1421,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -'configure' configures c-ares 1.33.0 to adapt to many kinds of systems. +'configure' configures c-ares 1.33.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1488,7 +1492,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of c-ares 1.33.0:";; + short | recursive ) echo "Configuration of c-ares 1.33.1:";; esac cat <<\_ACEOF @@ -1557,6 +1561,10 @@ Some influential environment variables: GMOCK_CFLAGS C compiler flags for GMOCK, overriding pkg-config GMOCK_LIBS linker flags for GMOCK, overriding pkg-config + GMOCK112_CFLAGS + C compiler flags for GMOCK112, overriding pkg-config + GMOCK112_LIBS + linker flags for GMOCK112, overriding pkg-config Use these variables to override the choices made by 'configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -1625,7 +1633,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -c-ares configure 1.33.0 +c-ares configure 1.33.1 generated by GNU Autoconf 2.72 Copyright (C) 2023 Free Software Foundation, Inc. @@ -1953,50 +1961,6 @@ fi } # ac_fn_cxx_try_link -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that -# executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -printf "%s\n" "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; } -then : - ac_retval=0 -else case e in #( - e) printf "%s\n" "$as_me: program exited with status $ac_status" >&5 - printf "%s\n" "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status ;; -esac -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. @@ -2245,6 +2209,50 @@ printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member + +# ac_fn_c_try_run LINENO +# ---------------------- +# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that +# executables *can* be run. +ac_fn_c_try_run () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if { { ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_link") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' + { { case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" +printf "%s\n" "$ac_try_echo"; } >&5 + (eval "$ac_try") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } +then : + ac_retval=0 +else case e in #( + e) printf "%s\n" "$as_me: program exited with status $ac_status" >&5 + printf "%s\n" "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_retval=$ac_status ;; +esac +fi + rm -rf conftest.dSYM conftest_ipa8_conftest.oo + eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno + as_fn_set_status $ac_retval + +} # ac_fn_c_try_run ac_configure_args_raw= for ac_arg do @@ -2269,7 +2277,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by c-ares $as_me 1.33.0, which was +It was created by c-ares $as_me 1.33.1, which was generated by GNU Autoconf 2.72. Invocation command line was $ $0$ac_configure_args_raw @@ -3261,7 +3269,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -CARES_VERSION_INFO="20:0:18" +CARES_VERSION_INFO="20:1:18" @@ -6182,7 +6190,7 @@ fi # Define the identity of the package. PACKAGE='c-ares' - VERSION='1.33.0' + VERSION='1.33.1' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -20044,190 +20052,6 @@ fi - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether user namespaces are supported" >&5 -printf %s "checking whether user namespaces are supported... " >&6; } -if test ${ax_cv_user_namespace+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - if test "$cross_compiling" = yes -then : - ax_cv_user_namespace=no -else case e in #( - e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include - -int userfn(void *d) { - usleep(100000); /* synchronize by sleep */ - return (getuid() != 0); -} -char userst[1024*1024]; -int main() { - char buffer[1024]; - int rc, status, fd; - pid_t child = clone(userfn, userst + 1024*1024, CLONE_NEWUSER|SIGCHLD, 0); - if (child < 0) return 1; - - snprintf(buffer, sizeof(buffer), "/proc/%d/uid_map", child); - fd = open(buffer, O_CREAT|O_WRONLY|O_TRUNC, 0755); - snprintf(buffer, sizeof(buffer), "0 %d 1\n", getuid()); - write(fd, buffer, strlen(buffer)); - close(fd); - - rc = waitpid(child, &status, 0); - if (rc <= 0) return 1; - if (!WIFEXITED(status)) return 1; - return WEXITSTATUS(status); -} - -_ACEOF -if ac_fn_c_try_run "$LINENO" -then : - ax_cv_user_namespace=yes -else case e in #( - e) ax_cv_user_namespace=no ;; -esac -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext ;; -esac -fi - - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - ;; -esac -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_user_namespace" >&5 -printf "%s\n" "$ax_cv_user_namespace" >&6; } - if test "$ax_cv_user_namespace" = yes; then - -printf "%s\n" "#define HAVE_USER_NAMESPACE 1" >>confdefs.h - - fi - - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether UTS namespaces are supported" >&5 -printf %s "checking whether UTS namespaces are supported... " >&6; } -if test ${ax_cv_uts_namespace+y} -then : - printf %s "(cached) " >&6 -else case e in #( - e) - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - if test "$cross_compiling" = yes -then : - ax_cv_uts_namespace=no -else case e in #( - e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include -#include -#include - -int utsfn(void *d) { - char buffer[1024]; - const char *name = "autoconftest"; - int rc = sethostname(name, strlen(name)); - if (rc != 0) return 1; - gethostname(buffer, 1024); - return (strcmp(buffer, name) != 0); -} - -char st2[1024*1024]; -int fn(void *d) { - pid_t child; - int rc, status; - usleep(100000); /* synchronize by sleep */ - if (getuid() != 0) return 1; - child = clone(utsfn, st2 + 1024*1024, CLONE_NEWUTS|SIGCHLD, 0); - if (child < 0) return 1; - rc = waitpid(child, &status, 0); - if (rc <= 0) return 1; - if (!WIFEXITED(status)) return 1; - return WEXITSTATUS(status); -} -char st[1024*1024]; -int main() { - char buffer[1024]; - int rc, status, fd; - pid_t child = clone(fn, st + 1024*1024, CLONE_NEWUSER|SIGCHLD, 0); - if (child < 0) return 1; - - snprintf(buffer, sizeof(buffer), "/proc/%d/uid_map", child); - fd = open(buffer, O_CREAT|O_WRONLY|O_TRUNC, 0755); - snprintf(buffer, sizeof(buffer), "0 %d 1\n", getuid()); - write(fd, buffer, strlen(buffer)); - close(fd); - - rc = waitpid(child, &status, 0); - if (rc <= 0) return 1; - if (!WIFEXITED(status)) return 1; - return WEXITSTATUS(status); -} - - -_ACEOF -if ac_fn_c_try_run "$LINENO" -then : - ax_cv_uts_namespace=yes -else case e in #( - e) ax_cv_uts_namespace=no ;; -esac -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext ;; -esac -fi - - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - ;; -esac -fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_uts_namespace" >&5 -printf "%s\n" "$ax_cv_uts_namespace" >&6; } - if test "$ax_cv_uts_namespace" = yes; then - -printf "%s\n" "#define HAVE_UTS_NAMESPACE 1" >>confdefs.h - - fi - # Check whether --enable-largefile was given. if test ${enable_largefile+y} then : @@ -24753,6 +24577,264 @@ printf "%s\n" "$as_me: WARNING: gmock could not be found, not building tests" >& else as_fn_error $? "tests require gmock" "$LINENO" 5 fi + else + +pkg_failed=no +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gmock >= 1.12.0" >&5 +printf %s "checking for gmock >= 1.12.0... " >&6; } + +if test -n "$GMOCK112_CFLAGS"; then + pkg_cv_GMOCK112_CFLAGS="$GMOCK112_CFLAGS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gmock >= 1.12.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gmock >= 1.12.0") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GMOCK112_CFLAGS=`$PKG_CONFIG --cflags "gmock >= 1.12.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi +if test -n "$GMOCK112_LIBS"; then + pkg_cv_GMOCK112_LIBS="$GMOCK112_LIBS" + elif test -n "$PKG_CONFIG"; then + if test -n "$PKG_CONFIG" && \ + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"gmock >= 1.12.0\""; } >&5 + ($PKG_CONFIG --exists --print-errors "gmock >= 1.12.0") 2>&5 + ac_status=$? + printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; then + pkg_cv_GMOCK112_LIBS=`$PKG_CONFIG --libs "gmock >= 1.12.0" 2>/dev/null` + test "x$?" != "x0" && pkg_failed=yes +else + pkg_failed=yes +fi + else + pkg_failed=untried +fi + + + +if test $pkg_failed = yes; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then + _pkg_short_errors_supported=yes +else + _pkg_short_errors_supported=no +fi + if test $_pkg_short_errors_supported = yes; then + GMOCK112_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "gmock >= 1.12.0" 2>&1` + else + GMOCK112_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "gmock >= 1.12.0" 2>&1` + fi + # Put the nasty error message in config.log where it belongs + echo "$GMOCK112_PKG_ERRORS" >&5 + + have_gmock_v112=no +elif test $pkg_failed = untried; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + have_gmock_v112=no +else + GMOCK112_CFLAGS=$pkg_cv_GMOCK112_CFLAGS + GMOCK112_LIBS=$pkg_cv_GMOCK112_LIBS + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + have_gmock_v112=yes +fi + if test "x$have_gmock_v112" = "xyes" ; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether user namespaces are supported" >&5 +printf %s "checking whether user namespaces are supported... " >&6; } +if test ${ax_cv_user_namespace+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test "$cross_compiling" = yes +then : + ax_cv_user_namespace=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +int userfn(void *d) { + usleep(100000); /* synchronize by sleep */ + return (getuid() != 0); +} +char userst[1024*1024]; +int main() { + char buffer[1024]; + int rc, status, fd; + pid_t child = clone(userfn, userst + 1024*1024, CLONE_NEWUSER|SIGCHLD, 0); + if (child < 0) return 1; + + snprintf(buffer, sizeof(buffer), "/proc/%d/uid_map", child); + fd = open(buffer, O_CREAT|O_WRONLY|O_TRUNC, 0755); + snprintf(buffer, sizeof(buffer), "0 %d 1\n", getuid()); + write(fd, buffer, strlen(buffer)); + close(fd); + + rc = waitpid(child, &status, 0); + if (rc <= 0) return 1; + if (!WIFEXITED(status)) return 1; + return WEXITSTATUS(status); +} + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ax_cv_user_namespace=yes +else case e in #( + e) ax_cv_user_namespace=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_user_namespace" >&5 +printf "%s\n" "$ax_cv_user_namespace" >&6; } + if test "$ax_cv_user_namespace" = yes; then + +printf "%s\n" "#define HAVE_USER_NAMESPACE 1" >>confdefs.h + + fi + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether UTS namespaces are supported" >&5 +printf %s "checking whether UTS namespaces are supported... " >&6; } +if test ${ax_cv_uts_namespace+y} +then : + printf %s "(cached) " >&6 +else case e in #( + e) + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + if test "$cross_compiling" = yes +then : + ax_cv_uts_namespace=no +else case e in #( + e) cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +int utsfn(void *d) { + char buffer[1024]; + const char *name = "autoconftest"; + int rc = sethostname(name, strlen(name)); + if (rc != 0) return 1; + gethostname(buffer, 1024); + return (strcmp(buffer, name) != 0); +} + +char st2[1024*1024]; +int fn(void *d) { + pid_t child; + int rc, status; + usleep(100000); /* synchronize by sleep */ + if (getuid() != 0) return 1; + child = clone(utsfn, st2 + 1024*1024, CLONE_NEWUTS|SIGCHLD, 0); + if (child < 0) return 1; + rc = waitpid(child, &status, 0); + if (rc <= 0) return 1; + if (!WIFEXITED(status)) return 1; + return WEXITSTATUS(status); +} +char st[1024*1024]; +int main() { + char buffer[1024]; + int rc, status, fd; + pid_t child = clone(fn, st + 1024*1024, CLONE_NEWUSER|SIGCHLD, 0); + if (child < 0) return 1; + + snprintf(buffer, sizeof(buffer), "/proc/%d/uid_map", child); + fd = open(buffer, O_CREAT|O_WRONLY|O_TRUNC, 0755); + snprintf(buffer, sizeof(buffer), "0 %d 1\n", getuid()); + write(fd, buffer, strlen(buffer)); + close(fd); + + rc = waitpid(child, &status, 0); + if (rc <= 0) return 1; + if (!WIFEXITED(status)) return 1; + return WEXITSTATUS(status); +} + + +_ACEOF +if ac_fn_c_try_run "$LINENO" +then : + ax_cv_uts_namespace=yes +else case e in #( + e) ax_cv_uts_namespace=no ;; +esac +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext ;; +esac +fi + + ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + ;; +esac +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_uts_namespace" >&5 +printf "%s\n" "$ax_cv_uts_namespace" >&6; } + if test "$ax_cv_uts_namespace" = yes; then + +printf "%s\n" "#define HAVE_UTS_NAMESPACE 1" >>confdefs.h + + fi + + fi fi fi if test "x$build_tests" != "xno" ; then @@ -26629,7 +26711,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by c-ares $as_me 1.33.0, which was +This file was extended by c-ares $as_me 1.33.1, which was generated by GNU Autoconf 2.72. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -26697,7 +26779,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -c-ares config.status 1.33.0 +c-ares config.status 1.33.1 configured by $0, generated by GNU Autoconf 2.72, with options \\"\$ac_cs_config\\" diff --git a/deps/cares/configure.ac b/deps/cares/configure.ac index be891e40621ffd..59fd975b64f873 100644 --- a/deps/cares/configure.ac +++ b/deps/cares/configure.ac @@ -2,10 +2,10 @@ dnl Copyright (C) The c-ares project and its contributors dnl SPDX-License-Identifier: MIT AC_PREREQ([2.69]) -AC_INIT([c-ares], [1.33.0], +AC_INIT([c-ares], [1.33.1], [c-ares mailing list: http://lists.haxx.se/listinfo/c-ares]) -CARES_VERSION_INFO="20:0:18" +CARES_VERSION_INFO="20:1:18" dnl This flag accepts an argument of the form current[:revision[:age]]. So, dnl passing -version-info 3:12:1 sets current to 3, revision to 12, and age to dnl 1. @@ -153,8 +153,6 @@ _EOF ]) AX_CODE_COVERAGE -AX_CHECK_USER_NAMESPACE -AX_CHECK_UTS_NAMESPACE AC_SYS_LARGEFILE case $host_os in @@ -819,6 +817,12 @@ if test "x$build_tests" != "xno" ; then else AC_MSG_ERROR([tests require gmock]) fi + else + PKG_CHECK_MODULES([GMOCK112], [gmock >= 1.12.0], [ have_gmock_v112=yes ], [ have_gmock_v112=no ]) + if test "x$have_gmock_v112" = "xyes" ; then + AX_CHECK_USER_NAMESPACE + AX_CHECK_UTS_NAMESPACE + fi fi fi if test "x$build_tests" != "xno" ; then diff --git a/deps/cares/docs/Makefile.in b/deps/cares/docs/Makefile.in index 155ab9d3017e5b..a57cd0abc18846 100644 --- a/deps/cares/docs/Makefile.in +++ b/deps/cares/docs/Makefile.in @@ -227,6 +227,8 @@ FGREP = @FGREP@ FILECMD = @FILECMD@ GCOV = @GCOV@ GENHTML = @GENHTML@ +GMOCK112_CFLAGS = @GMOCK112_CFLAGS@ +GMOCK112_LIBS = @GMOCK112_LIBS@ GMOCK_CFLAGS = @GMOCK_CFLAGS@ GMOCK_LIBS = @GMOCK_LIBS@ GREP = @GREP@ diff --git a/deps/cares/include/Makefile.in b/deps/cares/include/Makefile.in index 2960e5a55237c4..99936f8649748f 100644 --- a/deps/cares/include/Makefile.in +++ b/deps/cares/include/Makefile.in @@ -238,6 +238,8 @@ FGREP = @FGREP@ FILECMD = @FILECMD@ GCOV = @GCOV@ GENHTML = @GENHTML@ +GMOCK112_CFLAGS = @GMOCK112_CFLAGS@ +GMOCK112_LIBS = @GMOCK112_LIBS@ GMOCK_CFLAGS = @GMOCK_CFLAGS@ GMOCK_LIBS = @GMOCK_LIBS@ GREP = @GREP@ diff --git a/deps/cares/include/ares_version.h b/deps/cares/include/ares_version.h index fef66b739791be..c910d79209a3fb 100644 --- a/deps/cares/include/ares_version.h +++ b/deps/cares/include/ares_version.h @@ -32,11 +32,11 @@ #define ARES_VERSION_MAJOR 1 #define ARES_VERSION_MINOR 33 -#define ARES_VERSION_PATCH 0 +#define ARES_VERSION_PATCH 1 #define ARES_VERSION \ ((ARES_VERSION_MAJOR << 16) | (ARES_VERSION_MINOR << 8) | \ (ARES_VERSION_PATCH)) -#define ARES_VERSION_STR "1.33.0" +#define ARES_VERSION_STR "1.33.1" #define CARES_HAVE_ARES_LIBRARY_INIT 1 #define CARES_HAVE_ARES_LIBRARY_CLEANUP 1 diff --git a/deps/cares/libcares.pc.cmake b/deps/cares/libcares.pc.cmake index 74e4d0cf445978..257255d84d5ce9 100644 --- a/deps/cares/libcares.pc.cmake +++ b/deps/cares/libcares.pc.cmake @@ -7,9 +7,9 @@ # Copyright (C) The c-ares project and its contributors # SPDX-License-Identifier: MIT prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=@CMAKE_INSTALL_FULL_BINDIR@ -libdir=@CMAKE_INSTALL_FULL_LIBDIR@ -includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ +exec_prefix=${prefix}/@CMAKE_INSTALL_BINDIR@ +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ Name: c-ares URL: https://c-ares.org/ @@ -18,5 +18,6 @@ Version: @CARES_VERSION@ Requires: Requires.private: Cflags: -I${includedir} +Cflags.private: -DCARES_STATICLIB Libs: -L${libdir} -lcares Libs.private: @CARES_PRIVATE_LIBS@ diff --git a/deps/cares/src/Makefile.in b/deps/cares/src/Makefile.in index 45558374c870ad..3ad8a92a6a4f15 100644 --- a/deps/cares/src/Makefile.in +++ b/deps/cares/src/Makefile.in @@ -250,6 +250,8 @@ FGREP = @FGREP@ FILECMD = @FILECMD@ GCOV = @GCOV@ GENHTML = @GENHTML@ +GMOCK112_CFLAGS = @GMOCK112_CFLAGS@ +GMOCK112_LIBS = @GMOCK112_LIBS@ GMOCK_CFLAGS = @GMOCK_CFLAGS@ GMOCK_LIBS = @GMOCK_LIBS@ GREP = @GREP@ diff --git a/deps/cares/src/lib/Makefile.in b/deps/cares/src/lib/Makefile.in index c0d96ed81bb29b..30d33843d5d2d8 100644 --- a/deps/cares/src/lib/Makefile.in +++ b/deps/cares/src/lib/Makefile.in @@ -15,7 +15,7 @@ @SET_MAKE@ # aminclude_static.am generated automatically by Autoconf -# from AX_AM_MACROS_STATIC on Fri Aug 2 08:48:39 EDT 2024 +# from AX_AM_MACROS_STATIC on Fri Aug 23 09:37:25 EDT 2024 # Copyright (C) The c-ares project and its contributors # SPDX-License-Identifier: MIT @@ -490,6 +490,8 @@ FGREP = @FGREP@ FILECMD = @FILECMD@ GCOV = @GCOV@ GENHTML = @GENHTML@ +GMOCK112_CFLAGS = @GMOCK112_CFLAGS@ +GMOCK112_LIBS = @GMOCK112_LIBS@ GMOCK_CFLAGS = @GMOCK_CFLAGS@ GMOCK_LIBS = @GMOCK_LIBS@ GREP = @GREP@ diff --git a/deps/cares/src/lib/ares__close_sockets.c b/deps/cares/src/lib/ares__close_sockets.c index 27bbaacf0e8931..71c7e64f08ad38 100644 --- a/deps/cares/src/lib/ares__close_sockets.c +++ b/deps/cares/src/lib/ares__close_sockets.c @@ -37,7 +37,7 @@ static void ares__requeue_queries(ares_conn_t *conn, ares__tvnow(&now); while ((query = ares__llist_first_val(conn->queries_to_conn)) != NULL) { - ares__requeue_query(query, &now, requeue_status, ARES_TRUE); + ares__requeue_query(query, &now, requeue_status, ARES_TRUE, NULL); } } diff --git a/deps/cares/src/lib/ares__socket.c b/deps/cares/src/lib/ares__socket.c index 2e360efb4148d9..86e281fcddadd4 100644 --- a/deps/cares/src/lib/ares__socket.c +++ b/deps/cares/src/lib/ares__socket.c @@ -56,7 +56,7 @@ #include #include -#if defined(__linux__) && defined(MSG_FASTOPEN) +#if defined(__linux__) && defined(TCP_FASTOPEN_CONNECT) # define TFO_SUPPORTED 1 # define TFO_SKIP_CONNECT 0 # define TFO_USE_SENDTO 0 diff --git a/deps/cares/src/lib/ares_android.c b/deps/cares/src/lib/ares_android.c index 4c0ffa04f7c36e..06ab8940ad736d 100644 --- a/deps/cares/src/lib/ares_android.c +++ b/deps/cares/src/lib/ares_android.c @@ -27,6 +27,7 @@ # include "ares_private.h" # include # include +# include "ares_android.h" static JavaVM *android_jvm = NULL; static jobject android_connectivity_manager = NULL; @@ -227,7 +228,7 @@ int ares_library_init_android(jobject connectivity_manager) (*android_jvm)->DetachCurrentThread(android_jvm); } - return ret; + return (int)ret; } int ares_library_android_initialized(void) diff --git a/deps/cares/src/lib/ares_cookie.c b/deps/cares/src/lib/ares_cookie.c index 0680fe9ec7b6a3..bf9d1ba25da41d 100644 --- a/deps/cares/src/lib/ares_cookie.c +++ b/deps/cares/src/lib/ares_cookie.c @@ -427,7 +427,8 @@ ares_status_t ares_cookie_validate(ares_query_t *query, /* Resend the request, hopefully it will work the next time as we should * have recorded a server cookie */ ares__requeue_query(query, now, ARES_SUCCESS, - ARES_FALSE /* Don't increment try count */); + ARES_FALSE /* Don't increment try count */, + NULL); /* Parent needs to drop this response */ return ARES_EBADRESP; diff --git a/deps/cares/src/lib/ares_getaddrinfo.c b/deps/cares/src/lib/ares_getaddrinfo.c index f67acdec2fac81..713acf744a0dca 100644 --- a/deps/cares/src/lib/ares_getaddrinfo.c +++ b/deps/cares/src/lib/ares_getaddrinfo.c @@ -528,6 +528,13 @@ static void host_callback(void *arg, ares_status_t status, size_t timeouts, hquery->nodata_cnt++; } next_lookup(hquery, hquery->nodata_cnt ? ARES_ENODATA : status); + } else if ( + (status == ARES_ESERVFAIL || status == ARES_EREFUSED) && + ares__name_label_cnt(hquery->names[hquery->next_name_idx-1]) == 1 + ) { + /* Issue #852, systemd-resolved may return SERVFAIL or REFUSED on a + * single label domain name. */ + next_lookup(hquery, hquery->nodata_cnt ? ARES_ENODATA : status); } else { end_hquery(hquery, status); } diff --git a/deps/cares/src/lib/ares_metrics.c b/deps/cares/src/lib/ares_metrics.c index aa0ea8c01707a4..0e22fc37e7cb46 100644 --- a/deps/cares/src/lib/ares_metrics.c +++ b/deps/cares/src/lib/ares_metrics.c @@ -170,7 +170,7 @@ void ares_metrics_record(const ares_query_t *query, ares_server_t *server, } ares__timeval_diff(&tvdiff, &query->ts, &now); - query_ms = (unsigned int)(tvdiff.sec + (tvdiff.usec / 1000)); + query_ms = (unsigned int)((tvdiff.sec * 1000) + (tvdiff.usec / 1000)); if (query_ms == 0) { query_ms = 1; } diff --git a/deps/cares/src/lib/ares_private.h b/deps/cares/src/lib/ares_private.h index b85ecb5e14d73d..263c2a606d3708 100644 --- a/deps/cares/src/lib/ares_private.h +++ b/deps/cares/src/lib/ares_private.h @@ -462,10 +462,14 @@ ares_bool_t ares__timedout(const ares_timeval_t *now, /* Returns one of the normal ares status codes like ARES_SUCCESS */ ares_status_t ares__send_query(ares_query_t *query, const ares_timeval_t *now); -ares_status_t ares__requeue_query(ares_query_t *query, - const ares_timeval_t *now, - ares_status_t status, - ares_bool_t inc_try_count); +ares_status_t ares__requeue_query(ares_query_t *query, + const ares_timeval_t *now, + ares_status_t status, + ares_bool_t inc_try_count, + const ares_dns_record_t *dnsrec); + +/*! Count the number of labels (dots+1) in a domain */ +size_t ares__name_label_cnt(const char *name); /*! Retrieve a list of names to use for searching. The first successful * query in the list wins. This function also uses the HOSTSALIASES file diff --git a/deps/cares/src/lib/ares_process.c b/deps/cares/src/lib/ares_process.c index 65ee673f6edcd5..f05f67d8f2b176 100644 --- a/deps/cares/src/lib/ares_process.c +++ b/deps/cares/src/lib/ares_process.c @@ -571,7 +571,7 @@ static void process_timeouts(ares_channel_t *channel, const ares_timeval_t *now) conn = query->conn; server_increment_failures(conn->server, query->using_tcp); - ares__requeue_query(query, now, ARES_ETIMEOUT, ARES_TRUE); + ares__requeue_query(query, now, ARES_ETIMEOUT, ARES_TRUE, NULL); } } @@ -711,7 +711,7 @@ static ares_status_t process_answer(ares_channel_t *channel, } server_increment_failures(server, query->using_tcp); - ares__requeue_query(query, now, status, ARES_TRUE); + ares__requeue_query(query, now, status, ARES_TRUE, rdnsrec); /* Should any of these cause a connection termination? * Maybe SERVER_FAILURE? */ @@ -756,10 +756,11 @@ static void handle_conn_error(ares_conn_t *conn, ares_bool_t critical_failure, ares__close_connection(conn, failure_status); } -ares_status_t ares__requeue_query(ares_query_t *query, - const ares_timeval_t *now, - ares_status_t status, - ares_bool_t inc_try_count) +ares_status_t ares__requeue_query(ares_query_t *query, + const ares_timeval_t *now, + ares_status_t status, + ares_bool_t inc_try_count, + const ares_dns_record_t *dnsrec) { ares_channel_t *channel = query->channel; size_t max_tries = ares__slist_len(channel->servers) * channel->tries; @@ -783,7 +784,7 @@ ares_status_t ares__requeue_query(ares_query_t *query, query->error_status = ARES_ETIMEOUT; } - end_query(channel, NULL, query, query->error_status, NULL); + end_query(channel, NULL, query, query->error_status, dnsrec); return ARES_ETIMEOUT; } @@ -1078,7 +1079,7 @@ ares_status_t ares__send_query(ares_query_t *query, const ares_timeval_t *now) case ARES_ECONNREFUSED: case ARES_EBADFAMILY: server_increment_failures(server, query->using_tcp); - return ares__requeue_query(query, now, status, ARES_TRUE); + return ares__requeue_query(query, now, status, ARES_TRUE, NULL); /* Anything else is not retryable, likely ENOMEM */ default: @@ -1104,7 +1105,7 @@ ares_status_t ares__send_query(ares_query_t *query, const ares_timeval_t *now) case ARES_ECONNREFUSED: case ARES_EBADFAMILY: handle_conn_error(conn, ARES_TRUE, status); - status = ares__requeue_query(query, now, status, ARES_TRUE); + status = ares__requeue_query(query, now, status, ARES_TRUE, NULL); if (status == ARES_ETIMEOUT) { status = ARES_ECONNREFUSED; } @@ -1114,7 +1115,7 @@ ares_status_t ares__send_query(ares_query_t *query, const ares_timeval_t *now) * just requeue to a different server/connection. */ default: server_increment_failures(server, query->using_tcp); - status = ares__requeue_query(query, now, status, ARES_TRUE); + status = ares__requeue_query(query, now, status, ARES_TRUE, NULL); return status; } diff --git a/deps/cares/src/lib/ares_qcache.c b/deps/cares/src/lib/ares_qcache.c index aee1328b51c7bc..9725212fded7d1 100644 --- a/deps/cares/src/lib/ares_qcache.c +++ b/deps/cares/src/lib/ares_qcache.c @@ -121,9 +121,11 @@ static char *ares__qcache_calc_key(const ares_dns_record_t *dnsrec) name_len--; } - status = ares__buf_append(buf, (const unsigned char *)name, name_len); - if (status != ARES_SUCCESS) { - goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ + if (name_len > 0) { + status = ares__buf_append(buf, (const unsigned char *)name, name_len); + if (status != ARES_SUCCESS) { + goto fail; /* LCOV_EXCL_LINE: OutOfMemory */ + } } } @@ -346,8 +348,8 @@ static ares_status_t ares__qcache_insert(ares__qcache_t *qcache, } entry->dnsrec = qresp; - entry->expire_ts = now->sec + (time_t)ttl; - entry->insert_ts = now->sec; + entry->expire_ts = (time_t)now->sec + (time_t)ttl; + entry->insert_ts = (time_t)now->sec; /* We can't guarantee the server responded with the same flags as the * request had, so we have to re-parse the request in order to generate the diff --git a/deps/cares/src/lib/ares_search.c b/deps/cares/src/lib/ares_search.c index ae98df39a80a8f..2d3c0fc5145684 100644 --- a/deps/cares/src/lib/ares_search.c +++ b/deps/cares/src/lib/ares_search.c @@ -107,26 +107,37 @@ static void search_callback(void *arg, ares_status_t status, size_t timeouts, { struct search_query *squery = (struct search_query *)arg; ares_channel_t *channel = squery->channel; - ares_dns_rcode_t rcode; - size_t ancount; + ares_status_t mystatus; ares_bool_t skip_cleanup = ARES_FALSE; squery->timeouts += timeouts; - if (status != ARES_SUCCESS) { - end_squery(squery, status, dnsrec); - return; - } - - rcode = ares_dns_record_get_rcode(dnsrec); - ancount = ares_dns_record_rr_cnt(dnsrec, ARES_SECTION_ANSWER); - mystatus = ares_dns_query_reply_tostatus(rcode, ancount); - - if (mystatus != ARES_ENODATA && mystatus != ARES_ESERVFAIL && - mystatus != ARES_ENOTFOUND) { - end_squery(squery, mystatus, dnsrec); - return; + if (dnsrec) { + ares_dns_rcode_t rcode = ares_dns_record_get_rcode(dnsrec); + size_t ancount = ares_dns_record_rr_cnt(dnsrec, + ARES_SECTION_ANSWER); + mystatus = ares_dns_query_reply_tostatus(rcode, ancount); + } else { + mystatus = status; + } + + switch (mystatus) { + case ARES_ENODATA: + case ARES_ENOTFOUND: + break; + case ARES_ESERVFAIL: + case ARES_EREFUSED: + /* Issue #852, systemd-resolved may return SERVFAIL or REFUSED on a + * single label domain name. */ + if (ares__name_label_cnt(squery->names[squery->next_name_idx-1]) != 1) { + end_squery(squery, mystatus, dnsrec); + return; + } + break; + default: + end_squery(squery, mystatus, dnsrec); + return; } /* If we ever get ARES_ENODATA along the way, record that; if the search @@ -147,7 +158,6 @@ static void search_callback(void *arg, ares_status_t status, size_t timeouts, return; } - /* We have no more domains to search, return an appropriate response. */ if (mystatus == ARES_ENOTFOUND && squery->ever_got_nodata) { end_squery(squery, ARES_ENODATA, NULL); @@ -176,6 +186,25 @@ static ares_bool_t ares__search_eligible(const ares_channel_t *channel, return ARES_TRUE; } +size_t ares__name_label_cnt(const char *name) +{ + const char *p; + size_t ndots = 0; + + if (name == NULL) { + return 0; + } + + for (p = name; p != NULL && *p != 0; p++) { + if (*p == '.') { + ndots++; + } + } + + /* Label count is 1 greater than ndots */ + return ndots+1; +} + ares_status_t ares__search_name_list(const ares_channel_t *channel, const char *name, char ***names, size_t *names_len) @@ -186,7 +215,6 @@ ares_status_t ares__search_name_list(const ares_channel_t *channel, char *alias = NULL; size_t ndots = 0; size_t idx = 0; - const char *p; size_t i; /* Perform HOSTALIASES resolution */ @@ -223,12 +251,10 @@ ares_status_t ares__search_name_list(const ares_channel_t *channel, goto done; } - /* Count the number of dots in name */ - ndots = 0; - for (p = name; *p != 0; p++) { - if (*p == '.') { - ndots++; - } + /* Count the number of dots in name, 1 less than label count */ + ndots = ares__name_label_cnt(name); + if (ndots > 0) { + ndots--; } /* Allocate an entry for each search domain, plus one for as-is */ diff --git a/deps/cares/src/lib/ares_send.c b/deps/cares/src/lib/ares_send.c index 9441534404962f..64ff7edd3ac602 100644 --- a/deps/cares/src/lib/ares_send.c +++ b/deps/cares/src/lib/ares_send.c @@ -62,7 +62,11 @@ static ares_status_t ares_apply_dns0x20(ares_channel_t *channel, } len = ares_strlen(name); - if (len == 0 || len >= sizeof(dns0x20name)) { + if (len == 0) { + return ARES_SUCCESS; + } + + if (len >= sizeof(dns0x20name)) { status = ARES_EBADNAME; goto done; } diff --git a/deps/cares/src/lib/ares_sysconfig.c b/deps/cares/src/lib/ares_sysconfig.c index 2cd3df28235ec3..61e6a423a7578a 100644 --- a/deps/cares/src/lib/ares_sysconfig.c +++ b/deps/cares/src/lib/ares_sysconfig.c @@ -239,7 +239,7 @@ static ares_status_t ares__init_sysconfig_android(ares_sysconfig_t *sysconfig) char propname[PROP_NAME_MAX]; char propvalue[PROP_VALUE_MAX] = ""; for (i = 1; i <= MAX_DNS_PROPERTIES; i++) { - snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i); + snprintf(propname, sizeof(propname), "%s%zu", DNS_PROP_NAME_PREFIX, i); if (__system_property_get(propname, propvalue) < 1) { break; } @@ -494,6 +494,7 @@ ares_status_t ares__init_by_sysconfig(ares_channel_t *channel) ares_sysconfig_t sysconfig; memset(&sysconfig, 0, sizeof(sysconfig)); + sysconfig.ndots = 1; /* Default value if not otherwise set */ #if defined(USE_WINSOCK) status = ares__init_sysconfig_windows(&sysconfig); diff --git a/deps/cares/src/lib/dsa/ares__htable.c b/deps/cares/src/lib/dsa/ares__htable.c index d608d60ce3a51a..9049b3246b36f1 100644 --- a/deps/cares/src/lib/dsa/ares__htable.c +++ b/deps/cares/src/lib/dsa/ares__htable.c @@ -59,7 +59,7 @@ static unsigned int ares__htable_generate_seed(ares__htable_t *htable) * collision attack is very low with a small amount of effort */ seed |= (unsigned int)((size_t)htable & 0xFFFFFFFF); seed |= (unsigned int)((size_t)&seed & 0xFFFFFFFF); - seed |= (unsigned int)(t & 0xFFFFFFFF); + seed |= (unsigned int)(((ares_uint64_t)t) & 0xFFFFFFFF); return seed; } diff --git a/deps/cares/src/lib/event/ares_event_configchg.c b/deps/cares/src/lib/event/ares_event_configchg.c index 030c76c69c9148..10f0e21dde77fa 100644 --- a/deps/cares/src/lib/event/ares_event_configchg.c +++ b/deps/cares/src/lib/event/ares_event_configchg.c @@ -31,6 +31,8 @@ ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg, ares_event_thread_t *e) { + (void)configchg; + (void)e; /* No ability */ return ARES_ENOTIMP; } @@ -38,6 +40,7 @@ ares_status_t ares_event_configchg_init(ares_event_configchg_t **configchg, void ares_event_configchg_destroy(ares_event_configchg_t *configchg) { /* No-op */ + (void)configchg; } #elif defined(__linux__) @@ -107,7 +110,7 @@ static void ares_event_configchg_cb(ares_event_thread_t *e, ares_socket_t fd, * size provided, so I assume it won't ever return partial events. */ for (ptr = buf; ptr < buf + len; ptr += sizeof(struct inotify_event) + event->len) { - event = (const struct inotify_event *)ptr; + event = (const struct inotify_event *)((const void *)ptr); if (event->len == 0 || ares_strlen(event->name) == 0) { continue; diff --git a/deps/cares/src/lib/str/ares__buf.c b/deps/cares/src/lib/str/ares__buf.c index b855260ab37322..bf6d4a0e1d3712 100644 --- a/deps/cares/src/lib/str/ares__buf.c +++ b/deps/cares/src/lib/str/ares__buf.c @@ -213,10 +213,14 @@ ares_status_t ares__buf_append(ares__buf_t *buf, const unsigned char *data, { ares_status_t status; - if (data == NULL || data_len == 0) { + if (data == NULL && data_len != 0) { return ARES_EFORMERR; } + if (data_len == 0) { + return ARES_SUCCESS; + } + status = ares__buf_ensure_space(buf, data_len); if (status != ARES_SUCCESS) { return status; diff --git a/deps/cares/src/tools/Makefile.in b/deps/cares/src/tools/Makefile.in index 9c896092b1ec19..e1b661ec1d7cbf 100644 --- a/deps/cares/src/tools/Makefile.in +++ b/deps/cares/src/tools/Makefile.in @@ -275,6 +275,8 @@ FGREP = @FGREP@ FILECMD = @FILECMD@ GCOV = @GCOV@ GENHTML = @GENHTML@ +GMOCK112_CFLAGS = @GMOCK112_CFLAGS@ +GMOCK112_LIBS = @GMOCK112_LIBS@ GMOCK_CFLAGS = @GMOCK_CFLAGS@ GMOCK_LIBS = @GMOCK_LIBS@ GREP = @GREP@ From c00ea01f2bbee0427d38ba4573dae310394f42fe Mon Sep 17 00:00:00 2001 From: Robert Nagy Date: Tue, 27 Aug 2024 06:01:30 +0200 Subject: [PATCH 5/5] buffer: allow invalid encoding in from Looks like a bug to me but the change should probably done in a semver majpr. PR-URL: https://github.com/nodejs/node/pull/54533 Reviewed-By: Matteo Collina Reviewed-By: Benjamin Gruenbaum Reviewed-By: Jake Yuesong Li Reviewed-By: Rafael Gonzaga --- lib/buffer.js | 2 +- test/parallel/test-buffer-from.js | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/buffer.js b/lib/buffer.js index 05b57275f03dca..4467a555c7180e 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -476,7 +476,7 @@ function createFromString(string, ops, length = ops.byteLength(string)) { function fromString(string, encoding) { let ops; - if (!encoding || encoding === 'utf8') { + if (!encoding || encoding === 'utf8' || typeof encoding !== 'string') { ops = encodingOps.utf8; } else { ops = getEncodingOps(encoding); diff --git a/test/parallel/test-buffer-from.js b/test/parallel/test-buffer-from.js index 284c63e7d02e8e..416a3b3a3105b5 100644 --- a/test/parallel/test-buffer-from.js +++ b/test/parallel/test-buffer-from.js @@ -139,3 +139,6 @@ throws(() => { code: 'ERR_OUT_OF_RANGE', }) ); + +// Invalid encoding is allowed +Buffer.from('asd', 1);