Merge pull request #159 from christiansandberg/reduced-inflate-memory-usage

Reduce memory usage for inflate
This commit is contained in:
Martin Raiber
2022-02-06 14:16:40 +01:00
committed by GitHub
2 changed files with 61 additions and 47 deletions

View File

@@ -108,10 +108,10 @@ extern "C" {
/* It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a */ /* It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a */
/* Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the */ /* Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the */
/* bit buffer contains >=15 bits (deflate's max. Huffman code size). */ /* bit buffer contains >=15 bits (deflate's max. Huffman code size). */
#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \ #define TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree) \
do \ do \
{ \ { \
temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \ temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
if (temp >= 0) \ if (temp >= 0) \
{ \ { \
code_len = temp >> 9; \ code_len = temp >> 9; \
@@ -123,7 +123,7 @@ extern "C" {
code_len = TINFL_FAST_LOOKUP_BITS; \ code_len = TINFL_FAST_LOOKUP_BITS; \
do \ do \
{ \ { \
temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
} while ((temp < 0) && (num_bits >= (code_len + 1))); \ } while ((temp < 0) && (num_bits >= (code_len + 1))); \
if (temp >= 0) \ if (temp >= 0) \
break; \ break; \
@@ -139,7 +139,7 @@ extern "C" {
/* The slow path is only executed at the very end of the input buffer. */ /* The slow path is only executed at the very end of the input buffer. */
/* v1.16: The original macro handled the case at the very end of the passed-in input buffer, but we also need to handle the case where the user passes in 1+zillion bytes */ /* v1.16: The original macro handled the case at the very end of the passed-in input buffer, but we also need to handle the case where the user passes in 1+zillion bytes */
/* following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier. */ /* following the deflate data and our non-conservative read-ahead path won't kick in here on this code. This is much trickier. */
#define TINFL_HUFF_DECODE(state_index, sym, pHuff) \ #define TINFL_HUFF_DECODE(state_index, sym, pLookUp, pTree) \
do \ do \
{ \ { \
int temp; \ int temp; \
@@ -148,7 +148,7 @@ extern "C" {
{ \ { \
if ((pIn_buf_end - pIn_buf_cur) < 2) \ if ((pIn_buf_end - pIn_buf_cur) < 2) \
{ \ { \
TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \ TINFL_HUFF_BITBUF_FILL(state_index, pLookUp, pTree); \
} \ } \
else \ else \
{ \ { \
@@ -157,14 +157,14 @@ extern "C" {
num_bits += 16; \ num_bits += 16; \
} \ } \
} \ } \
if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \ if ((temp = pLookUp[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
code_len = temp >> 9, temp &= 511; \ code_len = temp >> 9, temp &= 511; \
else \ else \
{ \ { \
code_len = TINFL_FAST_LOOKUP_BITS; \ code_len = TINFL_FAST_LOOKUP_BITS; \
do \ do \
{ \ { \
temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \ temp = pTree[~temp + ((bit_buf >> code_len++) & 1)]; \
} while (temp < 0); \ } while (temp < 0); \
} \ } \
sym = temp; \ sym = temp; \
@@ -175,12 +175,15 @@ extern "C" {
tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags) tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags)
{ {
static const int s_length_base[31] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 }; static const mz_uint16 s_length_base[31] = { 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0 };
static const int s_length_extra[31] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0 }; static const mz_uint8 s_length_extra[31] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0 };
static const int s_dist_base[32] = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0 }; static const mz_uint16 s_dist_base[32] = { 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0 };
static const int s_dist_extra[32] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 }; static const mz_uint8 s_dist_extra[32] = { 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 };
static const mz_uint8 s_length_dezigzag[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 }; static const mz_uint8 s_length_dezigzag[19] = { 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
static const int s_min_table_sizes[3] = { 257, 1, 4 }; static const mz_uint16 s_min_table_sizes[3] = { 257, 1, 4 };
mz_int16 *pTrees[3];
mz_uint8 *pCode_sizes[3];
tinfl_status status = TINFL_STATUS_FAILED; tinfl_status status = TINFL_STATUS_FAILED;
mz_uint32 num_bits, dist, counter, num_extra; mz_uint32 num_bits, dist, counter, num_extra;
@@ -196,6 +199,13 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
return TINFL_STATUS_BAD_PARAM; return TINFL_STATUS_BAD_PARAM;
} }
pTrees[0] = r->m_tree_0;
pTrees[1] = r->m_tree_1;
pTrees[2] = r->m_tree_2;
pCode_sizes[0] = r->m_code_size_0;
pCode_sizes[1] = r->m_code_size_1;
pCode_sizes[2] = r->m_code_size_2;
num_bits = r->m_num_bits; num_bits = r->m_num_bits;
bit_buf = r->m_bit_buf; bit_buf = r->m_bit_buf;
dist = r->m_dist; dist = r->m_dist;
@@ -273,11 +283,11 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
{ {
if (r->m_type == 1) if (r->m_type == 1)
{ {
mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint8 *p = r->m_code_size_0;
mz_uint i; mz_uint i;
r->m_table_sizes[0] = 288; r->m_table_sizes[0] = 288;
r->m_table_sizes[1] = 32; r->m_table_sizes[1] = 32;
TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32); TINFL_MEMSET(r->m_code_size_1, 5, 32);
for (i = 0; i <= 143; ++i) for (i = 0; i <= 143; ++i)
*p++ = 8; *p++ = 8;
for (; i <= 255; ++i) for (; i <= 255; ++i)
@@ -294,26 +304,30 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]);
r->m_table_sizes[counter] += s_min_table_sizes[counter]; r->m_table_sizes[counter] += s_min_table_sizes[counter];
} }
MZ_CLEAR_ARR(r->m_tables[2].m_code_size); MZ_CLEAR_ARR(r->m_code_size_2);
for (counter = 0; counter < r->m_table_sizes[2]; counter++) for (counter = 0; counter < r->m_table_sizes[2]; counter++)
{ {
mz_uint s; mz_uint s;
TINFL_GET_BITS(14, s, 3); TINFL_GET_BITS(14, s, 3);
r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; r->m_code_size_2[s_length_dezigzag[counter]] = (mz_uint8)s;
} }
r->m_table_sizes[2] = 19; r->m_table_sizes[2] = 19;
} }
for (; (int)r->m_type >= 0; r->m_type--) for (; (int)r->m_type >= 0; r->m_type--)
{ {
int tree_next, tree_cur; int tree_next, tree_cur;
tinfl_huff_table *pTable; mz_int16 *pLookUp;
mz_int16 *pTree;
mz_uint8 *pCode_size;
mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16];
pTable = &r->m_tables[r->m_type]; pLookUp = r->m_look_up[r->m_type];
pTree = pTrees[r->m_type];
pCode_size = pCode_sizes[r->m_type];
MZ_CLEAR_ARR(total_syms); MZ_CLEAR_ARR(total_syms);
MZ_CLEAR_ARR(pTable->m_look_up); TINFL_MEMSET(pLookUp, 0, sizeof(r->m_look_up[0]));
MZ_CLEAR_ARR(pTable->m_tree); TINFL_MEMSET(pTree, 0, r->m_table_sizes[r->m_type] * sizeof(pTree[0]) * 2);
for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) for (i = 0; i < r->m_table_sizes[r->m_type]; ++i)
total_syms[pTable->m_code_size[i]]++; total_syms[pCode_size[i]]++;
used_syms = 0, total = 0; used_syms = 0, total = 0;
next_code[0] = next_code[1] = 0; next_code[0] = next_code[1] = 0;
for (i = 1; i <= 15; ++i) for (i = 1; i <= 15; ++i)
@@ -327,7 +341,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
} }
for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index) for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
{ {
mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; mz_uint rev_code = 0, l, cur_code, code_size = pCode_size[sym_index];
if (!code_size) if (!code_size)
continue; continue;
cur_code = next_code[code_size]++; cur_code = next_code[code_size]++;
@@ -338,14 +352,14 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
mz_int16 k = (mz_int16)((code_size << 9) | sym_index); mz_int16 k = (mz_int16)((code_size << 9) | sym_index);
while (rev_code < TINFL_FAST_LOOKUP_SIZE) while (rev_code < TINFL_FAST_LOOKUP_SIZE)
{ {
pTable->m_look_up[rev_code] = k; pLookUp[rev_code] = k;
rev_code += (1 << code_size); rev_code += (1 << code_size);
} }
continue; continue;
} }
if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) if (0 == (tree_cur = pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)]))
{ {
pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; pLookUp[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next;
tree_cur = tree_next; tree_cur = tree_next;
tree_next -= 2; tree_next -= 2;
} }
@@ -353,24 +367,24 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
{ {
tree_cur -= ((rev_code >>= 1) & 1); tree_cur -= ((rev_code >>= 1) & 1);
if (!pTable->m_tree[-tree_cur - 1]) if (!pTree[-tree_cur - 1])
{ {
pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; pTree[-tree_cur - 1] = (mz_int16)tree_next;
tree_cur = tree_next; tree_cur = tree_next;
tree_next -= 2; tree_next -= 2;
} }
else else
tree_cur = pTable->m_tree[-tree_cur - 1]; tree_cur = pTree[-tree_cur - 1];
} }
tree_cur -= ((rev_code >>= 1) & 1); tree_cur -= ((rev_code >>= 1) & 1);
pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index; pTree[-tree_cur - 1] = (mz_int16)sym_index;
} }
if (r->m_type == 2) if (r->m_type == 2)
{ {
for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);) for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);)
{ {
mz_uint s; mz_uint s;
TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); TINFL_HUFF_DECODE(16, dist, r->m_look_up[2], r->m_tree_2);
if (dist < 16) if (dist < 16)
{ {
r->m_len_codes[counter++] = (mz_uint8)dist; r->m_len_codes[counter++] = (mz_uint8)dist;
@@ -390,8 +404,8 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
{ {
TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED); TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
} }
TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_code_size_0, r->m_len_codes, r->m_table_sizes[0]);
TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]); TINFL_MEMCPY(r->m_code_size_1, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
} }
} }
for (;;) for (;;)
@@ -401,7 +415,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
{ {
if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2)) if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
{ {
TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]); TINFL_HUFF_DECODE(23, counter, r->m_look_up[0], r->m_tree_0);
if (counter >= 256) if (counter >= 256)
break; break;
while (pOut_buf_cur >= pOut_buf_end) while (pOut_buf_cur >= pOut_buf_end)
@@ -429,14 +443,14 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
num_bits += 16; num_bits += 16;
} }
#endif #endif
if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
code_len = sym2 >> 9; code_len = sym2 >> 9;
else else
{ {
code_len = TINFL_FAST_LOOKUP_BITS; code_len = TINFL_FAST_LOOKUP_BITS;
do do
{ {
sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
} while (sym2 < 0); } while (sym2 < 0);
} }
counter = sym2; counter = sym2;
@@ -453,14 +467,14 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
num_bits += 16; num_bits += 16;
} }
#endif #endif
if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) if ((sym2 = r->m_look_up[0][bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
code_len = sym2 >> 9; code_len = sym2 >> 9;
else else
{ {
code_len = TINFL_FAST_LOOKUP_BITS; code_len = TINFL_FAST_LOOKUP_BITS;
do do
{ {
sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; sym2 = r->m_tree_0[~sym2 + ((bit_buf >> code_len++) & 1)];
} while (sym2 < 0); } while (sym2 < 0);
} }
bit_buf >>= code_len; bit_buf >>= code_len;
@@ -489,7 +503,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
counter += extra_bits; counter += extra_bits;
} }
TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]); TINFL_HUFF_DECODE(26, dist, r->m_look_up[1], r->m_tree_1);
num_extra = s_dist_extra[dist]; num_extra = s_dist_extra[dist];
dist = s_dist_base[dist]; dist = s_dist_base[dist];
if (num_extra) if (num_extra)
@@ -574,7 +588,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
--pIn_buf_cur; --pIn_buf_cur;
num_bits -= 8; num_bits -= 8;
} }
bit_buf &= (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1); bit_buf &= ~(~(tinfl_bit_buf_t)0 << num_bits);
MZ_ASSERT(!num_bits); /* if this assert fires then we've read beyond the end of non-deflate/zlib streams with following data (such as gzip streams). */ MZ_ASSERT(!num_bits); /* if this assert fires then we've read beyond the end of non-deflate/zlib streams with following data (such as gzip streams). */
if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
@@ -606,7 +620,7 @@ common_exit:
} }
} }
r->m_num_bits = num_bits; r->m_num_bits = num_bits;
r->m_bit_buf = bit_buf & (tinfl_bit_buf_t)((((mz_uint64)1) << num_bits) - (mz_uint64)1); r->m_bit_buf = bit_buf & ~(~(tinfl_bit_buf_t)0 << num_bits);
r->m_dist = dist; r->m_dist = dist;
r->m_counter = counter; r->m_counter = counter;
r->m_num_extra = num_extra; r->m_num_extra = num_extra;

