|
1 | 1 | /***************************************************************************** |
2 | 2 |
|
3 | | -Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved. |
| 3 | +Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. |
4 | 4 |
|
5 | 5 | This program is free software; you can redistribute it and/or modify it under |
6 | 6 | the terms of the GNU General Public License as published by the Free Software |
@@ -55,40 +55,71 @@ mach_parse_compressed( |
55 | 55 | if (flag < 0x80UL) { |
56 | 56 | *val = flag; |
57 | 57 | return(ptr + 1); |
| 58 | + } |
| 59 | + |
| 60 | + /* Workaround GCC bug |
| 61 | + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77673: |
| 62 | + the compiler moves mach_read_from_4 right to the beginning of the |
| 63 | + function, causing and out-of-bounds read if we are reading a short |
| 64 | + integer close to the end of buffer. */ |
| 65 | +#if defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__clang__) |
| 66 | +#define DEPLOY_FENCE |
| 67 | +#endif |
| 68 | + |
| 69 | +#ifdef DEPLOY_FENCE |
| 70 | + __atomic_thread_fence(__ATOMIC_ACQUIRE); |
| 71 | +#endif |
58 | 72 |
|
59 | | - } else if (flag < 0xC0UL) { |
| 73 | + if (flag < 0xC0UL) { |
60 | 74 | if (end_ptr < ptr + 2) { |
61 | 75 | return(NULL); |
62 | 76 | } |
63 | 77 |
|
64 | 78 | *val = mach_read_from_2(ptr) & 0x7FFFUL; |
65 | 79 |
|
66 | 80 | return(ptr + 2); |
| 81 | + } |
| 82 | + |
| 83 | +#ifdef DEPLOY_FENCE |
| 84 | + __atomic_thread_fence(__ATOMIC_ACQUIRE); |
| 85 | +#endif |
67 | 86 |
|
68 | | - } else if (flag < 0xE0UL) { |
| 87 | + if (flag < 0xE0UL) { |
69 | 88 | if (end_ptr < ptr + 3) { |
70 | 89 | return(NULL); |
71 | 90 | } |
72 | 91 |
|
73 | 92 | *val = mach_read_from_3(ptr) & 0x3FFFFFUL; |
74 | 93 |
|
75 | 94 | return(ptr + 3); |
76 | | - } else if (flag < 0xF0UL) { |
| 95 | + } |
| 96 | + |
| 97 | +#ifdef DEPLOY_FENCE |
| 98 | + __atomic_thread_fence(__ATOMIC_ACQUIRE); |
| 99 | +#endif |
| 100 | + |
| 101 | + if (flag < 0xF0UL) { |
77 | 102 | if (end_ptr < ptr + 4) { |
78 | 103 | return(NULL); |
79 | 104 | } |
80 | 105 |
|
81 | 106 | *val = mach_read_from_4(ptr) & 0x1FFFFFFFUL; |
82 | 107 |
|
83 | 108 | return(ptr + 4); |
84 | | - } else { |
85 | | - ut_ad(flag == 0xF0UL); |
| 109 | + } |
86 | 110 |
|
87 | | - if (end_ptr < ptr + 5) { |
88 | | - return(NULL); |
89 | | - } |
| 111 | +#ifdef DEPLOY_FENCE |
| 112 | + __atomic_thread_fence(__ATOMIC_ACQUIRE); |
| 113 | +#endif |
| 114 | + |
| 115 | +#undef DEPLOY_FENCE |
| 116 | + |
| 117 | + ut_ad(flag == 0xF0UL); |
90 | 118 |
|
91 | | - *val = mach_read_from_4(ptr + 1); |
92 | | - return(ptr + 5); |
| 119 | + if (end_ptr < ptr + 5) { |
| 120 | + return(NULL); |
93 | 121 | } |
| 122 | + |
| 123 | + *val = mach_read_from_4(ptr + 1); |
| 124 | + return(ptr + 5); |
94 | 125 | } |
0 commit comments