]> git.saurik.com Git - cycript.git/commitdiff
Do not use corrupt struct to store type reference.
authorJay Freeman (saurik) <saurik@saurik.com>
Tue, 5 Jan 2016 03:41:34 +0000 (19:41 -0800)
committerJay Freeman (saurik) <saurik@saurik.com>
Tue, 5 Jan 2016 03:41:34 +0000 (19:41 -0800)
Decode.cpp
Execute.cpp
sig/copy.cpp
sig/ffi_type.cpp
sig/parse.cpp

index 1af478c189a32c2bec57fbf07a59a925d1f515ad..cf58ad4bcff48e0b6859c7f27daa28fbebb225ca 100644 (file)
@@ -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]);
index 8cf7b91e538bf6f5afb996a2134f171a3a4a1b4b..9af250c536f8d18c2823d8013f3d6af88ef7b3d7 100644 (file)
@@ -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<uint8_t *>(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<Type_privateData *>(JSObjectGetPrivate(object)));
             element.type = internal->type_;
+            _assert(element.type != NULL);
         }
 
         return CYMakeType(context, type);
index 8896ea84ffe471b18ba5a13d8757f42f666b66fd..1f9decdb35de5871371fe8ff226b52d93de6ec70 100644 (file)
@@ -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 {
index 2b6c0d3de61c4d24e701c39fa1dc139716c0096d..e0c4d0f900bd41e73a873563c266ac02cb98540c 100644 (file)
@@ -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;
index b2931ef3723d6dcfed3db48e0c2cae76f1696801..7c7c9c9333b340dbbb9e05c90593857713e81730 100644 (file)
@@ -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 {