From: Jay Freeman (saurik) Date: Tue, 5 Jan 2016 03:41:34 +0000 (-0800) Subject: Do not use corrupt struct to store type reference. X-Git-Tag: v0.9.590~57 X-Git-Url: https://git.saurik.com/cycript.git/commitdiff_plain/1fdd7c7aa3b4b5775135c4c58e535caf102207c1?hp=5c9d18fc8afb53b7478f4c7e6ab764c52b465769 Do not use corrupt struct to store type reference. --- diff --git a/Decode.cpp b/Decode.cpp index 1af478c..cf58ad4 100644 --- a/Decode.cpp +++ b/Decode.cpp @@ -166,6 +166,11 @@ CYTypedIdentifier *Enum::Decode(CYPool &pool) const { CYTypedIdentifier *Aggregate::Decode(CYPool &pool) const { _assert(!overlap); + if (signature.count == _not(size_t)) { + _assert(name != NULL); + return $ CYTypedIdentifier($ CYTypeReference(CYTypeReferenceStruct, $I($pool.strdup(name)))); + } + CYTypeStructField *fields(NULL); for (size_t i(signature.count); i != 0; --i) { sig::Element &element(signature.elements[i - 1]); diff --git a/Execute.cpp b/Execute.cpp index 8cf7b91..9af250c 100644 --- a/Execute.cpp +++ b/Execute.cpp @@ -785,6 +785,7 @@ void Enum::PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data void Aggregate::PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const { _assert(!overlap); + _assert(signature.count != _not(size_t)); size_t offset(0); uint8_t *base(reinterpret_cast(data)); @@ -877,6 +878,8 @@ JSValueRef Enum::FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool i } JSValueRef Aggregate::FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const { + _assert(!overlap); + _assert(signature.count != _not(size_t)); return Struct_privateData::Make(context, data, *this, ffi, context, owner); } @@ -1502,6 +1505,7 @@ static JSObjectRef Type_new(JSContextRef context, JSObjectRef object, size_t cou _assert(JSValueIsObjectOfClass(context, object, Type_privateData::Class_)); Type_privateData *internal(reinterpret_cast(JSObjectGetPrivate(object))); element.type = internal->type_; + _assert(element.type != NULL); } return CYMakeType(context, type); diff --git a/sig/copy.cpp b/sig/copy.cpp index 8896ea8..1f9decd 100644 --- a/sig/copy.cpp +++ b/sig/copy.cpp @@ -30,19 +30,21 @@ namespace sig { void Copy(CYPool &pool, Element &lhs, const Element &rhs) { lhs.name = pool.strdup(rhs.name); - if (rhs.type == NULL) - lhs.type = NULL; - else - lhs.type = rhs.type->Copy(pool); + _assert(rhs.type != NULL); + lhs.type = rhs.type->Copy(pool); lhs.offset = rhs.offset; } void Copy(CYPool &pool, Signature &lhs, const Signature &rhs) { size_t count(rhs.count); lhs.count = count; - lhs.elements = new(pool) Element[count]; - for (size_t index(0); index != count; ++index) - Copy(pool, lhs.elements[index], rhs.elements[index]); + if (count == _not(size_t)) + lhs.elements = NULL; + else { + lhs.elements = new(pool) Element[count]; + for (size_t index(0); index != count; ++index) + Copy(pool, lhs.elements[index], rhs.elements[index]); + } } Void *Void::Copy(CYPool &pool, const char *rename) const { diff --git a/sig/ffi_type.cpp b/sig/ffi_type.cpp index 2b6c0d3..e0c4d0f 100644 --- a/sig/ffi_type.cpp +++ b/sig/ffi_type.cpp @@ -176,8 +176,8 @@ ffi_type *Enum::GetFFI(CYPool &pool) const { } ffi_type *Aggregate::GetFFI(CYPool &pool) const { - // XXX: we can totally make overlap work _assert(!overlap); + _assert(signature.count != _not(size_t)); ffi_type *ffi(new(pool) ffi_type()); ffi->size = 0; diff --git a/sig/parse.cpp b/sig/parse.cpp index b2931ef..7c7c9c9 100644 --- a/sig/parse.cpp +++ b/sig/parse.cpp @@ -195,16 +195,22 @@ Type *Parse_(CYPool &pool, const char **encoding, char eos, bool named, Callback char end = next; const char *begin = *encoding; - do next = *(*encoding)++; - while ( - next != '=' && - next != '}' - ); + do switch (next = *(*encoding)++) { + case '\0': + _assert(false); + case '}': + // XXX: this is actually a type reference + aggregate->signature.count = _not(size_t); + next = '='; // this is a "break". I'm sorry + } while (next != '='); + size_t length = *encoding - begin - 1; if (strncmp(begin, "?", length) != 0) aggregate->name = (char *) pool.strmemdup(begin, length); - if (next == '=') + if (aggregate->signature.count == _not(size_t)) + aggregate->signature.elements = NULL; + else Parse_(pool, &aggregate->signature, encoding, end, callback); // XXX: this is a hack to support trivial unions @@ -386,7 +392,12 @@ const char *Enum::Encode(CYPool &pool) const { } const char *Aggregate::Encode(CYPool &pool) const { - return pool.strcat(overlap ? "(" : "{", name == NULL ? "?" : name, "=", Unparse(pool, &signature), overlap ? ")" : "}", NULL); + bool reference(signature.count == _not(size_t)); + return pool.strcat(overlap ? "(" : "{", + name == NULL ? "?" : name, + reference ? "" : "=", + reference ? "" : Unparse(pool, &signature), + overlap ? ")" : "}", NULL); } const char *Function::Encode(CYPool &pool) const {