mirror of
https://github.com/openmoh/openmohaa.git
synced 2025-04-28 21:57:57 +03:00
Backported ioquake3 fixes for https://www.cvedetails.com/cve/CVE-2017-11721/ (Buffer overflow)
This commit is contained in:
parent
377b0896c2
commit
8c59d6020e
4 changed files with 65 additions and 490 deletions
|
@ -1,454 +0,0 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 1999-2005 Id Software, Inc.
|
||||
|
||||
This file is part of Quake III Arena source code.
|
||||
|
||||
Quake III Arena source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Quake III Arena source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Quake III Arena source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
/* This is based on the Adaptive Huffman algorithm described in Sayood's Data
|
||||
* Compression book. The ranks are not actually stored, but implicitly defined
|
||||
* by the location of a node within a doubly-linked list */
|
||||
|
||||
#include "q_shared.h"
|
||||
#include "qcommon.h"
|
||||
|
||||
static int bloc = 0;
|
||||
|
||||
void Huff_putBit( int bit, byte *fout, int *offset) {
|
||||
bloc = *offset;
|
||||
if ((bloc&7) == 0) {
|
||||
fout[(bloc>>3)] = 0;
|
||||
}
|
||||
fout[(bloc>>3)] |= bit << (bloc&7);
|
||||
bloc++;
|
||||
*offset = bloc;
|
||||
}
|
||||
|
||||
int Huff_getBloc(void)
|
||||
{
|
||||
return bloc;
|
||||
}
|
||||
|
||||
void Huff_setBloc(int _bloc)
|
||||
{
|
||||
bloc = _bloc;
|
||||
}
|
||||
|
||||
int Huff_getBit( byte *fin, int *offset) {
|
||||
int t;
|
||||
bloc = *offset;
|
||||
t = (fin[(bloc>>3)] >> (bloc&7)) & 0x1;
|
||||
bloc++;
|
||||
*offset = bloc;
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Add a bit to the output file (buffered) */
|
||||
static void add_bit (char bit, byte *fout) {
|
||||
if ((bloc&7) == 0) {
|
||||
fout[(bloc>>3)] = 0;
|
||||
}
|
||||
fout[(bloc>>3)] |= bit << (bloc&7);
|
||||
bloc++;
|
||||
}
|
||||
|
||||
/* Receive one bit from the input file (buffered) */
|
||||
static int get_bit (byte *fin) {
|
||||
int t;
|
||||
t = (fin[(bloc>>3)] >> (bloc&7)) & 0x1;
|
||||
bloc++;
|
||||
return t;
|
||||
}
|
||||
|
||||
static node_t **get_ppnode(huff_t* huff) {
|
||||
node_t **tppnode;
|
||||
if (!huff->freelist) {
|
||||
return &(huff->nodePtrs[huff->blocPtrs++]);
|
||||
} else {
|
||||
tppnode = huff->freelist;
|
||||
huff->freelist = (node_t **)*tppnode;
|
||||
return tppnode;
|
||||
}
|
||||
}
|
||||
|
||||
static void free_ppnode(huff_t* huff, node_t **ppnode) {
|
||||
*ppnode = (node_t *)huff->freelist;
|
||||
huff->freelist = ppnode;
|
||||
}
|
||||
|
||||
/* Swap the location of these two nodes in the tree */
|
||||
static void swap (huff_t* huff, node_t *node1, node_t *node2) {
|
||||
node_t *par1, *par2;
|
||||
|
||||
par1 = node1->parent;
|
||||
par2 = node2->parent;
|
||||
|
||||
if (par1) {
|
||||
if (par1->left == node1) {
|
||||
par1->left = node2;
|
||||
} else {
|
||||
par1->right = node2;
|
||||
}
|
||||
} else {
|
||||
huff->tree = node2;
|
||||
}
|
||||
|
||||
if (par2) {
|
||||
if (par2->left == node2) {
|
||||
par2->left = node1;
|
||||
} else {
|
||||
par2->right = node1;
|
||||
}
|
||||
} else {
|
||||
huff->tree = node1;
|
||||
}
|
||||
|
||||
node1->parent = par2;
|
||||
node2->parent = par1;
|
||||
}
|
||||
|
||||
/* Swap these two nodes in the linked list (update ranks) */
|
||||
static void swaplist(node_t *node1, node_t *node2) {
|
||||
node_t *par1;
|
||||
|
||||
par1 = node1->next;
|
||||
node1->next = node2->next;
|
||||
node2->next = par1;
|
||||
|
||||
par1 = node1->prev;
|
||||
node1->prev = node2->prev;
|
||||
node2->prev = par1;
|
||||
|
||||
if (node1->next == node1) {
|
||||
node1->next = node2;
|
||||
}
|
||||
if (node2->next == node2) {
|
||||
node2->next = node1;
|
||||
}
|
||||
if (node1->next) {
|
||||
node1->next->prev = node1;
|
||||
}
|
||||
if (node2->next) {
|
||||
node2->next->prev = node2;
|
||||
}
|
||||
if (node1->prev) {
|
||||
node1->prev->next = node1;
|
||||
}
|
||||
if (node2->prev) {
|
||||
node2->prev->next = node2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do the increments */
|
||||
static void increment(huff_t* huff, node_t *node) {
|
||||
node_t *lnode;
|
||||
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node->next != NULL && node->next->weight == node->weight) {
|
||||
lnode = *node->head;
|
||||
if (lnode != node->parent) {
|
||||
swap(huff, lnode, node);
|
||||
}
|
||||
swaplist(lnode, node);
|
||||
}
|
||||
if (node->prev && node->prev->weight == node->weight) {
|
||||
*node->head = node->prev;
|
||||
} else {
|
||||
*node->head = NULL;
|
||||
free_ppnode(huff, node->head);
|
||||
}
|
||||
node->weight++;
|
||||
if (node->next && node->next->weight == node->weight) {
|
||||
node->head = node->next->head;
|
||||
} else {
|
||||
node->head = get_ppnode(huff);
|
||||
*node->head = node;
|
||||
}
|
||||
if (node->parent) {
|
||||
increment(huff, node->parent);
|
||||
if (node->prev == node->parent) {
|
||||
swaplist(node, node->parent);
|
||||
if (*node->head == node) {
|
||||
*node->head = node->parent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Huff_addRef(huff_t* huff, byte ch) {
|
||||
node_t *tnode, *tnode2;
|
||||
if (huff->loc[ch] == NULL) { /* if this is the first transmission of this node */
|
||||
tnode = &(huff->nodeList[huff->blocNode++]);
|
||||
tnode2 = &(huff->nodeList[huff->blocNode++]);
|
||||
|
||||
tnode2->symbol = INTERNAL_NODE;
|
||||
tnode2->weight = 1;
|
||||
tnode2->next = huff->lhead->next;
|
||||
if (huff->lhead->next) {
|
||||
huff->lhead->next->prev = tnode2;
|
||||
if (huff->lhead->next->weight == 1) {
|
||||
tnode2->head = huff->lhead->next->head;
|
||||
} else {
|
||||
tnode2->head = get_ppnode(huff);
|
||||
*tnode2->head = tnode2;
|
||||
}
|
||||
} else {
|
||||
tnode2->head = get_ppnode(huff);
|
||||
*tnode2->head = tnode2;
|
||||
}
|
||||
huff->lhead->next = tnode2;
|
||||
tnode2->prev = huff->lhead;
|
||||
|
||||
tnode->symbol = ch;
|
||||
tnode->weight = 1;
|
||||
tnode->next = huff->lhead->next;
|
||||
if (huff->lhead->next) {
|
||||
huff->lhead->next->prev = tnode;
|
||||
if (huff->lhead->next->weight == 1) {
|
||||
tnode->head = huff->lhead->next->head;
|
||||
} else {
|
||||
/* this should never happen */
|
||||
tnode->head = get_ppnode(huff);
|
||||
*tnode->head = tnode2;
|
||||
}
|
||||
} else {
|
||||
/* this should never happen */
|
||||
tnode->head = get_ppnode(huff);
|
||||
*tnode->head = tnode;
|
||||
}
|
||||
huff->lhead->next = tnode;
|
||||
tnode->prev = huff->lhead;
|
||||
tnode->left = tnode->right = NULL;
|
||||
|
||||
if (huff->lhead->parent) {
|
||||
if (huff->lhead->parent->left == huff->lhead) { /* lhead is guaranteed to by the NYT */
|
||||
huff->lhead->parent->left = tnode2;
|
||||
} else {
|
||||
huff->lhead->parent->right = tnode2;
|
||||
}
|
||||
} else {
|
||||
huff->tree = tnode2;
|
||||
}
|
||||
|
||||
tnode2->right = tnode;
|
||||
tnode2->left = huff->lhead;
|
||||
|
||||
tnode2->parent = huff->lhead->parent;
|
||||
huff->lhead->parent = tnode->parent = tnode2;
|
||||
|
||||
huff->loc[ch] = tnode;
|
||||
|
||||
increment(huff, tnode2->parent);
|
||||
} else {
|
||||
increment(huff, huff->loc[ch]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get a symbol */
|
||||
int Huff_Receive (node_t *node, int *ch, byte *fin) {
|
||||
while (node && node->symbol == INTERNAL_NODE) {
|
||||
if (get_bit(fin)) {
|
||||
node = node->right;
|
||||
} else {
|
||||
node = node->left;
|
||||
}
|
||||
}
|
||||
if (!node) {
|
||||
return 0;
|
||||
// Com_Error(ERR_DROP, "Illegal tree!");
|
||||
}
|
||||
return (*ch = node->symbol);
|
||||
}
|
||||
|
||||
/* Get a symbol */
|
||||
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) {
|
||||
*ch = 0;
|
||||
*offset = maxoffset + 1;
|
||||
return;
|
||||
}
|
||||
if (get_bit(fin)) {
|
||||
node = node->right;
|
||||
} else {
|
||||
node = node->left;
|
||||
}
|
||||
}
|
||||
if (!node) {
|
||||
*ch = 0;
|
||||
return;
|
||||
// Com_Error(ERR_DROP, "Illegal tree!");
|
||||
}
|
||||
*ch = node->symbol;
|
||||
*offset = bloc;
|
||||
}
|
||||
|
||||
/* Send the prefix code for this node */
|
||||
static void send(node_t *node, node_t *child, byte *fout, int maxoffset) {
|
||||
if (node->parent) {
|
||||
send(node->parent, node, fout, maxoffset);
|
||||
}
|
||||
if (child) {
|
||||
if (bloc >= maxoffset) {
|
||||
bloc = maxoffset + 1;
|
||||
return;
|
||||
}
|
||||
if (node->right == child) {
|
||||
add_bit(1, fout);
|
||||
} else {
|
||||
add_bit(0, fout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Send a symbol */
|
||||
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, maxoffset);
|
||||
for (i = 7; i >= 0; i--) {
|
||||
add_bit((char)((ch >> i) & 0x1), fout);
|
||||
}
|
||||
} else {
|
||||
send(huff->loc[ch], NULL, fout, maxoffset);
|
||||
}
|
||||
}
|
||||
|
||||
void Huff_offsetTransmit (huff_t *huff, int ch, byte *fout, int *offset, int maxoffset) {
|
||||
bloc = *offset;
|
||||
send(huff->loc[ch], NULL, fout, maxoffset);
|
||||
*offset = bloc;
|
||||
}
|
||||
|
||||
void Huff_Decompress(msg_t *mbuf, int offset) {
|
||||
int ch, cch, i, j, size;
|
||||
byte seq[65536];
|
||||
byte* buffer;
|
||||
huff_t huff;
|
||||
|
||||
size = mbuf->cursize - offset;
|
||||
buffer = mbuf->data + offset;
|
||||
|
||||
if ( size <= 0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
Com_Memset(&huff, 0, sizeof(huff_t));
|
||||
// Initialize the tree & list with the NYT node
|
||||
huff.tree = huff.lhead = huff.ltail = huff.loc[NYT] = &(huff.nodeList[huff.blocNode++]);
|
||||
huff.tree->symbol = NYT;
|
||||
huff.tree->weight = 0;
|
||||
huff.lhead->next = huff.lhead->prev = NULL;
|
||||
huff.tree->parent = huff.tree->left = huff.tree->right = NULL;
|
||||
|
||||
cch = buffer[0]*256 + buffer[1];
|
||||
// don't overflow with bad messages
|
||||
if ( cch > mbuf->maxsize - offset ) {
|
||||
cch = mbuf->maxsize - offset;
|
||||
}
|
||||
bloc = 16;
|
||||
|
||||
for ( j = 0; j < cch; j++ ) {
|
||||
ch = 0;
|
||||
// don't overflow reading from the messages
|
||||
// FIXME: would it be better to have an overflow check in get_bit ?
|
||||
if ( (bloc >> 3) > size ) {
|
||||
seq[j] = 0;
|
||||
break;
|
||||
}
|
||||
Huff_Receive(huff.tree, &ch, buffer); /* Get a character */
|
||||
if ( ch == NYT ) { /* We got a NYT, get the symbol associated with it */
|
||||
ch = 0;
|
||||
for ( i = 0; i < 8; i++ ) {
|
||||
ch = (ch<<1) + get_bit(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
seq[j] = ch; /* Write symbol */
|
||||
|
||||
Huff_addRef(&huff, (byte)ch); /* Increment node */
|
||||
}
|
||||
mbuf->cursize = cch + offset;
|
||||
Com_Memcpy(mbuf->data + offset, seq, cch);
|
||||
}
|
||||
|
||||
extern int oldsize;
|
||||
|
||||
void Huff_Compress(msg_t *mbuf, int offset) {
|
||||
int i, ch, size;
|
||||
byte seq[65536];
|
||||
byte* buffer;
|
||||
huff_t huff;
|
||||
|
||||
size = mbuf->cursize - offset;
|
||||
buffer = mbuf->data + offset;
|
||||
|
||||
if (size<=0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Com_Memset(&huff, 0, sizeof(huff_t));
|
||||
// Add the NYT (not yet transmitted) node into the tree/list */
|
||||
huff.tree = huff.lhead = huff.loc[NYT] = &(huff.nodeList[huff.blocNode++]);
|
||||
huff.tree->symbol = NYT;
|
||||
huff.tree->weight = 0;
|
||||
huff.lhead->next = huff.lhead->prev = NULL;
|
||||
huff.tree->parent = huff.tree->left = huff.tree->right = NULL;
|
||||
|
||||
seq[0] = (size>>8);
|
||||
seq[1] = size&0xff;
|
||||
|
||||
bloc = 16;
|
||||
|
||||
for (i=0; i<size; i++ ) {
|
||||
ch = buffer[i];
|
||||
Huff_transmit(&huff, ch, seq, size<<3); /* Transmit symbol */
|
||||
Huff_addRef(&huff, (byte)ch); /* Do update */
|
||||
}
|
||||
|
||||
bloc += 8; // next byte
|
||||
|
||||
mbuf->cursize = (bloc>>3) + offset;
|
||||
Com_Memcpy(mbuf->data+offset, seq, (bloc>>3));
|
||||
}
|
||||
|
||||
void Huff_Init(huffman_t *huff) {
|
||||
|
||||
Com_Memset(&huff->compressor, 0, sizeof(huff_t));
|
||||
Com_Memset(&huff->decompressor, 0, sizeof(huff_t));
|
||||
|
||||
// Initialize the tree & list with the NYT node
|
||||
huff->decompressor.tree = huff->decompressor.lhead = huff->decompressor.ltail = huff->decompressor.loc[NYT] = &(huff->decompressor.nodeList[huff->decompressor.blocNode++]);
|
||||
huff->decompressor.tree->symbol = NYT;
|
||||
huff->decompressor.tree->weight = 0;
|
||||
huff->decompressor.lhead->next = huff->decompressor.lhead->prev = NULL;
|
||||
huff->decompressor.tree->parent = huff->decompressor.tree->left = huff->decompressor.tree->right = NULL;
|
||||
|
||||
// Add the NYT (not yet transmitted) node into the tree/list */
|
||||
huff->compressor.tree = huff->compressor.lhead = huff->compressor.loc[NYT] = &(huff->compressor.nodeList[huff->compressor.blocNode++]);
|
||||
huff->compressor.tree->symbol = NYT;
|
||||
huff->compressor.tree->weight = 0;
|
||||
huff->compressor.lhead->next = huff->compressor.lhead->prev = NULL;
|
||||
huff->compressor.tree->parent = huff->compressor.tree->left = huff->compressor.tree->right = NULL;
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|||
#include "q_shared.h"
|
||||
#include "qcommon.h"
|
||||
|
||||
int bloc = 0;
|
||||
static int bloc = 0;
|
||||
|
||||
void Huff_putBit( int bit, byte *fout, int *offset) {
|
||||
bloc = *offset;
|
||||
|
@ -39,6 +39,16 @@ void Huff_putBit( int bit, byte *fout, int *offset) {
|
|||
*offset = bloc;
|
||||
}
|
||||
|
||||
int Huff_getBloc(void)
|
||||
{
|
||||
return bloc;
|
||||
}
|
||||
|
||||
void Huff_setBloc(int _bloc)
|
||||
{
|
||||
bloc = _bloc;
|
||||
}
|
||||
|
||||
int Huff_getBit( byte *fin, int *offset) {
|
||||
int t;
|
||||
bloc = *offset;
|
||||
|
@ -263,15 +273,20 @@ int Huff_Receive (node_t *node, int *ch, byte *fin) {
|
|||
}
|
||||
if (!node) {
|
||||
return 0;
|
||||
// Com_Error(ERR_DROP, "Illegal tree!\n");
|
||||
// Com_Error(ERR_DROP, "Illegal tree!");
|
||||
}
|
||||
return (*ch = node->symbol);
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
*ch = 0;
|
||||
*offset = maxoffset + 1;
|
||||
return;
|
||||
}
|
||||
if (get_bit(fin)) {
|
||||
node = node->right;
|
||||
} else {
|
||||
|
@ -281,18 +296,22 @@ void Huff_offsetReceive (node_t *node, int *ch, byte *fin, int *offset) {
|
|||
if (!node) {
|
||||
*ch = 0;
|
||||
return;
|
||||
// Com_Error(ERR_DROP, "Illegal tree!\n");
|
||||
// Com_Error(ERR_DROP, "Illegal tree!");
|
||||
}
|
||||
*ch = node->symbol;
|
||||
*offset = bloc;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
bloc = maxoffset + 1;
|
||||
return;
|
||||
}
|
||||
if (node->right == child) {
|
||||
add_bit(1, fout);
|
||||
} else {
|
||||
|
@ -302,22 +321,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;
|
||||
}
|
||||
|
||||
|
@ -354,7 +373,7 @@ void Huff_Decompress(msg_t *mbuf, int offset) {
|
|||
for ( j = 0; j < cch; j++ ) {
|
||||
ch = 0;
|
||||
// don't overflow reading from the messages
|
||||
// FIXME: would it be better to have a overflow check in get_bit ?
|
||||
// FIXME: would it be better to have an overflow check in get_bit ?
|
||||
if ( (bloc >> 3) > size ) {
|
||||
seq[j] = 0;
|
||||
break;
|
||||
|
@ -385,7 +404,7 @@ void Huff_Compress(msg_t *mbuf, int offset) {
|
|||
huff_t huff;
|
||||
|
||||
size = mbuf->cursize - offset;
|
||||
buffer = mbuf->data+ + offset;
|
||||
buffer = mbuf->data + offset;
|
||||
|
||||
if (size<=0) {
|
||||
return;
|
||||
|
@ -398,16 +417,15 @@ void Huff_Compress(msg_t *mbuf, int offset) {
|
|||
huff.tree->weight = 0;
|
||||
huff.lhead->next = huff.lhead->prev = NULL;
|
||||
huff.tree->parent = huff.tree->left = huff.tree->right = NULL;
|
||||
huff.loc[NYT] = huff.tree;
|
||||
|
||||
seq[0] = ( byte )(size>>8);
|
||||
seq[1] = ( byte )size&0xff;
|
||||
seq[0] = (byte)(size>>8);
|
||||
seq[1] = (byte)(size&0xff);
|
||||
|
||||
bloc = 16;
|
||||
|
||||
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 */
|
||||
}
|
||||
|
||||
|
|
|
@ -232,9 +232,7 @@ void MSG_WriteBits( msg_t *msg, int value, int bits ) {
|
|||
|
||||
oldsize += bits;
|
||||
|
||||
// this isn't an exact overflow check, but close enough
|
||||
if ( msg->maxsize - msg->cursize < 4 ) {
|
||||
msg->overflowed = qtrue;
|
||||
if ( msg->overflowed ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -294,6 +292,10 @@ void MSG_WriteBits( msg_t *msg, int value, int bits ) {
|
|||
if (bits&7) {
|
||||
int nbits;
|
||||
nbits = bits&7;
|
||||
if ( msg->bit + nbits > msg->maxsize << 3 ) {
|
||||
msg->overflowed = qtrue;
|
||||
return;
|
||||
}
|
||||
for(i=0;i<nbits;i++) {
|
||||
Huff_putBit((value&1), msg->data, &msg->bit);
|
||||
value = (value>>1);
|
||||
|
@ -302,8 +304,13 @@ void MSG_WriteBits( msg_t *msg, int value, int bits ) {
|
|||
}
|
||||
if (bits) {
|
||||
for(i=0;i<bits;i+=8) {
|
||||
Huff_offsetTransmit (&msgHuff.compressor, (value&0xff), msg->data, &msg->bit);
|
||||
Huff_offsetTransmit( &msgHuff.compressor, (value & 0xff), msg->data, &msg->bit, msg->maxsize << 3 );
|
||||
value = (value>>8);
|
||||
|
||||
if ( msg->bit > msg->maxsize << 3 ) {
|
||||
msg->overflowed = qtrue;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
msg->cursize = (msg->bit>>3)+1;
|
||||
|
@ -316,6 +323,10 @@ int MSG_ReadBits( msg_t *msg, int bits ) {
|
|||
qboolean sgn;
|
||||
int i, nbits;
|
||||
|
||||
if ( msg->readcount > msg->cursize ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
value = 0;
|
||||
|
||||
if ( bits < 0 ) {
|
||||
|
@ -358,6 +369,10 @@ int MSG_ReadBits( msg_t *msg, int bits ) {
|
|||
nbits = 0;
|
||||
if (bits&7) {
|
||||
nbits = bits&7;
|
||||
if (msg->bit + nbits > msg->cursize << 3) {
|
||||
msg->readcount = msg->cursize + 1;
|
||||
return 0;
|
||||
}
|
||||
for(i=0;i<nbits;i++) {
|
||||
value |= (Huff_getBit(msg->data, &msg->bit)<<i);
|
||||
}
|
||||
|
@ -365,8 +380,13 @@ int MSG_ReadBits( msg_t *msg, int bits ) {
|
|||
}
|
||||
if (bits) {
|
||||
for(i=0;i<bits;i+=8) {
|
||||
Huff_offsetReceive (msgHuff.decompressor.tree, &get, msg->data, &msg->bit);
|
||||
Huff_offsetReceive (msgHuff.decompressor.tree, &get, msg->data, &msg->bit, msg->cursize<<3);
|
||||
value |= (get<<(i+nbits));
|
||||
|
||||
if (msg->bit > msg->cursize<<3) {
|
||||
msg->readcount = msg->cursize + 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
msg->readcount = (msg->bit>>3)+1;
|
||||
|
@ -758,7 +778,7 @@ char *MSG_ReadString( msg_t *msg ) {
|
|||
l = 0;
|
||||
do {
|
||||
c = MSG_ReadByte(msg); // use ReadByte so -1 is out of bounds
|
||||
if (!c || c == -1) {
|
||||
if ( c == -1 || c == 0 ) {
|
||||
break;
|
||||
}
|
||||
// translate all fmt spec to avoid crash bugs
|
||||
|
@ -790,10 +810,6 @@ char *MSG_ReadBigString( msg_t *msg ) {
|
|||
if ( c == '%' ) {
|
||||
c = '.';
|
||||
}
|
||||
// don't allow higher ascii values
|
||||
if ( c > 127 ) {
|
||||
c = '.';
|
||||
}
|
||||
|
||||
string[l] = (char)c;
|
||||
l++;
|
||||
|
@ -811,18 +827,13 @@ char *MSG_ReadStringLine( msg_t *msg ) {
|
|||
l = 0;
|
||||
do {
|
||||
c = MSG_ReadByte(msg); // use ReadByte so -1 is out of bounds
|
||||
if (c <= 0 || c == '\n') {
|
||||
//if (c == -1 || c == 0 || c == '\n') { //Q3
|
||||
if (c == -1 || c == 0 || c == '\n') {
|
||||
break;
|
||||
}
|
||||
// translate all fmt spec to avoid crash bugs
|
||||
if ( c == '%' ) {
|
||||
c = '.';
|
||||
}
|
||||
// don't allow higher ascii values
|
||||
if ( c > 127 ) {
|
||||
c = '.';
|
||||
}
|
||||
|
||||
string[l] = c;
|
||||
l++;
|
||||
|
|
|
@ -1426,9 +1426,9 @@ void Huff_Decompress(msg_t *buf, int offset);
|
|||
void Huff_Init(huffman_t *huff);
|
||||
void Huff_addRef(huff_t* huff, byte ch);
|
||||
int Huff_Receive (node_t *node, int *ch, byte *fin);
|
||||
void Huff_transmit (huff_t *huff, int ch, byte *fout);
|
||||
void Huff_offsetReceive (node_t *node, int *ch, byte *fin, int *offset);
|
||||
void Huff_offsetTransmit (huff_t *huff, int ch, byte *fout, int *offset);
|
||||
void Huff_transmit (huff_t *huff, int ch, byte *fout, int maxoffset);
|
||||
void Huff_offsetReceive (node_t *node, int *ch, byte *fin, int *offset, int maxoffset);
|
||||
void Huff_offsetTransmit (huff_t *huff, int ch, byte *fout, int *offset, int maxoffset);
|
||||
void Huff_putBit( int bit, byte *fout, int *offset);
|
||||
int Huff_getBit( byte *fout, int *offset);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue