Skip to content

Commit

Permalink
update from review
Browse files Browse the repository at this point in the history
  • Loading branch information
arves100 committed Jan 7, 2021
1 parent f001d17 commit da9de8b
Show file tree
Hide file tree
Showing 3 changed files with 5 additions and 351 deletions.
10 changes: 2 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,22 +1,16 @@
cmake_minimum_required(VERSION 3.0)
project(tl-parser)
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(tl-parser LANGUAGES C)

set(SOURCES crc32.h crc32.c tlc.c tl-parser.c tl-parser.h tl-parser-tree.h tl-tl.h portable_endian.h)

if (WIN32)
add_definitions("-D_CRT_SECURE_NO_WARNINGS")
list(APPEND SOURCES wgetopt.c wgetopt.h)
if (MSVC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /utf-8")
endif()
endif()

# Set the output directories to the cmake build directory
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG .)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE .)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO .)

add_executable(${PROJECT_NAME} ${SOURCES})
if (NOT WIN32)
target_link_libraries(${PROJECT_NAME} m)
Expand Down
322 changes: 2 additions & 320 deletions crc32.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,6 @@

#include "crc32.h"

static inline unsigned _bswap32(unsigned x) {
return ((x << 24) & 0xff000000 ) |
((x << 8) & 0x00ff0000 ) |
((x >> 8) & 0x0000ff00 ) |
((x >> 24) & 0x000000ff );
}

