WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
152294
Web Inspector: Parse InjectedScriptSource as a built-in to get guaranteed non-user-overriden JSC built-ins
https://bugs.webkit.org/show_bug.cgi?id=152294
Summary
Web Inspector: Parse InjectedScriptSource as a built-in to get guaranteed non...
Joseph Pecoraro
Reported
2015-12-14 21:35:35 PST
* SUMMARY Parse InjectedScriptSource as a built-in to get guaranteed non-user-overriden built-ins. During debugging, InjectedScriptSource.js gets evaluated in the main context of each page / JSGlobalContext. Because of this it must be careful to avoid user overridable functions that may not behave as expected. For example instead it cannot just use `Object` because that is `global.Object` and can be overridden by the page to do whatever it wants, like `global.Object = function() { throw "Error"; }`. There are many functions which we cannot "avoid" using, but cannot be guaranteed that they aren't overriden by the user. Object, Array, String Object.getOwnPropertyNames Object.getOwnPropertyDescriptor Object.getOwnPropertySymbols Object.prototype.hasOwnProperty Object.prototype.__defineGetter__ Function.prototype.call Element.prototype.hasAttribute There are plenty we could re-implement ourselves, but would mostly be a waste: Set String.prototype.trim String.prototype.replace Instead, we should just use the built-in logic in which case we can guarantee we are using the built-in versions of these: @Set @Object.@getOwnPropertySymbols ... It might get a bit tricky as we move to WebCore accessors (Element.prototype.hasAttribute), but we can fix the majority of brittle code here by using builtins. * TEST <script> window.Set = function() { throw "Error"; } </script> * STEPS TO REPRODUCE 1. Inspect test page 2. js> window 3. Expand window object in the console => ASSERT in debug builds, No properties in Release builds
Attachments
WIP v0.1
(182.24 KB, patch)
2022-04-20 17:47 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
WIP v0.2
(180.57 KB, patch)
2022-04-20 17:52 PDT
,
Patrick Angle
ews-feeder
: commit-queue-
Details
Formatted Diff
Diff
WIP v0.3
(180.88 KB, patch)
2022-04-20 20:15 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
WIP v0.4
(75.79 KB, patch)
2022-04-21 17:36 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
WIP v0.5
(89.37 KB, patch)
2022-04-22 18:41 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
WIP v0.6
(103.25 KB, patch)
2022-04-23 23:34 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
WIP v0.7
(103.89 KB, patch)
2022-04-24 13:01 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
WIP v0.8
(109.78 KB, patch)
2022-04-25 16:29 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch v1.0
(99.19 KB, patch)
2022-04-26 12:42 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch v1.1 - More @s, more tests
(131.86 KB, patch)
2022-04-27 12:17 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch v1.2
(143.11 KB, patch)
2022-04-27 21:18 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch v1.2
(143.08 KB, patch)
2022-04-27 21:20 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch v1.3
(150.15 KB, patch)
2022-05-03 13:30 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch v1.4 - Review nits and notes
(153.07 KB, patch)
2022-05-03 19:02 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch
(153.49 KB, patch)
2022-05-04 08:33 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch
(153.43 KB, patch)
2022-05-04 08:53 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch v1.7 - For Windows EWS
(153.21 KB, patch)
2022-05-04 11:04 PDT
,
Patrick Angle
ews-feeder
: commit-queue-
Details
Formatted Diff
Diff
Patch v1.8 - For Windows EWS
(154.22 KB, patch)
2022-05-04 13:55 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch v1.8.1 - For Windows EWS
(152.78 KB, patch)
2022-05-04 14:34 PDT
,
Patrick Angle
ews-feeder
: commit-queue-
Details
Formatted Diff
Diff
Patch v1.8.2 - For Windows EWS
(153.15 KB, patch)
2022-05-04 18:51 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch v1.9 - Only a LinkTimeConstant
(4.28 KB, patch)
2022-05-05 09:02 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch v1.10 - This seems to actually pass the tests on Windows - still needs cleanup
(151.76 KB, patch)
2022-05-05 17:25 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch v2.0 - Rebase of v1.4
(153.45 KB, patch)
2022-05-06 13:51 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch v2.1 - With Windows build fix that prevents using a stale WebCoreJSBuiltinInternals.h for dependent targets
(155.02 KB, patch)
2022-05-09 00:03 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch v2.2 - With WIP build fix from bug 240297
(153.86 KB, patch)
2022-05-11 11:33 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch v2.2.1 - With WIP build fix from bug 240297
(153.85 KB, patch)
2022-05-11 11:48 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Patch v2.3 - For landing
(153.44 KB, patch)
2022-05-11 13:39 PDT
,
Patrick Angle
no flags
Details
Formatted Diff
Diff
Show Obsolete
(26)
View All
Add attachment
proposed patch, testcase, etc.
Radar WebKit Bug Importer
Comment 1
2015-12-14 21:36:08 PST
<
rdar://problem/23895760
>
Blaze Burg
Comment 2
2015-12-15 09:07:21 PST
This would be awesome. Are you going to put up a patch?
Timothy Hatcher
Comment 3
2016-02-18 12:27:23 PST
***
Bug 154403
has been marked as a duplicate of this bug. ***
Patrick Angle
Comment 4
2022-04-20 17:47:01 PDT
Created
attachment 458022
[details]
WIP v0.1
Patrick Angle
Comment 5
2022-04-20 17:47:53 PDT
Comment on
attachment 458022
[details]
WIP v0.1 Not intended for review yet - trying to gauge if/how many tests are broken in various corners of the test suite.
Patrick Angle
Comment 6
2022-04-20 17:52:06 PDT
Created
attachment 458023
[details]
WIP v0.2
Patrick Angle
Comment 7
2022-04-20 20:15:53 PDT
Created
attachment 458033
[details]
WIP v0.3
Patrick Angle
Comment 8
2022-04-21 17:36:49 PDT
Created
attachment 458104
[details]
WIP v0.4
Patrick Angle
Comment 9
2022-04-22 18:41:02 PDT
Created
attachment 458193
[details]
WIP v0.5
Yusuke Suzuki
Comment 10
2022-04-22 21:30:58 PDT
Comment on
attachment 458193
[details]
WIP v0.5 View in context:
https://bugs.webkit.org/attachment.cgi?id=458193&action=review
> Source/JavaScriptCore/runtime/JSGlobalObject.cpp:1085 > + auto* jsonProperty = JSONObject::create(vm, JSONObject::createStructure(vm, this, m_objectPrototype.get())); > + m_jsonProperty.set(vm, this, jsonProperty); > + m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::JSON)].set(vm, this, jsonProperty);
Let's not newly create JSONObject. Let's 1. Convert JSON object definition from PropertyCallback to CellProperty+LazyProperty 2. Define lazy init function to initialize it 3. Use that lazy initializer inside m_linkTimeConstants's initLater.
Yusuke Suzuki
Comment 11
2022-04-22 21:32:46 PDT
Comment on
attachment 458193
[details]
WIP v0.5 View in context:
https://bugs.webkit.org/attachment.cgi?id=458193&action=review
>> Source/JavaScriptCore/runtime/JSGlobalObject.cpp:1085 >> + m_linkTimeConstants[static_cast<unsigned>(LinkTimeConstant::JSON)].set(vm, this, jsonProperty); > > Let's not newly create JSONObject. Let's > > 1. Convert JSON object definition from PropertyCallback to CellProperty+LazyProperty > 2. Define lazy init function to initialize it > 3. Use that lazy initializer inside m_linkTimeConstants's initLater.
Ah, but in this case, probably, just exposing JSON.stringify / JSON.parse directly. And share the functions with JSON object by defining them lazily in JSGlobalObject. Anyway, we are not designing creating multiple JSONObject in one JSGlobalObject, so avoid it.
Patrick Angle
Comment 12
2022-04-23 23:34:58 PDT
Created
attachment 458228
[details]
WIP v0.6
Patrick Angle
Comment 13
2022-04-24 13:01:58 PDT
Created
attachment 458236
[details]
WIP v0.7
Patrick Angle
Comment 14
2022-04-25 16:29:54 PDT
Created
attachment 458308
[details]
WIP v0.8
Patrick Angle
Comment 15
2022-04-26 12:42:25 PDT
Created
attachment 458389
[details]
Patch v1.0
Devin Rousso
Comment 16
2022-04-26 13:24:29 PDT
Comment on
attachment 458389
[details]
Patch v1.0 View in context:
https://bugs.webkit.org/attachment.cgi?id=458389&action=review
omg yes so awesome =D as we discussed offline, i think there are still a few spots that need to be adjusted to use a builtin, but you got almost all of them :) it'd be super nice if we could have a test that simulates a page overriding some of these builtins to confirm that this is working as expected (e.g. have a page override `Array.prototype.push = function() { didPush = true; }` and then confirm `!didPush` once the injected script logic has finished)
> Source/JavaScriptCore/Scripts/wkbuiltins/builtins_model.py:337 > + # FIXME: <webkit.org/b/######> Regular expressions containing unbalanced quotation marks (like the one
oops?
> Source/JavaScriptCore/builtins/IteratorHelpers.js:64 > + if (@isUndefinedOrNull(iteratorFunction)) > + @throwTypeError("builtinIterable requires that the property `iterable[Symbol.iterator]` exists.");
NIT: is it really useful to distinguish between "not set" and "not callable"?
> Source/JavaScriptCore/inspector/InjectedScriptSource.js:1047 > + return value[@@toStringTag];
NIT: can we do `value.@@toStringTag?`
> Source/JavaScriptCore/inspector/InjectedScriptSource.js:1065 > + // FIXME: <
webkit.org/b/239774
> Injected script should use WebCore built-ins.
FWIW you could probably do this by having something similar to `_inspectObject` so that the WebCore builtins stay in WebCore :)
> Source/JavaScriptCore/inspector/InjectedScriptSource.js:1140 > + properties: isTableRowsRequest ? 1000 : (5 > firstLevelKeysCount ? 5 : firstLevelKeysCount), > + indexes: isTableRowsRequest ? 1000 : (10 > firstLevelKeysCount ? 10 : firstLevelKeysCount),
Style: I'd flip the order so that the variable is first (and this way the constant numbers are closer together) NIT: maybe we should make our `function max` along the lines of how we already have a `toString`?
> Source/WebCore/inspector/CommandLineAPIModule.cpp:56 > + ASSERT_NOT_REACHED();
should this be a `RELEASE_ASSERT_NOT_REACHED`?
> LayoutTests/ChangeLog:12 > + - The Injected script (and modules) will no longer appear as scripts in Web Inspector.
i wonder if we should find some other internal script (e.g. modern media controls) and use that as the thing we step inside
Patrick Angle
Comment 17
2022-04-27 12:17:51 PDT
Created
attachment 458460
[details]
Patch v1.1 - More @s, more tests
Patrick Angle
Comment 18
2022-04-27 21:18:56 PDT
Created
attachment 458489
[details]
Patch v1.2
Patrick Angle
Comment 19
2022-04-27 21:20:02 PDT
Created
attachment 458490
[details]
Patch v1.2
Patrick Angle
Comment 20
2022-05-03 13:30:07 PDT
Created
attachment 458754
[details]
Patch v1.3
Devin Rousso
Comment 21
2022-05-03 14:07:21 PDT
Comment on
attachment 458754
[details]
Patch v1.3 View in context:
https://bugs.webkit.org/attachment.cgi?id=458754&action=review
r=mews, awesome work! Thanks for iterating :)
> Source/JavaScriptCore/inspector/InjectedScriptSource.js:31 > +function createPrototypelessObject(/* key1, value1, key2, value2, ... */)
NIT: `createObjectWithoutPrototype`?
> Source/JavaScriptCore/inspector/InjectedScriptSource.js:44 > +function createPrototypelessArray(/* value1, value2, ... */)
ditto (:31) `createArrayWithoutPrototype`
> Source/JavaScriptCore/inspector/InjectedScriptSource.js:118 > +function createPrototypelessArrayFromArguments(argumentsObject) {
ditto (:31) `createArrayWithoutPrototypeFromArguments`
> Source/JavaScriptCore/inspector/InjectedScriptSource.js:269 > + return this._getProperties(objectId, collectionMode, @createPrototypelessObject("fetchStart", fetchStart, "fetchCount", fetchCount, "generatePreview", generatePreview));
NIT: I'd put this onto separate lines so that it's easier to read ditto for every `@createObjectWithoutPrototype` that has more than two arguments (i.e. one property) below
> Source/JavaScriptCore/inspector/InjectedScriptSource.js:811 > + if (@Object.@getOwnPropertySymbols) {
NIT: I dont think we need this check anymore 🤔
> Source/JavaScriptCore/inspector/InjectedScriptSource.js:912 > + let existingIndex = this._savedResults.@indexOf(result);
will this actually work if it doesn't inherit from `Array.prototype`?
> Source/JavaScriptCore/inspector/InjectedScriptSource.js:1243 > + if (firstLevelKeys && !firstLevelKeys.@includes(name))
ditto (:912)
> Source/JavaScriptCore/inspector/InjectedScriptSource.js:1347 > + entries.@pop();
ditto (:912)
> Source/JavaScriptCore/inspector/InjectedScriptSource.js:1357 > + preview.entries = entries.@map(function(entry) {
ditto (:912)
> LayoutTests/inspector/injected-script/observable.html:141 > + propertyString: "\"push\"",
we may also wanna add tests for something like `Array.prototype.get 42` and/or `Object.prototype.get subtype` and/or etc. (i.e. find something in one of the objects we pass into functions just like `options = {}` and see what happens if you make `Object.prototype` have one of those properties) to make sure that `createObjectWithoutPrototype`/`createArrayWithoutPrototype` are doing the right thing (i.e. not allowing getters on the prototype to interfere with the injected script)
Joseph Pecoraro
Comment 22
2022-05-03 15:44:04 PDT
Comment on
attachment 458754
[details]
Patch v1.3 View in context:
https://bugs.webkit.org/attachment.cgi?id=458754&action=review
Very cool!
> Source/JavaScriptCore/inspector/InjectedScriptSource.js:46 > + let array = new @Array();
Maybe `new @Array(arguments.length)`?
> Source/JavaScriptCore/inspector/InjectedScriptSource.js:1496 > +InjectedScript.CallFrameProxy._scopeTypeNames[0] = "global"; // GLOBAL_SCOPE
Was there an issue with the `@createPrototypelessObject` arguments convenience? ``` InjectedScript.CallFrameProxy._scopeTypeNames = @createPrototypelessObject( 0, "global", 1, "with", … ); ```
Patrick Angle
Comment 23
2022-05-03 17:14:23 PDT
Comment on
attachment 458754
[details]
Patch v1.3 View in context:
https://bugs.webkit.org/attachment.cgi?id=458754&action=review
>> Source/JavaScriptCore/inspector/InjectedScriptSource.js:912 >> + let existingIndex = this._savedResults.@indexOf(result); > > will this actually work if it doesn't inherit from `Array.prototype`?
This works by accident, it seems. I need to `array.__proto__ = null;` in the create method.
>> Source/JavaScriptCore/inspector/InjectedScriptSource.js:1496 >> +InjectedScript.CallFrameProxy._scopeTypeNames[0] = "global"; // GLOBAL_SCOPE > > Was there an issue with the `@createPrototypelessObject` arguments convenience? > > ``` > InjectedScript.CallFrameProxy._scopeTypeNames = @createPrototypelessObject( > 0, "global", > 1, "with", > … > ); > ```
No issue - I had actually made this change at one point, but must have reverted it locally somehow!
Patrick Angle
Comment 24
2022-05-03 19:02:53 PDT
Created
attachment 458769
[details]
Patch v1.4 - Review nits and notes
Patrick Angle
Comment 25
2022-05-04 08:33:31 PDT
Created
attachment 458798
[details]
Patch
Patrick Angle
Comment 26
2022-05-04 08:53:40 PDT
Created
attachment 458802
[details]
Patch
Patrick Angle
Comment 27
2022-05-04 11:04:50 PDT
Created
attachment 458813
[details]
Patch v1.7 - For Windows EWS
Patrick Angle
Comment 28
2022-05-04 13:55:13 PDT
Created
attachment 458825
[details]
Patch v1.8 - For Windows EWS
Patrick Angle
Comment 29
2022-05-04 14:34:21 PDT
Created
attachment 458826
[details]
Patch v1.8.1 - For Windows EWS
Patrick Angle
Comment 30
2022-05-04 18:51:54 PDT
Created
attachment 458840
[details]
Patch v1.8.2 - For Windows EWS
Patrick Angle
Comment 31
2022-05-05 09:02:35 PDT
Created
attachment 458877
[details]
Patch v1.9 - Only a LinkTimeConstant
Patrick Angle
Comment 32
2022-05-05 17:25:32 PDT
Created
attachment 458928
[details]
Patch v1.10 - This seems to actually pass the tests on Windows - still needs cleanup
Patrick Angle
Comment 33
2022-05-06 13:13:43 PDT
Windows test crashes have been narrowed down to something to do with building. If you build the patch twice back-to-back, the tests pass. I'm going to upload a rebased copy of this patch since it seems a few bits have gone stale since v1.4, which is the code that was intended to be landed.
Patrick Angle
Comment 34
2022-05-06 13:51:34 PDT
Created
attachment 458971
[details]
Patch v2.0 - Rebase of v1.4
Patrick Angle
Comment 35
2022-05-09 00:03:01 PDT
Created
attachment 459031
[details]
Patch v2.1 - With Windows build fix that prevents using a stale WebCoreJSBuiltinInternals.h for dependent targets
Patrick Angle
Comment 36
2022-05-09 00:05:02 PDT
(In reply to Patrick Angle from
comment #35
)
> Created
attachment 459031
[details]
> Patch v2.1 - With Windows build fix that prevents using a stale > WebCoreJSBuiltinInternals.h for dependent targets
Patch name is a bit misleading, really. This issue exists for all cmake platforms as best as I can tell, but only Windows is effected for testing because the other cmake platforms don't run their tests against WebKitLegacy/DumpRenderTree, which is where the stale header was being used.
Patrick Angle
Comment 37
2022-05-11 11:33:40 PDT
Created
attachment 459174
[details]
Patch v2.2 - With WIP build fix from
bug 240297
Patrick Angle
Comment 38
2022-05-11 11:48:45 PDT
Created
attachment 459176
[details]
Patch v2.2.1 - With WIP build fix from
bug 240297
Patrick Angle
Comment 39
2022-05-11 13:39:40 PDT
Created
attachment 459181
[details]
Patch v2.3 - For landing
Patrick Angle
Comment 40
2022-05-11 13:42:51 PDT
AppleWin bot will fail tests after first build, and begin passing tests after the next incremental build - this is being addressed in
bug 240297
. The build fix in that bug was used to test v2.2.1 of this patch.
EWS
Comment 41
2022-05-11 17:33:07 PDT
Committed
r294082
(
250474@main
): <
https://commits.webkit.org/250474@main
> All reviewed patches have been landed. Closing bug and clearing flags on
attachment 459181
[details]
.
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug