zlib question (compression/uncompression fails) - demo atatched


A

Anonymous

Slightly OT, but can't find a zlib specific ng - so hopefuly, someone
can point out why uncompressed strings are not matching the original
strings (lots of strange characters at end of string).

Heres a little prog that demonstrates the problem:

//include zlib header etc

int main(int argc, char * argv[])
{
unsigned long compressed_str_len, srclen ;
void * src_buffer = 0, * dest_buffer = 0;
void * compressed_str = 0, * uncompressed_str = 0 ;
char * test_string = 0;
uLongf temp, dest_buffer_len, uncompressed_str_len ;

if (argc < 1)
return -1 ;

test_string = argv[1];

// COMPRESSION

//get the size of the input
srclen = strlen(test_string) ;

//zlib states that the source buffer must be at least 0.1
//times larger than the source buffer plus 12 bytes
//to cope with the overhead of zlib data streams
temp = (uLongf)(srclen + (srclen * 0.1) + 12);
dest_buffer = calloc((size_t)(temp), sizeof(char));

src_buffer = test_string ;

//now compress the data
compress2((Bytef*)dest_buffer, (uLongf*)&dest_buffer_len,
(const Bytef*)src_buffer, (uLongf)srclen, Z_BEST_COMPRESSION);

//write the compressed data to disk
//fwrite(dest_buffer, dest_buffer_len, 1, FileOut);
printf("String to compress: '%s'\n", test_string );
printf("Length of string to compress: %d\n", strlen(test_string) ) ;

printf("Compressed string: '%s'\n", dest_buffer );
printf("Length of compressed string: %d\n", dest_buffer_len ) ;


// DECOMPRESSION
compressed_str_len = dest_buffer_len ;

//read in the contents of the file into the source buffer
compressed_str = dest_buffer ;

//allocate a buffer big enough to hold the uncompressed data, we can
cheat here
//because we know the size of the original
uncompressed_str_len = strlen(test_string);
uncompressed_str = calloc(uncompressed_str_len, sizeof(char));


//all data we require is ready so compress it into the source buffer,
the exact
//size will be stored in uncompressed_str_len
uncompress((Bytef*)uncompressed_str, &uncompressed_str_len, (const
Bytef*)compressed_str, compressed_str_len );

printf("\nString to uncompress: '%s'\n", compressed_str);
printf("Length of string to uncompress: %d\n", compressed_str_len ) ;

printf("UnCompressed string: '%s'\n", uncompressed_str );
printf("Length of Uncompressed string: %d\n", uncompressed_str_len ) ;

printf("\nCompression/Uncompression result: %s\n", strcmp(test_string,
(char*)uncompressed_str) == 0 ? "SUCCESS" : "FAIL" );

free(dest_buffer);
free(uncompressed_str);

return 0;
}


This always returns FAIL - because the strings don't match (uncompressed
string contains wierd chars after original string - why does this
happen, and how can I get rid of it without resorting to memcpy or strncpy?
 
Ad

Advertisements

P

pete

Anonymous said:
Slightly OT, but can't find a zlib specific ng - so hopefuly, someone
can point out why uncompressed strings are not matching the original
strings (lots of strange characters at end of string).

Heres a little prog that demonstrates the problem:

//include zlib header etc

I can't compile your code.
Is it possible to post the relevant parts of zlib.h ?
unsigned long compressed_str_len, srclen ;
uLongf temp, dest_buffer_len, uncompressed_str_len ;
//zlib states that the source buffer must be at least 0.1
//times larger than the source buffer plus 12 bytes
//to cope with the overhead of zlib data streams
temp = (uLongf)(srclen + (srclen * 0.1) + 12);

If temp is an integer type,
then your code does not do what your comment says it must do.

((int)(9 + 9 * 0.1)) is not greater than 9.
 
C

Chris Dollin

Anonymous said:
Slightly OT, but can't find a zlib specific ng - so hopefuly, someone
can point out why uncompressed strings are not matching the original
strings (lots of strange characters at end of string).
(fx:big-snip)

This always returns FAIL - because the strings don't match (uncompressed
string contains wierd chars after original string - why does this
happen, and how can I get rid of it without resorting to memcpy or
strncpy?

I'd lay odds that the result from zlib decompression /is not a string/,
ie, it's not null-terminated. (How could it be? zlib surely isn't
limited to compressing text data, and non-text data could easily have
null bytes in it. That's why you have to pass in a length on compressing,
and provide a length result parameter when uncompressing, yes?) So
your checking that the result is OK is wrong: you should not use
`strcmp`.
how can I get rid of it without resorting to memcpy or strncpy?

How about using `memcmp`?
 
M

Malcolm McLean

Chris Dollin said:
I'd lay odds that the result from zlib decompression /is not a string/,
ie, it's not null-terminated.
He's calling zlib with the string address, correctly, but then with the
length of the string, incorrectly. It should be length plus one.
zlib decompresses, but isn't clever enough to add a nul on the end. Hnece
the string is unterminated and C sees string plus random garbage.

Crashingly simple, like most bugs.
 
Ad

Advertisements

K

Keith Thompson

Malcolm McLean said:
He's calling zlib with the string address, correctly, but then with
the length of the string, incorrectly. It should be length plus one.
zlib decompresses, but isn't clever enough to add a nul on the
end. Hnece the string is unterminated and C sees string plus random
garbage.

Either that, or he needs to pass the length of the string and then
re-append the '\0' after decompression. It's hard to tell which
approach makes more sense.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top