From 73180f9a88e81f417fec82aae68ea2c48977418e Mon Sep 17 00:00:00 2001 From: "Jay Freeman (saurik)" Date: Tue, 15 Dec 2015 07:47:23 -0800 Subject: [PATCH] Avoid using NULL-terminated strings when possible. --- Execute.cpp | 15 ++++++++++----- ObjectiveC/Library.mm | 38 +++++++++++++++++++++----------------- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/Execute.cpp b/Execute.cpp index 2123b3f..c71bc9f 100644 --- a/Execute.cpp +++ b/Execute.cpp @@ -346,13 +346,17 @@ void CYArrayPush(JSContextRef context, JSObjectRef array, JSValueRef value) { } static JSValueRef System_print(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { + FILE *file(stdout); + if (count == 0) - printf("\n"); + fputc('\n', file); else { CYPool pool; - printf("%s\n", CYPoolCString(pool, context, arguments[0])); + CYUTF8String string(CYPoolUTF8String(pool, context, CYJSString(context, arguments[0]))); + fwrite(string.data, string.size, 1, file); } + fflush(file); return CYJSUndefined(context); } CYCatch(NULL) } @@ -364,9 +368,10 @@ _visible void CYGarbageCollect(JSContextRef context) { static JSValueRef Cycript_compile_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { CYPool pool; - std::stringstream value(CYPoolCString(pool, context, arguments[0])); - CYUTF8String code(CYPoolCode(pool, value)); - return CYCastJSValue(context, CYJSString(code)); + CYUTF8String before(CYPoolUTF8String(pool, context, CYJSString(context, arguments[0]))); + std::stringstream value(std::string(before.data, before.size)); + CYUTF8String after(CYPoolCode(pool, value)); + return CYCastJSValue(context, CYJSString(after)); } CYCatch_(NULL, "SyntaxError") } static JSValueRef Cycript_gc_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry { diff --git a/ObjectiveC/Library.mm b/ObjectiveC/Library.mm index e8c43d2..1147dcc 100644 --- a/ObjectiveC/Library.mm +++ b/ObjectiveC/Library.mm @@ -152,12 +152,18 @@ Type_ CYPoolRelease(CYPool *pool, Type_ object) { } /* }}} */ /* Objective-C Strings {{{ */ -const char *CYPoolCString(CYPool &pool, JSContextRef context, NSString *value) { - size_t size([value maximumLengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1); - char *string(new(pool) char[size]); +CYUTF8String CYPoolUTF8String(CYPool &pool, JSContextRef context, NSString *value) { + size_t size([value maximumLengthOfBytesUsingEncoding:NSUTF8StringEncoding]); + char *string(new(pool) char[size + 1]); if (![value getCString:string maxLength:size encoding:NSUTF8StringEncoding]) throw CYJSError(context, "[NSString getCString:maxLength:encoding:] == NO"); - return string; + return CYUTF8String(string, [value lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); +} + +const char *CYPoolCString(CYPool &pool, JSContextRef context, NSString *value) { + CYUTF8String utf8(CYPoolUTF8String(pool, context, value)); + _assert(memchr(utf8.data, '\0', utf8.size) == NULL); + return utf8.data; } #ifdef __clang__ @@ -175,7 +181,7 @@ JSStringRef CYCopyJSString(JSContextRef context, NSObject *value) { return CYCopyJSString(context, string); #else CYPool pool; - return CYCopyJSString(CYPoolCString(pool, context, string)); + return CYCopyJSString(CYPoolUTF8String(pool, context, string)); #endif } @@ -2152,22 +2158,20 @@ static void ObjectiveC_Image_Classes_getPropertyNames(JSContextRef context, JSOb static JSValueRef ObjectiveC_Images_getProperty(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry { CYPool pool; - const char *name(CYPoolCString(pool, context, property)); + CYUTF8String name(CYPoolUTF8String(pool, context, property)); + unsigned int size; const char **data(objc_copyImageNames(&size)); + pool.atexit(free, data); + for (size_t i(0); i != size; ++i) - if (strcmp(name, data[i]) == 0) { - name = data[i]; - goto free; + if (name == data[i]) { + JSObjectRef value(JSObjectMake(context, NULL, NULL)); + CYSetProperty(context, value, CYJSString("classes"), JSObjectMake(context, ObjectiveC_Image_Classes_, const_cast(data[i]))); + return value; } - name = NULL; - free: - free(data); - if (name == NULL) - return NULL; - JSObjectRef value(JSObjectMake(context, NULL, NULL)); - CYSetProperty(context, value, CYJSString("classes"), JSObjectMake(context, ObjectiveC_Image_Classes_, const_cast(name))); - return value; + + return NULL; } CYCatch(NULL) } static void ObjectiveC_Images_getPropertyNames(JSContextRef context, JSObjectRef object, JSPropertyNameAccumulatorRef names) { -- 2.45.2