Skip to content

Commit 164c355

Browse files
committed
1 parent a74a19c commit 164c355

7 files changed

Lines changed: 96 additions & 28 deletions

File tree

node_modules/tar/dist/commonjs/pack.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ const ONDRAIN = Symbol('ondrain');
9191
const path_1 = __importDefault(require("path"));
9292
const normalize_windows_path_js_1 = require("./normalize-windows-path.js");
9393
class Pack extends minipass_1.Minipass {
94+
sync = false;
9495
opt;
9596
cwd;
9697
maxReadSize;
@@ -279,6 +280,17 @@ class Pack extends minipass_1.Minipass {
279280
if (!this.filter(job.path, stat)) {
280281
job.ignore = true;
281282
}
283+
else if (stat.isFile() &&
284+
stat.nlink > 1 &&
285+
job === this[CURRENT] &&
286+
!this.linkCache.get(`${stat.dev}:${stat.ino}`) &&
287+
!this.sync) {
288+
// if it's not filtered, and it's a new File entry,
289+
// jump the queue in case any pending Link entries are about
290+
// to try to link to it. This prevents a hardlink from coming ahead
291+
// of its target in the archive.
292+
this[PROCESSJOB](job);
293+
}
282294
this[PROCESS]();
283295
}
284296
[READDIR](job) {

node_modules/tar/dist/commonjs/unpack.js

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -253,28 +253,50 @@ class Unpack extends parse_js_1.Parser {
253253
// return false if we need to skip this file
254254
// return true if the field was successfully sanitized
255255
[STRIPABSOLUTEPATH](entry, field) {
256-
const path = entry[field];
257-
if (!path || this.preservePaths)
256+
const p = entry[field];
257+
const { type } = entry;
258+
if (!p || this.preservePaths)
258259
return true;
259-
const parts = path.split('/');
260+
const parts = p.split('/');
260261
if (parts.includes('..') ||
261262
/* c8 ignore next */
262263
(isWindows && /^[a-z]:\.\.$/i.test(parts[0] ?? ''))) {
263-
this.warn('TAR_ENTRY_ERROR', `${field} contains '..'`, {
264-
entry,
265-
[field]: path,
266-
});
267-
// not ok!
268-
return false;
264+
// For linkpath, check if the resolved path escapes cwd rather than
265+
// just rejecting any path with '..' - relative symlinks like
266+
// '../sibling/file' are valid if they resolve within the cwd.
267+
// For paths, they just simply may not ever use .. at all.
268+
if (field === 'path' || type === 'Link') {
269+
this.warn('TAR_ENTRY_ERROR', `${field} contains '..'`, {
270+
entry,
271+
[field]: p,
272+
});
273+
// not ok!
274+
return false;
275+
}
276+
else {
277+
// Resolve linkpath relative to the entry's directory.
278+
// `path.posix` is safe to use because we're operating on
279+
// tar paths, not a filesystem.
280+
const entryDir = node_path_1.default.posix.dirname(entry.path);
281+
const resolved = node_path_1.default.posix.normalize(node_path_1.default.posix.join(entryDir, p));
282+
// If the resolved path escapes (starts with ..), reject it
283+
if (resolved.startsWith('../') || resolved === '..') {
284+
this.warn('TAR_ENTRY_ERROR', `${field} escapes extraction directory`, {
285+
entry,
286+
[field]: p,
287+
});
288+
return false;
289+
}
290+
}
269291
}
270292
// strip off the root
271-
const [root, stripped] = (0, strip_absolute_path_js_1.stripAbsolutePath)(path);
293+
const [root, stripped] = (0, strip_absolute_path_js_1.stripAbsolutePath)(p);
272294
if (root) {
273295
// ok, but triggers warning about stripping root
274296
entry[field] = String(stripped);
275297
this.warn('TAR_ENTRY_INFO', `stripping ${root} from absolute ${field}`, {
276298
entry,
277-
[field]: path,
299+
[field]: p,
278300
});
279301
}
280302
return true;

node_modules/tar/dist/esm/pack.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ const ONDRAIN = Symbol('ondrain');
5151
import path from 'path';
5252
import { normalizeWindowsPath } from './normalize-windows-path.js';
5353
export class Pack extends Minipass {
54+
sync = false;
5455
opt;
5556
cwd;
5657
maxReadSize;
@@ -239,6 +240,17 @@ export class Pack extends Minipass {
239240
if (!this.filter(job.path, stat)) {
240241
job.ignore = true;
241242
}
243+
else if (stat.isFile() &&
244+
stat.nlink > 1 &&
245+
job === this[CURRENT] &&
246+
!this.linkCache.get(`${stat.dev}:${stat.ino}`) &&
247+
!this.sync) {
248+
// if it's not filtered, and it's a new File entry,
249+
// jump the queue in case any pending Link entries are about
250+
// to try to link to it. This prevents a hardlink from coming ahead
251+
// of its target in the archive.
252+
this[PROCESSJOB](job);
253+
}
242254
this[PROCESS]();
243255
}
244256
[READDIR](job) {

node_modules/tar/dist/esm/unpack.js

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -214,28 +214,50 @@ export class Unpack extends Parser {
214214
// return false if we need to skip this file
215215
// return true if the field was successfully sanitized
216216
[STRIPABSOLUTEPATH](entry, field) {
217-
const path = entry[field];
218-
if (!path || this.preservePaths)
217+
const p = entry[field];
218+
const { type } = entry;
219+
if (!p || this.preservePaths)
219220
return true;
220-
const parts = path.split('/');
221+
const parts = p.split('/');
221222
if (parts.includes('..') ||
222223
/* c8 ignore next */
223224
(isWindows && /^[a-z]:\.\.$/i.test(parts[0] ?? ''))) {
224-
this.warn('TAR_ENTRY_ERROR', `${field} contains '..'`, {
225-
entry,
226-
[field]: path,
227-
});
228-
// not ok!
229-
return false;
225+
// For linkpath, check if the resolved path escapes cwd rather than
226+
// just rejecting any path with '..' - relative symlinks like
227+
// '../sibling/file' are valid if they resolve within the cwd.
228+
// For paths, they just simply may not ever use .. at all.
229+
if (field === 'path' || type === 'Link') {
230+
this.warn('TAR_ENTRY_ERROR', `${field} contains '..'`, {
231+
entry,
232+
[field]: p,
233+
});
234+
// not ok!
235+
return false;
236+
}
237+
else {
238+
// Resolve linkpath relative to the entry's directory.
239+
// `path.posix` is safe to use because we're operating on
240+
// tar paths, not a filesystem.
241+
const entryDir = path.posix.dirname(entry.path);
242+
const resolved = path.posix.normalize(path.posix.join(entryDir, p));
243+
// If the resolved path escapes (starts with ..), reject it
244+
if (resolved.startsWith('../') || resolved === '..') {
245+
this.warn('TAR_ENTRY_ERROR', `${field} escapes extraction directory`, {
246+
entry,
247+
[field]: p,
248+
});
249+
return false;
250+
}
251+
}
230252
}
231253
// strip off the root
232-
const [root, stripped] = stripAbsolutePath(path);
254+
const [root, stripped] = stripAbsolutePath(p);
233255
if (root) {
234256
// ok, but triggers warning about stripping root
235257
entry[field] = String(stripped);
236258
this.warn('TAR_ENTRY_INFO', `stripping ${root} from absolute ${field}`, {
237259
entry,
238-
[field]: path,
260+
[field]: p,
239261
});
240262
}
241263
return true;

node_modules/tar/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"author": "Isaac Z. Schlueter",
33
"name": "tar",
44
"description": "tar for node",
5-
"version": "7.5.4",
5+
"version": "7.5.7",
66
"repository": {
77
"type": "git",
88
"url": "https://github.com/isaacs/node-tar.git"

package-lock.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@
144144
"spdx-expression-parse": "^4.0.0",
145145
"ssri": "^13.0.0",
146146
"supports-color": "^10.2.2",
147-
"tar": "^7.5.4",
147+
"tar": "^7.5.7",
148148
"text-table": "~0.2.0",
149149
"tiny-relative-date": "^2.0.2",
150150
"treeverse": "^3.0.0",
@@ -13456,9 +13456,9 @@
1345613456
}
1345713457
},
1345813458
"node_modules/tar": {
13459-
"version": "7.5.4",
13460-
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.4.tgz",
13461-
"integrity": "sha512-AN04xbWGrSTDmVwlI4/GTlIIwMFk/XEv7uL8aa57zuvRy6s4hdBed+lVq2fAZ89XDa7Us3ANXcE3Tvqvja1kTA==",
13459+
"version": "7.5.7",
13460+
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.7.tgz",
13461+
"integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==",
1346213462
"inBundle": true,
1346313463
"license": "BlueOak-1.0.0",
1346413464
"dependencies": {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@
111111
"spdx-expression-parse": "^4.0.0",
112112
"ssri": "^13.0.0",
113113
"supports-color": "^10.2.2",
114-
"tar": "^7.5.4",
114+
"tar": "^7.5.7",
115115
"text-table": "~0.2.0",
116116
"tiny-relative-date": "^2.0.2",
117117
"treeverse": "^3.0.0",

0 commit comments

Comments
 (0)