소스 검색

Merge pull request #12687 from richardkchapman/sanitize_checks

HPCC-22178 Use sanitize options on debug builds to pick up undefined behaviour

Reviewed-by: Gavin Halliday <ghalliday@hpccsystems.com>
Gavin Halliday 5 년 전
부모
커밋
37055a35bf

+ 5 - 0
cmake_modules/commonSetup.cmake

@@ -338,6 +338,11 @@ IF ("${COMMONSETUP_DONE}" STREQUAL "")
   if (CMAKE_COMPILER_IS_GNUCC AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
     add_definitions (-fvisibility=hidden)
   endif ()
+  if (((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0.0) OR CMAKE_COMPILER_IS_CLANGXX) AND CMAKE_BUILD_TYPE STREQUAL "Debug")
+    add_definitions (-fsanitize=undefined -fno-sanitize=alignment -fsanitize-trap=undefined)
+    SET (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fsanitize=undefined")
+    SET (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined")
+  endif ()
   if (CMAKE_COMPILER_IS_CLANGXX)
     execute_process( COMMAND ${CMAKE_CXX_COMPILER} --version OUTPUT_VARIABLE clang_full_version_string )
     if (${clang_full_version_string} MATCHES "Apple LLVM version ([0-9]+\\.[0-9]+\\.[0-9]+).*")

+ 2 - 2
common/deftype/defvalue.cpp

@@ -1945,8 +1945,8 @@ IValue *createBitfieldValue(__int64 val, ITypeInfo * type)
 {
 #ifdef _DEBUG
     size32_t bitsize = type->getBitSize();
-    if (bitsize != sizeof(__int64) * 8)
-        val = val & (((__int64)1 << bitsize)-1);
+    if (bitsize != sizeof(__uint64) * 8)
+        val = val & (((__uint64)1 << bitsize)-1);
 #endif
     return new BitfieldValue(val, type);
 }

+ 0 - 1
common/thorhelper/roxiehelper.cpp

@@ -1959,7 +1959,6 @@ FlushingStringBuffer::FlushingStringBuffer(SafeSocket *_sock, bool _isBlocked, T
     isSoap = false;
     isEmpty = true;
     extend = false;
-    trim = false;
     emptyLength = 0;
     tagClosed = true;
 }

+ 0 - 1
common/thorhelper/roxiehelper.hpp

@@ -444,7 +444,6 @@ public:
     bool isSoap;
     bool isEmpty;
     bool extend;
-    bool trim;
     bool tagClosed;
     StringAttr queryName;
     StringBuffer s;

+ 2 - 2
common/thorhelper/thorrparse.cpp

@@ -3410,8 +3410,6 @@ bool RegexParser::performMatch(IMatchedAction & action, const void * row, unsign
         size32_t maxSize = algo->maxLength*charWidth;
 
         const byte * start = (const byte *)data;
-        const byte * endData = start + len;
-        const byte * end = endData - algo->minPatternLength;
 
         RegexState state(cache, algo->kind, helper, this, algo->inputFormat, len, start);
         state.row = row;
@@ -3419,6 +3417,8 @@ bool RegexParser::performMatch(IMatchedAction & action, const void * row, unsign
         state.best = NULL;
         if (len >= algo->minPatternLength)
         {
+            const byte * endData = start + len;
+            const byte * end = endData - algo->minPatternLength;
             for (const byte * curScan = start; curScan <= end;)
             {
                 state.cur = curScan;

+ 1 - 1
ecl/hql/hqlfold.cpp

@@ -1346,7 +1346,7 @@ IValue * doFoldExternalCall(IHqlExpression* expr, unsigned foldOptions, ITemplat
 #endif
         unsigned shift = (sizeof(int64result)-resultsize) * 8;
         if (retType->isSigned())
-            int64result = (int64result << shift) >> shift;
+            int64result = (__int64) ((__uint64)int64result << shift) >> shift;
         else
             int64result = (((__uint64)int64result) << shift) >> shift;
 

+ 1 - 1
ecl/hql/hqlgram.hpp

@@ -1311,7 +1311,7 @@ private:
         char *yyBuffer;
 
         static unsigned hex2digit(char c);
-        static __int64 str2int64(unsigned len, const char * digits, unsigned base);
+        static __uint64 str2uint64(unsigned len, const char * digits, unsigned base);
         static void hex2str(char * target, const char * digits, unsigned len);
 };
 

+ 6 - 6
ecl/hql/hqllex.l

@@ -911,7 +911,7 @@ RETRY               { RETURNSYM(RETRY); }
 RETURN              { RETURNSYM(RETURN); }
 RIGHT               { RETURNSYM(RIGHT); }
 RIGHT{digit}+       { 
-                        returnToken.setInt(str2int64(CUR_TOKEN_LENGTH-5, (const char *)CUR_TOKEN_TEXT+5, 10)); 
+                        returnToken.setInt(str2uint64(CUR_TOKEN_LENGTH-5, (const char *)CUR_TOKEN_TEXT+5, 10)); 
                         RETURNSYM(RIGHT_NN); 
                     }
 ROLLUP              { RETURNSYM(ROLLUP); }
@@ -1685,35 +1685,35 @@ FUNCTIONMACRO|MACRO {
                         setupdatepos;
                         bool isSigned = toupper(CUR_TOKEN_TEXT[CUR_TOKEN_LENGTH-1]) != 'U';
                         unsigned len = isSigned ? CUR_TOKEN_LENGTH-2 : CUR_TOKEN_LENGTH-3;
-                        returnToken.setExpr(createIntegerConstant(str2int64(len,(const char *)CUR_TOKEN_TEXT+2, 16), isSigned));
+                        returnToken.setExpr(createIntegerConstant(str2uint64(len,(const char *)CUR_TOKEN_TEXT+2, 16), isSigned));
                         return(INTEGER_CONST);
                     }
 {digit}{hexdigit}*XU? {
                         setupdatepos;
                         bool isSigned = toupper(CUR_TOKEN_TEXT[CUR_TOKEN_LENGTH-1]) != 'U';
                         unsigned len = isSigned ? CUR_TOKEN_LENGTH-1 : CUR_TOKEN_LENGTH-2;
-                        returnToken.setExpr(createIntegerConstant(str2int64(len,(const char *)CUR_TOKEN_TEXT, 16), isSigned));
+                        returnToken.setExpr(createIntegerConstant(str2uint64(len,(const char *)CUR_TOKEN_TEXT, 16), isSigned));
                         return(INTEGER_CONST);
                     }
 0b{bindigit}+U?     {
                         setupdatepos;
                         bool isSigned = toupper(CUR_TOKEN_TEXT[CUR_TOKEN_LENGTH-1]) != 'U';
                         unsigned len = isSigned ? CUR_TOKEN_LENGTH-2 : CUR_TOKEN_LENGTH-3;
-                        returnToken.setExpr(createIntegerConstant(str2int64(len,(const char *)CUR_TOKEN_TEXT+2, 2), isSigned));
+                        returnToken.setExpr(createIntegerConstant(str2uint64(len,(const char *)CUR_TOKEN_TEXT+2, 2), isSigned));
                         return(INTEGER_CONST);
                     }
 {bindigit}+BU?      {
                         setupdatepos;
                         bool isSigned = toupper(CUR_TOKEN_TEXT[CUR_TOKEN_LENGTH-1]) != 'U';
                         unsigned len = isSigned ? CUR_TOKEN_LENGTH-1 : CUR_TOKEN_LENGTH-2;
-                        returnToken.setExpr(createIntegerConstant(str2int64(len,(const char *)CUR_TOKEN_TEXT, 2), isSigned));
+                        returnToken.setExpr(createIntegerConstant(str2uint64(len,(const char *)CUR_TOKEN_TEXT, 2), isSigned));
                         return(INTEGER_CONST);
                     }
 {digit}+U?          {
                         setupdatepos;
                         bool isSigned = toupper(CUR_TOKEN_TEXT[CUR_TOKEN_LENGTH-1]) != 'U';
                         unsigned len = isSigned ? CUR_TOKEN_LENGTH : CUR_TOKEN_LENGTH-1;
-                        returnToken.setExpr(createIntegerConstant(str2int64(len, (const char *)CUR_TOKEN_TEXT, 10), isSigned));
+                        returnToken.setExpr(createIntegerConstant(str2uint64(len, (const char *)CUR_TOKEN_TEXT, 10), isSigned));
                         return(INTEGER_CONST);
                     }
 {digit}+(d|D)       { 

+ 2 - 2
ecl/hql/hqlparse.cpp

@@ -285,9 +285,9 @@ unsigned HqlLex::hex2digit(char c)
   return (c - '0');
 }
 
-__int64 HqlLex::str2int64(unsigned len, const char * digits, unsigned base)
+__uint64 HqlLex::str2uint64(unsigned len, const char * digits, unsigned base)
 {
-  __int64 value = 0;
+  __uint64 value = 0;
   while (len--)
   {
     char c = *digits++;

+ 1 - 1
ecl/hqlcpp/hqltcppc.cpp

@@ -1593,7 +1593,7 @@ void CColumnInfo::buildClear(HqlCppTranslator & translator, BuildCtx & ctx, IRef
             {
                 __int64 value = maxIntValue[type->getSize()];
                 if (direction == -1)
-                    value = 0-(value+1);
+                    value = -value-1;
                 null.setown(createConstant(type->castFrom(true, value)));
             }
             break;

+ 4 - 4
fs/dafsclient/rmtfile.cpp

@@ -2024,7 +2024,7 @@ extern DAFSCLIENT_API void installFileHooks(const char *hookFileSpec)
     }
 }
 
-typedef void *(HookInstallFunction)();
+typedef void (*HookInstallFunction)();
 
 static void installFileHook(const char *hookFile)
 {
@@ -2041,10 +2041,10 @@ static void installFileHook(const char *hookFile)
         }
         else if (file->isFile() == foundYes)
         {
-            HookInstallFunction *hookInstall;
+            HookInstallFunction hookInstall;
             SharedObject *so = new SharedObject(); // MORE - this leaks! Kind-of deliberate right now...
             if (so->load(file->queryFilename(), false) &&
-                (hookInstall = (HookInstallFunction *) GetSharedProcedure(so->getInstanceHandle(), "installFileHook")) != NULL)
+                (hookInstall = (HookInstallFunction) GetSharedProcedure(so->getInstanceHandle(), "installFileHook")) != NULL)
             {
                 hookInstall();
                 hookDlls->append(so);
@@ -2082,7 +2082,7 @@ extern DAFSCLIENT_API void removeFileHooks()
         ForEachItemIn(idx, *hookDlls)
         {
             SharedObject *so = hookDlls->item(idx);
-            HookInstallFunction *hookInstall = (HookInstallFunction *) GetSharedProcedure(so->getInstanceHandle(), "removeFileHook");
+            HookInstallFunction hookInstall = (HookInstallFunction) GetSharedProcedure(so->getInstanceHandle(), "removeFileHook");
             if (hookInstall)
                 hookInstall();
             delete so;

+ 0 - 3
roxie/ccd/ccdprotocol.cpp

@@ -527,7 +527,6 @@ protected:
     bool isBlocked;
     bool isRaw;
     bool isHTTP;
-    bool trim;   // MORE - this is never set!
     bool adaptiveRoot = false;
     bool onlyUseFirstRow = false;
 
@@ -557,7 +556,6 @@ public:
             else
                 result = new FlushingStringBuffer(client, isBlocked, mlFmt, isRaw, isHTTP, logctx);
             result->isSoap = isHTTP;
-            result->trim = trim;
             result->queryName.set(queryName);
             resultMap.replace(result, sequence);
         }
@@ -1051,7 +1049,6 @@ public:
         else
             content = new FlushingStringBuffer(client, getIsBlocked(), mlFmt, getIsRaw(), isHTTP, logctx);
         content->isSoap = isHTTP;
-        content->trim = getTrim();
         content->queryName.set(queryName);
         if (!isHTTP)
             content->startBlock();

+ 1 - 1
roxie/ccd/ccdqueue.cpp

@@ -194,7 +194,7 @@ void RoxiePacketHeader::setException(unsigned subChannel)
 
 unsigned RoxiePacketHeader::thisChannelRetries(unsigned subChannel)
 {
-    unsigned shift = SUBCHANNEL_BITS * (subChannel);
+    unsigned shift = SUBCHANNEL_BITS * subChannel;
     unsigned mask = SUBCHANNEL_MASK << shift;
     return (retries & mask) >> shift;
 }

+ 5 - 5
rtl/eclrtl/eclrtl.cpp

@@ -547,7 +547,7 @@ static double powerOfTen(int x)
 
 
 static double kk = (1.0 / ((unsigned __int64)1<<53));
-__int64 rtlRound(double x)
+NO_SANITIZE("undefined") __int64 rtlRound(double x)
 {
     //a fudge to make numbers that are inexact after a division round up "correctly".
     //coded rather oddly as microsoft's optimizer has a habit of throwing it away otherwise...
@@ -577,14 +577,14 @@ double rtlRoundTo(const double x, int places)
     }
 }
 
-__int64 rtlRoundDown(double x)
+NO_SANITIZE("undefined") __int64 rtlRoundDown(double x)
 {
     if (x >= 0.0)
         return (__int64)floor(x);
     return (__int64)ceil(x);
 }
 
-__int64 rtlRoundUp(double x)
+NO_SANITIZE("undefined") __int64 rtlRoundUp(double x)
 {
     if (x >= 0.0)
         return (__int64)ceil(x);
@@ -1064,7 +1064,7 @@ __int64 rtlStrToInt8(size32_t l, const char * t)
 {
     bool negate = false;
     SkipSignSpaces(l, t, negate);
-    __int64 v = 0;
+    __uint64 v = 0;
     while (l--)
     {
         char c = *t++;
@@ -1073,7 +1073,7 @@ __int64 rtlStrToInt8(size32_t l, const char * t)
         else
             break;
     }
-    return negate ? -v : v;
+    return negate ? (__int64) (0-v) : (__int64) v;
 }
 
 __int64 rtlUnicodeToInt8(size32_t l, UChar const * t)

+ 8 - 8
rtl/eclrtl/rtlint.cpp

@@ -60,7 +60,7 @@ int rtlReadInt3(const void * _data)
 { 
     const unsigned short * usdata = (const unsigned short *)_data;
     const signed char * scdata = (const signed char *)_data;
-    return ((int)scdata[2] << 16) | ((int)usdata[0]);
+    return ((unsigned)(int)scdata[2] << 16) | ((int)usdata[0]);
 }
 
 unsigned rtlReadUInt3(const void * _data)
@@ -177,14 +177,14 @@ __int64 rtlReadInt5(const void * _data)
 { 
     const unsigned * udata = (const unsigned *)_data;
     const signed char * scdata = (const signed char *)_data;
-    return ((__int64)scdata[4] << 32) | ((__int64)udata[0]);
+    return ((__uint64)(__int64)scdata[4] << 32) | ((__int64)udata[0]);
 }
 
 __int64 rtlReadInt6(const void * _data)     
 { 
     const unsigned * udata = (const unsigned *)_data;
     const signed short * ssdata = (const signed short *)_data;
-    return ((__int64)ssdata[2] << 32) | ((__int64)udata[0]);
+    return ((__uint64)(__int64)ssdata[2] << 32) | ((__int64)udata[0]);
 }
 
 __int64 rtlReadInt7(const void * _data)     
@@ -192,7 +192,7 @@ __int64 rtlReadInt7(const void * _data)
     const unsigned * udata = (const unsigned *)_data;
     const unsigned short * usdata = (const unsigned short *)_data;
     const signed char * scdata = (const signed char *)_data;
-    return ((__int64)scdata[6] << 48) | ((__int64)usdata[2] << 32) | ((__int64)udata[0]);
+    return ((__uint64)(__int64)scdata[6] << 48) | ((__int64)usdata[2] << 32) | ((__int64)udata[0]);
 }
 
 unsigned __int64 rtlReadUInt5(const void * _data)       
@@ -490,22 +490,22 @@ unsigned __int64 rtlCastUInt7(unsigned __int64 value)
 
 signed rtlCastInt3(signed value)
 {
-    return (value << 8) >> 8;
+    return ((signed) ((unsigned) value << 8)) >> 8;
 }
 
 __int64 rtlCastInt5(__int64 value)
 {
-    return (value << 24) >> 24;
+    return (__int64) ((__uint64) value << 24) >> 24;
 }
 
 __int64 rtlCastInt6(__int64 value)
 {
-    return (value << 16) >> 16;
+    return (__int64) ((__uint64) value << 16) >> 16;
 }
 
 __int64 rtlCastInt7(__int64 value)
 {
-    return (value << 8) >> 8;
+    return (__int64) ((__uint64) value << 8) >> 8;
 }
 
 

+ 2 - 2
system/include/hqlplugins.hpp

@@ -61,8 +61,8 @@ struct IPluginContextEx : public IPluginContext
     virtual const char *ctxQueryProp(const char *propName) const = 0;
 };
 
-typedef bool (*EclPluginSetCtx) (IPluginContext *);
-typedef bool (*EclPluginSetCtxEx) (IPluginContextEx *);
+typedef void (*EclPluginSetCtx) (IPluginContext *);
+typedef void (*EclPluginSetCtxEx) (IPluginContextEx *);
 #define CTXMALLOC(ctx,l)    (ctx ? ctx->ctxMalloc(l) : malloc(l))
 #define CTXREALLOC(ctx,p,l) (ctx ? ctx->ctxRealloc(p,l) : realloc(p,l))
 #define CTXFREE(ctx,p)      (ctx ? ctx->ctxFree(p) : free(p))

+ 13 - 0
system/include/platform.h

@@ -526,4 +526,17 @@ typedef unsigned __int64 timestamp_type;
  #define DECL_EXCEPTION
 #endif
 
+//Sanitize support is different on every compiler
+//use these macros before a function definition to disable a particular sanitize option for the body of that function
+
+#ifdef __clang__
+ #define NO_SANITIZE(a) [[clang::no_sanitize(a)]]
+#elif __GNUC__ >= 8
+ #define NO_SANITIZE(a) [[gnu::no_sanitize(a)]]
+#else
+ #define NO_SANITIZE(a)
+#endif
+
+
+
 #endif

+ 3 - 1
system/jlib/jexcept.cpp

@@ -1104,7 +1104,7 @@ static void throwSigSegV()
 }
 #endif
 
-void excsighandler(int signum, siginfo_t *info, void *extra) 
+NO_SANITIZE("alignment") void excsighandler(int signum, siginfo_t *info, void *extra)
 {
     static byte nested=0;
     if (nested++)
@@ -1424,7 +1424,9 @@ void jlib_decl enableSEHtoExceptionMapping()
 #endif
     act.sa_sigaction = &excsighandler; 
     sigaction(SIGSEGV, &act, NULL);
+#ifndef _DEBUG
     sigaction(SIGILL, &act, NULL);
+#endif
     sigaction(SIGBUS, &act, NULL);
     sigaction(SIGFPE, &act, NULL);
     sigaction(SIGABRT, &act, NULL);

+ 14 - 11
system/jlib/jptree.cpp

@@ -2917,21 +2917,24 @@ bool PTree::checkPattern(const char *&xxpath) const
 
 AttrValue *PTree::findAttribute(const char *key) const
 {
-    AttrValue *a = attrs+numAttrs;
-    if (isnocase())
+    if (attrs)
     {
-        while (a-- != attrs)
+        AttrValue *a = attrs+numAttrs;
+        if (isnocase())
         {
-            if (strieq(a->key.get(), key))
-                return a;
+            while (a-- != attrs)
+            {
+                if (strieq(a->key.get(), key))
+                    return a;
+            }
         }
-    }
-    else
-    {
-        while (a-- != attrs)
+        else
         {
-            if (streq(a->key.get(), key))
-                return a;
+            while (a-- != attrs)
+            {
+                if (streq(a->key.get(), key))
+                    return a;
+            }
         }
     }
     return nullptr;

+ 3 - 3
system/jlib/jsocket.cpp

@@ -2927,7 +2927,7 @@ bool isInterfaceIp(const IpAddress &ip, const char *ifname)
 #endif
 }
 
-bool getInterfaceIp(IpAddress &ip,const char *ifname)
+NO_SANITIZE("alignment") bool getInterfaceIp(IpAddress &ip,const char *ifname)
 {
 #if defined(_WIN32)
     return false;
@@ -3521,7 +3521,7 @@ unsigned IpAddress::ipsetrange( const char *text)  // e.g. 10.173.72.1-65  ('-'
 }
 
 
-size32_t IpAddress::getNetAddress(size32_t maxsz,void *dst) const
+NO_SANITIZE("alignment") size32_t IpAddress::getNetAddress(size32_t maxsz,void *dst) const
 {
     if (maxsz==sizeof(unsigned)) {
         if (::isIp4(netaddr)) {
@@ -3536,7 +3536,7 @@ size32_t IpAddress::getNetAddress(size32_t maxsz,void *dst) const
     return 0;
 }
 
-void IpAddress::setNetAddress(size32_t sz,const void *src)
+NO_SANITIZE("alignment") void IpAddress::setNetAddress(size32_t sz,const void *src)
 {
     if (sz==sizeof(unsigned)) { // IPv4
         netaddr[0] = 0;

+ 7 - 0
system/jlib/jsort.cpp

@@ -56,6 +56,7 @@ static bool sortParallel(unsigned &numcpus)
 #define COMPARE(search,position)    compare(search,position)
 #define INSERT(position,search)     memmove(position,search, width)
 
+NO_SANITIZE("function")
 void * binary_add(const void *newitem, const void *base,
              size32_t nmemb, 
              size32_t width,
@@ -74,6 +75,7 @@ void * binary_add(const void *newitem, const void *base,
 #define INSERT(position,search)     *(const void * *)(position) = search
 #define NEVER_ADD
 
+NO_SANITIZE("function")
 extern jlib_decl void * binary_vec_find(const void *newitem, const void * * base,
                                         size32_t nmemb, 
                                         sortCompareFunction compare,
@@ -94,6 +96,7 @@ extern jlib_decl void * binary_vec_find(const void *newitem, const void * * base
 #define INSERT(position,search)     *(const void * *)(position) = search
 #define NEVER_ADD
 
+NO_SANITIZE("function")
 extern jlib_decl void * binary_vec_find(const void *newitem, const void * * base,
                                         size32_t nmemb, 
                                         ICompare & compare,
@@ -114,6 +117,7 @@ extern jlib_decl void * binary_vec_find(const void *newitem, const void * * base
 #define INSERT(position,search)     *(const void * *)(position) = search
 #define ALWAYS_ADD
 
+NO_SANITIZE("function")
 extern jlib_decl void * binary_vec_insert(const void *newitem, const void * * base,
                                           size32_t nmemb, 
                                           sortCompareFunction compare)
@@ -131,6 +135,7 @@ extern jlib_decl void * binary_vec_insert(const void *newitem, const void * * ba
 #define INSERT(position,search)     *(const void * *)(position) = search
 #define ALWAYS_ADD
 
+NO_SANITIZE("function")
 extern jlib_decl void * binary_vec_insert(const void *newitem, const void * * base,
                                           size32_t nmemb, 
                                           ICompare const & compare)
@@ -149,6 +154,7 @@ extern jlib_decl void * binary_vec_insert(const void *newitem, const void * * ba
 #define ALWAYS_ADD
 #define SEEK_LAST_MATCH
 
+NO_SANITIZE("function")
 extern jlib_decl void * binary_vec_insert_stable(const void *newitem, const void * * base,
                                           size32_t nmemb, 
                                           sortCompareFunction compare)
@@ -168,6 +174,7 @@ extern jlib_decl void * binary_vec_insert_stable(const void *newitem, const void
 #define ALWAYS_ADD
 #define SEEK_LAST_MATCH
 
+NO_SANITIZE("function")
 extern jlib_decl void * binary_vec_insert_stable(const void *newitem, const void * * base,
                                           size32_t nmemb, 
                                           ICompare const & compare)

+ 2 - 2
system/jlib/jutil.cpp

@@ -701,14 +701,14 @@ make_unumtostr(short);
 make_unumtostr(int);
 make_unumtostr(long);
 
-int numtostr(char *dst, __int64 _value)
+NO_SANITIZE("signed-integer-overflow") int numtostr(char *dst, __int64 _value)
 {
     int c;
     unsigned __int64 value;
     if (_value<0)
     {
         *(dst++) = '-';
-        value = (unsigned __int64) -_value;
+        value = (unsigned __int64) -_value;  // This can overflow and thus behaviour is theoretically undefined.
         c = 1;
     }
     else

+ 2 - 1
system/lz4_sm/CMakeLists.txt

@@ -38,7 +38,8 @@ ADD_DEFINITIONS( -D_LIB )
 SET_SOURCE_FILES_PROPERTIES( ${SRCS} PROPERTIES LANGUAGE C )
 
 if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG)
-    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -std=c99")
+  set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC -std=c99")
+  remove_definitions (-fsanitize=undefined -fno-sanitize=alignment -fsanitize-trap=undefined)
 endif()
 
 HPCC_ADD_LIBRARY( lz4 STATIC ${SRCS} )

+ 4 - 0
system/lzma/CMakeLists.txt

@@ -31,6 +31,10 @@ set ( SRCS
         LzmaEnc.cpp
 )
 
+include_directories ( 
+        ${HPCC_SOURCE_DIR}/system/include
+    )
+
 ADD_DEFINITIONS( -D_LIB )
 
 SET_SOURCE_FILES_PROPERTIES( ${SRCS} PROPERTIES LANGUAGE CXX )

+ 6 - 14
system/lzma/LzmaEnc.cpp

@@ -1,6 +1,7 @@
 /* LzmaEnc.cpp -- LZMA Encoder
 2009-02-02 : Igor Pavlov : Public domain */
 
+#include "platform.h"
 #include <string.h>
 
 /* #define SHOW_STAT */
@@ -819,8 +820,7 @@ static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32
 }
 
 
-
-
+NO_SANITIZE("function")
 static void MovePos(CLzmaEnc *p, UInt32 num)
 {
   #ifdef SHOW_STAT
@@ -834,6 +834,7 @@ static void MovePos(CLzmaEnc *p, UInt32 num)
   }
 }
 
+NO_SANITIZE("function")
 static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
 {
   UInt32 lenRes = 0, numPairs;
@@ -947,6 +948,7 @@ static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
 
 #define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
 
+NO_SANITIZE("function")
 static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
 {
   UInt32 numAvail, mainLen, numPairs, repMaxIndex, i, posState, lenEnd, len, cur;
@@ -1507,6 +1509,7 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
 
 #define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
 
+NO_SANITIZE("function")
 static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
 {
   UInt32 numAvail, mainLen, mainDist, numPairs, repIndex, repLen, i;
@@ -1751,6 +1754,7 @@ void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
   alloc->Free(alloc, p);
 }
 
+NO_SANITIZE("function")
 static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
 {
   UInt32 nowPos32, startPos32;
@@ -2122,18 +2126,6 @@ static size_t MyWrite(void *pp, const void *data, size_t size)
 }
 
 
-UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
-{
-  const CLzmaEnc *p = (CLzmaEnc *)pp;
-  return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
-}
-
-const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
-{
-  const CLzmaEnc *p = (CLzmaEnc *)pp;
-  return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
-}
-
 SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
     Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
 {

+ 1 - 0
thorlcr/activities/project/thprojectslave.cpp

@@ -157,6 +157,7 @@ class CPrefetchProjectSlaveActivity : public CSlaveActivity
     public:
         CPrefetcher(CPrefetchProjectSlaveActivity &_parent) : threaded("CPrefetcher", this), parent(_parent)
         {
+            recordCount = 0; full = blocked = eoq = eoi = stopped = false; eog = true;
         }
         ~CPrefetcher() { stop(); }
         PrefetchInfo *pullRecord()