Commit caebf445 authored by Tommy Martino's avatar Tommy Martino Committed by Commit Bot

[SH iOS] URL-decoding values before passing to JS land

This fixes a bug where text fragments in the URL are not matched in the
page because spaces (and other special characters) are still URL-
encoded.

It also terminates early if no text fragment could be parsed, to avoid
needless JS calls.

Bug: 1099268
Change-Id: I3a135a4804bc57cde6ef1b1cc22785016507db53
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2422724
Commit-Queue: Tommy Martino <tmartino@chromium.org>
Reviewed-by: default avatarEugene But <eugenebut@chromium.org>
Cr-Commit-Position: refs/heads/master@{#809104}
parent 00ce3db0
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
#include <cstring.h> #include <cstring.h>
#include "base/json/json_writer.h" #include "base/json/json_writer.h"
#include "base/strings/escape.h"
#include "base/strings/string_split.h" #include "base/strings/string_split.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
...@@ -23,6 +24,10 @@ namespace { ...@@ -23,6 +24,10 @@ namespace {
const char kDirectivePrefix[] = ":~:"; const char kDirectivePrefix[] = ":~:";
const char kTextFragmentPrefix[] = "text="; const char kTextFragmentPrefix[] = "text=";
base::Value DecodeStringToValue(const std::string& str) {
return base::Value(base::UnescapeBinaryURLComponent(str));
}
} // namespace } // namespace
namespace web { namespace web {
...@@ -42,10 +47,14 @@ bool AreTextFragmentsAllowed(NavigationContext* context) { ...@@ -42,10 +47,14 @@ bool AreTextFragmentsAllowed(NavigationContext* context) {
} }
void HandleTextFragments(WebState* state) { void HandleTextFragments(WebState* state) {
base::Value parsed_fragments =
internal::ParseTextFragments(state->GetLastCommittedURL());
if (parsed_fragments.type() == base::Value::Type::NONE)
return;
std::string fragment_param; std::string fragment_param;
base::JSONWriter::Write( base::JSONWriter::Write(parsed_fragments, &fragment_param);
internal::ParseTextFragments(state->GetLastCommittedURL()),
&fragment_param);
std::string script = base::ReplaceStringPlaceholders( std::string script = base::ReplaceStringPlaceholders(
"__gCrWeb.textFragments.handleTextFragments($1, $2)", "__gCrWeb.textFragments.handleTextFragments($1, $2)",
...@@ -148,16 +157,16 @@ base::Value TextFragmentToValue(std::string fragment) { ...@@ -148,16 +157,16 @@ base::Value TextFragmentToValue(std::string fragment) {
} }
if (prefix.size()) if (prefix.size())
dict.SetKey("prefix", base::Value(prefix)); dict.SetKey("prefix", DecodeStringToValue(prefix));
// Guaranteed non-empty after checking for malformed input above. // Guaranteed non-empty after checking for malformed input above.
dict.SetKey("textStart", base::Value(text_start)); dict.SetKey("textStart", DecodeStringToValue(text_start));
if (text_end.size()) if (text_end.size())
dict.SetKey("textEnd", base::Value(text_end)); dict.SetKey("textEnd", DecodeStringToValue(text_end));
if (suffix.size()) if (suffix.size())
dict.SetKey("suffix", base::Value(suffix)); dict.SetKey("suffix", DecodeStringToValue(suffix));
return dict; return dict;
} }
......
...@@ -72,10 +72,8 @@ TEST_F(TextFragmentUtilsTest, ParseTextFragments) { ...@@ -72,10 +72,8 @@ TEST_F(TextFragmentUtilsTest, ParseTextFragments) {
"https://www.example.com/#idFrag:~:text=text%201&text=text%202"); "https://www.example.com/#idFrag:~:text=text%201&text=text%202");
base::Value result = internal::ParseTextFragments(url_with_fragment); base::Value result = internal::ParseTextFragments(url_with_fragment);
ASSERT_EQ(2u, result.GetList().size()); ASSERT_EQ(2u, result.GetList().size());
EXPECT_EQ("text%201", EXPECT_EQ("text 1", result.GetList()[0].FindKey(kTextStartKey)->GetString());
result.GetList()[0].FindKey(kTextStartKey)->GetString()); EXPECT_EQ("text 2", result.GetList()[1].FindKey(kTextStartKey)->GetString());
EXPECT_EQ("text%202",
result.GetList()[1].FindKey(kTextStartKey)->GetString());
GURL url_no_fragment("www.example.com"); GURL url_no_fragment("www.example.com");
base::Value empty_result = internal::ParseTextFragments(url_no_fragment); base::Value empty_result = internal::ParseTextFragments(url_no_fragment);
......
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