unsigned int crc32_table[256] =
{
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
Expand Down Expand Up @@ -304,36 +297,7 @@ unsigned int crc32_table0[256] = {
0xccb0a91f, 0x740cce7a, 0x66b96194, 0xde0506f1,
};

unsigned crc32_partial_old (const void *data, int len, unsigned crc) {
const char *p = data;
for (; len > 0; len--) {
crc = crc32_table[(crc ^ *p++) & 0xff] ^ (crc >> 8);
}
return crc;
}

/*
unsigned crc32_partial_fast (const void *data, int len, unsigned crc) {
const int *p = (const int *) data;
int x;
for (x = (len >> 2); x > 0; x--) {
crc ^= *p++;
crc = crc32_table0[crc & 0xff] ^ crc32_table1[(crc & 0xff00) >> 8] ^ crc32_table2[(crc & 0xff0000) >> 16] ^ crc32_table[crc >> 24];
}
const char *q = (const char *) p;
switch (len & 3) {
case 3:
crc = crc32_table[(crc ^ *q++) & 0xff] ^ (crc >> 8);
case 2:
crc = crc32_table[(crc ^ *q++) & 0xff] ^ (crc >> 8);
case 1:
crc = crc32_table[(crc ^ *q++) & 0xff] ^ (crc >> 8);
}
return crc;
}
*/

unsigned crc32_partial (const void *data, int len, unsigned crc) {
static unsigned int crc32_partial (const void *data, int len, unsigned crc) {
const int *p = (const int *) data;
int x;
#define DO_ONE(v) crc ^= v; crc = crc32_table0[crc & 0xff] ^ crc32_table1[(crc & 0xff00) >> 8] ^ crc32_table2[(crc & 0xff0000) >> 16] ^ crc32_table[crc >> 24];
Expand Down Expand Up @@ -375,289 +339,7 @@ unsigned crc32_partial (const void *data, int len, unsigned crc) {
return crc;
}

unsigned compute_crc32 (const void *data, int len) {
unsigned int compute_crc32 (const void *data, int len) {
return crc32_partial (data, len, -1) ^ -1;
}

unsigned long long crc64_table[256] = {
0x0000000000000000LL, 0xb32e4cbe03a75f6fLL, 0xf4843657a840a05bLL, 0x47aa7ae9abe7ff34LL,
0x7bd0c384ff8f5e33LL, 0xc8fe8f3afc28015cLL, 0x8f54f5d357cffe68LL, 0x3c7ab96d5468a107LL,
0xf7a18709ff1ebc66LL, 0x448fcbb7fcb9e309LL, 0x0325b15e575e1c3dLL, 0xb00bfde054f94352LL,
0x8c71448d0091e255LL, 0x3f5f08330336bd3aLL, 0x78f572daa8d1420eLL, 0xcbdb3e64ab761d61LL,
0x7d9ba13851336649LL, 0xceb5ed8652943926LL, 0x891f976ff973c612LL, 0x3a31dbd1fad4997dLL,
0x064b62bcaebc387aLL, 0xb5652e02ad1b6715LL, 0xf2cf54eb06fc9821LL, 0x41e11855055bc74eLL,
0x8a3a2631ae2dda2fLL, 0x39146a8fad8a8540LL, 0x7ebe1066066d7a74LL, 0xcd905cd805ca251bLL,
0xf1eae5b551a2841cLL, 0x42c4a90b5205db73LL, 0x056ed3e2f9e22447LL, 0xb6409f5cfa457b28LL,
0xfb374270a266cc92LL, 0x48190ecea1c193fdLL, 0x0fb374270a266cc9LL, 0xbc9d3899098133a6LL,
0x80e781f45de992a1LL, 0x33c9cd4a5e4ecdceLL, 0x7463b7a3f5a932faLL, 0xc74dfb1df60e6d95LL,
0x0c96c5795d7870f4LL, 0xbfb889c75edf2f9bLL, 0xf812f32ef538d0afLL, 0x4b3cbf90f69f8fc0LL,
0x774606fda2f72ec7LL, 0xc4684a43a15071a8LL, 0x83c230aa0ab78e9cLL, 0x30ec7c140910d1f3LL,
0x86ace348f355aadbLL, 0x3582aff6f0f2f5b4LL, 0x7228d51f5b150a80LL, 0xc10699a158b255efLL,
0xfd7c20cc0cdaf4e8LL, 0x4e526c720f7dab87LL, 0x09f8169ba49a54b3LL, 0xbad65a25a73d0bdcLL,
0x710d64410c4b16bdLL, 0xc22328ff0fec49d2LL, 0x85895216a40bb6e6LL, 0x36a71ea8a7ace989LL,
0x0adda7c5f3c4488eLL, 0xb9f3eb7bf06317e1LL, 0xfe5991925b84e8d5LL, 0x4d77dd2c5823b7baLL,
0x64b62bcaebc387a1LL, 0xd7986774e864d8ceLL, 0x90321d9d438327faLL, 0x231c512340247895LL,
0x1f66e84e144cd992LL, 0xac48a4f017eb86fdLL, 0xebe2de19bc0c79c9LL, 0x58cc92a7bfab26a6LL,
0x9317acc314dd3bc7LL, 0x2039e07d177a64a8LL, 0x67939a94bc9d9b9cLL, 0xd4bdd62abf3ac4f3LL,
0xe8c76f47eb5265f4LL, 0x5be923f9e8f53a9bLL, 0x1c4359104312c5afLL, 0xaf6d15ae40b59ac0LL,
0x192d8af2baf0e1e8LL, 0xaa03c64cb957be87LL, 0xeda9bca512b041b3LL, 0x5e87f01b11171edcLL,
0x62fd4976457fbfdbLL, 0xd1d305c846d8e0b4LL, 0x96797f21ed3f1f80LL, 0x2557339fee9840efLL,
0xee8c0dfb45ee5d8eLL, 0x5da24145464902e1LL, 0x1a083bacedaefdd5LL, 0xa9267712ee09a2baLL,
0x955cce7fba6103bdLL, 0x267282c1b9c65cd2LL, 0x61d8f8281221a3e6LL, 0xd2f6b4961186fc89LL,
0x9f8169ba49a54b33LL, 0x2caf25044a02145cLL, 0x6b055fede1e5eb68LL, 0xd82b1353e242b407LL,
0xe451aa3eb62a1500LL, 0x577fe680b58d4a6fLL, 0x10d59c691e6ab55bLL, 0xa3fbd0d71dcdea34LL,
0x6820eeb3b6bbf755LL, 0xdb0ea20db51ca83aLL, 0x9ca4d8e41efb570eLL, 0x2f8a945a1d5c0861LL,
0x13f02d374934a966LL, 0xa0de61894a93f609LL, 0xe7741b60e174093dLL, 0x545a57dee2d35652LL,
0xe21ac88218962d7aLL, 0x5134843c1b317215LL, 0x169efed5b0d68d21LL, 0xa5b0b26bb371d24eLL,
0x99ca0b06e7197349LL, 0x2ae447b8e4be2c26LL, 0x6d4e3d514f59d312LL, 0xde6071ef4cfe8c7dLL,
0x15bb4f8be788911cLL, 0xa6950335e42fce73LL, 0xe13f79dc4fc83147LL, 0x521135624c6f6e28LL,
0x6e6b8c0f1807cf2fLL, 0xdd45c0b11ba09040LL, 0x9aefba58b0476f74LL, 0x29c1f6e6b3e0301bLL,
0xc96c5795d7870f42LL, 0x7a421b2bd420502dLL, 0x3de861c27fc7af19LL, 0x8ec62d7c7c60f076LL,
0xb2bc941128085171LL, 0x0192d8af2baf0e1eLL, 0x4638a2468048f12aLL, 0xf516eef883efae45LL,
0x3ecdd09c2899b324LL, 0x8de39c222b3eec4bLL, 0xca49e6cb80d9137fLL, 0x7967aa75837e4c10LL,
0x451d1318d716ed17LL, 0xf6335fa6d4b1b278LL, 0xb199254f7f564d4cLL, 0x02b769f17cf11223LL,
0xb4f7f6ad86b4690bLL, 0x07d9ba1385133664LL, 0x4073c0fa2ef4c950LL, 0xf35d8c442d53963fLL,
0xcf273529793b3738LL, 0x7c0979977a9c6857LL, 0x3ba3037ed17b9763LL, 0x888d4fc0d2dcc80cLL,
0x435671a479aad56dLL, 0xf0783d1a7a0d8a02LL, 0xb7d247f3d1ea7536LL, 0x04fc0b4dd24d2a59LL,
0x3886b22086258b5eLL, 0x8ba8fe9e8582d431LL, 0xcc0284772e652b05LL, 0x7f2cc8c92dc2746aLL,
0x325b15e575e1c3d0LL, 0x8175595b76469cbfLL, 0xc6df23b2dda1638bLL, 0x75f16f0cde063ce4LL,
0x498bd6618a6e9de3LL, 0xfaa59adf89c9c28cLL, 0xbd0fe036222e3db8LL, 0x0e21ac88218962d7LL,
0xc5fa92ec8aff7fb6LL, 0x76d4de52895820d9LL, 0x317ea4bb22bfdfedLL, 0x8250e80521188082LL,
0xbe2a516875702185LL, 0x0d041dd676d77eeaLL, 0x4aae673fdd3081deLL, 0xf9802b81de97deb1LL,
0x4fc0b4dd24d2a599LL, 0xfceef8632775faf6LL, 0xbb44828a8c9205c2LL, 0x086ace348f355aadLL,
0x34107759db5dfbaaLL, 0x873e3be7d8faa4c5LL, 0xc094410e731d5bf1LL, 0x73ba0db070ba049eLL,
0xb86133d4dbcc19ffLL, 0x0b4f7f6ad86b4690LL, 0x4ce50583738cb9a4LL, 0xffcb493d702be6cbLL,
0xc3b1f050244347ccLL, 0x709fbcee27e418a3LL, 0x3735c6078c03e797LL, 0x841b8ab98fa4b8f8LL,
0xadda7c5f3c4488e3LL, 0x1ef430e13fe3d78cLL, 0x595e4a08940428b8LL, 0xea7006b697a377d7LL,
0xd60abfdbc3cbd6d0LL, 0x6524f365c06c89bfLL, 0x228e898c6b8b768bLL, 0x91a0c532682c29e4LL,
0x5a7bfb56c35a3485LL, 0xe955b7e8c0fd6beaLL, 0xaeffcd016b1a94deLL, 0x1dd181bf68bdcbb1LL,
0x21ab38d23cd56ab6LL, 0x9285746c3f7235d9LL, 0xd52f0e859495caedLL, 0x6601423b97329582LL,
0xd041dd676d77eeaaLL, 0x636f91d96ed0b1c5LL, 0x24c5eb30c5374ef1LL, 0x97eba78ec690119eLL,
0xab911ee392f8b099LL, 0x18bf525d915feff6LL, 0x5f1528b43ab810c2LL, 0xec3b640a391f4fadLL,
0x27e05a6e926952ccLL, 0x94ce16d091ce0da3LL, 0xd3646c393a29f297LL, 0x604a2087398eadf8LL,
0x5c3099ea6de60cffLL, 0xef1ed5546e415390LL, 0xa8b4afbdc5a6aca4LL, 0x1b9ae303c601f3cbLL,
0x56ed3e2f9e224471LL, 0xe5c372919d851b1eLL, 0xa26908783662e42aLL, 0x114744c635c5bb45LL,
0x2d3dfdab61ad1a42LL, 0x9e13b115620a452dLL, 0xd9b9cbfcc9edba19LL, 0x6a978742ca4ae576LL,
0xa14cb926613cf817LL, 0x1262f598629ba778LL, 0x55c88f71c97c584cLL, 0xe6e6c3cfcadb0723LL,
0xda9c7aa29eb3a624LL, 0x69b2361c9d14f94bLL, 0x2e184cf536f3067fLL, 0x9d36004b35545910LL,
0x2b769f17cf112238LL, 0x9858d3a9ccb67d57LL, 0xdff2a94067518263LL, 0x6cdce5fe64f6dd0cLL,
0x50a65c93309e7c0bLL, 0xe388102d33392364LL, 0xa4226ac498dedc50LL, 0x170c267a9b79833fLL,
0xdcd7181e300f9e5eLL, 0x6ff954a033a8c131LL, 0x28532e49984f3e05LL, 0x9b7d62f79be8616aLL,
0xa707db9acf80c06dLL, 0x14299724cc279f02LL, 0x5383edcd67c06036LL, 0xe0ada17364673f59LL
};

unsigned long long crc64_partial (const void *data, int len, unsigned long long crc) {
const char *p = data;
for (; len > 0; len--) {
crc = crc64_table[(crc ^ *p++) & 0xff] ^ (crc >> 8);
}
return crc;
}

unsigned long long crc64 (const void *data, int len) {
return crc64_partial (data, len, -1LL) ^ -1LL;
}

static unsigned gf32_matrix_times (unsigned *matrix, unsigned vector) {
unsigned sum = 0;
while (vector) {
if (vector & 1) {
sum ^= *matrix;
}
vector >>= 1;
matrix++;
}
return sum;
}

static void gf32_matrix_square (unsigned *square, unsigned *matrix) {
int n = 0;
do {
square[n] = gf32_matrix_times (matrix, matrix[n]);
} while (++n < 32);
}

unsigned compute_crc32_combine (unsigned crc1, unsigned crc2, int len2) {
assert (len2 < (1 << 29));
static int power_buf_initialized = 0;
static unsigned power_buf[1024];
int n;
/* degenerate case (also disallow negative lengths) */
if (len2 <= 0) {
return crc1;
}
if (!power_buf_initialized) {
power_buf[0] = 0xedb88320UL;
for (n = 0; n < 31; n++) {
power_buf[n+1] = 1U << n;
}
for (n = 1; n < 32; n++) {
gf32_matrix_square (power_buf + (n << 5), power_buf + ((n - 1) << 5));
}
power_buf_initialized = 1;
}

unsigned int *p = power_buf + 64;
do {
p += 32;
if (len2 & 1) {
crc1 = gf32_matrix_times (p, crc1);
}
len2 >>= 1;
} while (len2);
return crc1 ^ crc2;
}


/********************************* crc32 repair ************************/
struct fcb_table_entry {
unsigned p; //zeta ^ k
int i;
};

static inline unsigned gf32_mod (unsigned long long r, int high_bit) {
int j = high_bit;
for (j = high_bit; j >= 32; j--) {
if ((1ULL << j) & r) {
r ^= 0x04C11DB7ULL << (j - 32);
}
}
return (unsigned) r;
}

static unsigned gf32_mult (unsigned a, unsigned b) {
int i;
const unsigned long long m = b;
unsigned long long r = 0;
for (i = 0; i < 32; i++) {
if (a & (1U << i)) {
r ^= m << i;
}
}
return gf32_mod (r, 62);
}

static unsigned gf32_shl (unsigned int a, int shift) {
unsigned long long r = a;
r <<= shift;
return gf32_mod (r, 31 + shift);
}

static unsigned gf32_pow (unsigned a, int k) {
if (!k) { return 1; }
unsigned x = gf32_pow (gf32_mult (a, a), k >> 1);
if (k & 1) {
x = gf32_mult (x, a);
}
return x;
}

static int cmp_fcb_table_entry (const void *a, const void *b) {
const struct fcb_table_entry *x = a;
const struct fcb_table_entry *y = b;
if (x->p < y->p) { return -1; }
if (x->p > y->p) { return 1; }
if (x->i < y->i) { return -1; }
if (x->i > y->i) { return 1; }
return 0;
}

#define GROUP_SWAP(x,m,s) ((x & m) << s) | ((x & (~m)) >> s)
static unsigned revbin (unsigned x) {
x = GROUP_SWAP(x,0x55555555U,1);
x = GROUP_SWAP(x,0x33333333U,2);
x = GROUP_SWAP(x,0x0f0f0f0fU,4);
x = _bswap32 (x);
return x;
}
#undef GROUP_SWAP

static inline unsigned xmult (unsigned a) {
unsigned r = a << 1;
if (a & (1U<<31)) {
r ^= 0x04C11DB7U;
}
return r;
}

static int find_corrupted_bit (int size, unsigned d) {
int i, j;
size += 4;
d = revbin (d);
int n = size << 3;
int r = (int) (sqrt (n) + 0.5);
struct fcb_table_entry *T = calloc (r, sizeof (struct fcb_table_entry));
assert (T != NULL);
T[0].i = 0;
T[0].p = 1;
for (i = 1; i < r; i++) {
T[i].i = i;
T[i].p = xmult (T[i-1].p);
}
assert (xmult (0x82608EDB) == 1);
qsort (T, r, sizeof (T[0]), cmp_fcb_table_entry);
unsigned q = gf32_pow (0x82608EDB, r);

unsigned A[32];
for (i = 0; i < 32; i++) {
A[i] = gf32_shl (q, i);
}

unsigned x = d;
int max_j = n / r, res = -1;
for (j = 0; j <= max_j; j++) {
int a = -1, b = r;
while (b - a > 1) {
int c = ((a + b) >> 1);
if (T[c].p <= x) { a = c; } else { b = c; }
}
if (a >= 0 && T[a].p == x) {
res = T[a].i + r * j;
break;
}
x = gf32_matrix_times (A, x);
}
free (T);
return res;
}

static int repair_bit (unsigned char *input, int l, int k) {
if (k < 0) {
return -1;
}
int idx = k >> 5, bit = k & 31, i = (l - 1) - (idx - 1) * 4;
while (bit >= 8) {
i--;
bit -= 8;
}
if (i < 0) {
return -2;
}
if (i >= l) {
return -3;
}
int j = 7 - bit;
input[i] ^= 1 << j;
return 0;
}

int crc32_check_and_repair (void *input, int l, unsigned *input_crc32, int force_exit) {
unsigned computed_crc32 = compute_crc32 (input, l);
const unsigned crc32_diff = computed_crc32 ^ (*input_crc32);
if (!crc32_diff) {
return 0;
}
int k = find_corrupted_bit (l, crc32_diff);
int r = repair_bit (input, l, k);
if (!r) {
assert (compute_crc32 (input, l) == *input_crc32);
return 1;
}
if (!(crc32_diff & (crc32_diff - 1))) { /* crc32_diff is power of 2 */
*input_crc32 = computed_crc32;
return 2;
}
assert (!force_exit);
*input_crc32 = computed_crc32;
return -1;
}
24 changes: 1 addition & 23 deletions crc32.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,7 @@
extern "C" {
#endif

extern unsigned int crc32_table[256];
unsigned crc32_partial (const void *data, int len, unsigned crc);
//unsigned crc32_partial_fast (const void *data, int len, unsigned crc);
//unsigned crc32_partial_fastest (const void *data, int len, unsigned crc);
unsigned compute_crc32 (const void *data, int len);
unsigned compute_crc32_combine (unsigned crc1, unsigned crc2, int len2);

extern unsigned long long crc64_table[256];
unsigned long long crc64_partial (const void *data, int len, unsigned long long crc);
unsigned long long crc64 (const void *data, int len);

//unsigned gf32_matrix_times (unsigned *matrix, unsigned vector);

/* crc32_check_and_repair returns
0 : Cyclic redundancy check is ok
1 : Cyclic redundancy check fails, but we fix one bit in input
2 : Cyclic redundancy check fails, but we fix one bit in input_crc32
-1 : Cyclic redundancy check fails, no repair possible.
In this case *input_crc32 will be equal crc32 (input, l)
Case force_exit == 1 (case 1, 2: kprintf call, case -1: assert fail).
*/
int crc32_check_and_repair (void *input, int l, unsigned *input_crc32, int force_exit);
unsigned int compute_crc32 (const void *data, int len);

#ifdef __cplusplus
}
Expand Down

0 comments on commit da9de8b

Please sign in to comment.