@@ -39,6 +39,14 @@ import {
39
39
import { readAll } from "../streams/read_all.ts" ;
40
40
import type { Reader } from "../types.d.ts" ;
41
41
42
+ /**
43
+ * Extend TarMeta with the `linkName` property so that readers can access
44
+ * symbolic link values without polluting the world of archive writers.
45
+ */
46
+ export interface TarMetaWithLinkName extends TarMeta {
47
+ linkName ?: string ;
48
+ }
49
+
42
50
export interface TarHeader {
43
51
[ key : string ] : Uint8Array ;
44
52
}
@@ -73,7 +81,7 @@ function parseHeader(buffer: Uint8Array): { [key: string]: Uint8Array } {
73
81
}
74
82
75
83
// deno-lint-ignore no-empty-interface
76
- export interface TarEntry extends TarMeta { }
84
+ export interface TarEntry extends TarMetaWithLinkName { }
77
85
78
86
export class TarEntry implements Reader {
79
87
#header: TarHeader ;
@@ -83,7 +91,7 @@ export class TarEntry implements Reader {
83
91
#consumed = false ;
84
92
#entrySize: number ;
85
93
constructor (
86
- meta : TarMeta ,
94
+ meta : TarMetaWithLinkName ,
87
95
header : TarHeader ,
88
96
reader : Reader | ( Reader & Deno . Seeker ) ,
89
97
) {
@@ -244,22 +252,19 @@ export class Untar {
244
252
return header ;
245
253
}
246
254
247
- #getMetadata( header : TarHeader ) : TarMeta {
255
+ #getMetadata( header : TarHeader ) : TarMetaWithLinkName {
248
256
const decoder = new TextDecoder ( ) ;
249
257
// get meta data
250
- const meta : TarMeta = {
258
+ const meta : TarMetaWithLinkName = {
251
259
fileName : decoder . decode ( trim ( header . fileName ) ) ,
252
260
} ;
253
261
const fileNamePrefix = trim ( header . fileNamePrefix ) ;
254
262
if ( fileNamePrefix . byteLength > 0 ) {
255
263
meta . fileName = decoder . decode ( fileNamePrefix ) + "/" + meta . fileName ;
256
264
}
257
- ( [ "fileMode" , "mtime" , "uid" , "gid" ] as [
258
- "fileMode" ,
259
- "mtime" ,
260
- "uid" ,
261
- "gid" ,
262
- ] ) . forEach ( ( key ) => {
265
+ (
266
+ [ "fileMode" , "mtime" , "uid" , "gid" ] as [ "fileMode" , "mtime" , "uid" , "gid" ]
267
+ ) . forEach ( ( key ) => {
263
268
const arr = trim ( header [ key ] ) ;
264
269
if ( arr . byteLength > 0 ) {
265
270
meta [ key ] = parseInt ( decoder . decode ( arr ) , 8 ) ;
@@ -277,6 +282,12 @@ export class Untar {
277
282
meta . fileSize = parseInt ( decoder . decode ( header . fileSize ) , 8 ) ;
278
283
meta . type = FileTypes [ parseInt ( meta . type ! ) ] ?? meta . type ;
279
284
285
+ // Only create the `linkName` property for symbolic links to minimize
286
+ // the effect on existing code that only deals with non-links.
287
+ if ( meta . type === "symlink" ) {
288
+ meta . linkName = decoder . decode ( trim ( header . linkName ) ) ;
289
+ }
290
+
280
291
return meta ;
281
292
}
282
293
0 commit comments