diff options
author | /dev/humancontroller <devhc@example.com> | 2017-08-14 14:04:02 +0200 |
---|---|---|
committer | /dev/humancontroller <devhc@example.com> | 2017-08-14 14:04:02 +0200 |
commit | 57a3338110978b37baab6f7c45935a1dff5db603 (patch) | |
tree | a9b6be3eb4b16c1e8053e8ae64b79cd0b9377181 /src/qcommon/huffman.c | |
parent | a150f425666146fbdca921ea44838b81889ec9e9 (diff) |
apply the security patch for incoming-packet VoIP-data parsing and Huffman decompression
TODO: improve this description
Diffstat (limited to 'src/qcommon/huffman.c')
-rw-r--r-- | src/qcommon/huffman.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/src/qcommon/huffman.c b/src/qcommon/huffman.c index aa8ee226..ecec416b 100644 --- a/src/qcommon/huffman.c +++ b/src/qcommon/huffman.c @@ -280,9 +280,15 @@ int Huff_Receive (node_t *node, int *ch, byte *fin) { } /* Get a symbol */ -void Huff_offsetReceive (node_t *node, int *ch, byte *fin, int *offset) { +void Huff_offsetReceive (node_t *node, int *ch, byte *fin, int *offset, int maxoffset) { bloc = *offset; while (node && node->symbol == INTERNAL_NODE) { + if (bloc >= maxoffset) { + // overflow + *ch = 0; + *offset = maxoffset + 1; + return; + } if (get_bit(fin)) { node = node->right; } else { @@ -299,11 +305,16 @@ void Huff_offsetReceive (node_t *node, int *ch, byte *fin, int *offset) { } /* Send the prefix code for this node */ -static void send(node_t *node, node_t *child, byte *fout) { +static void send(node_t *node, node_t *child, byte *fout, int maxoffset) { if (node->parent) { - send(node->parent, node, fout); + send(node->parent, node, fout, maxoffset); } if (child) { + if (bloc >= maxoffset) { + // overflow + bloc = maxoffset + 1; + return; + } if (node->right == child) { add_bit(1, fout); } else { @@ -313,22 +324,22 @@ static void send(node_t *node, node_t *child, byte *fout) { } /* Send a symbol */ -void Huff_transmit (huff_t *huff, int ch, byte *fout) { +void Huff_transmit (huff_t *huff, int ch, byte *fout, int maxoffset) { int i; if (huff->loc[ch] == NULL) { /* node_t hasn't been transmitted, send a NYT, then the symbol */ - Huff_transmit(huff, NYT, fout); + Huff_transmit(huff, NYT, fout, maxoffset); for (i = 7; i >= 0; i--) { add_bit((char)((ch >> i) & 0x1), fout); } } else { - send(huff->loc[ch], NULL, fout); + send(huff->loc[ch], NULL, fout, maxoffset); } } -void Huff_offsetTransmit (huff_t *huff, int ch, byte *fout, int *offset) { +void Huff_offsetTransmit (huff_t *huff, int ch, byte *fout, int *offset, int maxoffset) { bloc = *offset; - send(huff->loc[ch], NULL, fout); + send(huff->loc[ch], NULL, fout, maxoffset); *offset = bloc; } @@ -414,7 +425,7 @@ void Huff_Compress(msg_t *mbuf, int offset) { for (i=0; i<size; i++ ) { ch = buffer[i]; - Huff_transmit(&huff, ch, seq); /* Transmit symbol */ + Huff_transmit(&huff, ch, seq, size<<3); /* Transmit symbol */ Huff_addRef(&huff, (byte)ch); /* Do update */ } |