🐛 Change char buffers to unsigned char buffers
This commit is contained in:
parent
04e8f80b20
commit
6b9b31c2bc
11 changed files with 67 additions and 47 deletions
|
@ -16,11 +16,13 @@ void initDecryptor(uint32_t key0, uint32_t key1, uint32_t key2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Decrypts the given input in-place. The input buffer will be modified. */
|
/** Decrypts the given input in-place. The input buffer will be modified. */
|
||||||
void decrypt(unsigned char chunk[], unsigned long length) {
|
void decrypt(uint8_t* chunk, unsigned long length) {
|
||||||
for (unsigned long i = 0; i < length; i += 1) {
|
for (unsigned long i = 0; i < length; i += 1) {
|
||||||
unsigned char testChar = chunk[i];
|
//uint8_t testChar = chunk[i];
|
||||||
testChar = testChar ^ decryptByte((uint16_t)(decryptor.key2 | 2));
|
uint8_t testChar = *(chunk + i);
|
||||||
|
testChar = testChar ^ decryptByte((uint16_t)((uint16_t)(decryptor.key2 & (uint16_t)0xFFFF) | (uint16_t)2));
|
||||||
updateKeys(&(decryptor.key0), &(decryptor.key1), &(decryptor.key2), testChar);
|
updateKeys(&(decryptor.key0), &(decryptor.key1), &(decryptor.key2), testChar);
|
||||||
chunk[i] = testChar;
|
//chunk[i] = testChar;
|
||||||
|
*(chunk + i) = testChar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,4 +5,4 @@
|
||||||
void initDecryptor(uint32_t key0, uint32_t key1, uint32_t key2);
|
void initDecryptor(uint32_t key0, uint32_t key1, uint32_t key2);
|
||||||
|
|
||||||
/** Decrypts the given input in-place. The input buffer will be modified. */
|
/** Decrypts the given input in-place. The input buffer will be modified. */
|
||||||
void decrypt(unsigned char chunk[], unsigned long length);
|
void decrypt(uint8_t* chunk, unsigned long length);
|
||||||
|
|
|
@ -32,7 +32,7 @@ void initFileReader(char path[], unsigned long offset) {
|
||||||
|
|
||||||
|
|
||||||
//Reads the given amount of bytes from the file and returns them. Automatically opens next file if EOF is reached.
|
//Reads the given amount of bytes from the file and returns them. Automatically opens next file if EOF is reached.
|
||||||
void getBytes(char* buffer, unsigned long numBytes) {
|
void getBytes(uint8_t* buffer, unsigned long numBytes) {
|
||||||
char* bufferPosition = buffer;
|
char* bufferPosition = buffer;
|
||||||
unsigned long remainingBytes = numBytes;
|
unsigned long remainingBytes = numBytes;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
void initFileReader(char path[], unsigned long offset);
|
void initFileReader(char path[], unsigned long offset);
|
||||||
|
|
||||||
void getBytes(char* buffer, unsigned long numBytes);
|
void getBytes(uint8_t* buffer, unsigned long numBytes);
|
||||||
|
|
|
@ -14,25 +14,25 @@
|
||||||
#include "inflate.h"
|
#include "inflate.h"
|
||||||
|
|
||||||
//The compressed and uncompressed buffer arrays
|
//The compressed and uncompressed buffer arrays
|
||||||
const char* comprBuffer;
|
static const uint8_t* comprBuffer;
|
||||||
char* uncomprBuffer;
|
static uint8_t* uncomprBuffer;
|
||||||
//Position of the inflater in the buffer arrays
|
//Position of the inflater in the buffer arrays
|
||||||
const char* comprBufferNext;
|
static const uint8_t* comprBufferNext;
|
||||||
char* uncomprBufferNext;
|
static uint8_t* uncomprBufferNext;
|
||||||
//Buffer lengths
|
//Buffer lengths
|
||||||
unsigned long uncomprBufferSize;
|
static unsigned long uncomprBufferSize;
|
||||||
unsigned long remainingInput;
|
static size_t remainingInput;
|
||||||
unsigned long spaceInOutput;
|
static size_t spaceInOutput;
|
||||||
//Internal variables used by miniz
|
//Internal variables used by miniz
|
||||||
tinfl_decompressor inflator;
|
static tinfl_decompressor decompressor;
|
||||||
tdefl_status status;
|
static tdefl_status status;
|
||||||
size_t in_bytes, out_bytes;
|
static size_t in_bytes, out_bytes;
|
||||||
|
|
||||||
void inflateInit(char* comprBufferIn, char* uncomprBufferIn, unsigned long uncomprBufferSizeIn) {
|
void inflateInit(uint8_t* comprBufferIn, uint8_t* uncomprBufferIn, unsigned long uncomprBufferSizeIn) {
|
||||||
comprBuffer = comprBufferIn;
|
comprBuffer = comprBufferIn;
|
||||||
uncomprBuffer = uncomprBufferIn;
|
uncomprBuffer = uncomprBufferIn;
|
||||||
uncomprBufferSize = uncomprBufferSizeIn;
|
uncomprBufferSize = uncomprBufferSizeIn;
|
||||||
tinfl_init(&inflator);
|
tinfl_init(&decompressor);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InflateOutput inflateInflate(unsigned long numInputBytes, bool hasMoreBytes) {
|
struct InflateOutput inflateInflate(unsigned long numInputBytes, bool hasMoreBytes) {
|
||||||
|
@ -40,12 +40,13 @@ struct InflateOutput inflateInflate(unsigned long numInputBytes, bool hasMoreByt
|
||||||
//continue in input buffer where we were before
|
//continue in input buffer where we were before
|
||||||
} else {
|
} else {
|
||||||
//go back to beginning of input buffer
|
//go back to beginning of input buffer
|
||||||
|
comprBufferNext = comprBuffer;
|
||||||
remainingInput = numInputBytes;
|
remainingInput = numInputBytes;
|
||||||
comprBufferNext = (const mz_uint8 *)comprBuffer;
|
|
||||||
}
|
}
|
||||||
//output buffer has been emptied
|
|
||||||
spaceInOutput = uncomprBufferSize;
|
//output buffer was previously fully filled and all output was processed. New uncompressed data can be written starting at offset 0
|
||||||
uncomprBufferNext = (mz_uint8 *)uncomprBuffer;
|
uncomprBufferNext = (mz_uint8 *)uncomprBuffer;
|
||||||
|
spaceInOutput = uncomprBufferSize;
|
||||||
|
|
||||||
struct InflateOutput out;
|
struct InflateOutput out;
|
||||||
out.hasReachedEnd = false;
|
out.hasReachedEnd = false;
|
||||||
|
@ -56,19 +57,19 @@ struct InflateOutput inflateInflate(unsigned long numInputBytes, bool hasMoreByt
|
||||||
|
|
||||||
//Call decompression
|
//Call decompression
|
||||||
status = tinfl_decompress(
|
status = tinfl_decompress(
|
||||||
&inflator,
|
&decompressor,
|
||||||
(const mz_uint8 *)comprBufferNext,
|
(const mz_uint8 *)comprBufferNext,
|
||||||
&in_bytes,
|
&in_bytes,
|
||||||
uncomprBuffer,
|
(mz_uint8 *)uncomprBuffer,
|
||||||
(mz_uint8 *)uncomprBufferNext,
|
(mz_uint8 *)uncomprBufferNext,
|
||||||
&out_bytes,
|
&out_bytes,
|
||||||
(hasMoreBytes ? TINFL_FLAG_HAS_MORE_INPUT : 0)
|
(hasMoreBytes ? TINFL_FLAG_HAS_MORE_INPUT : 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
//Adjust buffer positions by the amount of bytes processed
|
//Adjust buffer positions by the amount of bytes processed
|
||||||
comprBufferNext = (const mz_uint8 *)comprBufferNext + in_bytes;
|
comprBufferNext = (const uint8_t *)(comprBufferNext + in_bytes);
|
||||||
remainingInput -= in_bytes;
|
remainingInput -= in_bytes;
|
||||||
uncomprBufferNext = (mz_uint8 *)uncomprBufferNext + out_bytes;
|
uncomprBufferNext = (uint8_t *)(uncomprBufferNext + out_bytes);
|
||||||
spaceInOutput -= out_bytes;
|
spaceInOutput -= out_bytes;
|
||||||
|
|
||||||
//Check for errors
|
//Check for errors
|
||||||
|
@ -84,15 +85,25 @@ struct InflateOutput inflateInflate(unsigned long numInputBytes, bool hasMoreByt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//If output buffer is filled, we need to clear it before decompressing more data
|
if (status == TINFL_STATUS_NEEDS_MORE_INPUT && remainingInput != 0) {
|
||||||
if (spaceInOutput == 0) {
|
fprintf(stderr, "Received status NEEDS_MORE_INPUT, with remaining input %lu and space in output %lu.\n", remainingInput, spaceInOutput);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (status == TINFL_STATUS_HAS_MORE_OUTPUT && spaceInOutput != 0) {
|
||||||
|
fprintf(stderr, "Received status HAS_MORE_OUTPUT, with remaining input %lu and space in output %lu.\n", remainingInput, spaceInOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
//commented out because we immediately exit while loop if it is zero
|
||||||
|
//If output buffer is filled, we need to clear it before decompressing more data
|
||||||
|
/*if (spaceInOutput == 0) {
|
||||||
|
break;
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//Return output
|
//Return output
|
||||||
if (remainingInput == 0) {
|
if (remainingInput == 0) {
|
||||||
out.needMoreInput = hasMoreBytes;
|
out.needMoreInput = hasMoreBytes;
|
||||||
|
} else {
|
||||||
|
out.needMoreInput = false;
|
||||||
}
|
}
|
||||||
out.numBytesWrittenToOutput = uncomprBufferSize - spaceInOutput;
|
out.numBytesWrittenToOutput = uncomprBufferSize - spaceInOutput;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void inflateInit(char* comprBuffer, char* uncomprBuffer, unsigned long uncomprBufferSize);
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void inflateInit(uint8_t* comprBuffer, uint8_t* uncomprBuffer, unsigned long uncomprBufferSize);
|
||||||
|
|
||||||
struct InflateOutput {
|
struct InflateOutput {
|
||||||
bool needMoreInput;
|
bool needMoreInput;
|
||||||
|
|
19
src/main.c
19
src/main.c
|
@ -11,15 +11,15 @@
|
||||||
#include "inflate.h"
|
#include "inflate.h"
|
||||||
#include "utils/min.h"
|
#include "utils/min.h"
|
||||||
|
|
||||||
#define BUFFER_SIZE 512UL * 1024UL //512 KiB
|
#define BUFFER_SIZE 32UL * 1024UL //512 KiB
|
||||||
#define ENCRYPTION_HEADER_LENGTH 12UL
|
#define ENCRYPTION_HEADER_LENGTH 12UL
|
||||||
#define LOCAL_FILE_HEADER_MAGIC (uint32_t)0x04034b50
|
#define LOCAL_FILE_HEADER_MAGIC (uint32_t)0x04034b50
|
||||||
|
|
||||||
uint16_t getUint16(char* buffer) {
|
uint16_t getUint16(uint8_t* buffer) {
|
||||||
return (uint16_t)buffer[0] | \
|
return (uint16_t)buffer[0] | \
|
||||||
(uint16_t)buffer[1] << 8;
|
(uint16_t)buffer[1] << 8;
|
||||||
}
|
}
|
||||||
uint32_t getUint32(char* buffer) {
|
uint32_t getUint32(uint8_t* buffer) {
|
||||||
return (uint32_t)buffer[0] | \
|
return (uint32_t)buffer[0] | \
|
||||||
(uint32_t)buffer[1] << 8 | \
|
(uint32_t)buffer[1] << 8 | \
|
||||||
(uint32_t)buffer[2] << 16 | \
|
(uint32_t)buffer[2] << 16 | \
|
||||||
|
@ -47,19 +47,19 @@ int main(int argc, unsigned char *argv[]) {
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
char* compressedChunk = malloc(BUFFER_SIZE);
|
uint8_t* compressedChunk = malloc(BUFFER_SIZE);
|
||||||
if (compressedChunk == NULL) {
|
if (compressedChunk == NULL) {
|
||||||
fprintf(stderr, "Could not allocate %lu bytes for compressed buffer.\n", BUFFER_SIZE);
|
fprintf(stderr, "Could not allocate %lu bytes for compressed buffer.\n", BUFFER_SIZE);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
//memset(compressedChunk, (uint8_t)0, BUFFER_SIZE);
|
||||||
|
|
||||||
char* uncompressedChunk = malloc(BUFFER_SIZE);
|
uint8_t* uncompressedChunk = malloc(BUFFER_SIZE);
|
||||||
if (uncompressedChunk == NULL) {
|
if (uncompressedChunk == NULL) {
|
||||||
fprintf(stderr, "Could not allocate %lu bytes for uncompressed buffer.\n", BUFFER_SIZE);
|
fprintf(stderr, "Could not allocate %lu bytes for uncompressed buffer.\n", BUFFER_SIZE);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
memset(compressedChunk, 0, BUFFER_SIZE);
|
memset(uncompressedChunk, (uint8_t)0, BUFFER_SIZE);
|
||||||
memset(uncompressedChunk, 0, BUFFER_SIZE);
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ int main(int argc, unsigned char *argv[]) {
|
||||||
while (remainingBytes > 0 || !hasReachedEnd) {
|
while (remainingBytes > 0 || !hasReachedEnd) {
|
||||||
if (needToRead) {
|
if (needToRead) {
|
||||||
chunkSize = min(BUFFER_SIZE, remainingBytes);
|
chunkSize = min(BUFFER_SIZE, remainingBytes);
|
||||||
memset(compressedChunk, 0, chunkSize);
|
//memset(compressedChunk, 0, chunkSize);
|
||||||
getBytes(compressedChunk, chunkSize);
|
getBytes(compressedChunk, chunkSize);
|
||||||
remainingBytes -= chunkSize;
|
remainingBytes -= chunkSize;
|
||||||
|
|
||||||
|
@ -110,11 +110,12 @@ int main(int argc, unsigned char *argv[]) {
|
||||||
|
|
||||||
//Decompress file
|
//Decompress file
|
||||||
//bytes are contained in uncompressedChunk from [0, inflateResult.numBytesWrittenToOutput - 1]
|
//bytes are contained in uncompressedChunk from [0, inflateResult.numBytesWrittenToOutput - 1]
|
||||||
memset(uncompressedChunk, 0, BUFFER_SIZE);
|
|
||||||
inflateResult = inflateInflate(needToRead ? chunkSize : 0, remainingBytes > 0);
|
inflateResult = inflateInflate(needToRead ? chunkSize : 0, remainingBytes > 0);
|
||||||
needToRead = inflateResult.needMoreInput;
|
needToRead = inflateResult.needMoreInput;
|
||||||
hasReachedEnd = inflateResult.hasReachedEnd;
|
hasReachedEnd = inflateResult.hasReachedEnd;
|
||||||
|
|
||||||
|
//important: we must not modify uncompressedChunk since miniz may use it as dictionary and read from it during the next invocation of inflateInflate()
|
||||||
|
|
||||||
write(1, uncompressedChunk, inflateResult.numBytesWrittenToOutput);
|
write(1, uncompressedChunk, inflateResult.numBytesWrittenToOutput);
|
||||||
|
|
||||||
//Optionally perform xdelta3
|
//Optionally perform xdelta3
|
||||||
|
|
|
@ -46,16 +46,16 @@ const uint32_t crc32_tab[] = {
|
||||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t getCrc(uint32_t old_crc, unsigned char c) {
|
uint32_t getCrc(uint32_t old_crc, uint8_t c) {
|
||||||
return (old_crc >> 8) ^ crc32_tab[(old_crc & 0xffU) ^ c];
|
return (old_crc >> 8) ^ crc32_tab[(old_crc & (uint32_t)0xff) ^ c];
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateKeys(uint32_t *key_0, uint32_t *key_1, uint32_t *key_2, unsigned char c) {
|
void updateKeys(uint32_t *key_0, uint32_t *key_1, uint32_t *key_2, uint8_t c) {
|
||||||
*key_0 = getCrc(*key_0, c);
|
*key_0 = getCrc(*key_0, c);
|
||||||
*key_1 = ((*key_1) + ((*key_0) & (uint32_t)0xffU)) * ((uint32_t)134775813U) + ((uint32_t)1U);
|
*key_1 = ((*key_1) + ((*key_0) & (uint32_t)0xffU)) * ((uint32_t)134775813U) + ((uint32_t)1U);
|
||||||
*key_2 = getCrc(*key_2, (*key_1) >> 24);
|
*key_2 = getCrc(*key_2, (*key_1) >> 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char decryptByte(uint16_t keyPart) {
|
uint8_t decryptByte(uint16_t keyPart) {
|
||||||
return (keyPart * (keyPart ^ 1)) >> 8;
|
return (keyPart * (keyPart ^ 1)) >> 8;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
void updateKeys(uint32_t *key_0, uint32_t *key_1, uint32_t *key_2, unsigned char c);
|
void updateKeys(uint32_t *key_0, uint32_t *key_1, uint32_t *key_2, uint8_t c);
|
||||||
|
|
||||||
unsigned char decryptByte(unsigned short keyPart);
|
uint8_t decryptByte(uint16_t keyPart);
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
|
|
||||||
//Reads the given amount of bytes from the currently open file into the given buffer.
|
//Reads the given amount of bytes from the currently open file into the given buffer.
|
||||||
void readBytesIntoBuffer(char* buffer, long numBytes) {
|
void readBytesIntoBuffer(uint8_t* buffer, long numBytes) {
|
||||||
const size_t result = fread(buffer, 1, numBytes, file.filePointer);
|
const size_t result = fread(buffer, 1, numBytes, file.filePointer);
|
||||||
file.offset += result;
|
file.offset += result;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
//A structure to store various information needed when reading from a file.
|
//A structure to store various information needed when reading from a file.
|
||||||
struct FILE_INFO {
|
struct FILE_INFO {
|
||||||
char* name;
|
char* name;
|
||||||
|
@ -12,7 +14,7 @@ struct FILE_INFO file;
|
||||||
|
|
||||||
|
|
||||||
//Reads the given amount of bytes from the currently open file into the given buffer.
|
//Reads the given amount of bytes from the currently open file into the given buffer.
|
||||||
void readBytesIntoBuffer(char* buffer, long numBytes);
|
void readBytesIntoBuffer(uint8_t* buffer, long numBytes);
|
||||||
|
|
||||||
|
|
||||||
//Closes the currently opened file and opens the next file at its beginning.
|
//Closes the currently opened file and opens the next file at its beginning.
|
||||||
|
|
Loading…
Reference in a new issue