在以相反顺序比较文件时查找特殊情况

时间:2016-10-29 20:53:33

标签: c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BS 12

void reverse(char * buffer, int size)
{
  char tmp;
  int i;
  for(i = 0; i < size / 2; i++)
  {
    tmp = (char)buffer[i];
    buffer[i] = buffer[size - i - 1];
    buffer[size - i - 1] = tmp;
  }
}

int compare_bin(char * buffer, char * buffer2, int size)
{
  // because strncmp is only for string without \x00, so there must be a customized compare function
  int i;
  for(i = 0; i < size; i++)
  {
    if(buffer[i] != buffer2[i])
      return 0;
  }
  return 1;
}

int main (const int argc, const char** argv)
{
  if(argc != 3)
    exit(-1);

  int equal = 1;
  char * buffer = malloc(BS), * buffer2 = malloc(BS);
  FILE * f1, * f2;
  f1 = fopen(argv[1], "r");
  f2 = fopen(argv[2], "r");

  fseek(f1, 0, SEEK_END);
  fseek(f2, 0, SEEK_END);

  long i = ftell(f1), j = ftell(f2);
  if(i != j)
  {
    equal = 0;
    goto endp;
  }

  fseek(f2, 0, SEEK_SET);

  int need = 0;
  int count;
  int f2_pos = 0;

  do
  {
    i = i - BS;
    if(i < 0)
    {
      need = BS - abs((int)i);
      i = 0;
    }
    else
      need = BS;

    fseek(f1, i, SEEK_SET);
    count = fread(buffer, need, 1, f1);

    reverse(buffer, count * need);
    // fwrite(buffer, count * need, 1, f2);
    fread(buffer2, need * need, 1, f2);

    // printf("compare...\n");
    // for(int i = 0; i < need * count; i++)
    // {
    //   printf("%02hhX", buffer[i]);
    // }
    // printf("\n");
    // for (int i = 0; i < need * count; i++)
    // {
    //   printf("%02hhX", buffer2[i]);
    // }
    // printf("\n");


    if(compare_bin(buffer, buffer2, need * count) == 0)
    {
      equal = 0;
      break;
    }

    f2_pos += need * count;
    fseek(f2, f2_pos, SEEK_SET);

    if(i == 0)
      break;
  }while(i > 0);

  fclose(f1);
  fclose(f2);
  free(buffer);
  free(buffer2);

  endp:
  if(equal)
    return 0;
  else
  {
    printf("2 files not equal is reversed order\n");
    return 1;
  }

  return 0;
}

所以我编写了一个程序,以相反的顺序比较文件内容。我已经在二进制文件中考虑了\x00,并且未使用strncmp。但仍有缺陷。有一个测试服务器来测试这个程序。但我无法访问它。该程序始终在该服务器上失败。因此必须有一些特殊情况才能使其失败。任何的想法?

还有其他方法。例如,计算MD5。但我想解决这个问题。

1 个答案:

答案 0 :(得分:1)

在您阅读数据的第一次迭代中

fread(buffer2, need * need, 1, f2);

问题是,在这种情况下need12,这是为buffer2分配的内存大小,但是您要求读取12 * 12个字节。< / p>

如果第二个文件足够大,您将在内存中写出越界,导致未定义的行为。如果文件足够大,那么你将不会阅读任何内容。

另请注意,fread的两个中间参数的顺序很重要。如果你改变了顺序,那么如果文件大于need * need,你就会写出超出缓冲区的范围。你应该真正阅读count字节大小的对象(第二个参数应该是1而第三个应该是count,这当然意味着你需要在第一次调用时更改顺序孔)。

简而言之,您的两个fread来电应该是

count = fread(buffer, 1, BS, f1);
fread(buffer2, 1, count, f2);

PS。不要忘记错误检查。