Package: eccodes / 2.12.0-1

grib_bits.diff Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
From: Dragoslav Sicarov <Dragoslav.Sicarov@imgtec.com>
Subject: FTBFS: grib-api - tests fail for mips
Date: Sun, 29 Dec 2013 15:13:16 +0000
Forwarded: https://software.ecmwf.int/issues/browse/SUP-1589
Last-Updated: 2016-07-27

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=733510

FTBFS: 21 of 38 tests fail when trying to build package from source on
mips. Part of build log has been attached.

The root cause of failing tests for mips is in function
grib_encode_unsigned_long() that is used for writing into grib message
buffer (function is implemented differently for big-endian and
little-endian architectures).

On big-endian architectures, function uses shift operations, where in
some corner-case situations left operand (which is of type unsigned
long; size of long equals 4 bytes for 32bit system) is shifted right by
32 bits.

According to C standard, if the value of the right operand of shift
operation is negative, or is greater than or equal to the width of the
left operand, the behaviour is undefined.

On 32-bit mips architecture shift operations by a variable number of
bits are translated to/use 'srlv' and 'sllv' instructions which shift
left operand by (right_operand mod 32) bits. In case of shifting by 32
bits, this results in left operand being unchanged. However, in order
for this package to function properly a result of 0 is expected.

Proposed patch fixes these corner-cases by setting the result of shift
operation to 0 if right operand is greater than or equal to size of long
(actually, no shifting is performed, the result is set to zero).

Index: eccodes-2.9.0/src/grib_bits.c
===================================================================
--- eccodes-2.9.0.orig/src/grib_bits.c
+++ eccodes-2.9.0/src/grib_bits.c
@@ -24,7 +24,7 @@
 long GRIB_MASK = -1;       /* Mask of sword bits */
 
 # define VALUE(p,q,b) \
- (((b)==max_nbits ? GRIB_MASK : ~(GRIB_MASK<<(b))) & ((p)>>(max_nbits-((q)+(b)))))
+ (((b)==max_nbits ? GRIB_MASK : ~(GRIB_MASK<<(b))) & (((max_nbits-((q)+(b))) >= max_nbits) ? 0 : ((p)>>(max_nbits-((q)+(b))))))
 
 # define MASKVALUE(q,b) \
  ((b)==max_nbits ? GRIB_MASK : (~(GRIB_MASK<<(b))<<(max_nbits-((q)+(b)))))
Index: eccodes-2.9.0/src/grib_bits_fast_big_endian.c
===================================================================
--- eccodes-2.9.0.orig/src/grib_bits_fast_big_endian.c
+++ eccodes-2.9.0/src/grib_bits_fast_big_endian.c
@@ -154,9 +154,16 @@ int grib_encode_unsigned_long(unsigned c
         countOfLeftmostBits = max_nbits - startBit;
         startBit = max_nbits - remainingBits;
         remainingBits -= countOfLeftmostBits;
-        destination[nextWord] =
-                ((destination[nextWord] >> countOfLeftmostBits) << countOfLeftmostBits)
-                + (VALUE(val,startBit,countOfLeftmostBits));
+	if (countOfLeftmostBits < max_nbits)
+	  {
+	    destination[nextWord] =
+	      ((destination[nextWord] >> countOfLeftmostBits) << countOfLeftmostBits)
+	      + (VALUE(val,startBit,countOfLeftmostBits));
+	  }
+	else
+	  {
+	    destination[nextWord] = (VALUE(val,startBit,countOfLeftmostBits));
+	  }
         startBit = 0;
         nextWord++;
     }