Closed Bug 1418904 Opened 7 years ago Closed 1 year ago

mozImageSmoothingEnabled warning when printing 2d Canvas context

Categories

(DevTools :: Console, defect, P3)

57 Branch
defect

Tracking

(Not tracked)

RESOLVED DUPLICATE of bug 860312

People

(Reporter: charlesmaher01, Unassigned)

References

()

Details

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0
Build ID: 20171112125346

Steps to reproduce:

1. Go to any website containing a <canvas> element
2. Open the developer console
3. Type document.getElementById("canvas-id").getContext("2d")


Actual results:

I get a warning message about mozImageSmoothingEnabled being deprecated, and to use imageSmoothingEnabled instead. This warning should not appear as I never used mozImageSmoothingEnabled.


Expected results:

It should have printed the context without a warning. Additionally, it should print imageSmoothingEnabled rather than mozImageSmoothingEnabled.
Status: UNCONFIRMED → NEW
Component: Untriaged → Canvas: 2D
Ever confirmed: true
Product: Firefox → Core
it looks like it's because devtools is accessing it.
evaluating the following doesn't cause the warning:
  !document.getElementById("canvas-id").getContext("2d")
so it means that returning the canvas to console causes it.
Component: Canvas: 2D → Developer Tools: Console
Product: Core → Firefox
Simpler Steps to reproduce:
1. Go to `data:text/html,<canvas></canvas><script>console.log(document.querySelector("canvas").getContext("2d"))</script>`


Expected results:

No warning message

Actual results:

Following warning message is displayed 
`Use of mozImageSmoothingEnabled is deprecated. Please use the unprefixed imageSmoothingEnabled property instead.`
Looks like the message is generated by the Deprecated attribute: https://dxr.mozilla.org/mozilla-central/source/dom/webidl/CanvasRenderingContext2D.webidl#55, which was added in Bug 768072.

Thomas, do you have an idea why this message would be showing up on the test case in Comment 2, which doesn't reference mozImageSmoothing?
Blocks: 768072
Flags: needinfo?(wisniewskit)
I just forced a crash whenever get_mozImageSmoothingEnabled is called, and it *is* being called from JS at some point, while the devtools are being opened (via js::jit::DoCallFallback). However, the message doesn't appear if I remove getContext("2d") from the data URL, and I don't see any immediately obvious place in the devtools where mozImageSmoothingEnabled is read, so I can't be sure what's reading it.
Flags: needinfo?(wisniewskit)
Huh, the forced crash only happens when devtools is opened and not when loading the tab without the toolbox opened?  I don't see any devtools specific references in https://dxr.mozilla.org/mozilla-central/search?q=mozImageSmoothingEnabled&redirect=true.

I do see two references to ctx.imageSmoothingEnabled but neither of them should happen when only console is opened: https://dxr.mozilla.org/mozilla-central/search?q=path%3Adevtools+imagesmoothing&redirect=false.
here's js backtrace for the getter, on d4753dc14b2a revision

#0   7f1e6c11e890 i   resource://devtools/shared/base-loader.js -> resource://devtools/server/actors/object.js:386 (7f1e5e6f3d08 @ 694)
#1   7f1e6c11e730 i   resource://devtools/shared/base-loader.js -> resource://devtools/server/actors/object.js:1607 (7f1e5e6ef718 @ 1341)
#2   7f1e6c11e698 i   resource://devtools/shared/base-loader.js -> resource://devtools/server/actors/object.js:2004 (7f1e5e400d08 @ 20)
#3   7fffffff6300 b   resource://devtools/shared/base-loader.js -> resource://devtools/server/actors/object.js:142 (7f1e5e6f0f68 @ 806)
#4   7f1e6c11e518 i   resource://devtools/shared/base-loader.js -> resource://devtools/server/actors/webconsole.js:483 (7f1e5e43c4b8 @ 145)
#5   7fffffff7060 b   self-hosted:953 (7f1e6195f4b8 @ 440)
#6   7f1e6c11e470 i   resource://devtools/shared/base-loader.js -> resource://devtools/server/actors/object.js:2374 (7f1e5e6f0388 @ 496)
#7   7f1e6c11e3d8 i   resource://devtools/shared/base-loader.js -> resource://devtools/server/actors/webconsole.js:431 (7f1e5e43c258 @ 37)
#8   7f1e6c11e348 i   resource://devtools/shared/base-loader.js -> resource://devtools/server/actors/webconsole.js:1809 (7f1e5e443718 @ 55)
#9   7fffffff80e0 b   self-hosted:295 (7f1e6192dd08 @ 245)
#10   7f1e6c11e298 i   self-hosted:307 (7f1e628a1848 @ 142)
#11   7f1e6c11e1f0 i   resource://devtools/shared/base-loader.js -> resource://devtools/server/actors/webconsole.js:1807 (7f1e5e4435e8 @ 198)
#12   7f1e6c11e148 i   resource://devtools/shared/base-loader.js -> resource://devtools/server/actors/webconsole.js:827 (7f1e5e43d978 @ 73)
#13   7fffffff9960 b   self-hosted:271 (7f1e619311c0 @ 223)
#14   7f1e6c11e0b8 i   resource://devtools/shared/base-loader.js -> resource://devtools/server/actors/webconsole.js:819 (7f1e5e43d848 @ 319)
#15   7fffffffab30 b   self-hosted:953 (7f1e6195f4b8 @ 440)
#16   7fffffffb6c0 b   resource://devtools/shared/base-loader.js -> resource://devtools/server/main.js:1791 (7f1e5ffdc1c0 @ 468)
#17   7f1e6c11e020 i   resource://devtools/shared/base-loader.js -> resource://devtools/shared/transport/transport.js:761 (7f1e5ffba718 @ 66)
so... it's calling every each getter...?

