Changeset 49510 in webkit


Ignore:
Timestamp:
Oct 13, 2009 2:44:38 PM (15 years ago)
Author:
atwilson@chromium.org
Message:

window attributes (like localStorage) that are disabled at runtime are still visible
https://bugs.webkit.org/show_bug.cgi?id=30240

Patch by Drew Wilson <atwilson@atwilson-macpro.local> on 2009-10-13
Reviewed by Dimitri Glazkov.

Adding codegen/bindings to support runtime disabling of attributes.

No new tests (only supported by chrome currently)

  • bindings/scripts/CodeGeneratorV8.pm:

Refactored the guts of GenerateBatchedAttributeData into a separate GenerateSingleBatchedAttribute with a passed-in indentation level to allow generating a single BatchedAttribute struct.
Added support for the EnabledAtRuntime extended attribute, which generates a call to the appropriate XXXXEnabled() API before adding the attribute to the instance.

  • bindings/v8/V8Proxy.cpp:

(WebCore::batchConfigureAttributes):
Refactored attribute setting code into a common inline routine.

  • bindings/v8/V8Proxy.h:

(WebCore::configureAttribute):
Inline function which configures a single attribute given a BatchedAttribute struct.

  • bindings/v8/custom/V8CustomBinding.h:

Added (DECLARE_)ACCESSOR_RUNTIME_ENABLER to allow enabling attributes at runtime.

  • bindings/v8/custom/V8DOMWindowCustom.cpp:

Added code to enable window.Audio only if MediaPlayer.isAvailable() == true

  • page/DOMWindow.idl:

Added [EnabledAtRuntime] extended attribute to the Audio attribute.

