Commit 31072bbb authored by Andy Paicu's avatar Andy Paicu Committed by Commit Bot

SPV event should have some required init fields

Spec: https://w3c.github.io/webappsec-csp/#dictdef-securitypolicyviolationeventinit

Bug: 897646
Change-Id: Id4c4947455a095c09aa34d16c7ff298ba4ba046e
Reviewed-on: https://chromium-review.googlesource.com/c/1292566
Commit-Queue: Andy Paicu <andypaicu@chromium.org>
Reviewed-by: default avatarMike West <mkwst@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605300}
parent 05eb6e23
<!doctype html>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script>
// basic tests.
test(function() {
assert_throws(TypeError(),
function() { new SecurityPolicyViolationEvent(); });
}, "SecurityPolicyViolationEvent constructor should throw with no parameters");
test(function() {
assert_not_equals(new SecurityPolicyViolationEvent("securitypolicyviolation", {
documentURI: "http://example.com",
referrer: "http://example.com",
blockedURI: "http://example.com",
violatedDirective: "default-src",
effectiveDirective: "default-src",
originalPolicy: "default-src 'none'",
sourceFile: "example.js",
sample: "<script>alert('1');</scr" + "ipt>",
disposition: "enforce",
statusCode: 200,
lineNumber: 1,
columnNumber: 1,
}), undefined);
}, "SecurityPolicyViolationEvent constructor works with an init dict");
// missing required members
test(function() {
assert_throws(TypeError(),
function() { new SecurityPolicyViolationEvent("securitypolicyviolation", {
// documentURI: "http://example.com",
referrer: "http://example.com",
blockedURI: "http://example.com",
violatedDirective: "default-src",
effectiveDirective: "default-src",
originalPolicy: "default-src 'none'",
sourceFile: "example.js",
sample: "<script>alert('1');</scr" + "ipt>",
disposition: "enforce",
statusCode: 200,
lineNumber: 1,
columnNumber: 1,
})});
}, "SecurityPolicyViolationEvent constructor requires documentURI");
test(function() {
assert_throws(TypeError(),
function() { new SecurityPolicyViolationEvent("securitypolicyviolation", {
documentURI: "http://example.com",
referrer: "http://example.com",
blockedURI: "http://example.com",
// violatedDirective: "default-src",
effectiveDirective: "default-src",
originalPolicy: "default-src 'none'",
sourceFile: "example.js",
sample: "<script>alert('1');</scr" + "ipt>",
disposition: "enforce",
statusCode: 200,
lineNumber: 1,
columnNumber: 1,
})});
}, "SecurityPolicyViolationEvent constructor requires violatedDirective");
test(function() {
assert_throws(TypeError(),
function() { new SecurityPolicyViolationEvent("securitypolicyviolation", {
documentURI: "http://example.com",
referrer: "http://example.com",
blockedURI: "http://example.com",
violatedDirective: "default-src",
// effectiveDirective: "default-src",
originalPolicy: "default-src 'none'",
sourceFile: "example.js",
sample: "<script>alert('1');</scr" + "ipt>",
disposition: "enforce",
statusCode: 200,
lineNumber: 1,
columnNumber: 1,
})});
}, "SecurityPolicyViolationEvent constructor requires effectiveDirective");
test(function() {
assert_throws(TypeError(),
function() { new SecurityPolicyViolationEvent("securitypolicyviolation", {
documentURI: "http://example.com",
referrer: "http://example.com",
blockedURI: "http://example.com",
violatedDirective: "default-src",
effectiveDirective: "default-src",
// originalPolicy: "default-src 'none'",
sourceFile: "example.js",
sample: "<script>alert('1');</scr" + "ipt>",
disposition: "enforce",
statusCode: 200,
lineNumber: 1,
columnNumber: 1,
})});
}, "SecurityPolicyViolationEvent constructor requires originalPolicy");
test(function() {
assert_throws(TypeError(),
function() { new SecurityPolicyViolationEvent("securitypolicyviolation", {
documentURI: "http://example.com",
referrer: "http://example.com",
blockedURI: "http://example.com",
violatedDirective: "default-src",
effectiveDirective: "default-src",
originalPolicy: "default-src 'none'",
sourceFile: "example.js",
sample: "<script>alert('1');</scr" + "ipt>",
// disposition: "enforce",
statusCode: 200,
lineNumber: 1,
columnNumber: 1,
})});
}, "SecurityPolicyViolationEvent constructor requires disposition");
test(function() {
assert_throws(TypeError(),
function() { new SecurityPolicyViolationEvent("securitypolicyviolation", {
documentURI: "http://example.com",
referrer: "http://example.com",
blockedURI: "http://example.com",
violatedDirective: "default-src",
effectiveDirective: "default-src",
originalPolicy: "default-src 'none'",
sourceFile: "example.js",
sample: "<script>alert('1');</scr" + "ipt>",
disposition: "enforce",
// statusCode: 200,
lineNumber: 1,
columnNumber: 1,
})});
}, "SecurityPolicyViolationEvent constructor requires statusCode");
// missing optional members
test(function() {
assert_not_equals(new SecurityPolicyViolationEvent("securitypolicyviolation", {
documentURI: "http://example.com",
// referrer: "http://example.com",
blockedURI: "http://example.com",
violatedDirective: "default-src",
effectiveDirective: "default-src",
originalPolicy: "default-src 'none'",
sourceFile: "example.js",
sample: "<script>alert('1');</scr" + "ipt>",
disposition: "enforce",
statusCode: 200,
lineNumber: 1,
columnNumber: 1,
}), undefined);
}, "SecurityPolicyViolationEvent constructor does not require referrer");
test(function() {
assert_not_equals(new SecurityPolicyViolationEvent("securitypolicyviolation", {
documentURI: "http://example.com",
referrer: "http://example.com",
// blockedURI: "http://example.com",
violatedDirective: "default-src",
effectiveDirective: "default-src",
originalPolicy: "default-src 'none'",
sourceFile: "example.js",
sample: "<script>alert('1');</scr" + "ipt>",
disposition: "enforce",
statusCode: 200,
lineNumber: 1,
columnNumber: 1,
}), undefined);
}, "SecurityPolicyViolationEvent constructor does not require blockedURI");
test(function() {
assert_not_equals(new SecurityPolicyViolationEvent("securitypolicyviolation", {
documentURI: "http://example.com",
referrer: "http://example.com",
blockedURI: "http://example.com",
violatedDirective: "default-src",
effectiveDirective: "default-src",
originalPolicy: "default-src 'none'",
// sourceFile: "example.js",
sample: "<script>alert('1');</scr" + "ipt>",
disposition: "enforce",
statusCode: 200,
lineNumber: 1,
columnNumber: 1,
}), undefined);
}, "SecurityPolicyViolationEvent constructor does not require sourceFile");
test(function() {
assert_not_equals(new SecurityPolicyViolationEvent("securitypolicyviolation", {
documentURI: "http://example.com",
referrer: "http://example.com",
blockedURI: "http://example.com",
violatedDirective: "default-src",
effectiveDirective: "default-src",
originalPolicy: "default-src 'none'",
sourceFile: "example.js",
// sample: "<script>alert('1');</scr" + "ipt>",
disposition: "enforce",
statusCode: 200,
lineNumber: 1,
columnNumber: 1,
}), undefined);
}, "SecurityPolicyViolationEvent constructor does not require sample");
test(function() {
assert_not_equals(new SecurityPolicyViolationEvent("securitypolicyviolation", {
documentURI: "http://example.com",
referrer: "http://example.com",
blockedURI: "http://example.com",
violatedDirective: "default-src",
effectiveDirective: "default-src",
originalPolicy: "default-src 'none'",
sourceFile: "example.js",
sample: "<script>alert('1');</scr" + "ipt>",
disposition: "enforce",
statusCode: 200,
// lineNumber: 1,
columnNumber: 1,
}), undefined);
}, "SecurityPolicyViolationEvent constructor does not require lineNumber");
test(function() {
assert_not_equals(new SecurityPolicyViolationEvent("securitypolicyviolation", {
documentURI: "http://example.com",
referrer: "http://example.com",
blockedURI: "http://example.com",
violatedDirective: "default-src",
effectiveDirective: "default-src",
originalPolicy: "default-src 'none'",
sourceFile: "example.js",
sample: "<script>alert('1');</scr" + "ipt>",
disposition: "enforce",
statusCode: 200,
lineNumber: 1,
// columnNumber: 1,
}), undefined);
}, "SecurityPolicyViolationEvent constructor does not require columnNumber");
</script>
......@@ -15,21 +15,27 @@ PASS new SecurityPolicyViolationEvent('eventType').disposition is "enforce"
PASS new SecurityPolicyViolationEvent('eventType').lineNumber is 0
PASS new SecurityPolicyViolationEvent('eventType').columnNumber is 0
PASS new SecurityPolicyViolationEvent('eventType').statusCode is 0
PASS new SecurityPolicyViolationEvent('eventType', { bubbles: false }).bubbles is true
PASS new SecurityPolicyViolationEvent('eventType', { bubbles: true }).bubbles is true
PASS new SecurityPolicyViolationEvent('eventType', { cancelable: false }).cancelable is false
PASS new SecurityPolicyViolationEvent('eventType', { cancelable: true }).cancelable is false
PASS new SecurityPolicyViolationEvent('eventType', { documentURI: 'foo' }).documentURI is "foo"
PASS new SecurityPolicyViolationEvent('eventType', { referrer: 'foo' }).referrer is "foo"
PASS new SecurityPolicyViolationEvent('eventType', { blockedURI: 'foo' }).blockedURI is "foo"
PASS new SecurityPolicyViolationEvent('eventType', { violatedDirective: 'foo' }).violatedDirective is "foo"
PASS new SecurityPolicyViolationEvent('eventType', { effectiveDirective: 'foo' }).effectiveDirective is "foo"
PASS new SecurityPolicyViolationEvent('eventType', { originalPolicy: 'foo' }).originalPolicy is "foo"
PASS new SecurityPolicyViolationEvent('eventType', { sourceFile: 'foo' }).sourceFile is "foo"
PASS new SecurityPolicyViolationEvent('eventType', { disposition: 'foo' }).disposition threw exception TypeError: Failed to construct 'SecurityPolicyViolationEvent': The provided value 'foo' is not a valid enum value of type SecurityPolicyViolationEventDisposition..
PASS new SecurityPolicyViolationEvent('eventType', { lineNumber: 42 }).lineNumber is 42
PASS new SecurityPolicyViolationEvent('eventType', { columnNumber: 42 }).columnNumber is 42
PASS new SecurityPolicyViolationEvent('eventType', { statusCode: 42 }).statusCode is 42
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({ bubbles: false})).bubbles is true
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({ bubbles: true})).bubbles is true
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({ cancelable: false})).cancelable is false
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({ cancelable: true})).cancelable is false
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({ documentURI: 'foo' })).documentURI is "foo"
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({ referrer: 'foo' })).referrer is "foo"
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({ blockedURI: 'foo' })).blockedURI is "foo"
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({ violatedDirective: 'foo' })).violatedDirective is "foo"
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({ effectiveDirective: 'foo' })).effectiveDirective is "foo"
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({ originalPolicy: 'foo' })).originalPolicy is "foo"
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({ sourceFile: 'foo' })).sourceFile is "foo"
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({ disposition: 'foo' })) threw exception TypeError: Failed to construct 'SecurityPolicyViolationEvent': The provided value 'foo' is not a valid enum value of type SecurityPolicyViolationEventDisposition..
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({ lineNumber: 42 })).lineNumber is 42
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({ columnNumber: 42 })).columnNumber is 42
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({ statusCode: 42 })).statusCode is 42
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({}, "documentURI")) threw exception TypeError: Failed to construct 'SecurityPolicyViolationEvent': required member documentURI is undefined..
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({}, "violatedDirective")) threw exception TypeError: Failed to construct 'SecurityPolicyViolationEvent': required member violatedDirective is undefined..
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({}, "effectiveDirective")) threw exception TypeError: Failed to construct 'SecurityPolicyViolationEvent': required member effectiveDirective is undefined..
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({}, "originalPolicy")) threw exception TypeError: Failed to construct 'SecurityPolicyViolationEvent': required member originalPolicy is undefined..
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({}, "statusCode")) threw exception TypeError: Failed to construct 'SecurityPolicyViolationEvent': required member statusCode is undefined..
PASS new SecurityPolicyViolationEvent('eventType', add_required_members({}, "disposition")) threw exception TypeError: Failed to construct 'SecurityPolicyViolationEvent': required member disposition is undefined..
PASS successfullyParsed is true
TEST COMPLETE
......
......@@ -26,25 +26,52 @@ shouldBe("new SecurityPolicyViolationEvent('eventType').lineNumber", "0");
shouldBe("new SecurityPolicyViolationEvent('eventType').columnNumber", "0");
shouldBe("new SecurityPolicyViolationEvent('eventType').statusCode", "0");
/*
required DOMString documentURI;
required DOMString violatedDirective;
required DOMString effectiveDirective;
required DOMString originalPolicy;
required SecurityPolicyViolationEventDisposition disposition;
required unsigned short statusCode;
*/
// This function will add to the init dict any missing required members
function add_required_members(init_dict, deleted_member) {
["documentURI", "violatedDirective", "effectiveDirective", "originalPolicy"].forEach(function(member) {
if (!(member in init_dict)) init_dict[member] = 'bar';
})
if (!("statusCode" in init_dict)) init_dict["statusCode"] = 200;
if (!("disposition" in init_dict)) init_dict["disposition"] = 'enforce';
// for tests that test the absence of required members
if (deleted_member != undefined && deleted_member in init_dict) delete init_dict[deleted_member];
return init_dict;
}
// bubbles is always true.
shouldBeTrue("new SecurityPolicyViolationEvent('eventType', { bubbles: false }).bubbles");
shouldBeTrue("new SecurityPolicyViolationEvent('eventType', { bubbles: true }).bubbles");
shouldBeTrue("new SecurityPolicyViolationEvent('eventType', add_required_members({ bubbles: false})).bubbles");
shouldBeTrue("new SecurityPolicyViolationEvent('eventType', add_required_members({ bubbles: true})).bubbles");
// cancelable is always false.
shouldBeFalse("new SecurityPolicyViolationEvent('eventType', { cancelable: false }).cancelable");
shouldBeFalse("new SecurityPolicyViolationEvent('eventType', { cancelable: true }).cancelable");
shouldBeFalse("new SecurityPolicyViolationEvent('eventType', add_required_members({ cancelable: false})).cancelable");
shouldBeFalse("new SecurityPolicyViolationEvent('eventType', add_required_members({ cancelable: true})).cancelable");
// String members are passed.
["documentURI", "referrer", "blockedURI", "violatedDirective", "effectiveDirective", "originalPolicy", "sourceFile"].forEach(function(member) {
shouldBeEqualToString("new SecurityPolicyViolationEvent('eventType', { " + member + ": 'foo' })." + member, "foo");
shouldBeEqualToString("new SecurityPolicyViolationEvent('eventType', add_required_members({ " + member + ": 'foo' }))." + member, "foo");
});
// Enum members throw on unknown initializer values.
shouldThrow("new SecurityPolicyViolationEvent('eventType', { disposition: 'foo' }).disposition");
shouldThrow("new SecurityPolicyViolationEvent('eventType', add_required_members({ disposition: 'foo' }))");
// Number members are passed.
["lineNumber", "columnNumber", "statusCode"].forEach(function(member) {
shouldBe("new SecurityPolicyViolationEvent('eventType', { " + member + ": 42 })." + member, "42");
shouldBe("new SecurityPolicyViolationEvent('eventType', add_required_members({ " + member + ": 42 }))." + member, "42");
});
// Missing required members throw
["documentURI", "violatedDirective", "effectiveDirective", "originalPolicy", "statusCode", "disposition"].forEach(function(member) {
shouldThrow("new SecurityPolicyViolationEvent('eventType', add_required_members({}, \"" + member + "\"))")
});
</script>
</body>
......
......@@ -36,13 +36,17 @@ const char kReport[] = "report";
} // namespace
SecurityPolicyViolationEvent::SecurityPolicyViolationEvent(
const AtomicString& type,
const SecurityPolicyViolationEventInit* initializer)
const AtomicString& type)
: Event(type, Bubbles::kYes, Cancelable::kNo, ComposedMode::kComposed),
disposition_(kContentSecurityPolicyHeaderTypeEnforce),
line_number_(0),
column_number_(0),
status_code_(0) {
status_code_(0) {}
SecurityPolicyViolationEvent::SecurityPolicyViolationEvent(
const AtomicString& type,
const SecurityPolicyViolationEventInit* initializer)
: SecurityPolicyViolationEvent(type) {
if (initializer->hasDocumentURI())
document_uri_ = initializer->documentURI();
if (initializer->hasReferrer())
......
......@@ -37,6 +37,10 @@ class SecurityPolicyViolationEvent final : public Event {
DEFINE_WRAPPERTYPEINFO();
public:
static SecurityPolicyViolationEvent* Create(const AtomicString& type) {
return new SecurityPolicyViolationEvent(type);
}
static SecurityPolicyViolationEvent* Create(
const AtomicString& type,
const SecurityPolicyViolationEventInit* initializer) {
......@@ -63,6 +67,7 @@ class SecurityPolicyViolationEvent final : public Event {
void Trace(blink::Visitor* visitor) override { Event::Trace(visitor); }
private:
explicit SecurityPolicyViolationEvent(const AtomicString& type);
SecurityPolicyViolationEvent(
const AtomicString& type,
const SecurityPolicyViolationEventInit* initializer);
......
......@@ -30,7 +30,8 @@ enum SecurityPolicyViolationEventDisposition {
};
[
Constructor(DOMString type, optional SecurityPolicyViolationEventInit eventInitDict)
Constructor(DOMString type),
Constructor(DOMString type, SecurityPolicyViolationEventInit eventInitDict)
] interface SecurityPolicyViolationEvent : Event {
// TODO(foolip): The spec says "documentURL".
[Measure] readonly attribute DOMString documentURI;
......
......@@ -5,18 +5,18 @@
// https://w3c.github.io/webappsec-csp/#idl-index
dictionary SecurityPolicyViolationEventInit : EventInit {
// TODO(foolip): The spec says "documentURL".
DOMString documentURI;
DOMString referrer;
// TODO(foolip): The spec says "blockedURL".
DOMString blockedURI;
DOMString violatedDirective;
DOMString effectiveDirective;
DOMString originalPolicy;
SecurityPolicyViolationEventDisposition disposition;
DOMString sourceFile;
unsigned short statusCode;
long lineNumber;
long columnNumber;
DOMString sample;
// TODO(foolip): The spec says "documentURL".
required DOMString documentURI;
DOMString referrer;
// TODO(foolip): The spec says "blockedURL".
DOMString blockedURI;
required DOMString violatedDirective;
required DOMString effectiveDirective;
required DOMString originalPolicy;
required SecurityPolicyViolationEventDisposition disposition;
DOMString sourceFile;
required unsigned short statusCode;
long lineNumber;
long columnNumber;
DOMString sample;
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment