summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2006-03-09 13:36:19 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2006-03-09 13:36:19 +0000
commit178b823802560ea03d381e95659f581bb20018ef (patch)
treed8eeec0b37216f0dee29f2d96f609485c18bab9a /src
parent21ca3f1f6f2c67ac62c48e1edcc93730d443f35c (diff)
Diffstat (limited to 'src')
-rw-r--r--src/ChunkedEncoding.cc67
-rw-r--r--src/ChunkedEncoding.h1
2 files changed, 38 insertions, 30 deletions
diff --git a/src/ChunkedEncoding.cc b/src/ChunkedEncoding.cc
index a9bd694e..496f02aa 100644
--- a/src/ChunkedEncoding.cc
+++ b/src/ChunkedEncoding.cc
@@ -31,7 +31,7 @@
ChunkedEncoding::ChunkedEncoding() {
strbufSize = 4096;
strbuf = new char[strbufSize];
- strbuf[0] = '\0';
+ strbufTail = strbuf;
state = READ_SIZE;
chunkSize = 0;
}
@@ -76,21 +76,21 @@ void ChunkedEncoding::inflate(char* outbuf, int& outlen, const char* inbuf, int
} else {
break;
}
- // Was all bytes in strbuf examined?
- if(strbuf+strlen(strbuf) <= p) {
+ // all bytes in strbuf were examined?
+ if(strbufTail <= p) {
break;
}
}
- if(strbuf+strlen(strbuf) <= p) {
- // make strbuf NULL-string
- strbuf[0] = '\0';
+ if(strbufTail <= p) {
+ strbufTail = strbuf;
} else {
- // copy string between [p, strbuf+strlen(strbuf)+1], +1 is for NULL
- // character.
+ // copy string between [p, strbufTail]
+ int unreadSize = strbufTail-p;
char* temp = new char[strbufSize];
- memcpy(temp, p, strbuf+strlen(strbuf)-p+1);
+ memcpy(temp, p, unreadSize);
delete [] strbuf;
strbuf = temp;
+ strbufTail = strbuf+unreadSize;
}
outlen = clen;
}
@@ -103,8 +103,8 @@ int ChunkedEncoding::readData(char** pp, char* buf, int& len, int maxlen) {
return readDataEOL(pp);
}
int wsize;
- if(strlen(*pp) < (unsigned long int)chunkSize) {
- wsize = strlen(*pp) <= (unsigned int)maxlen-len ? strlen(*pp) : maxlen-len;
+ if(strbufTail-*pp < chunkSize) {
+ wsize = strbufTail-*pp <= maxlen-len ? strbufTail-*pp : maxlen-len;
} else {
wsize = chunkSize <= maxlen-len ? chunkSize : maxlen-len;
}
@@ -112,7 +112,6 @@ int ChunkedEncoding::readData(char** pp, char* buf, int& len, int maxlen) {
chunkSize -= wsize;
len += wsize;
*pp += wsize;
-
if(chunkSize == 0) {
return readDataEOL(pp);
} else {
@@ -121,54 +120,62 @@ int ChunkedEncoding::readData(char** pp, char* buf, int& len, int maxlen) {
}
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;
return 0;
- } else if(strlen(*pp) < 2) {
+ } else if(strbufTail-*pp < 2) {
return -1;
} else {
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) {
// we read chunk-size from *pp
- char* p = strstr(*pp, "\r\n");
- // \r\n is not found. Return -1
- if(p == NULL) {
+ 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
return -1;
}
+ p = rp;
+
// We ignore chunk-extension
- char* exsp = index(*pp, ';');
+ char* exsp = (char*)memchr(*pp, ';', strbufTail-*pp);
if(exsp == NULL) {
exsp = p;
}
// 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) {
throw new DlAbortEx(EX_INVALID_CHUNK_SIZE);
} else if(errno == ERANGE && (chunkSize == LONG_MAX || chunkSize == LONG_MIN)) {
throw new DlAbortEx(strerror(errno));
}
*pp = p+2;
-
return 0;
}
void ChunkedEncoding::addBuffer(const char* inbuf, int inlen) {
- if(strlen(strbuf)+inlen >= (unsigned int)strbufSize) {
- if(strlen(strbuf)+inlen+1 > MAX_BUFSIZE) {
- throw new DlAbortEx(EX_TOO_LARGE_CHUNK, strlen(strbuf)+inlen+1);
+ int realbufSize = strbufTail-strbuf;
+ if(realbufSize+inlen >= strbufSize) {
+ 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];
- memcpy(temp, strbuf, strlen(strbuf)+1);
+ memcpy(temp, strbuf, realbufSize);
delete [] strbuf;
strbuf = temp;
+ strbufTail = strbuf+realbufSize;
}
- int origlen = strlen(strbuf);
- memcpy(strbuf+origlen, inbuf, inlen);
- strbuf[origlen+inlen] = '\0';
+ memcpy(strbufTail, inbuf, inlen);
+ strbufTail += inlen;
}
diff --git a/src/ChunkedEncoding.h b/src/ChunkedEncoding.h
index 954f4bf9..94bc3242 100644
--- a/src/ChunkedEncoding.h
+++ b/src/ChunkedEncoding.h
@@ -35,6 +35,7 @@ private:
int state;
char* strbuf;
int strbufSize;
+ char* strbufTail;
int readChunkSize(char** pp);
int readData(char** pp, char* buf, int& len, int maxlen);