Bug 1657260 - ensure we register with a valid FxA device name. r=rfkelly

Differential Revision: https://phabricator.services.mozilla.com/D87837
This commit is contained in:
Mark Hammond 2020-08-25 01:35:11 +00:00
Родитель 013846f716
Коммит b9d69d8d9b
2 изменённых файлов: 53 добавлений и 7 удалений

Просмотреть файл

@ -40,6 +40,21 @@ XPCOMUtils.defineLazyPreferenceGetter(
const PREF_DEPRECATED_DEVICE_NAME = "services.sync.client.name";
// Sanitizes all characters which the FxA server considers invalid, replacing
// them with the unicode replacement character.
// At time of writing, FxA has a regex DISPLAY_SAFE_UNICODE_WITH_NON_BMP, which
// the regex below is based on.
// eslint-disable-next-line no-control-regex
const INVALID_NAME_CHARS = /[\u0000-\u001F\u007F\u0080-\u009F\u2028-\u2029\uE000-\uF8FF\uFFF9-\uFFFC\uFFFE-\uFFFF]/g;
const MAX_NAME_LEN = 255;
const REPLACEMENT_CHAR = "\uFFFD";
function sanitizeDeviceName(name) {
return name
.substr(0, MAX_NAME_LEN)
.replace(INVALID_NAME_CHARS, REPLACEMENT_CHAR);
}
// Everything to do with FxA devices.
class FxAccountsDevice {
constructor(fxai) {
@ -125,11 +140,13 @@ class FxAccountsDevice {
let syncStrings = Services.strings.createBundle(
"chrome://weave/locale/sync.properties"
);
return syncStrings.formatStringFromName("client.name2", [
user,
brandName,
system,
]);
return sanitizeDeviceName(
syncStrings.formatStringFromName("client.name2", [
user,
brandName,
system,
])
);
}
getLocalName() {
@ -148,12 +165,17 @@ class FxAccountsDevice {
name = this.getDefaultLocalName();
Services.prefs.setStringPref(PREF_LOCAL_DEVICE_NAME, name);
}
return name;
// We need to sanitize here because some names were generated before we
// started sanitizing.
return sanitizeDeviceName(name);
}
setLocalName(newName) {
Services.prefs.clearUserPref(PREF_DEPRECATED_DEVICE_NAME);
Services.prefs.setStringPref(PREF_LOCAL_DEVICE_NAME, newName);
Services.prefs.setStringPref(
PREF_LOCAL_DEVICE_NAME,
sanitizeDeviceName(newName)
);
// Update the registration in the background.
this.updateDeviceRegistration().catch(error => {
log.warn("failed to update fxa device registration", error);

Просмотреть файл

@ -90,3 +90,27 @@ add_task(async function test_reset() {
await fxAccounts.signOut(/* localOnly = */ true);
ok(!Services.prefs.prefHasUserValue(namePref));
});
add_task(async function test_name_sanitization() {
fxAccounts.device.setLocalName("emoji is valid \u2665");
Assert.equal(fxAccounts.device.getLocalName(), "emoji is valid \u2665");
let invalid = "x\uFFFD\n\r\t" + "x".repeat(255);
let sanitized = "x\uFFFD\uFFFD\uFFFD\uFFFD" + "x".repeat(250); // 255 total.
// If the pref already has the invalid value we still get the valid one back.
Services.prefs.setStringPref(
"identity.fxaccounts.account.device.name",
invalid
);
Assert.equal(fxAccounts.device.getLocalName(), sanitized);
// But if we explicitly set it to an invalid name, the sanitized value ends
// up in the pref.
fxAccounts.device.setLocalName(invalid);
Assert.equal(fxAccounts.device.getLocalName(), sanitized);
Assert.equal(
Services.prefs.getStringPref("identity.fxaccounts.account.device.name"),
sanitized
);
});