View File

@@ -112,12 +112,6 @@ enum
TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
}; };
typedef struct
{
mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
} tinfl_huff_table;
#if MINIZ_HAS_64BIT_REGISTERS #if MINIZ_HAS_64BIT_REGISTERS
#define TINFL_USE_64BIT_BITBUF 1 #define TINFL_USE_64BIT_BITBUF 1
#else #else
@@ -137,7 +131,13 @@ struct tinfl_decompressor_tag
mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES]; mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
tinfl_bit_buf_t m_bit_buf; tinfl_bit_buf_t m_bit_buf;
size_t m_dist_from_out_buf_start; size_t m_dist_from_out_buf_start;
tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES]; mz_int16 m_look_up[TINFL_MAX_HUFF_TABLES][TINFL_FAST_LOOKUP_SIZE];
mz_int16 m_tree_0[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
mz_int16 m_tree_1[TINFL_MAX_HUFF_SYMBOLS_1 * 2];
mz_int16 m_tree_2[TINFL_MAX_HUFF_SYMBOLS_2 * 2];
mz_uint8 m_code_size_0[TINFL_MAX_HUFF_SYMBOLS_0];
mz_uint8 m_code_size_1[TINFL_MAX_HUFF_SYMBOLS_1];
mz_uint8 m_code_size_2[TINFL_MAX_HUFF_SYMBOLS_2];
mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137]; mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
}; };