-
-
Notifications
You must be signed in to change notification settings - Fork 45
Reject symbolic links in build zip path #538
Changes from all commits
dd4beb0
0345733
5b73ad6
2d60d05
cfdef20
ae69aae
32a2a10
f118e75
21f4e2a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,7 +28,7 @@ | |
|
|
||
| import type { BuildCredentials, BuildOptionsPayload, BuildRequestOptions, BuildRequestResult } from '../schemas/build' | ||
| import { Buffer } from 'node:buffer' | ||
| import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs' | ||
| import { existsSync, lstatSync, readdirSync, readFileSync, statSync } from 'node:fs' | ||
| import { mkdir, readFile as readFileAsync, rm, stat, writeFile } from 'node:fs/promises' | ||
| import { tmpdir } from 'node:os' | ||
| import { basename, join, resolve } from 'node:path' | ||
|
|
@@ -707,7 +707,29 @@ function addDirectoryToZip( | |
| for (const item of items) { | ||
| const itemPath = join(dirPath, item) | ||
| const itemZipPath = zipPath ? `${zipPath}/${item}` : item | ||
| const stats = statSync(itemPath) | ||
| const lstats = lstatSync(itemPath) | ||
| const isSymbolicLink = lstats.isSymbolicLink() | ||
| let stats = lstats | ||
|
|
||
| if (isSymbolicLink) { | ||
| try { | ||
| stats = statSync(itemPath) | ||
| } | ||
| catch (error) { | ||
| const code = (error as NodeJS.ErrnoException).code | ||
| if (code === 'ENOENT' || code === 'ENOTDIR') { | ||
| // Broken symlink: skip gracefully to avoid failing the whole zip. | ||
| continue | ||
| } | ||
| throw error | ||
| } | ||
| } | ||
|
Comment on lines
+866
to
+878
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Keep followed symlinks inside Once the symlink branch resolves successfully, the later recursion walks whatever target it points to. A repo can hang Also applies to: 905-961 🤖 Prompt for AI Agents |
||
| const shouldInclude = shouldIncludeFile( | ||
| itemZipPath, | ||
| platform, | ||
| nativeDeps, | ||
| platformDir, | ||
| ) | ||
|
|
||
| if (stats.isDirectory()) { | ||
| // Skip excluded directories | ||
|
|
@@ -735,7 +757,7 @@ function addDirectoryToZip( | |
| // 1. This directory itself should be included (matches a pattern) | ||
| // 2. This directory is a prefix of a dependency path (need to traverse to reach it) | ||
| const normalizedItemPath = itemZipPath.replace(/\\/g, '/') | ||
| const shouldRecurse = shouldIncludeFile(itemZipPath, platform, nativeDeps, platformDir) | ||
| const shouldRecurse = shouldInclude | ||
| // Ensure we can reach nested platform directories like projects/app/android. | ||
| || platformDir === normalizedItemPath | ||
| || platformDir.startsWith(`${normalizedItemPath}/`) | ||
|
|
@@ -744,17 +766,24 @@ function addDirectoryToZip( | |
| return depPath.startsWith(`${normalizedItemPath}/`) || normalizedItemPath.startsWith(`node_modules/${pkg}`) | ||
| }) | ||
|
|
||
| // Skip unrelated symlinks instead of failing hard. | ||
| if (isSymbolicLink && !shouldRecurse) | ||
| continue | ||
|
|
||
| if (shouldRecurse) { | ||
| addDirectoryToZip(zip, itemPath, itemZipPath, platform, nativeDeps, platformDir) | ||
| } | ||
| } | ||
| else if (stats.isFile()) { | ||
| if (isSymbolicLink) | ||
| continue | ||
|
Comment on lines
+778
to
+779
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This unconditional skip regresses projects that share build-critical files via symlink. Useful? React with 👍 / 👎. |
||
|
|
||
| // Skip excluded files | ||
| if (item === '.DS_Store' || item.endsWith('.log')) | ||
| continue | ||
|
|
||
| // Check if we should include this file | ||
| if (shouldIncludeFile(itemZipPath, platform, nativeDeps, platformDir)) { | ||
| if (shouldInclude) { | ||
| zip.addLocalFile(itemPath, zipPath || undefined) | ||
| } | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.