Commit 31d74bdc authored by jochen's avatar jochen Committed by Commit bot

Move referrer policy to a different field when serializing.

Also try to fix old entries when possible and play nice with older
versions

BUG=450589
R=mkwst@chromium.org,marja@chromium.org,atwilson@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#313742}
parent ae4b5eec
......@@ -11,6 +11,13 @@
namespace sessions {
namespace {
const int kObsoleteReferrerPolicyAlways = 0;
const int kObsoleteReferrerPolicyDefault = 1;
const int kObsoleteReferrerPolicyNever = 2;
const int kObsoleteReferrerPolicyOrigin = 3;
} // namespace
// static
SerializedNavigationDriver* SerializedNavigationDriver::Get() {
return ContentSerializedNavigationDriver::GetInstance();
......@@ -33,6 +40,45 @@ int ContentSerializedNavigationDriver::GetDefaultReferrerPolicy() const {
return blink::WebReferrerPolicyDefault;
}
bool ContentSerializedNavigationDriver::MapReferrerPolicyToOldValues(
int referrer_policy,
int* mapped_referrer_policy) const {
switch (referrer_policy) {
case blink::WebReferrerPolicyAlways:
case blink::WebReferrerPolicyDefault:
// "always" and "default" are the same value in all versions.
*mapped_referrer_policy = referrer_policy;
return true;
case blink::WebReferrerPolicyOrigin:
// "origin" exists in the old encoding.
*mapped_referrer_policy = kObsoleteReferrerPolicyOrigin;
return true;
default:
// Everything else is mapped to never.
*mapped_referrer_policy = kObsoleteReferrerPolicyNever;
return false;
}
}
bool ContentSerializedNavigationDriver::MapReferrerPolicyToNewValues(
int referrer_policy,
int* mapped_referrer_policy) const {
switch (referrer_policy) {
case kObsoleteReferrerPolicyAlways:
case kObsoleteReferrerPolicyDefault:
// "always" and "default" are the same value in all versions.
*mapped_referrer_policy = referrer_policy;
return true;
default:
// Since we don't know what encoding was used, we map the rest to "never".
*mapped_referrer_policy = blink::WebReferrerPolicyNever;
return false;
}
}
std::string
ContentSerializedNavigationDriver::GetSanitizedPageStateForPickle(
const SerializedNavigationEntry* navigation) const {
......
......@@ -26,6 +26,10 @@ class SESSIONS_EXPORT_PRIVATE ContentSerializedNavigationDriver
// SerializedNavigationDriver implementation.
int GetDefaultReferrerPolicy() const override;
bool MapReferrerPolicyToOldValues(int referrer_policy,
int* mapped_referrer_policy) const override;
bool MapReferrerPolicyToNewValues(int referrer_policy,
int* mapped_referrer_policy) const override;
std::string GetSanitizedPageStateForPickle(
const SerializedNavigationEntry* navigation) const override;
void Sanitize(SerializedNavigationEntry* navigation) const override;
......
......@@ -25,6 +25,18 @@ class SESSIONS_EXPORT_PRIVATE SerializedNavigationDriver {
// Returns the default referrer policy.
virtual int GetDefaultReferrerPolicy() const = 0;
// Maps current referrer policies to old values to work around
// crbug.com/450589. Returns false if the referrer should be stripped.
virtual bool MapReferrerPolicyToOldValues(
int referrer_policy,
int* mapped_referrer_policy) const = 0;
// Sanitizes a referrer policy that might either be in the old or the new
// format. Returns false if the referrer should be stripped.
virtual bool MapReferrerPolicyToNewValues(
int referrer_policy,
int* mapped_referrer_policy) const = 0;
// Returns a sanitized version of the given |navigation|'s encoded_page_state
// suitable for writing to disk.
virtual std::string GetSanitizedPageStateForPickle(
......
......@@ -10,6 +10,13 @@
namespace sessions {
namespace {
const int kObsoleteReferrerPolicyAlways = 0;
const int kObsoleteReferrerPolicyDefault = 1;
const int kObsoleteReferrerPolicyNever = 2;
const int kObsoleteReferrerPolicyOrigin = 3;
} // namespace
// static
SerializedNavigationDriver* SerializedNavigationDriver::Get() {
return IOSSerializedNavigationDriver::GetInstance();
......@@ -32,6 +39,45 @@ int IOSSerializedNavigationDriver::GetDefaultReferrerPolicy() const {
return web::ReferrerPolicyDefault;
}
bool IOSSerializedNavigationDriver::MapReferrerPolicyToOldValues(
int referrer_policy,
int* mapped_referrer_policy) const {
switch (referrer_policy) {
case web::ReferrerPolicyAlways:
case web::ReferrerPolicyDefault:
// "always" and "default" are the same value in all versions.
*mapped_referrer_policy = referrer_policy;
return true;
case web::ReferrerPolicyOrigin:
// "origin" exists in the old encoding.
*mapped_referrer_policy = kObsoleteReferrerPolicyOrigin;
return true;
default:
// Everything else is mapped to never.
*mapped_referrer_policy = kObsoleteReferrerPolicyNever;
return false;
}
}
bool IOSSerializedNavigationDriver::MapReferrerPolicyToNewValues(
int referrer_policy,
int* mapped_referrer_policy) const {
switch (referrer_policy) {
case kObsoleteReferrerPolicyAlways:
case kObsoleteReferrerPolicyDefault:
// "always" and "default" are the same value in all versions.
*mapped_referrer_policy = referrer_policy;
return true;
default:
// Since we don't know what encoding was used, we map the rest to "never".
*mapped_referrer_policy = web::ReferrerPolicyNever;
return false;
}
}
std::string
IOSSerializedNavigationDriver::GetSanitizedPageStateForPickle(
const SerializedNavigationEntry* navigation) const {
......@@ -48,13 +94,20 @@ void IOSSerializedNavigationDriver::Sanitize(
!referrer.url.SchemeIsHTTPOrHTTPS()) {
referrer.url = GURL();
} else {
if (referrer.policy < 0 || referrer.policy > web::ReferrerPolicyLast) {
NOTREACHED();
referrer.policy = web::ReferrerPolicyNever;
}
bool is_downgrade = referrer.url.SchemeIsSecure() &&
!navigation->virtual_url_.SchemeIsSecure();
switch (referrer.policy) {
case web::ReferrerPolicyDefault:
if (referrer.url.SchemeIsSecure() &&
!navigation->virtual_url_.SchemeIsSecure()) {
if (is_downgrade)
referrer.url = GURL();
}
break;
case web::ReferrerPolicyNoReferrerWhenDowngrade:
if (is_downgrade)
referrer.url = GURL();
case web::ReferrerPolicyAlways:
break;
case web::ReferrerPolicyNever:
......@@ -63,8 +116,9 @@ void IOSSerializedNavigationDriver::Sanitize(
case web::ReferrerPolicyOrigin:
referrer.url = referrer.url.GetOrigin();
break;
default:
NOTREACHED();
case web::ReferrerPolicyOriginWhenCrossOrigin:
if (navigation->virtual_url_.GetOrigin() != referrer.url.GetOrigin())
referrer.url = referrer.url.GetOrigin();
break;
}
}
......
......@@ -24,6 +24,10 @@ class IOSSerializedNavigationDriver
// SerializedNavigationDriver implementation.
int GetDefaultReferrerPolicy() const override;
bool MapReferrerPolicyToOldValues(int referrer_policy,
int* mapped_referrer_policy) const override;
bool MapReferrerPolicyToNewValues(int referrer_policy,
int* mapped_referrer_policy) const override;
std::string GetSanitizedPageStateForPickle(
const SerializedNavigationEntry* navigation) const override;
void Sanitize(SerializedNavigationEntry* navigation) const override;
......
......@@ -36,8 +36,19 @@ SerializedNavigationEntry SerializedNavigationEntry::FromSyncData(
SerializedNavigationEntry navigation;
navigation.index_ = index;
navigation.unique_id_ = sync_data.unique_id();
navigation.referrer_url_ = GURL(sync_data.referrer());
navigation.referrer_policy_ = sync_data.referrer_policy();
if (sync_data.has_correct_referrer_policy()) {
navigation.referrer_url_ = GURL(sync_data.referrer());
navigation.referrer_policy_ = sync_data.correct_referrer_policy();
} else {
int mapped_referrer_policy;
if (SerializedNavigationDriver::Get()->MapReferrerPolicyToNewValues(
sync_data.obsolete_referrer_policy(), &mapped_referrer_policy)) {
navigation.referrer_url_ = GURL(sync_data.referrer());
} else {
navigation.referrer_url_ = GURL();
}
navigation.referrer_policy_ = mapped_referrer_policy;
}
navigation.virtual_url_ = GURL(sync_data.virtual_url());
navigation.title_ = base::UTF8ToUTF16(sync_data.title());
navigation.encoded_page_state_ = sync_data.state();
......@@ -183,12 +194,13 @@ enum TypeMask {
//
// type_mask (has_post_data_)
// referrer_url_
// referrer_policy_
// referrer_policy_ (broken, crbug.com/450589)
// original_request_url_
// is_overriding_user_agent_
// timestamp_
// search_terms_
// http_status_code_
// referrer_policy_
void SerializedNavigationEntry::WriteToPickle(int max_size,
Pickle* pickle) const {
......@@ -210,11 +222,15 @@ void SerializedNavigationEntry::WriteToPickle(int max_size,
const int type_mask = has_post_data_ ? HAS_POST_DATA : 0;
pickle->WriteInt(type_mask);
WriteStringToPickle(
pickle, &bytes_written, max_size,
referrer_url_.is_valid() ? referrer_url_.spec() : std::string());
pickle->WriteInt(referrer_policy_);
int mapped_referrer_policy;
if (SerializedNavigationDriver::Get()->MapReferrerPolicyToOldValues(
referrer_policy_, &mapped_referrer_policy) &&
referrer_url_.is_valid()) {
WriteStringToPickle(pickle, &bytes_written, max_size, referrer_url_.spec());
} else {
WriteStringToPickle(pickle, &bytes_written, max_size, std::string());
}
pickle->WriteInt(mapped_referrer_policy);
// Save info required to override the user agent.
WriteStringToPickle(
......@@ -227,6 +243,8 @@ void SerializedNavigationEntry::WriteToPickle(int max_size,
WriteString16ToPickle(pickle, &bytes_written, max_size, search_terms_);
pickle->WriteInt(http_status_code_);
pickle->WriteInt(referrer_policy_);
}
bool SerializedNavigationEntry::ReadFromPickle(PickleIterator* iterator) {
......@@ -258,9 +276,13 @@ bool SerializedNavigationEntry::ReadFromPickle(PickleIterator* iterator) {
// The "referrer policy" property was added even later, so we fall back to
// the default policy if the property is not present.
if (!iterator->ReadInt(&referrer_policy_))
//
// Note: due to crbug.com/450589 this value might be incorrect, and a
// corrected version is stored later in the pickle.
if (!iterator->ReadInt(&referrer_policy_)) {
referrer_policy_ =
SerializedNavigationDriver::Get()->GetDefaultReferrerPolicy();
}
// If the original URL can't be found, leave it empty.
std::string original_request_url_spec;
......@@ -285,6 +307,19 @@ bool SerializedNavigationEntry::ReadFromPickle(PickleIterator* iterator) {
if (!iterator->ReadInt(&http_status_code_))
http_status_code_ = 0;
// Correct referrer policy (if present).
int correct_referrer_policy;
if (iterator->ReadInt(&correct_referrer_policy)) {
referrer_policy_ = correct_referrer_policy;
} else {
int mapped_referrer_policy;
if (!SerializedNavigationDriver::Get()->MapReferrerPolicyToNewValues(
referrer_policy_, &mapped_referrer_policy)) {
referrer_url_ = GURL();
}
referrer_policy_ = mapped_referrer_policy;
}
}
SerializedNavigationDriver::Get()->Sanitize(this);
......@@ -299,8 +334,15 @@ bool SerializedNavigationEntry::ReadFromPickle(PickleIterator* iterator) {
sync_pb::TabNavigation SerializedNavigationEntry::ToSyncData() const {
sync_pb::TabNavigation sync_data;
sync_data.set_virtual_url(virtual_url_.spec());
sync_data.set_referrer(referrer_url_.spec());
sync_data.set_referrer_policy(referrer_policy_);
int mapped_referrer_policy;
if (SerializedNavigationDriver::Get()->MapReferrerPolicyToOldValues(
referrer_policy_, &mapped_referrer_policy)) {
sync_data.set_referrer(referrer_url_.spec());
} else {
sync_data.set_referrer(std::string());
}
sync_data.set_obsolete_referrer_policy(mapped_referrer_policy);
sync_data.set_correct_referrer_policy(referrer_policy_);
sync_data.set_title(base::UTF16ToUTF8(title_));
// Page transition core.
......
......@@ -30,7 +30,8 @@ sync_pb::TabNavigation MakeSyncDataForTest() {
sync_pb::TabNavigation sync_data;
sync_data.set_virtual_url(test_data::kVirtualURL.spec());
sync_data.set_referrer(test_data::kReferrerURL.spec());
sync_data.set_referrer_policy(test_data::kReferrerPolicy);
sync_data.set_obsolete_referrer_policy(test_data::kReferrerPolicy);
sync_data.set_correct_referrer_policy(test_data::kReferrerPolicy);
sync_data.set_title(base::UTF16ToUTF8(test_data::kTitle));
sync_data.set_state(test_data::kEncodedPageState);
sync_data.set_page_transition(
......
......@@ -211,10 +211,11 @@ base::DictionaryValue* TabNavigationToValue(
SET_ENUM(blocked_state, GetBlockedStateString);
SET_STR_REP(content_pack_categories);
SET_INT32(http_status_code);
SET_INT32(referrer_policy);
SET_INT32(obsolete_referrer_policy);
SET_BOOL(is_restored);
SET_REP(navigation_redirect, NavigationRedirectToValue);
SET_STR(last_navigation_redirect_url);
SET_INT32(correct_referrer_policy);
return value;
}
......
......@@ -137,9 +137,8 @@ message TabNavigation {
// The status code from the last navigation.
optional int32 http_status_code = 20;
// Referrer policy. Valid enums are defined in
// third_party/WebKit/public/platform/WebReferrerPolicy.h.
optional int32 referrer_policy = 21 [default = 1];
// Referrer policy. Old, broken value.
optional int32 obsolete_referrer_policy = 21 [default = 1];
// True if created from restored navigation entry that hasn't been loaded.
optional bool is_restored = 22;
// The chain of redirections for this navigation, from the original URL
......@@ -148,6 +147,9 @@ message TabNavigation {
// Normally not present.
// The last URL traversed when different from the virtual_url.
optional string last_navigation_redirect_url = 24;
// Correct referrer policy. Valid enums are defined in
// third_party/WebKit/public/platform/WebReferrerPolicy.h.
optional int32 correct_referrer_policy = 25 [default = 1];
}
// Navigation information for a single redirection within a single navigation.
......
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