--- MPlayer-1.0pre5/libmpdemux/pnm.c 2003-10-04 19:29:01.000000000 +0200 +++ MPlayer-1.0pre5try2/libmpdemux/pnm.c 2004-12-15 21:37:11.000000000 +0100 @@ -307,9 +307,12 @@ 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 @@ 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 @@ 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 */ + 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 @@ } 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 @@ 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);