Reputation: 41
This is my program to compress data (it is free but has copyright for commercial usage) . This program suppose to read a file as data-number and find a huge nth root of file (depending on file size) and write as root to exponent and also find the remain numbers and write it to the file for compression (for decompression, it does the reverse). But this code I wrote, writes excessive useless and even weird data in them :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <gmp.h>
int main(void)
{
FILE * fr, * fw;
char input[201];
char output[201];
unsigned long int size = 0;
unsigned long int rt;
unsigned char ch[5] = {112,111,119,101,114};
unsigned char plus[4]={112,108,117,115};
printf("Enter filename : ");
char * r1;
r1 = fgets(input, 200, stdin);
input[strcspn(input, "\r\n")] = 0;
printf("%s\n", r1);
fr = fopen(input, "rb");
if (fr == NULL)
{
fprintf(stderr, "Error during opening of file %s\n", input);
perror("");
return 1;
}
fseek(fr, 0L, SEEK_END);
size = ftell(fr);
fseek(fr, 0L, SEEK_SET);
if (size == -1)
{
fprintf(stderr, "Size doesn't match\n'");
perror("");
return 1;
}
if ( size > SIZE_MAX)
{
fprintf(stderr, "The size of file is greater than acceptable\n");
perror("");
return 1;
}
unsigned char * buf = NULL;
buf = malloc((size_t)size);
if(buf == NULL)
{
fprintf(stderr, "Buffer failure\n");
perror("");
return 1;
}
int r2;
r2 = fread(buf, size, 1, fr);
printf("%d\n", r2);
if (ferror(fr))
{
fprintf(stderr, "Error during reading from file %s\n", input);
perror("");
fclose(fr);
return 1;
}
fclose(fr);
fr = NULL;
mpz_t x;
mpz_init(x);
mpz_t y;
mpz_init(y);
mpz_import(x, size, 1, (size_t)1u, 0, 0, buf);
if (size<=15)
rt = 1;
else if((size>15)&&(size<=100))
rt = 9;
else if((size>100)&&(size<=1000))
rt = 99;
else if((size>1000)&&(size<=10000))
rt = 999;
else if((size>10000)&&(size<=100000))
rt = 9999;
else if((size>100000)&&(size<=1000000))
rt = 99999;
else if((size>1000000)&&(size<=10000000))
rt = 999999;
else if((size>10000000)&&(size<=100000000))
rt = 9999999;
else
rt = 99999999;
mpz_root (y, x, rt);
mpz_t a;
mpz_init(a);
mpz_t b;
mpz_init(b);
mpz_rootrem (a, b, y, rt);
int rootnum = 0;
unsigned long int num = rt;
do
{
num = num/10;
++rootnum;
}while(num != 0);
printf("\nEnter compressed filename : ");
char * r3;
r3 = fgets(output, 200, stdin);
output[strcspn(output, "\r\n")] = 0;
printf("%s\n", r3);
memset (buf, 0u, size);
mpz_export(buf, NULL, 1, (size_t)1u, 0, 0, y);
fw = fopen(output, "wb");
if (fw == NULL) {
fprintf(stderr, "Error during opening of file %s\n", output);
perror("");
return 1;
}
int w;
w = fwrite(buf, mpz_sizeinbase(y, 10), 1, fw);
printf("%d\n", w);
if (ferror(fw)) {
fprintf(stderr, "Error during writing to file %s\n", output);
perror("");
fclose(fw);
return 1;
}
fclose(fw);
fw = fopen(output, "ab");
if(fw == NULL)
{
printf("File can't be written\n'");
return 1;
}
if(ferror(fw))
{
fprintf(stderr, "Error during writing to file %s\n", output);
perror("");
fclose(fw);
return 1;
}
int w2;
w2 = fwrite(ch, 5, 1, fw);
printf("%d\n", w2);
fclose(fw);
fw = fopen(output, "ab");
if(fw == NULL)
{
printf("File can't be written\n'");
return 1;
}
if(ferror(fw))
{
fprintf(stderr, "Error during writing to file %s\n", output);
perror("");
fclose(fw);
return 1;
}
int w3;
w3 = fwrite(&rt, rootnum, 1, fw);
printf("%d\n", w3);
fclose(fw);
fw = fopen(output, "ab");
if(fw == NULL)
{
printf("File can't be written\n'");
return 1;
}
if(ferror(fw))
{
fprintf(stderr, "Error during writing to file %s\n", output);
perror("");
fclose(fw);
return 1;
}
int w4;
w4 = fwrite(plus, 4, 1, fw);
printf("%d\n", w4);
fclose(fw);
fw = fopen(output, "ab");
if(fw == NULL)
{
printf("File can't be written\n'");
return 1;
}
if(ferror(fw))
{
fprintf(stderr, "Error during writing to file %s\n", output);
perror("");
fclose(fw);
return 1;
}
int w5;
w5 = fwrite(b, mpz_sizeinbase(b, 10), 1, fw);
printf("%d\n", w5);
fclose(fw);
free(buf);
mpz_clear(x);
mpz_clear(y);
mpz_clear(a);
mpz_clear(b);
return 0;
}
I wrote minimal code and everyone said I must check every reading and writing functions . This is the whole program ...
This is a file compressed from Alizee J'en Ai Marre music video on YouTube :
You see two 01 s
This is another file compressed from Mike Oldfield Secrets and Far Above The Clouds from YouTube :
You see two 02 s and two 01 s
This is Terminator 2 : The Judgement Day mkv file and worse than the 2 former files, it has two 0E and filename and pluspower in it :
I'm on Debian 12.8 and compiled GMP 6.3.0 These are not acceptable and reasonable. Is there any GMP pro to say why this trash data is written in the files ?
The code edited as demanded
Upvotes: 0
Views: 157
Reputation: 154169
Perhaps this issue?
Code should return when fw == NULL
.
fw = fopen(output, "ab");
if (fw == NULL)
printf("File can't be written\n'");
// I'd expect code to `return 1;` when `fw == NULL`
// and not go on to do `ferror(fw)`
if (ferror(fw))
{
fprintf(stderr, "Error during writing to file %s\n", output);
perror("");
fclose(fw);
return 1;
}
Upvotes: 2