New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 603782 link

Starred by 2 users

Issue metadata

Status: Fixed
Owner:
Long OOO (go/where-is-mgiuca)
Closed: Apr 2016
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: All
Pri: 1
Type: Bug

Blocked on:
issue 604292

Blocking:
issue 595608



Sign in to add a comment

IDL bindings generator applies the attributes of the alphabetically first partial interface to the entire interface

Project Member Reported by mgiuca@chromium.org, Apr 15 2016

Issue description

Version: 52
OS: All

What steps will reproduce the problem?
(1) Add a new API to "navigator". Call it something that comes alphabetically before "Battery". Say, "NavigatorActions".
(2) Create a partial interface, NavigatorActions.idl.
(3) Give the new partial interface a RuntimeEnabled condition with status=experimental:

[
  RuntimeEnabled=Ballista,
] partial interface Navigator {
  readonly attribute Actions actions;
};

(see: https://codereview.chromium.org/1806253002/#ps240001)

What is the expected output?
New attribute navigator.actions is present only when --enable-experimental-web-platform-features is on. When that flag is off, navigator.actions is undefined.

What do you see instead?
When --enable-experimental-web-platform-features is off, MOST OF THE ATTRIBUTES IN navigator ARE UNDEFINED!!!
For example:

> navigator.getBattery()
Uncaught TypeError: navigator.getBattery is not a function(…)

This is the generated code in V8NavigatorPartial.cpp; V8NavigatorPartial::installV8NavigatorTemplate:


    // Register DOM constants, attributes and operations.
    if (RuntimeEnabledFeatures::ballistaEnabled()) {
        V8DOMConfiguration::installAccessors(isolate, instanceTemplate, prototypeTemplate, interfaceTemplate, signature, V8NavigatorAccessors, WTF_ARRAY_LENGTH(V8NavigatorAccessors));
        V8DOMConfiguration::installMethods(isolate, instanceTemplate, prototypeTemplate, interfaceTemplate, signature, V8NavigatorMethods, WTF_ARRAY_LENGTH(V8NavigatorMethods));
    } // if (RuntimeEnabledFeatures::ballistaEnabled())

    if (RuntimeEnabledFeatures::ballistaEnabled()) {
        const V8DOMConfiguration::AccessorConfiguration accessoractionsConfiguration = \
        {"actions", NavigatorPartialV8Internal::actionsAttributeGetterCallback, 0, 0, 0, 0, v8::DEFAULT, static_cast<v8::PropertyAttribute>(v8::ReadOnly), V8DOMConfiguration::ExposedToAllScripts, V8DOMConfiguration::OnPrototype, V8DOMConfiguration::CheckHolder};
        V8DOMConfiguration::installAccessor(isolate, instanceTemplate, prototypeTemplate, interfaceTemplate, signature, accessoractionsConfiguration);
    }

    ....

All of the accessors and methods in the default set (V8NavigatorAccessors and V8NavigatorMethods) are conditional on ballistaEnabled() for some reason. The RuntimeEnabled=Ballista flag is now controlling ALL the features in navigator.

So it turns out that whichever partial interface comes first alphabetically will have its extended attributes (such as the RuntimeEnabled attribute) applied to the entire interface. Currently, the Navigator interface is getting its extended attributes from the NavigatorBattery partial interface, which fortunately has no extended attributes so everything is "fine". If you try to add a new partial interface that alphabetically precedes "Battery", you're gonna have a bad time.

Some debug logging of interfaces ("x of y" refers to the interface name and idl_name) and extended attributes to show the problem:

1) DEBUG:root:generate_code(['NavigatorActions'], 'Navigator')
2) DEBUG:root:interface_context(<IdlInterface: Navigator of NavigatorActions>)
3) DEBUG:root:runtime_feature_name(<IdlInterface: Navigator of NavigatorActions> => extended_attributes = {'RuntimeEnabled': 'Ballista', 'GarbageCollected': None})
4) DEBUG:root:runtime_enabled_function_name(<IdlInterface: Navigator of NavigatorActions> => 'RuntimeEnabledFeatures::ballistaEnabled')
5) DEBUG:root:runtime_enabled_function_name(<IdlAttribute: actions of NavigatorActions> => 'RuntimeEnabledFeatures::ballistaEnabled')
6) DEBUG:root:runtime_enabled_function_name(<IdlAttribute: bluetooth of NavigatorBluetooth> => None)
....

Note: Lines 5 onwards are correctly getting the extended attributes of the specific IDL attributes ("actions of NavigatorActions" is correct). But Lines 1--4 show that the main IdlInterface keyed by "Navigator" is in fact the NavigatorActions partial interface, and so it incorrectly inherits NavigatorActions' extended attributes.
 

Comment 1 by bashi@chromium.org, Apr 15 2016

Cc: -nbarth@chromium.org haraken@chromium.org yukishiino@chromium.org

Comment 2 by mgiuca@chromium.org, Apr 15 2016

CL to fix this issue: https://codereview.chromium.org/1884423002/

Note, it doesn't address the root cause (which is that all of the partial interfaces are being piled onto the alphabetically first partial interface), but it does address the immediate problem by removing the extended attributes from the merged interface (which have been transferred onto the individual attributes).

Comment 3 by mgiuca@chromium.org, Apr 18 2016

Blocking: 604292

Comment 4 by mgiuca@chromium.org, Apr 18 2016

Actually, while fixing this, I found that this bug is affecting real Chrome APIs right now: WorkerNavigator is inheriting the extended attributes of WorkerNavigatorGeofencing.idl which is experimental only, so some attributes of WorkerNavigator are actually undefined (apparently not any that anyone cares about).  Issue 604292 .

Comment 5 by mgiuca@chromium.org, Apr 19 2016

Blocking: -604292

Comment 6 by mgiuca@chromium.org, Apr 19 2016

Blockedon: 604292
Project Member

Comment 7 by bugdroid1@chromium.org, Apr 20 2016

The following revision refers to this bug:
  https://chromium.googlesource.com/chromium/src.git/+/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43

commit 4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43
Author: mgiuca <mgiuca@chromium.org>
Date: Wed Apr 20 02:48:56 2016

IDL bindings: Avoid extended attributes leaking onto merged interface.

Some extended attributes from dependency interface definitions are
transferred onto the definition's attributes before being merged.
However, the merged interfaces still retain the extended attributes from
the definition that comes first alphabetically, which can result in
extended attributes from one partial interface "leaking" onto all of the
others. The transferred extended attributes are now deleted from the
dependency interface so that they do not leak onto the merged interface.

Fixes a bug where adding a new RuntimeEnabled condition in a partial
interface can apply the condition to all members of the final interface.

BUG= 603782 , 604292 

Review URL: https://codereview.chromium.org/1884423002

Cr-Commit-Position: refs/heads/master@{#388409}

[modify] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Source/bindings/scripts/interface_dependency_resolver.py
[add] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Source/bindings/tests/idls/modules/TestInterface2Partial.idl
[add] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Source/bindings/tests/idls/modules/TestInterface2Partial2.idl
[modify] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.cpp
[modify] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Source/bindings/tests/results/core/V8TestInterface2.h
[add] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface2Partial.cpp
[add] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Source/bindings/tests/results/modules/V8TestInterface2Partial.h
[modify] https://crrev.com/4ea3a097a861c6b3ce5ef7ac9b3fd33c3ed92c43/third_party/WebKit/Tools/Scripts/webkitpy/bindings/main.py

Comment 8 by mgiuca@chromium.org, Apr 20 2016

Status: Fixed (was: Started)

Sign in to add a comment