diff --git a/c_unpacker/readme.txt b/c_unpacker/readme.txt new file mode 100644 index 0000000..c412634 --- /dev/null +++ b/c_unpacker/readme.txt @@ -0,0 +1,4 @@ +a very simple unpacker in c, as a reference for people wanting to implement their own unpacker. +absolutely not production ready, it makes no effort to ensure the output buffer can actually +hold the uncompressed data. +!!! Never run on untrusted input !!! diff --git a/c_unpacker/unpack.c b/c_unpacker/unpack.c index 2318ed5..b93d8a3 100644 --- a/c_unpacker/unpack.c +++ b/c_unpacker/unpack.c @@ -34,9 +34,9 @@ int upkr_decode_bit(int context_index) { if(bit) { upkr_state = prob * (upkr_state >> 8) + (upkr_state & 255); - upkr_probs[context_index] = prob + ((255 - prob + 8) >> 4); + upkr_probs[context_index] = prob + ((256 - prob + 8) >> 4); } else { - upkr_state = (255 - prob) * (upkr_state >> 8) + (upkr_state & 255) - prob; + upkr_state = (256 - prob) * (upkr_state >> 8) + (upkr_state & 255) - prob; upkr_probs[context_index] = prob - ((prob + 8) >> 4); } @@ -75,20 +75,18 @@ int upkr_unpack(void* destination, void* compressed_data) { } } int length = upkr_decode_length(257 + 64); - while(length-- > 1) { + while(length--) { *write_ptr = write_ptr[-offset]; ++write_ptr; } prev_was_match = 1; } else { - int context_index = 1; - int byte = 0; + u8 context_index = 1; for(int i = 0; i < 8; ++i) { int bit = upkr_decode_bit(context_index); context_index = (context_index << 1) + bit; - byte |= bit << i; } - *write_ptr++ = byte; + *write_ptr++ = context_index; prev_was_match = 0; } }