From 26b82f35d8ad765d223c4f1deec0678b6c90ed40 Mon Sep 17 00:00:00 2001 From: "yann.collet.73@gmail.com" Date: Fri, 21 Dec 2012 16:49:17 +0000 Subject: Improved endianess detection git-svn-id: https://lz4.googlecode.com/svn/trunk@86 650e7d94-2a16-8b24-b05c-7c0b3f6821cd --- fuzzer.c | 27 ++++++++++++++++++++++++++- lz4.c | 26 ++++++++++++++++++-------- lz4demo.c | 2 +- lz4hc.c | 32 ++++++++++++++++++++++++-------- 4 files changed, 69 insertions(+), 18 deletions(-) diff --git a/fuzzer.c b/fuzzer.c index 9ba79d4..a5f9e2b 100644 --- a/fuzzer.c +++ b/fuzzer.c @@ -92,6 +92,29 @@ int test_canary(unsigned char *buf) { return 1; } +int FUZ_SecurityTest() +{ + char* output; + char* input; + int i, r; + + printf("Starting security tests..."); + input = (char*) malloc (20<<20); + output = (char*) malloc (20<<20); + input[0] = 0x0F; + input[1] = 0x00; + input[2] = 0x00; + for(i = 3; i < 16840000; i++) + input[i] = 0xff; + r = LZ4_uncompress(input, output, 20<<20); + + free(input); + free(output); + printf(" Completed (r=%i)\n",r); + return 0; +} + + //int main(int argc, char *argv[]) { int main() { unsigned long long bytes = 0; @@ -116,7 +139,9 @@ int main() { } printf("Seed = %u\n", seed); - for (i = 0; i < 2048; i++) + FUZ_SecurityTest(); + + for (i = 0; i < 2048; i++) cbuf[FUZ_avail + i] = cbuf[FUZ_avail + 2048 + i] = FUZ_rand(&seed) >> 16; for (i = 0; i < NB_ATTEMPTS; i++) { diff --git a/lz4.c b/lz4.c index 00d6f95..a35f12b 100644 --- a/lz4.c +++ b/lz4.c @@ -68,8 +68,18 @@ #endif // Little Endian or Big Endian ? -// Note : overwrite the below #define if you know your architecture endianess -#if (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN) || defined(_ARCH_PPC) || defined(__PPC__) || defined(__PPC) || defined(PPC) || defined(__powerpc__) || defined(__powerpc) || defined(powerpc) || ((defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))) ) +// Overwrite the #define below if you know your architecture endianess +#if defined (__GLIBC__) +# include +# if (__BYTE_ORDER == __BIG_ENDIAN) +# define LZ4_BIG_ENDIAN 1 +# endif +#elif (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)) && !(defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN)) +# define LZ4_BIG_ENDIAN 1 +#elif defined(__sparc) || defined(__sparc__) \ + || defined(__ppc__) || defined(_POWER) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(__PPC__) || defined(__PPC) || defined(PPC) || defined(__powerpc__) || defined(__powerpc) || defined(powerpc) \ + || defined(__hpux) || defined(__hppa) \ + || defined(_MIPSEB) || defined(__s390__) # define LZ4_BIG_ENDIAN 1 #else // Little Endian assumed. PDP Endian and other very rare endian format are unsupported. @@ -77,7 +87,7 @@ // Unaligned memory access is automatically enabled for "common" CPU, such as x86. // For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected -// If you know your target CPU supports unaligned memory access, you may want to force this option manually to improve performance +// If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance #if defined(__ARM_FEATURE_UNALIGNED) # define LZ4_FORCE_UNALIGNED_ACCESS 1 #endif @@ -721,7 +731,7 @@ int LZ4_uncompress(const char* source, cpy = op+length; if unlikely(cpy>oend-COPYLENGTH) { - if (cpy != oend) goto _output_error; // Error : we must necessarily stand at EOF + if (cpy != oend) goto _output_error; // Error : not enough place for another match (min 4) + 5 literals memcpy(op, ip, length); ip += length; break; // EOF @@ -743,13 +753,13 @@ int LZ4_uncompress(const char* source, #else const int dec64 = 0; #endif - op[0] = ref[0]; + op[0] = ref[0]; op[1] = ref[1]; op[2] = ref[2]; op[3] = ref[3]; op += 4, ref += 4; ref -= dec32table[op-ref]; A32(op) = A32(ref); - op += STEPSIZE-4; ref -= dec64; + op += STEPSIZE-4; ref -= dec64; } else { LZ4_COPYSTEP(ref,op); } cpy = op + length - (STEPSIZE-4); if (cpy>oend-COPYLENGTH) @@ -832,13 +842,13 @@ int LZ4_uncompress_unknownOutputSize( #else const int dec64 = 0; #endif - op[0] = ref[0]; + op[0] = ref[0]; op[1] = ref[1]; op[2] = ref[2]; op[3] = ref[3]; op += 4, ref += 4; ref -= dec32table[op-ref]; A32(op) = A32(ref); - op += STEPSIZE-4; ref -= dec64; + op += STEPSIZE-4; ref -= dec64; } else { LZ4_COPYSTEP(ref,op); } cpy = op + length - (STEPSIZE-4); if (cpy>oend-COPYLENGTH) diff --git a/lz4demo.c b/lz4demo.c index 067ac2e..8b9a0b9 100644 --- a/lz4demo.c +++ b/lz4demo.c @@ -59,7 +59,7 @@ #if defined(_MSC_VER) // Visual Studio #define swap32 _byteswap_ulong -#elif GCC_VERSION >= 430 +#elif GCC_VERSION >= 403 #define swap32 __builtin_bswap32 #else static inline unsigned int swap32(unsigned int x) { diff --git a/lz4hc.c b/lz4hc.c index 7cd8bb4..200efda 100644 --- a/lz4hc.c +++ b/lz4hc.c @@ -37,23 +37,39 @@ //************************************** // 32 or 64 bits ? #if (defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64) || defined(__ppc64__) || defined(_WIN64) || defined(__LP64__) || defined(_LP64) ) // Detects 64 bits mode -#define LZ4_ARCH64 1 +# define LZ4_ARCH64 1 #else -#define LZ4_ARCH64 0 +# define LZ4_ARCH64 0 #endif -// Little Endian or Big Endian ? -#if (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN) || defined(_ARCH_PPC) || defined(__PPC__) || defined(__PPC) || defined(PPC) || defined(__powerpc__) || defined(__powerpc) || defined(powerpc) || ((defined(__BYTE_ORDER__)&&(__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))) ) -#define LZ4_BIG_ENDIAN 1 +// Little Endian or Big Endian ? +// Overwrite the #define below if you know your architecture endianess +#if defined (__GLIBC__) +# include +# if (__BYTE_ORDER == __BIG_ENDIAN) +# define LZ4_BIG_ENDIAN 1 +# endif +#elif (defined(__BIG_ENDIAN__) || defined(__BIG_ENDIAN) || defined(_BIG_ENDIAN)) && !(defined(__LITTLE_ENDIAN__) || defined(__LITTLE_ENDIAN) || defined(_LITTLE_ENDIAN)) +# define LZ4_BIG_ENDIAN 1 +#elif defined(__sparc) || defined(__sparc__) \ + || defined(__ppc__) || defined(_POWER) || defined(__powerpc__) || defined(_ARCH_PPC) || defined(__PPC__) || defined(__PPC) || defined(PPC) || defined(__powerpc__) || defined(__powerpc) || defined(powerpc) \ + || defined(__hpux) || defined(__hppa) \ + || defined(_MIPSEB) || defined(__s390__) +# define LZ4_BIG_ENDIAN 1 #else // Little Endian assumed. PDP Endian and other very rare endian format are unsupported. #endif // Unaligned memory access is automatically enabled for "common" CPU, such as x86. // For others CPU, the compiler will be more cautious, and insert extra code to ensure aligned access is respected -// If you know your target CPU supports unaligned memory access, you may want to force this option manually to improve performance +// If you know your target CPU supports unaligned memory access, you want to force this option manually to improve performance #if defined(__ARM_FEATURE_UNALIGNED) -#define LZ4_FORCE_UNALIGNED_ACCESS 1 +# define LZ4_FORCE_UNALIGNED_ACCESS 1 +#endif + +// Define this parameter if your target system or compiler does not support hardware bit count +#if defined(_MSC_VER) && defined(_WIN32_WCE) // Visual Studio for Windows CE does not support Hardware bit count +# define LZ4_FORCE_SW_BITCOUNT #endif @@ -63,7 +79,7 @@ #if __STDC_VERSION__ >= 199901L // C99 /* "restrict" is a known keyword */ #else -#define restrict // Disable restrict +# define restrict // Disable restrict #endif #ifdef _MSC_VER -- cgit v0.12