control: tag -1 + patch
control: retitle -1: sqlite FTBFS with gcc-7/8 on architectures with unsigned 
char

On 2017-08-18 11:07, Adrian Bunk wrote:
> Source: sqlite
> Version: 2.8.17-14
> Severity: serious
> Tags: buster sid
> 
> https://tests.reproducible-builds.org/debian/rb-pkg/unstable/arm64/sqlite.html
> 
> ...
> cc -g -O2 -fstack-protector-strong -Wformat -Werror=format-security 
> -DTHREADSAFE=1 -o lemon ./tool/lemon.c
> ./tool/lemon.c: In function 'tplt_open':
> ./tool/lemon.c:2821:7: warning: implicit declaration of function 'access' 
> [-Wimplicit-function-declaration]
>    if( access(buf,004)==0 ){
>        ^~~~~~
> ./tool/lemon.c:2713:14: note: previous declaration of 'access' was here
>    extern int access();
>               ^~~~~~
> cp ./tool/lempar.c .
> cp ./src/parse.y .
> ./lemon parse.y
> Makefile:261: recipe for target 'parse.c' failed
> make[2]: *** [parse.c] Segmentation fault
> make[2]: *** Deleting file 'parse.c'
> make[2]: Leaving directory '/build/1st/sqlite-2.8.17'
> debian/rules:37: recipe for target 'override_dh_auto_build' failed
> make[1]: *** [override_dh_auto_build] Error 2

The crash happens in that part of the code (line 3073):

|    hash = 0;
|    for(j=0; stddt[j]; j++){
|      hash = hash*53 + stddt[j];
|    }
|    hash = (hash & 0x7fffffff)%arraysize;
|    while( types[hash] ){
|      if( strcmp(types[hash],stddt)==0 ){

In some cases, hash ends up with a negative value, causing the crash.
Starting with gcc-7, the & 0x7fffffff is optimized out on architectures
which have an unsigned char. stddt is defined as a char, and hash as a
(signed) int. Integer wraparound (overflow) is not defined by the C
standard, so GCC is allowed to optimize out the bitwise operation if
sddt is unsigned.

The correct way to fix that is to define has as an unsigned type, like
in the patch below:

--- sqlite-2.8.17.orig/tool/lemon.c
+++ sqlite-2.8.17/tool/lemon.c
@@ -3018,7 +3018,7 @@ int mhflag;                 /* True if g
   int maxdtlength;          /* Maximum length of any ".datatype" field. */
   char *stddt;              /* Standardized name for a datatype */
   int i,j;                  /* Loop counters */
-  int hash;                 /* For hashing the name of a type */
+  unsigned int hash;        /* For hashing the name of a type */
   char *name;               /* Name of the parser */

-- 
Aurelien Jarno                          GPG: 4096R/1DDD8C9B
aurel...@aurel32.net                 http://www.aurel32.net

Reply via email to