Location:
trunk/WebCore
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r49508 r49510  
     12009-10-13  Drew Wilson  <atwilson@atwilson-macpro.local>
     2
     3        Reviewed by Dimitri Glazkov.
     4
     5        window attributes (like localStorage) that are disabled at runtime are still visible
     6        https://bugs.webkit.org/show_bug.cgi?id=30240
     7
     8        Adding codegen/bindings to support runtime disabling of attributes.
     9
     10        No new tests (only supported by chrome currently)
     11
     12        * bindings/scripts/CodeGeneratorV8.pm:
     13        Refactored the guts of GenerateBatchedAttributeData into a separate GenerateSingleBatchedAttribute with a passed-in indentation level to allow generating a single BatchedAttribute struct.
     14        Added support for the EnabledAtRuntime extended attribute, which generates a call to the appropriate XXXXEnabled() API before adding the attribute to the instance.
     15        * bindings/v8/V8Proxy.cpp:
     16        (WebCore::batchConfigureAttributes):
     17        Refactored attribute setting code into a common inline routine.
     18        * bindings/v8/V8Proxy.h:
     19        (WebCore::configureAttribute):
     20        Inline function which configures a single attribute given a BatchedAttribute struct.
     21        * bindings/v8/custom/V8CustomBinding.h:
     22        Added (DECLARE_)ACCESSOR_RUNTIME_ENABLER to allow enabling attributes at runtime.
     23        * bindings/v8/custom/V8DOMWindowCustom.cpp:
     24        Added code to enable window.Audio only if MediaPlayer.isAvailable() == true
     25        * page/DOMWindow.idl:
     26        Added [EnabledAtRuntime] extended attribute to the Audio attribute.
     27
    1282009-10-13  Michelangelo De Simone  <micdesim@gmail.com>
    229
  • trunk/WebCore/bindings/scripts/CodeGeneratorV8.pm

    r49432 r49510  
    949949
    950950    foreach my $attribute (@$attributes) {
    951         my $attrName = $attribute->signature->name;
    952         my $attrExt = $attribute->signature->extendedAttributes;
    953 
    954         my $accessControl = "v8::DEFAULT";
    955         if ($attrExt->{"DoNotCheckDomainSecurityOnGet"}) {
    956             $accessControl = "v8::ALL_CAN_READ";
    957         } elsif ($attrExt->{"DoNotCheckDomainSecurityOnSet"}) {
    958             $accessControl = "v8::ALL_CAN_WRITE";
    959         } elsif ($attrExt->{"DoNotCheckDomainSecurity"}) {
    960             $accessControl = "v8::ALL_CAN_READ";
    961             if (!($attribute->type =~ /^readonly/) && !($attrExt->{"V8ReadOnly"})) {
    962                 $accessControl .= "|v8::ALL_CAN_WRITE";
    963             }
    964         }
    965         if ($attrExt->{"V8DisallowShadowing"}) {
    966             $accessControl .= "|v8::PROHIBITS_OVERWRITING";
    967         }
    968         $accessControl = "static_cast<v8::AccessControl>(" . $accessControl . ")";
    969 
    970         my $customAccessor =
    971             $attrExt->{"Custom"} ||
    972             $attrExt->{"CustomSetter"} ||
    973             $attrExt->{"CustomGetter"} ||
    974             $attrExt->{"V8Custom"} ||
    975             $attrExt->{"V8CustomSetter"} ||
    976             $attrExt->{"V8CustomGetter"} ||
    977             "";
    978         if ($customAccessor eq 1) {
    979             # use the naming convension, interface + (capitalize) attr name
    980             $customAccessor = $interfaceName . $codeGenerator->WK_ucfirst($attrName);
    981         }
    982 
    983         my $getter;
    984         my $setter;
    985         my $propAttr = "v8::None";
    986         my $hasCustomSetter = 0;
    987 
    988         # Check attributes.
    989         if ($attrExt->{"DontEnum"}) {
    990             $propAttr .= "|v8::DontEnum";
    991         }
    992         if ($attrExt->{"V8DisallowShadowing"}) {
    993             $propAttr .= "|v8::DontDelete";
    994         }
    995 
    996         my $on_proto = "0 /* on instance */";
    997         my $data = "V8ClassIndex::INVALID_CLASS_INDEX /* no data */";
    998 
    999         # Constructor
    1000         if ($attribute->signature->type =~ /Constructor$/) {
    1001             my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
    1002             $constructorType =~ s/Constructor$//;
    1003             my $constructorIndex = uc($constructorType);
    1004             if ($customAccessor) {
    1005                 $getter = "V8Custom::v8${customAccessor}AccessorGetter";
    1006             } else {
    1007                 $data = "V8ClassIndex::${constructorIndex}";
    1008                 $getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter";
    1009             }
    1010             $setter = "0";
    1011             $propAttr = "v8::ReadOnly";
    1012 
    1013         } else {
    1014             # Default Getter and Setter
    1015             $getter = "${interfaceName}Internal::${attrName}AttrGetter";
    1016             $setter = "${interfaceName}Internal::${attrName}AttrSetter";
    1017 
    1018             # Custom Setter
    1019             if ($attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
    1020                 $hasCustomSetter = 1;
    1021                 $setter = "V8Custom::v8${customAccessor}AccessorSetter";
    1022             }
    1023 
    1024             # Custom Getter
    1025             if ($attrExt->{"CustomGetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
    1026                 $getter = "V8Custom::v8${customAccessor}AccessorGetter";
    1027             }
    1028         }
    1029 
    1030         # Replaceable
    1031         if ($attrExt->{"Replaceable"} && !$hasCustomSetter) {
    1032             $setter = "0";
    1033             # Handle the special case of window.top being marked as Replaceable.
    1034             # FIXME: Investigate whether we could treat window.top as replaceable
    1035             # and allow shadowing without it being a security hole.
    1036             if (!($interfaceName eq "DOMWindow" and $attrName eq "top")) {
    1037                 $propAttr .= "|v8::ReadOnly";
    1038             }
    1039         }
    1040 
    1041         # Read only attributes
    1042         if ($attribute->type =~ /^readonly/ || $attrExt->{"V8ReadOnly"}) {
    1043             $setter = "0";
    1044         }
    1045 
    1046         # An accessor can be installed on the proto
    1047         if ($attrExt->{"v8OnProto"}) {
    1048             $on_proto = "1 /* on proto */";
    1049         }
    1050 
    1051         my $commentInfo = "Attribute '$attrName' (Type: '" . $attribute->type .
    1052                           "' ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
    1053        
    1054951        my $conditionalString = GenerateConditionalString($attribute->signature);
    1055952        push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
    1056 
    1057         push(@implContent, <<END);
    1058   // $commentInfo
    1059   { "$attrName",
    1060     $getter,
    1061     $setter,
    1062     $data,
    1063     $accessControl,
    1064     static_cast<v8::PropertyAttribute>($propAttr),
    1065     $on_proto },
    1066 END
     953        GenerateSingleBatchedAttribute($interfaceName, $attribute, ",", "");
    1067954        push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
    1068955    }
    1069956}
    1070957
     958sub GenerateSingleBatchedAttribute
     959{
     960    my $interfaceName = shift;
     961    my $attribute = shift;
     962    my $delimiter = shift;
     963    my $indent = shift;
     964    my $attrName = $attribute->signature->name;
     965    my $attrExt = $attribute->signature->extendedAttributes;
     966
     967    my $accessControl = "v8::DEFAULT";
     968    if ($attrExt->{"DoNotCheckDomainSecurityOnGet"}) {
     969        $accessControl = "v8::ALL_CAN_READ";
     970    } elsif ($attrExt->{"DoNotCheckDomainSecurityOnSet"}) {
     971        $accessControl = "v8::ALL_CAN_WRITE";
     972    } elsif ($attrExt->{"DoNotCheckDomainSecurity"}) {
     973        $accessControl = "v8::ALL_CAN_READ";
     974        if (!($attribute->type =~ /^readonly/) && !($attrExt->{"V8ReadOnly"})) {
     975            $accessControl .= "|v8::ALL_CAN_WRITE";
     976        }
     977    }
     978    if ($attrExt->{"V8DisallowShadowing"}) {
     979        $accessControl .= "|v8::PROHIBITS_OVERWRITING";
     980    }
     981    $accessControl = "static_cast<v8::AccessControl>(" . $accessControl . ")";
     982
     983    my $customAccessor =
     984        $attrExt->{"Custom"} ||
     985        $attrExt->{"CustomSetter"} ||
     986        $attrExt->{"CustomGetter"} ||
     987        $attrExt->{"V8Custom"} ||
     988        $attrExt->{"V8CustomSetter"} ||
     989        $attrExt->{"V8CustomGetter"} ||
     990        "";
     991    if ($customAccessor eq 1) {
     992        # use the naming convension, interface + (capitalize) attr name
     993        $customAccessor = $interfaceName . $codeGenerator->WK_ucfirst($attrName);
     994    }
     995
     996    my $getter;
     997    my $setter;
     998    my $propAttr = "v8::None";
     999    my $hasCustomSetter = 0;
     1000
     1001    # Check attributes.
     1002    if ($attrExt->{"DontEnum"}) {
     1003        $propAttr .= "|v8::DontEnum";
     1004    }
     1005    if ($attrExt->{"V8DisallowShadowing"}) {
     1006        $propAttr .= "|v8::DontDelete";
     1007    }
     1008
     1009    my $on_proto = "0 /* on instance */";
     1010    my $data = "V8ClassIndex::INVALID_CLASS_INDEX /* no data */";
     1011
     1012    # Constructor
     1013    if ($attribute->signature->type =~ /Constructor$/) {
     1014        my $constructorType = $codeGenerator->StripModule($attribute->signature->type);
     1015        $constructorType =~ s/Constructor$//;
     1016        my $constructorIndex = uc($constructorType);
     1017        if ($customAccessor) {
     1018            $getter = "V8Custom::v8${customAccessor}AccessorGetter";
     1019        } else {
     1020            $data = "V8ClassIndex::${constructorIndex}";
     1021            $getter = "${interfaceName}Internal::${interfaceName}ConstructorGetter";
     1022        }
     1023        $setter = "0";
     1024        $propAttr = "v8::ReadOnly";
     1025
     1026    } else {
     1027        # Default Getter and Setter
     1028        $getter = "${interfaceName}Internal::${attrName}AttrGetter";
     1029        $setter = "${interfaceName}Internal::${attrName}AttrSetter";
     1030
     1031        # Custom Setter
     1032        if ($attrExt->{"CustomSetter"} || $attrExt->{"V8CustomSetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
     1033            $hasCustomSetter = 1;
     1034            $setter = "V8Custom::v8${customAccessor}AccessorSetter";
     1035        }
     1036
     1037        # Custom Getter
     1038        if ($attrExt->{"CustomGetter"} || $attrExt->{"Custom"} || $attrExt->{"V8Custom"}) {
     1039            $getter = "V8Custom::v8${customAccessor}AccessorGetter";
     1040        }
     1041    }
     1042
     1043    # Replaceable
     1044    if ($attrExt->{"Replaceable"} && !$hasCustomSetter) {
     1045        $setter = "0";
     1046        # Handle the special case of window.top being marked as Replaceable.
     1047        # FIXME: Investigate whether we could treat window.top as replaceable
     1048        # and allow shadowing without it being a security hole.
     1049        if (!($interfaceName eq "DOMWindow" and $attrName eq "top")) {
     1050            $propAttr .= "|v8::ReadOnly";
     1051        }
     1052    }
     1053
     1054    # Read only attributes
     1055    if ($attribute->type =~ /^readonly/ || $attrExt->{"V8ReadOnly"}) {
     1056        $setter = "0";
     1057    }
     1058
     1059    # An accessor can be installed on the proto
     1060    if ($attrExt->{"v8OnProto"}) {
     1061        $on_proto = "1 /* on proto */";
     1062    }
     1063
     1064    my $commentInfo = "Attribute '$attrName' (Type: '" . $attribute->type .
     1065                      "' ExtAttr: '" . join(' ', keys(%{$attrExt})) . "')";
     1066
     1067    push(@implContent, $indent . "    {\n");
     1068    push(@implContent, $indent . "        \/\/ $commentInfo\n");
     1069    push(@implContent, $indent . "        \"$attrName\",\n");
     1070    push(@implContent, $indent . "        $getter,\n");
     1071    push(@implContent, $indent . "        $setter,\n");
     1072    push(@implContent, $indent . "        $data,\n");
     1073    push(@implContent, $indent . "        $accessControl,\n");
     1074    push(@implContent, $indent . "        static_cast<v8::PropertyAttribute>($propAttr),\n");
     1075    push(@implContent, $indent . "        $on_proto\n");
     1076    push(@implContent, $indent . "    }" . $delimiter . "\n");
     1077END
     1078}
    10711079
    10721080sub GenerateImplementation
     
    11811189    # For the DOMWindow interface we partition the attributes into the
    11821190    # ones that disallows shadowing and the rest.
    1183     my @disallows_shadowing;
     1191    my @disallowsShadowing;
     1192    # Also separate out attributes that are enabled at runtime so we can process them specially.
     1193    my @enabledAtRuntime;
    11841194    my @normal;
    1185     if ($interfaceName eq "DOMWindow") {
    1186         foreach my $attribute (@$attributes) {
    1187             if ($attribute->signature->extendedAttributes->{"V8DisallowShadowing"}) {
    1188                 push(@disallows_shadowing, $attribute);
    1189             } else {
    1190                 push(@normal, $attribute);
    1191             }
    1192         }
    1193         # Put the attributes that disallow shadowing on the shadow object.
    1194         $attributes = \@normal;
     1195    foreach my $attribute (@$attributes) {
     1196        if ($interfaceName eq "DOMWindow" && $attribute->signature->extendedAttributes->{"V8DisallowShadowing"}) {
     1197            push(@disallowsShadowing, $attribute);
     1198        } elsif ($attribute->signature->extendedAttributes->{"EnabledAtRuntime"}) {
     1199            push(@enabledAtRuntime, $attribute);
     1200        } else {
     1201            push(@normal, $attribute);
     1202        }
     1203    }
     1204    $attributes = \@normal;
     1205    # Put the attributes that disallow shadowing on the shadow object.
     1206    if (@disallowsShadowing) {
    11951207        push(@implContent, "static const BatchedAttribute shadow_attrs[] = {\n");
    1196         GenerateBatchedAttributeData($dataNode, \@disallows_shadowing);
     1208        GenerateBatchedAttributeData($dataNode, \@disallowsShadowing);
    11971209        push(@implContent, "};\n");
    11981210    }
     
    12741286  batchConfigureAttributes(instance, proto, ${interfaceName}_attrs, sizeof(${interfaceName}_attrs)/sizeof(*${interfaceName}_attrs));
    12751287END
     1288    }
     1289
     1290    # Setup the enable-at-runtime attrs if we have them
     1291    foreach my $runtime_attr (@enabledAtRuntime) {
     1292        $enable_function = $interfaceName . $codeGenerator->WK_ucfirst($runtime_attr->signature->name);
     1293        my $conditionalString = GenerateConditionalString($runtime_attr->signature);
     1294        push(@implContent, "\n#if ${conditionalString}\n") if $conditionalString;
     1295        push(@implContent, "    if (V8Custom::v8${enable_function}Enabled()) {\n");
     1296        push(@implContent, "        static const BatchedAttribute attrData =\\\n");
     1297        GenerateSingleBatchedAttribute($interfaceName, $runtime_attr, ";", "    ");
     1298        push(@implContent, <<END);
     1299        configureAttribute(instance, proto, attrData);
     1300    }
     1301END
     1302        push(@implContent, "\n#endif // ${conditionalString}\n") if $conditionalString;
    12761303    }
    12771304
  • trunk/WebCore/bindings/v8/V8Proxy.cpp

    r49278 r49510  
    7373void batchConfigureAttributes(v8::Handle<v8::ObjectTemplate> instance, v8::Handle<v8::ObjectTemplate> proto, const BatchedAttribute* attributes, size_t attributeCount)
    7474{
    75     for (size_t i = 0; i < attributeCount; ++i) {
    76         const BatchedAttribute* attribute = &attributes[i];
    77         (attribute->onProto ? proto : instance)->SetAccessor(v8::String::New(attribute->name),
    78             attribute->getter,
    79             attribute->setter,
    80             attribute->data == V8ClassIndex::INVALID_CLASS_INDEX ? v8::Handle<v8::Value>() : v8::Integer::New(V8ClassIndex::ToInt(attribute->data)),
    81             attribute->settings,
    82             attribute->attribute);
    83     }
     75    for (size_t i = 0; i < attributeCount; ++i)
     76        configureAttribute(instance, proto, attributes[i]);
    8477}
    8578
  • trunk/WebCore/bindings/v8/V8Proxy.h

    r49278 r49510  
    8383    void batchConfigureAttributes(v8::Handle<v8::ObjectTemplate>, v8::Handle<v8::ObjectTemplate>, const BatchedAttribute*, size_t attributeCount);
    8484
     85    inline void configureAttribute(v8::Handle<v8::ObjectTemplate> instance, v8::Handle<v8::ObjectTemplate> proto, const BatchedAttribute& attribute)
     86    {
     87        (attribute.onProto ? proto : instance)->SetAccessor(v8::String::New(attribute.name),
     88            attribute.getter,
     89            attribute.setter,
     90            attribute.data == V8ClassIndex::INVALID_CLASS_INDEX ? v8::Handle<v8::Value>() : v8::Integer::New(V8ClassIndex::ToInt(attribute.data)),
     91            attribute.settings,
     92            attribute.attribute);
     93    }
     94
    8595    // BatchedConstant translates into calls to Set() for setting up an object's
    8696    // constants. It sets the constant on both the FunctionTemplate and the
  • trunk/WebCore/bindings/v8/custom/V8CustomBinding.h

    r49488 r49510  
    7979        uint32_t index, v8::AccessType type, v8::Local<v8::Value> data)
    8080
     81#define ACCESSOR_RUNTIME_ENABLER(NAME) bool V8Custom::v8##NAME##Enabled()
     82
    8183namespace WebCore {
    8284
     
    233235        uint32_t index, v8::AccessType type, v8::Local<v8::Value> data)
    234236
     237#define DECLARE_ACCESSOR_RUNTIME_ENABLER(NAME) static bool v8##NAME##Enabled()
     238
    235239        DECLARE_PROPERTY_ACCESSOR(CanvasRenderingContext2DStrokeStyle);
    236240        DECLARE_PROPERTY_ACCESSOR(CanvasRenderingContext2DFillStyle);
     
    242246#if ENABLE(VIDEO)
    243247        DECLARE_PROPERTY_ACCESSOR_GETTER(DOMWindowAudio);
     248        DECLARE_ACCESSOR_RUNTIME_ENABLER(DOMWindowAudio);
    244249#endif
    245250
  • trunk/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp

    r49248 r49510  
    4646#include "FrameView.h"
    4747#include "HTMLCollection.h"
     48#include "MediaPlayer.h"
    4849#include "Page.h"
    4950#include "PlatformScreen.h"
     
    234235    DOMWindow* window = V8DOMWrapper::convertToNativeObject<DOMWindow>(V8ClassIndex::DOMWINDOW, info.Holder());
    235236    return V8DOMWrapper::getConstructor(V8ClassIndex::AUDIO, window);
     237}
     238
     239ACCESSOR_RUNTIME_ENABLER(DOMWindowAudio)
     240{
     241    return MediaPlayer::isAvailable();
    236242}
    237243
  • trunk/WebCore/page/DOMWindow.idl

    r49400 r49510  
    524524#endif
    525525
    526         attribute [CustomGetter,Conditional=VIDEO] HTMLAudioElementConstructor Audio; // Usable with the new operator
     526        attribute [CustomGetter,Conditional=VIDEO,EnabledAtRuntime] HTMLAudioElementConstructor Audio; // Usable with the new operator
    527527        attribute [Conditional=VIDEO] HTMLAudioElementConstructor HTMLAudioElement;
    528528        attribute [Conditional=VIDEO] HTMLMediaElementConstructor HTMLMediaElement;
Note: See TracChangeset for help on using the changeset viewer.