Light-Untar-for-iOS icon indicating copy to clipboard operation
Light-Untar-for-iOS copied to clipboard

Tar file with two files decompresses into four files

Open lloydsargent opened this issue 11 years ago • 2 comments

The two bogus files have the same names but start with "._"

So listing the directory what I see is:

._FirstFile.ext
._SecondFile.ext
FirstFile.ext
SecondFile.ext

Oddly it didn't happen with a tar with 32 files in it. The only thing that is different is that this file had French names (which shouldn't have mattered).

Stepping through your code I can see it breaking and creating the files with ._

I just decompressed the tar file and there are only two files. I'm at my wits end.

lloydsargent avatar Jul 29 '13 00:07 lloydsargent

Okay, I've discovered the issue. It appears your code does not handle extended attributes. As such, they end up appearing as separate files when you untar.

Another solution is to use the following when creating the tar file:

COPYFILE_DISABLE=1 tar -cf MyTarFile.tar files*

However this assumes that the user will remember to do this every time. Perhaps a better solution (not great, but better) is to discard files that start with "._" as it appears it is impossible to put such a file in a tar (interesting).

How To Duplicate My Results

  • In the terminal type the following: mkdir MyTar

  • cd to MyTar

  • Create two dummy files (FirstFile.ext and SecondFile.ext).

  • Add attributes using the following line: xattr -w com.apple.metadata:MyAttribute FirstFile.ext

    xattr -w com.apple.metadata:MyAttribute SecondFile.ext

  • cd ..

  • tar -cf MyTar.tar MyTar

You now have a tar file that has four items in it, two of which are extended attributes.

lloydsargent avatar Jul 29 '13 15:07 lloydsargent

Here is my solution. I don't guarantee it being a great solution, but it appears to solve my immediate problem.

Okay, in createFilesAndDirectoriesAtPath:withTarObject:size:error: I modified the code by adding:

if (![[name lastPathComponent] hasPrefix: @"._"])

See below:

case '0': // It's a File
{
    NSString *name = [NSFileManager nameForObject:object atOffset:location];
#ifdef TAR_VERBOSE_LOG_MODE
    NSLog(@"UNTAR - file - %@", name);
#endif
    NSString *filePath = [path stringByAppendingPathComponent:name]; // Create a full path from the name

    unsigned long long size = [NSFileManager sizeForObject:object atOffset:location];

    if (size == 0) {
#ifdef TAR_VERBOSE_LOG_MODE
        NSLog(@"UNTAR - empty_file - %@", filePath);
#endif
        [@"" writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:error];
        break;
    }

    blockCount += (size - 1) / TAR_BLOCK_SIZE + 1; // size/TAR_BLOCK_SIZE rounded up

    // [self writeFileDataForObject:object inRange:NSMakeRange(location+TAR_BLOCK_SIZE, size) atPath:filePath];
    if (![[name lastPathComponent] hasPrefix: @"._"])  //// **ADDED THIS LINE**
       [self writeFileDataForObject:object atLocation:(location + TAR_BLOCK_SIZE) withLength:size atPath:filePath];
    break;
}

Note that it appears ONLY bsdtar allows extended attributes. So if you were using gnutar you probably didn't see this problem.

lloydsargent avatar Jul 29 '13 16:07 lloydsargent