Skip to content

Commit ba6246a

Browse files
authored
fix #2773: eval dependency symlinks instead of reading symlink target (#2774)
1 parent cf8ea74 commit ba6246a

File tree

3 files changed

+33
-25
lines changed

3 files changed

+33
-25
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@
3232
3333
However, this transformation is impossible if the code contains direct `eval` because direct `eval` "poisons" all containing scopes by preventing anything in those scopes from being renamed. That prevents esbuild from splitting up accesses to `foo` into two separate variables with different names. Previously esbuild still did this transformation but with two variables both named `foo`, which is a syntax error. With this release esbuild will now skip doing this transformation when direct `eval` is present to avoid generating code with a syntax error. This means that the generated code may no longer behave as intended since the behavior depends on the run-time strict mode setting instead of the strict mode setting present in the original source code. To fix this problem, you will need to remove the use of direct `eval`.
3434
35+
* Fix a bundling scenario involving multiple symlinks ([#2773](https://github.com/evanw/esbuild/issues/2773), [#2774](https://github.com/evanw/esbuild/issues/2774))
36+
37+
This release contains a fix for a bundling scenario involving an import path where multiple path segments are symlinks. Previously esbuild was unable to resolve certain import paths in this scenario, but these import paths should now work starting with this release. This fix was contributed by [@onebytegone](https://github.com/onebytegone).
38+
3539
## 0.16.10
3640
3741
* Change the default "legal comment" behavior again ([#2745](https://github.com/evanw/esbuild/issues/2745))

internal/fs/fs_real.go

+13-25
Original file line numberDiff line numberDiff line change
@@ -405,33 +405,21 @@ func (fs *realFS) kind(dir string, base string) (symlink string, kind EntryKind)
405405

406406
// Follow symlinks now so the cache contains the translation
407407
if (mode & os.ModeSymlink) != 0 {
408-
symlink = entryPath
409-
linksWalked := 0
410-
for {
411-
linksWalked++
412-
if linksWalked > 255 {
413-
return // Error: too many links
414-
}
415-
link, err := os.Readlink(symlink)
416-
if err != nil {
417-
return // Skip over this entry
418-
}
419-
if !fs.fp.isAbs(link) {
420-
link = fs.fp.join([]string{dir, link})
421-
}
422-
symlink = fs.fp.clean(link)
408+
link, err := fs.fp.evalSymlinks(entryPath)
409+
if err != nil {
410+
return // Skip over this entry
411+
}
423412

424-
// Re-run "lstat" on the symlink target
425-
stat2, err2 := os.Lstat(symlink)
426-
if err2 != nil {
427-
return // Skip over this entry
428-
}
429-
mode = stat2.Mode()
430-
if (mode & os.ModeSymlink) == 0 {
431-
break
432-
}
433-
dir = fs.fp.dir(symlink)
413+
// Re-run "lstat" on the symlink target to see if it's a file or not
414+
stat2, err2 := os.Lstat(link)
415+
if err2 != nil {
416+
return // Skip over this entry
417+
}
418+
mode = stat2.Mode()
419+
if (mode & os.ModeSymlink) != 0 {
420+
return // This should no longer be a symlink, so this is unexpected
434421
}
422+
symlink = link
435423
}
436424

437425
// We consider the entry either a directory or a file

scripts/end-to-end-tests.js

+16
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,22 @@ if (process.platform !== 'win32') {
441441
export function fn() { return foo(); }
442442
`,
443443
}),
444+
445+
// These tests are for https://github.com/evanw/esbuild/issues/2773
446+
test(['--bundle', 'in.js', '--outfile=node.js'], {
447+
'in.js': `import {foo} from './baz/bar/foo'; if (foo !== 444) throw 'fail'`,
448+
'foo/index.js': `import {qux} from '../qux'; export const foo = 123 + qux`,
449+
'qux/index.js': `export const qux = 321`,
450+
'bar/foo': { symlink: `../foo` },
451+
'baz/bar': { symlink: `../bar` },
452+
}),
453+
test(['--bundle', 'in.js', '--outfile=node.js'], {
454+
'in.js': `import {foo} from './baz/bar/foo'; if (foo !== 444) throw 'fail'`,
455+
'foo/index.js': `import {qux} from '../qux'; export const foo = 123 + qux`,
456+
'qux/index.js': `export const qux = 321`,
457+
'bar/foo': { symlink: `TEST_DIR_ABS_PATH/foo` },
458+
'baz/bar': { symlink: `TEST_DIR_ABS_PATH/bar` },
459+
}),
444460
)
445461
}
446462

0 commit comments

Comments
 (0)