mirror of https://github.com/aria2/aria2
* ChunkedEncoding.{h,cc}: fixed the bug that if chunk data is binary,
decoding did not work properly.pull/1/head
parent
2a1b2c8ab4
commit
a59301bef0
|
@ -1,3 +1,8 @@
|
||||||
|
2006-03-09 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
|
* ChunkedEncoding.{h,cc}: fixed the bug that if chunk data is binary,
|
||||||
|
decoding did not work properly.
|
||||||
|
|
||||||
2006-03-07 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
2006-03-07 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||||
|
|
||||||
* DownloadEngine.h: included sys/time.h
|
* DownloadEngine.h: included sys/time.h
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
ChunkedEncoding::ChunkedEncoding() {
|
ChunkedEncoding::ChunkedEncoding() {
|
||||||
strbufSize = 4096;
|
strbufSize = 4096;
|
||||||
strbuf = new char[strbufSize];
|
strbuf = new char[strbufSize];
|
||||||
strbuf[0] = '\0';
|
strbufTail = strbuf;
|
||||||
state = READ_SIZE;
|
state = READ_SIZE;
|
||||||
chunkSize = 0;
|
chunkSize = 0;
|
||||||
}
|
}
|
||||||
|
@ -76,21 +76,21 @@ void ChunkedEncoding::inflate(char* outbuf, int& outlen, const char* inbuf, int
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Was all bytes in strbuf examined?
|
// all bytes in strbuf were examined?
|
||||||
if(strbuf+strlen(strbuf) <= p) {
|
if(strbufTail <= p) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(strbuf+strlen(strbuf) <= p) {
|
if(strbufTail <= p) {
|
||||||
// make strbuf NULL-string
|
strbufTail = strbuf;
|
||||||
strbuf[0] = '\0';
|
|
||||||
} else {
|
} else {
|
||||||
// copy string between [p, strbuf+strlen(strbuf)+1], +1 is for NULL
|
// copy string between [p, strbufTail]
|
||||||
// character.
|
int unreadSize = strbufTail-p;
|
||||||
char* temp = new char[strbufSize];
|
char* temp = new char[strbufSize];
|
||||||
memcpy(temp, p, strbuf+strlen(strbuf)-p+1);
|
memcpy(temp, p, unreadSize);
|
||||||
delete [] strbuf;
|
delete [] strbuf;
|
||||||
strbuf = temp;
|
strbuf = temp;
|
||||||
|
strbufTail = strbuf+unreadSize;
|
||||||
}
|
}
|
||||||
outlen = clen;
|
outlen = clen;
|
||||||
}
|
}
|
||||||
|
@ -103,8 +103,8 @@ int ChunkedEncoding::readData(char** pp, char* buf, int& len, int maxlen) {
|
||||||
return readDataEOL(pp);
|
return readDataEOL(pp);
|
||||||
}
|
}
|
||||||
int wsize;
|
int wsize;
|
||||||
if(strlen(*pp) < (unsigned long int)chunkSize) {
|
if(strbufTail-*pp < chunkSize) {
|
||||||
wsize = strlen(*pp) <= (unsigned int)maxlen-len ? strlen(*pp) : maxlen-len;
|
wsize = strbufTail-*pp <= maxlen-len ? strbufTail-*pp : maxlen-len;
|
||||||
} else {
|
} else {
|
||||||
wsize = chunkSize <= maxlen-len ? chunkSize : maxlen-len;
|
wsize = chunkSize <= maxlen-len ? chunkSize : maxlen-len;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,6 @@ int ChunkedEncoding::readData(char** pp, char* buf, int& len, int maxlen) {
|
||||||
chunkSize -= wsize;
|
chunkSize -= wsize;
|
||||||
len += wsize;
|
len += wsize;
|
||||||
*pp += wsize;
|
*pp += wsize;
|
||||||
|
|
||||||
if(chunkSize == 0) {
|
if(chunkSize == 0) {
|
||||||
return readDataEOL(pp);
|
return readDataEOL(pp);
|
||||||
} else {
|
} else {
|
||||||
|
@ -121,54 +120,62 @@ int ChunkedEncoding::readData(char** pp, char* buf, int& len, int maxlen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int ChunkedEncoding::readDataEOL(char** pp) {
|
int ChunkedEncoding::readDataEOL(char** pp) {
|
||||||
if(strstr(*pp, "\r\n") == *pp) {
|
char* np = (char*)memchr(*pp, '\n', strbufTail-*pp);
|
||||||
|
char* rp = (char*)memchr(*pp, '\r', strbufTail-*pp);
|
||||||
|
if(np != NULL && rp != NULL && np-rp == 1 && *pp == rp) {
|
||||||
*pp += 2;
|
*pp += 2;
|
||||||
return 0;
|
return 0;
|
||||||
} else if(strlen(*pp) < 2) {
|
} else if(strbufTail-*pp < 2) {
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
throw new DlAbortEx(EX_INVALID_CHUNK_SIZE);
|
throw new DlAbortEx(EX_INVALID_CHUNK_SIZE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// strbuf is NULL terminated string, and inlen is strlen(strbuf).
|
|
||||||
// therefore, strbuf[inlen] = '\0'
|
|
||||||
int ChunkedEncoding::readChunkSize(char** pp) {
|
int ChunkedEncoding::readChunkSize(char** pp) {
|
||||||
// we read chunk-size from *pp
|
// we read chunk-size from *pp
|
||||||
char* p = strstr(*pp, "\r\n");
|
char* p;
|
||||||
|
char* np = (char*)memchr(*pp, '\n', strbufTail-*pp);
|
||||||
|
char* rp = (char*)memchr(*pp, '\r', strbufTail-*pp);
|
||||||
|
if(np == NULL || rp == NULL || np-rp != 1) {
|
||||||
// \r\n is not found. Return -1
|
// \r\n is not found. Return -1
|
||||||
if(p == NULL) {
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
p = rp;
|
||||||
|
|
||||||
// We ignore chunk-extension
|
// We ignore chunk-extension
|
||||||
char* exsp = index(*pp, ';');
|
char* exsp = (char*)memchr(*pp, ';', strbufTail-*pp);
|
||||||
if(exsp == NULL) {
|
if(exsp == NULL) {
|
||||||
exsp = p;
|
exsp = p;
|
||||||
}
|
}
|
||||||
// TODO check invalid characters in buffer
|
// TODO check invalid characters in buffer
|
||||||
chunkSize = strtol(*pp, NULL, 16);
|
char* temp = new char[exsp-*pp+1];
|
||||||
|
memcpy(temp, *pp, exsp-*pp);
|
||||||
|
temp[exsp-*pp] = '\0';
|
||||||
|
|
||||||
|
chunkSize = strtol(temp, NULL, 16);
|
||||||
if(chunkSize < 0) {
|
if(chunkSize < 0) {
|
||||||
throw new DlAbortEx(EX_INVALID_CHUNK_SIZE);
|
throw new DlAbortEx(EX_INVALID_CHUNK_SIZE);
|
||||||
} else if(errno == ERANGE && (chunkSize == LONG_MAX || chunkSize == LONG_MIN)) {
|
} else if(errno == ERANGE && (chunkSize == LONG_MAX || chunkSize == LONG_MIN)) {
|
||||||
throw new DlAbortEx(strerror(errno));
|
throw new DlAbortEx(strerror(errno));
|
||||||
}
|
}
|
||||||
*pp = p+2;
|
*pp = p+2;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChunkedEncoding::addBuffer(const char* inbuf, int inlen) {
|
void ChunkedEncoding::addBuffer(const char* inbuf, int inlen) {
|
||||||
if(strlen(strbuf)+inlen >= (unsigned int)strbufSize) {
|
int realbufSize = strbufTail-strbuf;
|
||||||
if(strlen(strbuf)+inlen+1 > MAX_BUFSIZE) {
|
if(realbufSize+inlen >= strbufSize) {
|
||||||
throw new DlAbortEx(EX_TOO_LARGE_CHUNK, strlen(strbuf)+inlen+1);
|
if(realbufSize+inlen > MAX_BUFSIZE) {
|
||||||
|
throw new DlAbortEx(EX_TOO_LARGE_CHUNK, realbufSize+inlen);
|
||||||
}
|
}
|
||||||
strbufSize = strlen(strbuf)+inlen+1;
|
strbufSize = realbufSize+inlen;
|
||||||
char* temp = new char[strbufSize];
|
char* temp = new char[strbufSize];
|
||||||
memcpy(temp, strbuf, strlen(strbuf)+1);
|
memcpy(temp, strbuf, realbufSize);
|
||||||
delete [] strbuf;
|
delete [] strbuf;
|
||||||
strbuf = temp;
|
strbuf = temp;
|
||||||
|
strbufTail = strbuf+realbufSize;
|
||||||
}
|
}
|
||||||
int origlen = strlen(strbuf);
|
memcpy(strbufTail, inbuf, inlen);
|
||||||
memcpy(strbuf+origlen, inbuf, inlen);
|
strbufTail += inlen;
|
||||||
strbuf[origlen+inlen] = '\0';
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ private:
|
||||||
int state;
|
int state;
|
||||||
char* strbuf;
|
char* strbuf;
|
||||||
int strbufSize;
|
int strbufSize;
|
||||||
|
char* strbufTail;
|
||||||
|
|
||||||
int readChunkSize(char** pp);
|
int readChunkSize(char** pp);
|
||||||
int readData(char** pp, char* buf, int& len, int maxlen);
|
int readData(char** pp, char* buf, int& len, int maxlen);
|
||||||
|
|
Loading…
Reference in New Issue