diff --git a/src/core/abstract.c b/src/core/abstract.c index 1132c470..0536fc98 100644 --- a/src/core/abstract.c +++ b/src/core/abstract.c @@ -26,10 +26,19 @@ #endif /* Create new userdata */ -void *janet_abstract(const JanetAbstractType *atype, size_t size) { - JanetAbstractHead *header = janet_gcalloc(JANET_MEMORY_ABSTRACT, +void *janet_abstract_begin(const JanetAbstractType *atype, size_t size) { + JanetAbstractHead *header = janet_gcalloc(JANET_MEMORY_NONE, sizeof(JanetAbstractHead) + size); header->size = size; header->type = atype; return (void *) & (header->data); } + +void *janet_abstract_end(void *x) { + janet_gc_settype((void *)(janet_gc_header(x)), JANET_MEMORY_ABSTRACT); + return x; +} + +void *janet_abstract(const JanetAbstractType *atype, size_t size) { + return janet_abstract_end(janet_abstract_begin(atype, size)); +} diff --git a/src/core/peg.c b/src/core/peg.c index 85b907e3..924ea665 100644 --- a/src/core/peg.c +++ b/src/core/peg.c @@ -990,6 +990,11 @@ static void peg_unmarshal(void *p, JanetMarshalContext *ctx) { peg->bytecode = NULL; peg->constants = NULL; + /* Ensure not too large */ + if (constants_start + sizeof(Janet) * peg->num_constants > janet_abstract_size(p)) { + janet_panic("size mismatch"); + } + for (size_t i = 0; i < peg->bytecode_len; i++) bytecode[i] = (uint32_t) janet_unmarshal_int(ctx); for (uint32_t j = 0; j < peg->num_constants; j++) diff --git a/src/include/janet.h b/src/include/janet.h index 335b909f..e92700fd 100644 --- a/src/include/janet.h +++ b/src/include/janet.h @@ -1219,7 +1219,9 @@ JANET_API const JanetKV *janet_dictionary_next(const JanetKV *kvs, int32_t cap, #define janet_abstract_head(u) ((JanetAbstractHead *)((char *)u - offsetof(JanetAbstractHead, data))) #define janet_abstract_type(u) (janet_abstract_head(u)->type) #define janet_abstract_size(u) (janet_abstract_head(u)->size) -JANET_API void *janet_abstract(const JanetAbstractType *type, size_t size); +JANET_API void *janet_abstract_begin(const JanetAbstractType *type, size_t size); +JANET_API void *janet_abstract_end(void *); +JANET_API void *janet_abstract(const JanetAbstractType *type, size_t size); /* begin and end in one call */ /* Native */ typedef void (*JanetModule)(JanetTable *);