Commit abea1062 authored by Matt Giuca's avatar Matt Giuca Committed by Commit Bot

Badging: Throw TypeError if the scope URL parses invalid.

Bug: 1001405
Change-Id: I918c57d6922915e624b731432b393311d8ab1a3b
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1802780
Commit-Queue: Matt Giuca <mgiuca@chromium.org>
Reviewed-by: default avatarEric Willigers <ericwilligers@chromium.org>
Cr-Commit-Position: refs/heads/master@{#696721}
parent d9745011
...@@ -37,7 +37,8 @@ void Badge::set(ScriptState* script_state, ...@@ -37,7 +37,8 @@ void Badge::set(ScriptState* script_state,
const BadgeOptions* options, const BadgeOptions* options,
ExceptionState& exception_state) { ExceptionState& exception_state) {
BadgeFromState(script_state) BadgeFromState(script_state)
->SetBadge(options->scope(), mojom::blink::BadgeValue::NewFlag(0)); ->SetBadge(options->scope(), mojom::blink::BadgeValue::NewFlag(0),
exception_state);
} }
// static // static
...@@ -53,28 +54,38 @@ void Badge::set(ScriptState* script_state, ...@@ -53,28 +54,38 @@ void Badge::set(ScriptState* script_state,
const BadgeOptions* options, const BadgeOptions* options,
ExceptionState& exception_state) { ExceptionState& exception_state) {
if (content == 0) { if (content == 0) {
Badge::clear(script_state, options); Badge::clear(script_state, options, exception_state);
} else { } else {
BadgeFromState(script_state) BadgeFromState(script_state)
->SetBadge(options->scope(), ->SetBadge(options->scope(),
mojom::blink::BadgeValue::NewNumber(content)); mojom::blink::BadgeValue::NewNumber(content),
exception_state);
} }
} }
// static // static
void Badge::clear(ScriptState* script_state, const BadgeOptions* options) { void Badge::clear(ScriptState* script_state,
BadgeFromState(script_state)->ClearBadge(options->scope()); const BadgeOptions* options,
ExceptionState& exception_state) {
BadgeFromState(script_state)->ClearBadge(options->scope(), exception_state);
} }
void Badge::SetBadge(WTF::String scope, mojom::blink::BadgeValuePtr value) { void Badge::SetBadge(WTF::String scope,
// Resolve |scope| against the URL of the current document/worker. mojom::blink::BadgeValuePtr value,
KURL scope_url = KURL(execution_context_->Url(), scope); ExceptionState& exception_state) {
badge_service_->SetBadge(scope_url, std::move(value)); base::Optional<KURL> scope_url = ScopeStringToURL(scope, exception_state);
if (!scope_url)
return;
badge_service_->SetBadge(*scope_url, std::move(value));
} }
void Badge::ClearBadge(WTF::String scope) { void Badge::ClearBadge(WTF::String scope, ExceptionState& exception_state) {
// Resolve |scope| against the URL of the current document/worker. base::Optional<KURL> scope_url = ScopeStringToURL(scope, exception_state);
badge_service_->ClearBadge(KURL(execution_context_->Url(), scope)); if (!scope_url)
return;
badge_service_->ClearBadge(*scope_url);
} }
void Badge::Trace(blink::Visitor* visitor) { void Badge::Trace(blink::Visitor* visitor) {
...@@ -95,4 +106,22 @@ Badge* Badge::BadgeFromState(ScriptState* script_state) { ...@@ -95,4 +106,22 @@ Badge* Badge::BadgeFromState(ScriptState* script_state) {
return Badge::From(ExecutionContext::From(script_state)); return Badge::From(ExecutionContext::From(script_state));
} }
base::Optional<KURL> Badge::ScopeStringToURL(WTF::String& scope,
ExceptionState& exception_state) {
// Resolve |scope| against the URL of the current document/worker.
KURL scope_url = KURL(execution_context_->Url(), scope);
if (!scope_url.IsValid()) {
exception_state.ThrowTypeError("Invalid scope URL");
return base::nullopt;
}
// TODO(mgiuca): Check that URL is same-origin as the execution context. If
// not, fail with SecurityError (https://crbug.com/1001404). (This is not a
// security bug, since the same-origin check is currently done on the browser
// side, but we still want to report the failure as an exception.)
return base::Optional<KURL>(scope_url);
}
} // namespace blink } // namespace blink
...@@ -5,10 +5,12 @@ ...@@ -5,10 +5,12 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_BADGE_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_BADGE_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_BADGE_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_BADGING_BADGE_H_
#include "base/optional.h"
#include "mojo/public/cpp/bindings/remote.h" #include "mojo/public/cpp/bindings/remote.h"
#include "third_party/blink/public/mojom/badging/badging.mojom-blink.h" #include "third_party/blink/public/mojom/badging/badging.mojom-blink.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/supplementable.h" #include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
namespace blink { namespace blink {
...@@ -39,16 +41,22 @@ class Badge final : public ScriptWrappable, ...@@ -39,16 +41,22 @@ class Badge final : public ScriptWrappable,
ExceptionState&); ExceptionState&);
static void set(ScriptState*, ExceptionState&); static void set(ScriptState*, ExceptionState&);
static void set(ScriptState*, uint64_t content, ExceptionState&); static void set(ScriptState*, uint64_t content, ExceptionState&);
static void clear(ScriptState*, const BadgeOptions*); static void clear(ScriptState*, const BadgeOptions*, ExceptionState&);
void SetBadge(WTF::String scope, mojom::blink::BadgeValuePtr value); void SetBadge(WTF::String scope,
void ClearBadge(WTF::String scope); mojom::blink::BadgeValuePtr value,
ExceptionState&);
void ClearBadge(WTF::String scope, ExceptionState&);
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) override;
private: private:
static Badge* BadgeFromState(ScriptState* script_state); static Badge* BadgeFromState(ScriptState* script_state);
// If the URL is invalid, sets an exception and returns nullopt, which callers
// should check for and stop doing work.
base::Optional<KURL> ScopeStringToURL(WTF::String& scope, ExceptionState&);
mojo::Remote<blink::mojom::blink::BadgeService> badge_service_; mojo::Remote<blink::mojom::blink::BadgeService> badge_service_;
Member<ExecutionContext> execution_context_; Member<ExecutionContext> execution_context_;
}; };
......
...@@ -13,5 +13,5 @@ ...@@ -13,5 +13,5 @@
] interface ExperimentalBadge { ] interface ExperimentalBadge {
[CallWith=ScriptState, RaisesException, MeasureAs=BadgeSet] [CallWith=ScriptState, RaisesException, MeasureAs=BadgeSet]
static void set(optional [EnforceRange] unsigned long long contents, optional BadgeOptions options); static void set(optional [EnforceRange] unsigned long long contents, optional BadgeOptions options);
[CallWith=ScriptState, MeasureAs=BadgeClear] static void clear(optional BadgeOptions options); [CallWith=ScriptState, RaisesException, MeasureAs=BadgeClear] static void clear(optional BadgeOptions options);
}; };
...@@ -41,10 +41,9 @@ badge_test(() => { ExperimentalBadge.set({}); }, undefined, undefined, ...@@ -41,10 +41,9 @@ badge_test(() => { ExperimentalBadge.set({}); }, undefined, undefined,
// }, undefined, undefined, 'SecurityError'); // }, undefined, undefined, 'SecurityError');
// Invalid URL. // Invalid URL.
// TODO(mgiuca): Currently succeeds with scope = "". https://crbug.com/1001405 badge_test(() => {
// badge_test(() => { ExperimentalBadge.set(1, {scope: 'https://example.com:99999'});
// ExperimentalBadge.set(1, {scope: 'https://example.com:99999'}); }, undefined, undefined, 'TypeError');
// }, undefined, undefined, 'TypeError');
</script> </script>
</body> </body>
......
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