{ "id": "161542", "key": "TIMOB-23609", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [], "resolution": { "id": "11", "description": "Is not a bug in our product", "name": "Not Our Bug" }, "resolutiondate": "2016-07-05T10:12:52.000+0000", "created": "2016-07-01T20:38:32.000+0000", "priority": { "name": "Critical", "id": "1" }, "labels": [], "versions": [], "issuelinks": [ { "id": "52165", "type": { "id": "10001", "name": "Cloners", "inward": "is cloned into", "outward": "is cloned from" }, "outwardIssue": { "id": "160963", "key": "TIMOB-23489", "fields": { "summary": "iOS: read-only properties with no setter show as configurable: true", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "Critical", "id": "1" }, "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false } } } }, { "id": "52166", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "inwardIssue": { "id": "155985", "key": "TIMOB-20624", "fields": { "summary": "Parity: Combine unit tests for SDKs into common suite/repo", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "High", "id": "2" }, "issuetype": { "id": "7", "description": "gh.issue.story.desc", "name": "Story", "subtask": false } } } } ], "assignee": { "name": "kiguchi", "key": "kota", "displayName": "Kota Iguchi", "active": false, "timeZone": "America/Los_Angeles" }, "updated": "2017-03-24T18:55:45.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "12642", "name": "Windows", "description": "Windows authoring support" } ], "description": "Properties like apiName on all proxies, or Ti.App.version are marked as read-only properties in our docs. That means the user should not be able to overwrite their values or delete them.On Windows, we cannot delete the property, but the common way of checking is to look at the configurable value of the property descriptor. That is oddly reporting true (which should mean it can be deleted).\r\n\r\n{code:javascript}\r\nvar target = Ti.API,\r\n propName = 'apiName';\r\n\r\n\r\nwhile (!Object.prototype.hasOwnProperty.call(target, propName)) {\r\n target = Object.getPrototypeOf(target); // go up the prototype chain\r\n if (!target) {\r\n alert('Failed!');\r\n }\r\n}\r\n\r\nTi.API.info(JSON.stringify(Object.getOwnPropertyDescriptor(Object(target), propName)));\r\n\r\n\r\nTi.API.info(Ti.API.apiName);\r\ndelete Ti.API.apiName;\r\nTi.API.info(Ti.API.apiName);\r\n{code}", "attachment": [], "flagged": false, "summary": "Windows: read-only properties incorrectly identify themselves as configurable", "creator": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "subtasks": [], "reporter": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "environment": null, "closedSprints": [ { "id": 678, "state": "closed", "name": "2016 Sprint 14 SDK", "startDate": "2016-07-02T00:25:57.921Z", "endDate": "2016-07-16T00:25:00.000Z", "completeDate": "2016-07-18T03:18:29.729Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "389785", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "Note that the linked ticket for iOS may also have the same behavior? Maybe it's just reporting configurable: true but isn't actually able to be deleted?", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2016-07-01T20:44:01.000+0000", "updated": "2016-07-01T20:44:01.000+0000" }, { "id": "389941", "author": { "name": "kiguchi", "key": "kota", "displayName": "Kota Iguchi", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Confirmed that JavaScriptCore doesn't handle {{enumerable}} and {{configurable}} well with {{getOwnPropertyDescriptor}} even on OS X. I assume it doesn't work well on iOS too.\r\n\r\nFound WebKit bug reports related to this:\r\n\r\nhttps://bugs.webkit.org/show_bug.cgi?id=158116\r\nhttps://bugs.webkit.org/show_bug.cgi?id=151348\r\n\r\nMaybe related:\r\nhttps://github.com/adobe/webkit/blob/master/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h#L216\r\n\r\n*Test Code*\r\n\r\n{code:c++}\r\n#include \r\n#include \r\n#include \r\n\r\nstatic JSValueRef GetX(JSContextRef ctx, JSObjectRef object, JSStringRef propertyNameJS, JSValueRef* exception)\r\n{\r\n\treturn JSValueMakeNumber(ctx, 101.0);\r\n}\r\n\r\nstatic JSStaticValue staticValues[] = {\r\n\t{\r\n\t\t\"X\", GetX, nullptr,\r\n\t\t// writable: false, configurable: false, enumerable: false\r\n\t\tkJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete /* | kJSPropertyAttributeDontEnum */\r\n\t},\r\n {0,0,0,0}\r\n};\r\n\r\nint main(int argc, const char * argv[]) {\r\n\tauto group = JSContextGroupCreate();\r\n\tauto ctx = JSGlobalContextCreateInGroup(group, nullptr);\r\n\tauto global = JSContextGetGlobalObject(ctx);\r\n\t\r\n\tauto definition = kJSClassDefinitionEmpty;\r\n\tdefinition.staticValues = staticValues;\r\n\tauto myClass = JSClassCreate(&definition);\r\n\t\r\n\tauto myClassObject = JSObjectMake(ctx, myClass, nullptr);\r\n\t\r\n\tJSStringRef myClassName = JSStringCreateWithUTF8CString(\"MyClass\");\r\n\tJSObjectSetProperty(ctx, global, myClassName, myClassObject, kJSPropertyAttributeNone, nullptr);\r\n\tJSStringRelease(myClassName);\r\n\r\n\tJSStringRef strX = JSStringCreateWithUTF8CString(\"X\");\r\n\tassert(JSObjectHasProperty(ctx, myClassObject, strX));\r\n\tauto propX = JSObjectGetProperty(ctx, myClassObject, strX, nullptr);\r\n\tassert(JSValueIsNumber(ctx, propX));\r\n\tJSStringRelease(strX);\r\n\t\r\n\t\r\n\tJSStringRef script = JSStringCreateWithUTF8CString(R\"JS(\r\n var target = MyClass, propName = 'X';\r\n while (!Object.prototype.hasOwnProperty.call(target, propName)) {\r\n target = Object.getPrototypeOf(target);\r\n }\r\n if (target) {\r\n Object.getOwnPropertyDescriptor(Object(target), propName);\r\n } else {\r\n\t\t{};\r\n }\r\n\t)JS\");\r\n\r\n\tJSStringRef writable = JSStringCreateWithUTF8CString(\"writable\");\r\n\tJSStringRef enumerable = JSStringCreateWithUTF8CString(\"enumerable\");\r\n\tJSStringRef configurable = JSStringCreateWithUTF8CString(\"configurable\");\r\n\r\n\tauto result = JSValueToObject(ctx, JSEvaluateScript(ctx, script, global, nullptr, 0, nullptr), nullptr);\r\n\tJSObjectHasProperty(ctx, result, writable);\r\n\tJSObjectHasProperty(ctx, result, enumerable);\r\n\tJSObjectHasProperty(ctx, result, configurable);\r\n\t\r\n\t//\r\n\t// enumerable and configurable go wrong. Even on OS X.\r\n\t//\r\n\r\n\t// Maybe related?\r\n\t// https://bugs.webkit.org/show_bug.cgi?id=158116\r\n\t// https://bugs.webkit.org/show_bug.cgi?id=151348\r\n\t// https://github.com/adobe/webkit/blob/master/Source/JavaScriptCore/API/JSCallbackObjectFunctions.h#L216\r\n\t\r\n\t// writable should return false, because we did specify kJSPropertyAttributeReadOnly\r\n\tassert(!JSValueToBoolean(ctx, JSObjectGetProperty(ctx, result, writable, nullptr)));\r\n\t\r\n\t// enumerable should return true, because we didn't specifykJSPropertyAttributeDontEnum\r\n\tassert(JSValueToBoolean(ctx, JSObjectGetProperty(ctx, result, enumerable, nullptr)));\r\n\r\n\t// configurable should return false, because we did specify kJSPropertyAttributeDontDelete\r\n\tassert(!JSValueToBoolean(ctx, JSObjectGetProperty(ctx, result, configurable, nullptr)));\r\n\t\r\n\tJSStringRelease(writable);\r\n\tJSStringRelease(enumerable);\r\n\tJSStringRelease(configurable);\r\n\t\r\n\tJSGlobalContextRelease(ctx);\r\n\t\r\n\treturn 0;\r\n}\r\n{code}", "updateAuthor": { "name": "kiguchi", "key": "kota", "displayName": "Kota Iguchi", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2016-07-05T10:12:52.000+0000", "updated": "2016-07-05T10:12:52.000+0000" }, { "id": "393286", "author": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "body": "[~kota] [~cwilliams] as this is resolved as not our bug, could the fix version be removed. Thanks!", "updateAuthor": { "name": "eharris", "key": "eharris", "displayName": "Ewan Harris", "active": true, "timeZone": "Europe/Dublin" }, "created": "2016-08-16T15:42:40.000+0000", "updated": "2016-08-16T15:42:40.000+0000" }, { "id": "415711", "author": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket with reference to the previous comments.", "updateAuthor": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-03-24T18:55:45.000+0000", "updated": "2017-03-24T18:55:45.000+0000" } ], "maxResults": 5, "total": 5, "startAt": 0 } } }