{ "id": "160768", "key": "TIMOB-23476", "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": [ { "id": "16980", "description": "New V8", "name": "Release 6.0.0", "archived": false, "released": true, "releaseDate": "2016-11-15" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2016-06-27T17:17:57.000+0000", "created": "2016-06-03T19:01:06.000+0000", "priority": { "name": "Critical", "id": "1" }, "labels": [], "versions": [], "issuelinks": [ { "id": "51953", "type": { "id": "10001", "name": "Cloners", "inward": "is cloned into", "outward": "is cloned from" }, "outwardIssue": { "id": "160766", "key": "TIMOB-23475", "fields": { "summary": "Android: read-only properties with no setter are writable/delete-able", "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": "51955", "type": { "id": "10003", "name": "Relates", "inward": "relates to", "outward": "relates to" }, "outwardIssue": { "id": "159984", "key": "TIMOB-23310", "fields": { "summary": "Android: Upgrade v8 and rebuild it with NDK 11", "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 } } } }, { "id": "51954", "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": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "updated": "2016-08-12T22:58:02.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": "10202", "name": "Android", "description": "Android Platform" } ], "description": "Constants in Android are able to be \"overwritten\". Things like Ti.App.EVENT_ACCESSIBILITY_ANNOUNCEMENT should be truly constant and the user shouldn't be able to overwrite the value or delete the property.\r\n\r\nCurrently you can \"overwrite\" the value:\r\n\r\n{code:javascript}\r\nTi.API.info('original value: ' + Ti.App.EVENT_ACCESSIBILITY_ANNOUNCEMENT);\r\nTi.App.EVENT_ACCESSIBILITY_ANNOUNCEMENT = 'my very own made-up value';\r\nTi.API.info('modified value: ' + Ti.App.EVENT_ACCESSIBILITY_ANNOUNCEMENT);\r\n{code}'\r\n\r\nI think the underlying cause here is actually different than TIMOB-23475. I Believe this is because we hang 'constants' on the prototype of the proxy (i.e. {{Object.getPrototypeOf(Ti.App);}}) while the global object living at {{Ti.App}} is an instance. So what's happening looks to be \"property shadowing\" where we're actually adding a new {{EVENT_ACCESSIBILITY_ANNOUNCEMENT}} property with our own value onto the instance of {{Ti.App}} that lives in the global namespace at {{Ti.App}}. This instance property \"shadows\" the original constant declared on the prototype.\r\n\r\nTo prove my point, calling Object.getPrototypeOf(Ti.App) gives:\r\n{code:javascript}\r\n{\"Properties\":{\"apiName\":\"Ti.App.Properties\",\"bubbleParent\":true},\"Android\":{\"bubbleParent\":true,\"launchIntent\":{\"action\":null,\"bubbleParent\":true,\"packageName\":\"dfg.df\",\"data\":null,\"type\":null,\"apiName\":\"Ti.Android.Intent\",\"className\":\"dfg.df.ExampleActivity\",\"flags\":268435456},\"appVersionCode\":1,\"appVersionName\":\"1.0\",\"apiName\":\"Ti.App.Android\",\"R\":{\"bubbleParent\":true,\"apiName\":\"Ti.Android.R\"}},\"EVENT_ACCESSIBILITY_ANNOUNCEMENT\":\"accessibilityannouncement\",\"EVENT_ACCESSIBILITY_CHANGED\":\"accessibilitychanged\"}\r\n{code}\r\nYou can clearly see the constants there.\r\n\r\nIt makes sense to hang the constants at the \"prototype\" level since they're supposed to be \"class-level/static\" constants and we shouldn't need to have every instance hold a copy. However, it looks like we're not preventing shadowing properly (even though it appears we're setting the constant property attributes to ReadOnly|DontDelete).\r\n\r\nSee https://github.com/getify/You-Dont-Know-JS/issues/91 for discussion on cases where there seems to be prevented shadowing.\r\n\r\nOne possible solution may be to do an Object.seal() on all our proxies after they're set up. This marks all properties as DontDelete and prevents new properties from being added.", "attachment": [], "flagged": false, "summary": "Android: constants are writable", "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": 649, "state": "closed", "name": "2016 Sprint 13 SDK", "startDate": "2016-06-18T00:25:17.303Z", "endDate": "2016-07-02T00:25:00.000Z", "completeDate": "2016-07-04T04:25:16.889Z", "originBoardId": 114 } ], "comment": { "comments": [ { "id": "387543", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "Note that our V8 version is way out of date, and using the latest V8 may help bring us the behavior described in that link whereby a non-writable property on the prototype prevents shadowing on instances?", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2016-06-03T19:39:25.000+0000", "updated": "2016-06-03T19:39:25.000+0000" }, { "id": "387547", "author": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "body": "Just tested using the new V8 locally and can confirm that this _does_ fix the behavior for shadowing constants marked as read-only on the prototype. So, once TIMOB-23310 is merged, this will be fixed as well.", "updateAuthor": { "name": "cwilliams", "key": "cwilliams", "displayName": "Christopher Williams", "active": true, "timeZone": "America/New_York" }, "created": "2016-06-03T20:37:56.000+0000", "updated": "2016-06-03T20:37:56.000+0000" }, { "id": "393063", "author": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Verified the fix.\r\n\r\nConstants do not get overwritten anymore.\r\nClosing.\r\n\r\nEnvironment:\r\nAppc Studio : 4.7.0.201607250649\r\nTi SDK : 6.0.0.v20160811221444\r\nTi CLI : 5.0.9\r\nAlloy : 1.9.1\r\nMAC El Capitan : 10.11.6\r\nAppc NPM : 4.2.7\r\nAppc CLI : 6.0.0-24\r\nNode: 4.4.4\r\nNexus 5 - Android 6.0.1", "updateAuthor": { "name": "lchoudhary", "key": "lchoudhary", "displayName": "Lokesh Choudhary", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2016-08-12T22:57:53.000+0000", "updated": "2016-08-12T22:57:53.000+0000" } ], "maxResults": 3, "total": 3, "startAt": 0 } } }