Bug 1301008 - Pass safebrowsing v4 list state in base64 format to avoid truncation.
MozReview-Commit-ID: 6oVdQvEoMm2
--- a/toolkit/components/url-classifier/content/listmanager.js
+++ b/toolkit/components/url-classifier/content/listmanager.js
@@ -396,17 +396,17 @@ PROT_ListManager.prototype.makeUpdateReq
// never been downloaded. See Bug 1287058 for supporting
// partial update.
let stateArray = [];
tableArray.forEach(listName => {
// See Bug 1287059. We save the state to prefs until we support
// "saving states to HashStore".
let statePrefName = "browser.safebrowsing.provider.google4.state." + listName;
let stateBase64 = this.prefs_.getPref(statePrefName, "");
- stateArray.push(stateBase64 ? atob(stateBase64) : "");
+ stateArray.push(stateBase64);
});
let urlUtils = Cc["@mozilla.org/url-classifier/utils;1"]
.getService(Ci.nsIUrlClassifierUtils);
let requestPayload = urlUtils.makeUpdateRequestV4(tableArray,
stateArray,
tableArray.length);
// Use a base64-encoded request.
--- a/toolkit/components/url-classifier/nsIUrlClassifierUtils.idl
+++ b/toolkit/components/url-classifier/nsIUrlClassifierUtils.idl
@@ -49,17 +49,17 @@ interface nsIUrlClassifierUtils : nsISup
* @returns The threat type in integer.
*/
uint32_t convertListNameToThreatType(in ACString listName);
/**
* Make update request for given lists and their states.
*
* @param aListNames An array of list name represented in string.
- * @param aState An array of states (in string) for each list.
+ * @param aState An array of states (encoded in base64 format) for each list.
* @param aCount The array length of aList and aState.
*
* @returns A string to store request. Not null-terminated.
*/
ACString makeUpdateRequestV4([array, size_is(aCount)] in string aListNames,
- [array, size_is(aCount)] in string aStates,
+ [array, size_is(aCount)] in string aStatesBase64,
in uint32_t aCount);
};
--- a/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierUtils.cpp
@@ -95,32 +95,36 @@ GetPlatformType()
#endif
}
typedef FetchThreatListUpdatesRequest_ListUpdateRequest ListUpdateRequest;
typedef FetchThreatListUpdatesRequest_ListUpdateRequest_Constraints Constraints;
static void
InitListUpdateRequest(ThreatType aThreatType,
- const char* aState,
+ const char* aStateBase64,
ListUpdateRequest* aListUpdateRequest)
{
aListUpdateRequest->set_threat_type(aThreatType);
aListUpdateRequest->set_platform_type(GetPlatformType());
aListUpdateRequest->set_threat_entry_type(URL);
// Only RAW data is supported for now.
// TODO: Bug 1285848 Supports Rice-Golomb encoding.
Constraints* contraints = new Constraints();
contraints->add_supported_compressions(RAW);
aListUpdateRequest->set_allocated_constraints(contraints);
// Only set non-empty state.
- if (aState[0] != '\0') {
- aListUpdateRequest->set_state(aState);
+ if (aStateBase64[0] != '\0') {
+ nsCString stateBinary;
+ nsresult rv = Base64Decode(nsCString(aStateBase64), stateBinary);
+ if (NS_SUCCEEDED(rv)) {
+ aListUpdateRequest->set_state(stateBinary.get());
+ }
}
}
static ClientInfo*
CreateClientInfo()
{
ClientInfo* c = new ClientInfo();
@@ -262,34 +266,34 @@ nsUrlClassifierUtils::GetProtocolVersion
aVersion = DEFAULT_PROTOCOL_VERSION;
}
return NS_OK;
}
NS_IMETHODIMP
nsUrlClassifierUtils::MakeUpdateRequestV4(const char** aListNames,
- const char** aStates,
+ const char** aStatesBase64,
uint32_t aCount,
nsACString &aRequest)
{
using namespace mozilla::safebrowsing;
FetchThreatListUpdatesRequest r;
r.set_allocated_client(CreateClientInfo());
for (uint32_t i = 0; i < aCount; i++) {
nsCString listName(aListNames[i]);
uint32_t threatType;
nsresult rv = ConvertListNameToThreatType(listName, &threatType);
if (NS_FAILED(rv)) {
continue; // Unknown list name.
}
auto lur = r.mutable_list_update_requests()->Add();
- InitListUpdateRequest(static_cast<ThreatType>(threatType), aStates[i], lur);
+ InitListUpdateRequest(static_cast<ThreatType>(threatType), aStatesBase64[i], lur);
}
// Then serialize.
std::string s;
r.SerializeToString(&s);
nsCString out;
out.Assign(s.c_str(), s.size());
--- a/toolkit/components/url-classifier/tests/unit/test_listmanager.js
+++ b/toolkit/components/url-classifier/tests/unit/test_listmanager.js
@@ -149,17 +149,17 @@ add_test(function test_partialUpdateV4()
disableAllUpdates();
gListManager.enableUpdate(TEST_TABLE_DATA_V4.tableName);
// Since the new client state has been responded and saved in
// test_update_all_tables, this update request should send
// a partial update to the server.
let requestV4 = gUrlUtils.makeUpdateRequestV4([TEST_TABLE_DATA_V4.tableName],
- [NEW_CLIENT_STATE],
+ [btoa(NEW_CLIENT_STATE)],
1);
gExpectedQueryV4 = "&$req=" + btoa(requestV4);
forceTableUpdate();
});
// Tests nsIUrlListManager.getGethashUrl.
add_test(function test_getGethashUrl() {
@@ -306,34 +306,22 @@ function readFileToString(aFilename) {
let f = do_get_file(aFilename);
let stream = Cc["@mozilla.org/network/file-input-stream;1"]
.createInstance(Ci.nsIFileInputStream);
stream.init(f, -1, 0, 0);
let buf = NetUtil.readInputStreamToString(stream, stream.available());
return buf;
}
-function buildUpdateRequestV4InBase64() {
-
- let request = urlUtils.makeUpdateRequestV4([TEST_TABLE_DATA_V4.tableName],
- [""],
- 1);
- return btoa(request);
-}
-
function waitUntilStateSavedToPref(expectedState, callback) {
const STATE_PREF_NAME_PREFIX = 'browser.safebrowsing.provider.google4.state.';
let stateBase64 = '';
try {
- // The reason we get pref from 'googpub-phish-proto' instead of
- // 'test-phish-proto' is 'googpub-phish-proto' would be returned
- // while we look up the list name from SOCIAL_ENGINEERING_PUBLIC.
- // See nsUrlClassifierUtils::THREAT_TYPE_CONV_TABLE.
stateBase64 =
prefBranch.getCharPref(STATE_PREF_NAME_PREFIX + 'test-phish-proto');
} catch (e) {}
if (stateBase64 === btoa(expectedState)) {
do_print('State has been saved to pref!');
callback();
return;