summaryrefslogtreecommitdiffstats
path: root/libmpdemux
diff options
context:
space:
mode:
authorrtognimp <rtognimp@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-12-15 21:27:14 +0000
committerrtognimp <rtognimp@b3059339-0415-0410-9bf9-f77b7e298cf2>2004-12-15 21:27:14 +0000
commit74abb5e853e5784ef43fe2aca8e087fbd9b3231d (patch)
treea5de5fd0eeb7ed0f9443d7f5d8fb54acae32959d /libmpdemux
parent343d83d5a694c7a6f10a2b8a8c70839d9bbb9d57 (diff)
downloadmpv-74abb5e853e5784ef43fe2aca8e087fbd9b3231d.tar.bz2
mpv-74abb5e853e5784ef43fe2aca8e087fbd9b3231d.tar.xz
Security fixes ported from upstream (xine)
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@14165 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpdemux')
-rw-r--r--libmpdemux/pnm.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/libmpdemux/pnm.c b/libmpdemux/pnm.c
index da9e2b6f83..2a1850ee6b 100644
--- a/libmpdemux/pnm.c
+++ b/libmpdemux/pnm.c
@@ -307,9 +307,12 @@ static unsigned int pnm_get_chunk(pnm_t *p,
char *data, int *need_response) {
unsigned int chunk_size;
- int n;
+ unsigned int n;
char *ptr;
+ if (max < PREAMBLE_SIZE)
+ return -1;
+
/* get first PREAMBLE_SIZE bytes and ignore checksum */
rm_read (p->s, data, CHECKSUM_SIZE);
if (data[0] == 0x72)
@@ -317,6 +320,8 @@ static unsigned int pnm_get_chunk(pnm_t *p,
else
rm_read (p->s, data+CHECKSUM_SIZE, PREAMBLE_SIZE-CHECKSUM_SIZE);
+ max -= PREAMBLE_SIZE;
+
*chunk_type = BE_32(data);
chunk_size = BE_32(data+4);
@@ -324,18 +329,30 @@ static unsigned int pnm_get_chunk(pnm_t *p,
case PNA_TAG:
*need_response=0;
ptr=data+PREAMBLE_SIZE;
+ if (max < 1)
+ return -1;
rm_read (p->s, ptr++, 1);
+ max -= 1;
while(1) {
/* expecting following chunk format: 0x4f <chunk size> <data...> */
+ if (max < 2)
+ return -1;
rm_read (p->s, ptr, 2);
+ max -= 2;
if (*ptr == 'X') /* checking for server message */
{
printf("input_pnm: got a message from server:\n");
+ if (max < 1)
+ return -1;
rm_read (p->s, ptr+2, 1);
+ max = -1;
n=BE_16(ptr+1);
+ if (max < n)
+ return -1;
rm_read (p->s, ptr+3, n);
+ max -= n;
ptr[3+n]=0;
printf("%s\n",ptr+3);
return -1;
@@ -354,10 +371,15 @@ static unsigned int pnm_get_chunk(pnm_t *p,
}
if (*ptr != 0x4f) break;
n=ptr[1];
+ if (max < n)
+ return -1;
rm_read (p->s, ptr+2, n);
+ max -= n;
ptr+=(n+2);
}
/* the checksum of the next chunk is ignored here */
+ if (max < 1)
+ return -1;
rm_read (p->s, ptr+2, 1);
ptr+=3;
chunk_size=ptr-data;
@@ -367,10 +389,12 @@ static unsigned int pnm_get_chunk(pnm_t *p,
case PROP_TAG:
case MDPR_TAG:
case CONT_TAG:
- if (chunk_size > max) {
+ if (chunk_size > max || chunk_size < PREAMBLE_SIZE) {
printf("error: max chunk size exeeded (max was 0x%04x)\n", max);
+#ifdef LOG
n=rm_read (p->s, &data[PREAMBLE_SIZE], 0x100 - PREAMBLE_SIZE);
hexdump(data,n+PREAMBLE_SIZE);
+#endif
return -1;
}
rm_read (p->s, &data[PREAMBLE_SIZE], chunk_size-PREAMBLE_SIZE);