mirror of
https://github.com/cesanta/mongoose.git
synced 2026-11-10 16:31:44 +00:00
Handle OOM situations in iobuf expansion
This commit is contained in:
1 parent
b53d8439e5
commit
b8994f8bc3
9 files changed
+264
-224
No files matched your search
@@ -1,6 +1,6 @@
|
||||
#include "ssi.h"
|
||||
#include "log.h"
|
||||
#include "printf.h"
|
||||
#include "ssi.h"
|
||||
#include "util.h"
|
||||
|
||||
#ifndef MG_MAX_SSI_DEPTH
|
||||
@@ -31,31 +31,35 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
|
||||
mg_snprintf(tmp, sizeof(tmp), "%.*s%s", (int) (p - path), path, arg);
|
||||
if (depth < MG_MAX_SSI_DEPTH &&
|
||||
(data = mg_ssi(tmp, root, depth + 1)) != NULL) {
|
||||
mg_iobuf_add(&b, b.len, data, strlen(data));
|
||||
size_t datalen = strlen(data);
|
||||
size_t ret = mg_iobuf_add(&b, b.len, data, datalen);
|
||||
mg_free(data);
|
||||
if (datalen > 0 && ret == 0) goto fail;
|
||||
} else {
|
||||
MG_ERROR(("%s: file=%s error or too deep", path, arg));
|
||||
}
|
||||
} // TODO(): or OOM at recursive call
|
||||
} else if (sscanf(buf, "<!--#include virtual=\"%[^\"]", arg) > 0) {
|
||||
char tmp[MG_PATH_MAX + MG_SSI_BUFSIZ + 10], *data;
|
||||
mg_snprintf(tmp, sizeof(tmp), "%s%s", root, arg);
|
||||
if (depth < MG_MAX_SSI_DEPTH &&
|
||||
(data = mg_ssi(tmp, root, depth + 1)) != NULL) {
|
||||
mg_iobuf_add(&b, b.len, data, strlen(data));
|
||||
size_t datalen = strlen(data);
|
||||
size_t ret = mg_iobuf_add(&b, b.len, data, datalen);
|
||||
mg_free(data);
|
||||
if (datalen > 0 && ret == 0) goto fail;
|
||||
} else {
|
||||
MG_ERROR(("%s: virtual=%s error or too deep", path, arg));
|
||||
}
|
||||
} // TODO(): or OOM at recursive call
|
||||
} else {
|
||||
// Unknown SSI tag
|
||||
MG_ERROR(("Unknown SSI tag: %.*s", (int) len, buf));
|
||||
mg_iobuf_add(&b, b.len, buf, len);
|
||||
if (len > 0 && mg_iobuf_add(&b, b.len, buf, len) == 0) goto fail;
|
||||
}
|
||||
intag = 0;
|
||||
len = 0;
|
||||
} else if (ch == '<') {
|
||||
intag = 1;
|
||||
if (len > 0) mg_iobuf_add(&b, b.len, buf, len);
|
||||
if (len > 0 && mg_iobuf_add(&b, b.len, buf, len) == 0) goto fail;
|
||||
len = 0;
|
||||
buf[len++] = (char) (ch & 0xff);
|
||||
} else if (intag) {
|
||||
@@ -69,24 +73,33 @@ static char *mg_ssi(const char *path, const char *root, int depth) {
|
||||
} else {
|
||||
buf[len++] = (char) (ch & 0xff);
|
||||
if (len >= sizeof(buf)) {
|
||||
mg_iobuf_add(&b, b.len, buf, len);
|
||||
if (mg_iobuf_add(&b, b.len, buf, len) == 0) goto fail;
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (len > 0) mg_iobuf_add(&b, b.len, buf, len);
|
||||
if (b.len > 0) mg_iobuf_add(&b, b.len, "", 1); // nul-terminate
|
||||
if (len > 0 && mg_iobuf_add(&b, b.len, buf, len) == 0) goto fail;
|
||||
if (b.len > 0 && mg_iobuf_add(&b, b.len, "", 1) == 0) // nul-terminate
|
||||
goto fail;
|
||||
fclose(fp);
|
||||
}
|
||||
(void) depth;
|
||||
(void) root;
|
||||
return (char *) b.buf;
|
||||
|
||||
fail:
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mg_http_serve_ssi(struct mg_connection *c, const char *root,
|
||||
const char *fullpath) {
|
||||
const char *headers = "Content-Type: text/html; charset=utf-8\r\n";
|
||||
char *data = mg_ssi(fullpath, root, 0);
|
||||
if (data == NULL) {
|
||||
mg_error(c, "OOM");
|
||||
return;
|
||||
}
|
||||
mg_http_reply(c, 200, headers, "%s", data == NULL ? "" : data);
|
||||
mg_free(data);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user