@@ -70,7 +70,7 @@ public TarFile(Stream fileStream)
7070 }
7171
7272 var record = new TarFileRecord ( hdr , _fileStream . Position ) ;
73- if ( hdr . FileType == UnixFileType . TarEntryLongLink &&
73+ if ( hdr . FileType == TarFileType . TarEntryLongLink &&
7474 hdr . FileName == "././@LongLink" )
7575 {
7676 var buffer = ArrayPool < byte > . Shared . Rent ( checked ( ( int ) hdr . FileLength ) ) ;
@@ -199,6 +199,7 @@ public static IEnumerable<TarFileData> EnumerateFiles(Stream archive)
199199 var hdrBuf = StreamUtilities . GetUninitializedArray < byte > ( 512 ) ;
200200
201201 string long_path = null ;
202+ string long_link_path = null ;
202203
203204 for ( ; ; )
204205 {
@@ -209,12 +210,20 @@ public static IEnumerable<TarFileData> EnumerateFiles(Stream archive)
209210
210211 var hdr = new TarHeader ( hdrBuf ) ;
211212
212- if ( long_path is not null )
213+ if ( long_path is not null
214+ && hdr . FileType is not TarFileType . TarEntryLongLink and not TarFileType . TarEntryLongLinkTarget )
213215 {
214216 hdr . FileName = long_path ;
215217 long_path = null ;
216218 }
217219
220+ if ( long_link_path is not null
221+ && hdr . FileType is not TarFileType . TarEntryLongLink and not TarFileType . TarEntryLongLinkTarget )
222+ {
223+ hdr . LinkName = long_link_path ;
224+ long_link_path = null ;
225+ }
226+
218227 if ( hdr . FileLength == 0 && string . IsNullOrEmpty ( hdr . FileName ) )
219228 {
220229 break ;
@@ -224,7 +233,7 @@ public static IEnumerable<TarFileData> EnumerateFiles(Stream archive)
224233 {
225234 yield return new ( hdr , source : null ) ;
226235 }
227- else if ( hdr . FileType == UnixFileType . TarEntryLongLink &&
236+ else if ( hdr . FileType == TarFileType . TarEntryLongLink &&
228237 hdr . FileName == "././@LongLink" )
229238 {
230239 var data = ArrayPool < byte > . Shared . Rent ( checked ( ( int ) hdr . FileLength ) ) ;
@@ -248,6 +257,30 @@ public static IEnumerable<TarFileData> EnumerateFiles(Stream archive)
248257 break ;
249258 }
250259 }
260+ else if ( hdr . FileType == TarFileType . TarEntryLongLinkTarget &&
261+ hdr . FileName == "././@LongLink" )
262+ {
263+ var data = ArrayPool < byte > . Shared . Rent ( checked ( ( int ) hdr . FileLength ) ) ;
264+ try
265+ {
266+ archive . ReadExactly ( data , 0 , ( int ) hdr . FileLength ) ;
267+
268+ long_link_path = EncodingUtilities
269+ . GetLatin1Encoding ( )
270+ . GetString ( TarHeader . ReadNullTerminatedString ( data . AsSpan ( 0 , ( int ) hdr . FileLength ) ) ) ;
271+ }
272+ finally
273+ {
274+ ArrayPool < byte > . Shared . Return ( data ) ;
275+ }
276+
277+ var moveForward = ( int ) ( - ( hdr . FileLength & 511 ) & 511 ) ;
278+
279+ if ( archive . ReadMaximum ( hdrBuf , 0 , moveForward ) < moveForward )
280+ {
281+ break ;
282+ }
283+ }
251284 else if ( archive . CanSeek )
252285 {
253286 var location = archive . Position ;
@@ -300,22 +333,33 @@ public static async IAsyncEnumerable<TarFileData> EnumerateFilesAsync(Stream arc
300333 var hdrBuf = StreamUtilities . GetUninitializedArray < byte > ( 512 ) ;
301334
302335 string long_path = null ;
336+ string long_link_path = null ;
303337
304338 for ( ; ; )
305339 {
340+ cancellationToken . ThrowIfCancellationRequested ( ) ;
341+
306342 if ( await archive . ReadMaximumAsync ( hdrBuf . AsMemory ( 0 , 512 ) , cancellationToken ) . ConfigureAwait ( false ) < 512 )
307343 {
308344 break ;
309345 }
310346
311347 var hdr = new TarHeader ( hdrBuf ) ;
312348
313- if ( long_path is not null )
349+ if ( long_path is not null
350+ && hdr . FileType is not TarFileType . TarEntryLongLink and not TarFileType . TarEntryLongLinkTarget )
314351 {
315352 hdr . FileName = long_path ;
316353 long_path = null ;
317354 }
318355
356+ if ( long_link_path is not null
357+ && hdr . FileType is not TarFileType . TarEntryLongLink and not TarFileType . TarEntryLongLinkTarget )
358+ {
359+ hdr . LinkName = long_link_path ;
360+ long_link_path = null ;
361+ }
362+
319363 if ( hdr . FileLength == 0 && string . IsNullOrEmpty ( hdr . FileName ) )
320364 {
321365 break ;
@@ -325,7 +369,7 @@ public static async IAsyncEnumerable<TarFileData> EnumerateFilesAsync(Stream arc
325369 {
326370 yield return new ( hdr , source : null ) ;
327371 }
328- else if ( hdr . FileType == UnixFileType . TarEntryLongLink &&
372+ else if ( hdr . FileType == TarFileType . TarEntryLongLink &&
329373 hdr . FileName == "././@LongLink" )
330374 {
331375 var data = ArrayPool < byte > . Shared . Rent ( checked ( ( int ) hdr . FileLength ) ) ;
@@ -349,6 +393,30 @@ public static async IAsyncEnumerable<TarFileData> EnumerateFilesAsync(Stream arc
349393 break ;
350394 }
351395 }
396+ else if ( hdr . FileType == TarFileType . TarEntryLongLinkTarget &&
397+ hdr . FileName == "././@LongLink" )
398+ {
399+ var data = ArrayPool < byte > . Shared . Rent ( checked ( ( int ) hdr . FileLength ) ) ;
400+ try
401+ {
402+ await archive . ReadExactlyAsync ( data . AsMemory ( 0 , ( int ) hdr . FileLength ) , cancellationToken ) . ConfigureAwait ( false ) ;
403+
404+ long_link_path = EncodingUtilities
405+ . GetLatin1Encoding ( )
406+ . GetString ( TarHeader . ReadNullTerminatedString ( data . AsSpan ( 0 , ( int ) hdr . FileLength ) ) ) ;
407+ }
408+ finally
409+ {
410+ ArrayPool < byte > . Shared . Return ( data ) ;
411+ }
412+
413+ var moveForward = ( int ) ( - ( hdr . FileLength & 511 ) & 511 ) ;
414+
415+ if ( await archive . ReadMaximumAsync ( hdrBuf . AsMemory ( 0 , moveForward ) , cancellationToken ) . ConfigureAwait ( false ) < moveForward )
416+ {
417+ break ;
418+ }
419+ }
352420 else if ( archive . CanSeek )
353421 {
354422 var location = archive . Position ;
@@ -378,7 +446,7 @@ public static async IAsyncEnumerable<TarFileData> EnumerateFilesAsync(Stream arc
378446 {
379447 var data = StreamUtilities . GetUninitializedArray < byte > ( ( int ) hdr . FileLength ) ;
380448
381- await archive . ReadExactlyAsync ( data , cancellationToken ) . ConfigureAwait ( false ) ;
449+ await archive . ReadExactlyAsync ( data . AsMemory ( 0 , data . Length ) , cancellationToken ) . ConfigureAwait ( false ) ;
382450
383451 datastream = new MemoryStream ( data , writable : false ) ;
384452 }
0 commit comments