summary refs log tree commit diff
path: root/gnu/packages/patches/graphite2-fix-32-bit-wrap-arounds.patch
blob: 57d4ce2c6e3420afab3e1eca75bc8898b81bf250 (plain) (blame)
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
This patch incorporates the following 6 consecutive commits from the upstream
graphite2 repository:

75b83cd..: Martin Hosken 2017-03-28 Fix 32-bit wrap arounds
1f97e36..: Martin Hosken 2017-03-28 balance comparisons in decompressor
9493785..: Martin Hosken 2017-03-29 Speculative rounding fix
09af043..: Tim Eves      2017-03-31 Move a MINMATCH to rhs of a comparisio
28cc60d..: Tim Eves      2017-03-31 Deal with similar wrap around in literal_len
8afc7d0..: Martin Hosken 2017-04-03 Fix 32-bit rollover in decompressor, again

This diff was generated by the following command:

  git diff 1ce331d5548b98ed..8afc7d0081959866


diff --git a/src/Decompressor.cpp b/src/Decompressor.cpp
index 084570f..56d531f 100644
--- a/src/Decompressor.cpp
+++ b/src/Decompressor.cpp
@@ -51,7 +51,7 @@ bool read_sequence(u8 const * &src, u8 const * const end, u8 const * &literal, u
     literal = src;
     src += literal_len;
     
-    if (src > end - 2)
+    if (src > end - 2 || src < literal)
         return false;
     
     match_dist  = *src++;
@@ -85,7 +85,7 @@ int lz4::decompress(void const *in, size_t in_size, void *out, size_t out_size)
         {
             // Copy in literal. At this point the last full sequence must be at
             // least MINMATCH + 5 from the end of the output buffer.
-            if (dst + align(literal_len) > dst_end - (MINMATCH+5))
+            if (align(literal_len) > unsigned(dst_end - dst - (MINMATCH+5)) || dst_end - dst < MINMATCH + 5)
                 return -1;
             dst = overrun_copy(dst, literal, literal_len);
         }
@@ -94,7 +94,8 @@ int lz4::decompress(void const *in, size_t in_size, void *out, size_t out_size)
         //  decoded output.
         u8 const * const pcpy = dst - match_dist;
         if (pcpy < static_cast<u8*>(out)
-                  || dst + match_len + MINMATCH > dst_end - 5)
+                  || match_len > unsigned(dst_end - dst - (MINMATCH+5))
+                  || dst_end - dst < MINMATCH + 5)
             return -1;
         if (dst > pcpy+sizeof(unsigned long) 
             && dst + align(match_len + MINMATCH) <= dst_end)
@@ -103,8 +104,8 @@ int lz4::decompress(void const *in, size_t in_size, void *out, size_t out_size)
             dst = safe_copy(dst, pcpy, match_len + MINMATCH);
     }
     
-    if (literal + literal_len > src_end
-              || dst + literal_len > dst_end)
+    if (literal_len > src_end - literal
+              || literal_len > dst_end - dst)
         return -1;
     dst = fast_copy(dst, literal, literal_len);
     
diff --git a/src/Pass.cpp b/src/Pass.cpp
index a4bac2e..683143c 100644
--- a/src/Pass.cpp
+++ b/src/Pass.cpp
@@ -171,7 +171,7 @@ bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t su
     const uint16 * const o_actions = reinterpret_cast<const uint16 *>(p);
     be::skip<uint16>(p, m_numRules + 1);
     const byte * const states = p;
-    if (e.test(p + 2u*m_numTransition*m_numColumns >= pass_end, E_BADPASSLENGTH)) return face.error(e);
+    if (e.test(2u*m_numTransition*m_numColumns >= (unsigned)(pass_end - p), E_BADPASSLENGTH)) return face.error(e);
     be::skip<int16>(p, m_numTransition*m_numColumns);
     be::skip<uint8>(p);
     if (e.test(p != pcCode, E_BADPASSCCODEPTR)) return face.error(e);
@@ -192,7 +192,7 @@ bool Pass::readPass(const byte * const pass_start, size_t pass_length, size_t su
         m_cPConstraint = vm::Machine::Code(true, pcCode, pcCode + pass_constraint_len, 
                                   precontext[0], be::peek<uint16>(sort_keys), *m_silf, face, PASS_TYPE_UNKNOWN);
         if (e.test(!m_cPConstraint, E_OUTOFMEM)
-                || e.test(!m_cPConstraint, m_cPConstraint.status() + E_CODEFAILURE))
+                || e.test(m_cPConstraint.status() != Code::loaded, m_cPConstraint.status() + E_CODEFAILURE))
             return face.error(e);
         face.error_context(face.error_context() - 1);
     }
diff --git a/src/Silf.cpp b/src/Silf.cpp
index 72a22cd..d661992 100644
--- a/src/Silf.cpp
+++ b/src/Silf.cpp
@@ -191,7 +191,7 @@ bool Silf::readGraphite(const byte * const silf_start, size_t lSilf, Face& face,
 
     const size_t clen = readClassMap(p, passes_start - p, version, e);
     m_passes = new Pass[m_numPasses];
-    if (e || e.test(p + clen > passes_start, E_BADPASSESSTART)
+    if (e || e.test(clen > unsigned(passes_start - p), E_BADPASSESSTART)
           || e.test(!m_passes, E_OUTOFMEM))
     { releaseBuffers(); return face.error(e); }