blaze822: don't prefix first header with nul bytes

Instead, look for the first header as a special case.
This allows us to parse a header as-is without shifting in memory.
pull/1/merge
Christian Neukirchen 8 years ago
parent 0552c3708e
commit 7c0663e0e5

@ -227,6 +227,52 @@ blaze822_addr(char *s, char **dispo, char **addro)
return s; return s;
} }
static void
unfold_hdr(char *buf, char *end)
{
char *s = buf;
while (s < end && *s != ':') {
*s = lc(*s);
s++;
}
for (; s < end; s++) {
if (*s == 0) // sanitize nul bytes in headers
*s = ' ';
if (*s == '\r') {
if (*(s+1) == '\n') {
*s++ = '\n';
} else {
*s = ' ';
}
}
if (iswsp(*s)) {
// change prior \n to spaces
int j;
for (j = 1; s - j >= buf && *(s-j) == '\n'; j++)
*(s-j) = ' ';
}
if (*s == '\n') {
s++;
if (iswsp(*s)) {
*(s-1) = ' ';
} else {
*(s-1) = 0;
if (s-2 > buf && *(s-2) == '\n') // ex-crlf
*(s-2) = 0;
while (s < end && *s != ':') {
*s = lc(*s);
s++;
}
}
}
}
}
struct message * struct message *
blaze822(char *file) blaze822(char *file)
{ {
@ -237,25 +283,27 @@ blaze822(char *file)
ssize_t used; ssize_t used;
char *end; char *end;
struct message *mesg = malloc(sizeof (struct message));
if (!mesg)
return 0;
fd = open(file, O_RDONLY); fd = open(file, O_RDONLY);
if (fd < 0) { if (fd < 0) {
// perror("open"); // perror("open");
return 0; return 0;
} }
buf = malloc(3); buf = 0;
if (!buf) bufalloc = 0;
return 0; used = 0;
buf[0] = '\n';
buf[1] = '\n';
buf[2] = '\n';
bufalloc = 3;
used = 3;
while (1) { while (1) {
int overlap = used > 3 ? 3 : 0;
bufalloc += bufsiz; bufalloc += bufsiz;
buf = realloc(buf, bufalloc); buf = realloc(buf, bufalloc);
if (!buf) { if (!buf) {
free(mesg);
close(fd); close(fd);
return 0; return 0;
} }
@ -266,13 +314,14 @@ blaze822(char *file)
break; break;
} }
if (rd < 0) { if (rd < 0) {
free(mesg);
free(buf); free(buf);
close(fd); close(fd);
return 0; return 0;
} }
if ((end = memmem(buf-1+used, rd+1, "\n\n", 2)) || if ((end = memmem(buf-overlap+used, rd+overlap, "\n\n", 2)) ||
(end = memmem(buf-3+used, rd+3, "\r\n\r\n", 4))) { (end = memmem(buf-overlap+used, rd+overlap, "\r\n\r\n", 4))) {
used += rd; used += rd;
end++; end++;
break; break;
@ -284,51 +333,7 @@ blaze822(char *file)
*end = 0; // dereferencing *end is safe *end = 0; // dereferencing *end is safe
char *s; unfold_hdr(buf, end);
for (s = buf; s < end; s++) {
if (*s == 0) // sanitize nul bytes in headers
*s = ' ';
if (*s == '\r') {
if (*(s+1) == '\n') {
*s++ = '\n';
} else {
*s = ' ';
}
}
if (iswsp(*s)) {
// change prior \n to spaces
int j;
for (j = 1; s - j >= buf && *(s-j) == '\n'; j++)
*(s-j) = ' ';
}
if (*s == '\n') {
s++;
if (iswsp(*s)) {
*(s-1) = ' ';
} else {
*(s-1) = 0;
if (s-2 > buf && *(s-2) == '\n') // ex-crlf
*(s-2) = 0;
while (s < end && *s != ':') {
*s = lc(*s);
s++;
}
}
}
}
buf[0] = 0;
buf[1] = 0;
buf[2] = 0;
struct message *mesg = malloc(sizeof (struct message));
if (!mesg) {
free(buf);
return 0;
}
mesg->msg = buf; mesg->msg = buf;
mesg->end = end; mesg->end = end;
@ -345,12 +350,9 @@ blaze822_mem(char *src, size_t len)
char *buf; char *buf;
char *end; char *end;
buf = malloc(3); struct message *mesg = malloc(sizeof (struct message));
if (!buf) if (!mesg)
return 0; return 0;
buf[0] = '\n';
buf[1] = '\n';
buf[2] = '\n';
end = memmem(src, len, "\n\n", 2); end = memmem(src, len, "\n\n", 2);
if (!end) end = memmem(src, len, "\r\n\r\n", 4); if (!end) end = memmem(src, len, "\r\n\r\n", 4);
@ -358,59 +360,15 @@ blaze822_mem(char *src, size_t len)
len = end - src; len = end - src;
buf = realloc(buf, len+3+1); buf = malloc(len+1);
memcpy(buf+3, src, len); if (!buf)
return 0;
memcpy(buf, src, len);
end = buf+3+1+len; end = buf+len+1;
*end = 0; // dereferencing *end is safe *end = 0; // dereferencing *end is safe
/// XXX merge with below unfold_hdr(buf, end);
char *s;
for (s = buf; s < end; s++) {
if (*s == 0) // sanitize nul bytes in headers
*s = ' ';
if (*s == '\r') {
if (*(s+1) == '\n') {
*s++ = '\n';
} else {
*s = ' ';
}
}
if (iswsp(*s)) {
// change prior \n to spaces
int j;
for (j = 1; s - j >= buf && *(s-j) == '\n'; j++)
*(s-j) = ' ';
}
if (*s == '\n') {
s++;
if (iswsp(*s)) {
*(s-1) = ' ';
} else {
*(s-1) = 0;
if (s-2 > buf && *(s-2) == '\n') // ex-crlf
*(s-2) = 0;
while (s < end && *s != ':') {
*s = lc(*s);
s++;
}
}
}
}
buf[0] = 0;
buf[1] = 0;
buf[2] = 0;
struct message *mesg = malloc(sizeof (struct message));
if (!mesg) {
free(buf);
return 0;
}
mesg->msg = buf; mesg->msg = buf;
mesg->end = end; mesg->end = end;
@ -440,7 +398,11 @@ blaze822_hdr_(struct message *mesg, const char *hdr, size_t hdrlen)
{ {
char *v; char *v;
v = memmem(mesg->msg, mesg->end - mesg->msg, hdr, hdrlen); // special case: first header, no leading nul
if (memcmp(mesg->msg, hdr+1, hdrlen-1) == 0)
v = mesg->msg;
else
v = memmem(mesg->msg, mesg->end - mesg->msg, hdr, hdrlen);
if (!v) if (!v)
return 0; return 0;
v += hdrlen; v += hdrlen;

Loading…
Cancel
Save