Неожиданный конец файла в файле tar.gz - PullRequest
0 голосов
/ 23 сентября 2019

Я хочу подписать файл tar.gz и проверить подпись, для этого я помещаю подпись (в символ) в свой файл.Затем у меня есть другой исполняемый файл, который проверяет знак и, если она в порядке, удаляет это, и для этого я получаю содержимое файла без моей подписи и копирую в другой файл, который создает.

Но здесьпроблема, когда я делаю это, мой оригинальный файл tar.gz имеет размер 141, а мой вновь созданный файл - 140. Затем, когда они распаковываются, у меня появляется следующее сообщение об ошибке:

gzip: stdin: неожиданный конец файла tar:

Дочерний элемент вернул статус 1 tar:

Ошибка не может быть исправлена: выход из сейчас

Я думаю, когда получаюсодержание я забыл персонажа.Я попытался использовать clearerr или feof whitout success.

Это мой код для получения содержимого подписанного файла:

#define SIZE_SIGNATURE (423)

int get_size(char *file)
{
  struct stat sb;
  int size = 0;

  if (stat(file, &sb) == -1) {
    fprintf(stderr, "Cant access the %s file\n", file);
    return (-1);
  }
  size = sb.st_size - SIZE_SIGNATURE;
  size = size / 4;
  if (size <= 0) {
    fprintf(stderr, "The content of the file is invalid\n");
    return (-1);
  }
  return (size);
}


int *get_content(char *file, int size)
{
  FILE *fp = NULL;
  int *content = NULL;
  int i = 0;

  content = malloc(sizeof(int) * size);
  if (!content) {
    fprintf(stderr, "Error, malloc fail\n");
    return (NULL);
  }
  fp = fopen(file,"rb");
  if (!fp) {
    fprintf(stderr, "Cant open %s file\n", file);
    return (NULL);
  }
  fread(content, sizeof(int), size, fp);
  fclose(fp);
  return (content);
}

И когда я создал свой новый файл, я поместил содержимоена них вот так:

 fp = fopen(new_name, "a");
  if (!fp) {
    fprintf(stderr, "A problem has occured during file creation.\n Cant delete signature\n");
    free(new_name);
    return;
  }
  fwrite(content, sizeof(int), size, fp);

Почему я это делаю: размер = размер / 4 (я не знаю, стоит ли это делать)

Он небольшой код для понимания того, что яПроще говоря, три int в неотмечаемом символе

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

void ecriture1()
{
  FILE* F;
  int a = 5;
  int b = 6;
  int d = 42;

  F = fopen("test.bin","wb");
  fwrite(&a,sizeof(int),1,F);
  fwrite(&d,sizeof(int),1,F);
  fwrite(&b,sizeof(int),1,F);
  fclose(F);
}

void lecture1()
{
  int *tab;
  int i = 0;
  int size;
  struct stat sb;
  FILE* F;

  stat("test.bin", &sb);
  F = fopen("test.bin","rb");
  size = sb.st_size;
  tab = malloc(sizeof(int) * size);
  while (i < size) {
    fread(&tab[i], sizeof(int), 1, F);
    i++;
  }
 for (i = 0; i < size; i++)
    printf("[i] = %d,", tab[i]);
 printf("\n");
 fclose(F);
}

int main()
{
  ecriture1();
  lecture1();
  return 0;
}

Он является результатом, когда я не помещаю / 4:

[i] = 5, [i] = 42,[i] = 6, [i] = 0, [i] = 0, [i] = 0, [i] = 0, [i] = 0, [i] = 0, [i] = 0, [i] = 0, [i] = 0,

И когда я ставлю / 4:

[i] = 5, [i] = 42, [i]= 6,

РЕДАКТИРОВАТЬ:

В моей программе, когда я удаляю / 4 и декомпрессирую новый .tar.gz, у меня появляется это сообщение об ошибке:

gzip: stdin: недопустимые сжатые данные - ошибка длины

tar: дочерний возвращенный статус 1

tar: ошибка не может быть исправлена: выход сейчас

Так что я думаю, что тыОшибка с моей стороны, что я должен поставить / 4, но я не могу объяснить это.

1 Ответ

1 голос
/ 23 сентября 2019

У вас есть ошибка округления, потому что вы делите размер на 4.

Я думаю, что причина, по которой вы делаете size / 4, заключается в том, что позже вы делаете sizeof(int) * size, и если у вас есть 4-байтовые целые числа, тогда это будетзаставьте ваш размер быть в 4 раза больше, чем вы хотите.Поэтому я думаю, что вы написали там две ошибки, которые уничтожают друг друга.

Я бы посоветовал вам удалить / 4, а также удалить sizeof(int) * и, таким образом, всегда просто позволять size быть числом байтов.

В качестве бонуса это устранит возможную ошибку округления, которая, вероятно, является полной причиной вашей проблемы.Потому что 141/4 = 35,25, который будет округлен до 35.Тогда 35 * sizeof(int) = 35 * 4 = 140.

Также я бы не рекомендовал хранить произвольные двоичные данные произвольного размера в массиве int, потому что массив int должен иметь размер, равномерно делимый на 4. Я бы, вероятно, пошел наchar * или просто void *, а не int *.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...