Repository: nodejs/node
Pull request: module,win: fix long subpath import

This change fixes the linked issue and adds a regression test.

Fixes: https://github.com/nodejs/node/issues/62043

Changed files:
filename: src/node_modules.cc
patch: @@ -425,8 +425,16 @@ void BindingData::GetPackageScopeConfig(
       url::ThrowInvalidURL(realm->env(), resolved.ToStringView(), std::nullopt);
       return;
     }
+    BufferValue file_path_buf(realm->isolate(),
+                              String::NewFromUtf8(realm->isolate(),
+                                                  file_url->c_str(),
+                                                  NewStringType::kInternalized,
+                                                  file_url->size())
+                                  .ToLocalChecked());
+    ToNamespacedPath(realm->env(), &file_path_buf);
     error_context.specifier = resolved.ToString();
-    auto package_json = GetPackageJSON(realm, *file_url, &error_context);
+    auto package_json =
+        GetPackageJSON(realm, file_path_buf.ToStringView(), &error_context);
     if (package_json != nullptr) {
       if constexpr (return_only_type) {
         Local<Value> value;

filename: test/es-module/test-esm-long-path-win.js
patch: @@ -60,7 +60,7 @@ describe('long path on Windows', () => {
     tmpdir.refresh();
 
     fs.mkdirSync(packageDirPath);
-    fs.writeFileSync(packageJSPath, '');
+    fs.writeFileSync(packageJSPath, '{}');
     fs.writeFileSync(indexJSPath, '');
 
     const packageJsonUrl = pathToFileURL(
@@ -83,7 +83,7 @@ describe('long path on Windows', () => {
     tmpdir.refresh();
 
     fs.mkdirSync(packageDirPath);
-    fs.writeFileSync(packageJSPath, '');
+    fs.writeFileSync(packageJSPath, '{}');
     fs.writeFileSync(indexJSPath, '');
 
     const packageJsonUrl = pathToFileURL(

filename: test/parallel/test-module-subpath-import-long-path.js
patch: @@ -0,0 +1,40 @@
+// Regression test for https://github.com/nodejs/node/issues/62043
+'use strict';
+
+const common = require('../common');
+if (!common.isWindows) {
+  common.skip('this test is Windows-specific.');
+}
+
+const fs = require('fs');
+const { createRequire } = require('module');
+const path = require('path');
+const tmpdir = require('../common/tmpdir');
+
+tmpdir.refresh();
+
+const TARGET = 260; // Shortest length that used to trigger the bug
+const fixedLen = tmpdir.path.length + 2 + 'package.json'.length;
+const dirNameLen = Math.max(TARGET - fixedLen, 1);
+
+const dir = path.join(tmpdir.path, 'a'.repeat(dirNameLen));
+const depDir = path.join(dir, 'node_modules', 'dep');
+const packageJsonPath = path.join(dir, 'package.json');
+
+fs.mkdirSync(depDir, { recursive: true });
+fs.writeFileSync(
+  packageJsonPath,
+  JSON.stringify({ imports: { '#foo': './foo.mjs' } }),
+);
+fs.writeFileSync(path.join(dir, 'foo.mjs'), 'export default 1;\n');
+fs.writeFileSync(
+  path.join(depDir, 'package.json'),
+  JSON.stringify({ name: 'dep', exports: { '.': './index.mjs' } }),
+);
+fs.writeFileSync(path.join(depDir, 'index.mjs'), 'export default 1;\n');
+
+const req = createRequire(path.join(dir, '_.mjs'));
+
+// Both resolves should succeed without throwing
+req.resolve('dep');
+req.resolve('#foo');