libarchive читает слишком много символов при извлечении файла - PullRequest
3 голосов
/ 21 мая 2010

Я написал программу на C для извлечения файлов из архива tar с использованием libarchive.

Я бы хотел извлечь файл из этого архива и распечатать его на стандартный вывод. Но я получаю дополнительные символы . Это мусор, но это из другого файла (возможно, рядом с ним в архиве.) Я ожидаю, что вывод закончится на </html>.

Вот код, который читает этот tar-файл :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "archive.h"
#include "archive_entry.h"


int main (int argc, const char * argv[]) 
{
    struct archive *a;
    struct archive_entry *entry;
    int r;
    int64_t entry_size;
    a = archive_read_new();
    archive_read_support_compression_none(a);
    archive_read_support_format_tar(a);
    r = archive_read_open_filename(a, "0000.tar", 1024);
    if (r != ARCHIVE_OK)
    {
        printf("archive not found");
    }
    else 
    {
        while (archive_read_next_header(a, &entry) == ARCHIVE_OK) 
        {
            const char *currentFile = archive_entry_pathname(entry);
            char *fileContents;
            entry_size = archive_entry_size(entry); //get the size of the file
            fileContents = malloc(entry_size); //alloc enough for string - from my testing I see that this is how many bytes tar and ls report from command line
            archive_read_data(a, fileContents, entry_size); //read data into fileContents string for the HTML file size
            if(strcmp(currentFile, "vendar-definition.html") == 0)
            {
                printf("file name = %s, size = %lld\n", currentFile, entry_size);
                printf("%s\n\n", fileContents); //this output over-reads chars from another file in this tar file
            }           
            free(fileContents); //free the C string because I malloc'd
        }
    }
    printf("exit");
    return 0;
}

libarchive 2.8.3 скомпилировано на Mac OS X 10.6.3. gcc 4.2 x86_64

ls -l vendar-definition.html дает мне 1921 для размера файла. И так показывает tar tfv 0000.tar | grep vendar-definition.html. Поэтому сообщает о выходе C, в котором указывается размер файла. Мне это кажется правильным.

Я вижу две возможности, почему мой вывод не соответствует ожиданиям:

  1. Я сделал ошибку новичка или
  2. многобайтовые символы в файлах архива как-то связаны с этим.

Ответы [ 2 ]

2 голосов
/ 21 мая 2010

Я могу быть очень неправильно, но это не похоже на строку с нулем в конце (я не думаю, что archive_read_data позаботится об этом) Добавьте символ NULL или посмотрите this и расскажите нам, как это происходит.

1 голос
/ 21 мая 2010

Я подозреваю, что вы не читаете слишком много символов, но только печатаете слишком много.

Вы выводите содержимое файла, используя спецификатор %s в printf, что предполагает, что ввод будет строкой с нулевым символом в конце. Содержимое файла в архиве не может заканчиваться нулем и может содержать произвольные нули в середине.

Попробуйте вместо этого вывести:

fwrite(fileContents, sizeof(char), entry_size, stdout);
...