resource://devtools/server/actors/object.js:386
>   _findSafeGetterValues: function (ownProperties, limit = 0) {
> ...
>     while (obj) {
> ...
>       let getters = this._findSafeGetters(obj);
>       for (let name of getters) {
> ...
>         let result = getter.call(this.obj);

resource://devtools/server/actors/object.js:1607
> function GenericObject(objectActor, grip, rawObj, specialStringBehavior = false) {
> ...
>   if (i < OBJECT_PREVIEW_MAX_ITEMS) {
>     preview.safeGetterValues = objectActor._findSafeGetterValues(
>       Object.keys(preview.ownProperties),
>       OBJECT_PREVIEW_MAX_ITEMS - i);

resource://devtools/server/actors/object.js:2004
>   function Object(objectActor, grip, rawObj) {
>     return GenericObject(objectActor, grip, rawObj, /* specialStringBehavior = */ false);
>   },

resource://devtools/server/actors/object.js:142
>   grip: function () {
> ...
>     let previewers = DebuggerServer.ObjectActorPreviewers[g.class] ||
>                      DebuggerServer.ObjectActorPreviewers.Object;
>     for (let fn of previewers) {
>       try {
>         if (fn(this, g, raw)) {

resource://devtools/server/actors/webconsole.js:483
>   objectGrip: function (object, pool) {
>     let actor = new ObjectActor(object, {
> ...
>     });
>     pool.addActor(actor);
>     return actor.grip();
>   },
Yes, that loop seems to be the culprit. When getContext creates the CanvasRenderingContext2D object that loop tries to read its getters, including mozImageSmoothingEnabled. If you tell the loop to explicitly skip over that property, the console deprecation message isn't generated. I'm not sure what a "correct" fix would be here, however.
(In reply to Thomas Wisniewski from comment #8)
> Yes, that loop seems to be the culprit. When getContext creates the
> CanvasRenderingContext2D object that loop tries to read its getters,
> including mozImageSmoothingEnabled. If you tell the loop to explicitly skip
> over that property, the console deprecation message isn't generated. I'm not
> sure what a "correct" fix would be here, however.

One option may be to whitelist "mozImageSmoothingEnabled" in DevToolsUtils.hasSafeGetter: https://dxr.mozilla.org/mozilla-central/source/devtools/shared/DevToolsUtils.js#238-252. Of course then if someone set that property on a plain object it wouldn't show up either. Oriol, do you have any ideas how to handle this case?
Flags: needinfo?(oriol-bugzilla)
This is somewhat like the typical [LenientThis] error that occurs when you inspect some prototypes like HTMLEmbedElement.prototype:
> Ignoring get or set of property that has [LenientThis] because the “this” object is incorrect.

As said in comment 7, all safe getters are called. The console does not distinguish mozImageSmoothingEnabled from imageSmoothingEnabled, it can't know the former is deprecated. So my ideas are

 - Change it to only call a list of whitelisted getters, depending on the class. Of course this would be a considerable amount of work, the list would be huge, and probably it would miss various properties.
 - Add a list of blacklisted properties. Curently only "__proto__" is blacklisted:
   https://searchfox.org/mozilla-central/rev/c633ffa4c4611f202ca11270dcddb7b29edddff8/devtools/server/actors/object.js#370-372
 - Blacklist all safe getters starting with "moz" followed by an upper-case letter if there is another safe getter without that prefix.

I wouldn't modify DevtoolsUtils.hasSafeGetter because mozImageSmoothingEnabled is safe in the sense that does not run any JS, which is what hasSafeGetter checks. The blacklisting should happen in _findSafeGetters or _findSafeGetterValues.
Flags: needinfo?(oriol-bugzilla)
Product: Firefox → DevTools
Severity: normal → S3

This is a duplicate of bug 860312

Flags: needinfo?(nchevobbe)

(In reply to Mathew Hodson from comment #11)

This is a duplicate of bug 860312

yes, and I should try to finish that work at some point

Status: NEW → RESOLVED
Closed: 1 year ago
Duplicate of bug: 860312
Flags: needinfo?(nchevobbe)
Resolution: --- → DUPLICATE
You need to log in before you can comment on or make changes to this bug.