dir_import.c: Put a limit on the recursion depth
Этот коммит содержится в:
родитель
10dca5503a
Коммит
e6eaec30ba
@ -30,7 +30,6 @@
|
|||||||
* parser doesn't know anything about encoding).
|
* parser doesn't know anything about encoding).
|
||||||
* - Doesn't validate that there are no duplicate keys in JSON objects.
|
* - Doesn't validate that there are no duplicate keys in JSON objects.
|
||||||
* - Isn't very strict with validating non-integer numbers.
|
* - Isn't very strict with validating non-integer numbers.
|
||||||
* - Does not check nesting level, easily allows stack overflow. (TODO: FIX!)
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
@ -55,6 +54,12 @@
|
|||||||
* improves performance. */
|
* improves performance. */
|
||||||
#define READ_BUF_SIZE (32*1024)
|
#define READ_BUF_SIZE (32*1024)
|
||||||
|
|
||||||
|
/* Maximum nesting level for JSON objects / arrays. (Well, approximately. In
|
||||||
|
* some cases an object/array can be nested inside an other object/array while
|
||||||
|
* only counting as a single level rather than two. Anyway, the point of this
|
||||||
|
* limit is to prevent stack overflow, which it should do.) */
|
||||||
|
#define MAX_LEVEL 100
|
||||||
|
|
||||||
|
|
||||||
/* Use a struct for easy batch-allocation and deallocation of state data. */
|
/* Use a struct for easy batch-allocation and deallocation of state data. */
|
||||||
struct ctx {
|
struct ctx {
|
||||||
@ -64,6 +69,7 @@ struct ctx {
|
|||||||
int byte;
|
int byte;
|
||||||
int eof;
|
int eof;
|
||||||
int items;
|
int items;
|
||||||
|
int level;
|
||||||
char *buf; /* points into readbuf, always zero-terminated. */
|
char *buf; /* points into readbuf, always zero-terminated. */
|
||||||
char *lastfill; /* points into readbuf, location of the zero terminator. */
|
char *lastfill; /* points into readbuf, location of the zero terminator. */
|
||||||
|
|
||||||
@ -315,6 +321,9 @@ static int rkey(char *dest, int destlen) {
|
|||||||
|
|
||||||
/* (Recursively) parse and consume any JSON value. The result is discarded. */
|
/* (Recursively) parse and consume any JSON value. The result is discarded. */
|
||||||
static int rval() {
|
static int rval() {
|
||||||
|
ctx->level++;
|
||||||
|
E(ctx->level > MAX_LEVEL, "Recursion depth exceeded");
|
||||||
|
|
||||||
C(rfill1);
|
C(rfill1);
|
||||||
switch(*ctx->buf) {
|
switch(*ctx->buf) {
|
||||||
case 't': /* true */
|
case 't': /* true */
|
||||||
@ -355,6 +364,8 @@ static int rval() {
|
|||||||
C(rnum());
|
C(rnum());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ctx->level--;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,6 +400,9 @@ static int item(uint64_t);
|
|||||||
|
|
||||||
/* Read and add dir contents */
|
/* Read and add dir contents */
|
||||||
static int itemdir(uint64_t dev) {
|
static int itemdir(uint64_t dev) {
|
||||||
|
ctx->level++;
|
||||||
|
E(ctx->level > MAX_LEVEL, "Recursion depth exceeded");
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
C(cons());
|
C(cons());
|
||||||
if(*ctx->buf == ']')
|
if(*ctx->buf == ']')
|
||||||
@ -400,6 +414,7 @@ static int itemdir(uint64_t dev) {
|
|||||||
}
|
}
|
||||||
con(1);
|
con(1);
|
||||||
C(cons());
|
C(cons());
|
||||||
|
ctx->level--;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,7 +580,7 @@ int dir_import_init(const char *fn) {
|
|||||||
ctx = malloc(sizeof(struct ctx));
|
ctx = malloc(sizeof(struct ctx));
|
||||||
ctx->stream = stream;
|
ctx->stream = stream;
|
||||||
ctx->line = 1;
|
ctx->line = 1;
|
||||||
ctx->byte = ctx->eof = ctx->items = 0;
|
ctx->byte = ctx->eof = ctx->items = ctx->level = 0;
|
||||||
ctx->buf = ctx->lastfill = ctx->readbuf;
|
ctx->buf = ctx->lastfill = ctx->readbuf;
|
||||||
ctx->readbuf[0] = 0;
|
ctx->readbuf[0] = 0;
|
||||||
|
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user