Wahib Mkadmi Wahib Mkadmi - 4 months ago 17
Javascript Question

Override JavaScript default locale. [SpiderMonkey]

I'm modding firefox and I'm looking for a way to modify the date.toLocaleString JavaScript method behavior on FireFox.

It is a "Chameleon" mod to spoof the return value. I want to add an extra argument if none was passed:

e.g

var date = new Date();
date.toLocaleString(); // "6/28/2016, 6:16:18 PM"
date.toLocateString("ar-TN"); // "٢٨‏/٦‏/٢٠١٦ ٦:١٦:١٨ م"


I'd like to get the second result from the first call (normally used by websites when fingerprinting), given the locale without changing the whole browser's locale, just the JS.

I have already tried JavaScript approaches (overriding the function, proxy pattern, you name it..) but couldn't get a clean implementation (that can be removed from the DOM without problem) and patching the underlying C++ code without success (didn't dig too much on that honestly).

Can you point me to an appropriate approach, and/or a specific patch location ?

Answer

A bit late maybe, but I've solved the problem on my own, it could help someone someday. (Explained in the most boring way so any one gets it, these lands are kind of dark...)

There is no easy way to override the locale in JavaScript, as there is no such feature in ECMA Specification.

The targets here are the Date and Number. These are self hosted objects. and It's difficult to find a way to achieve this goal in self hosted js, as available options are quite restricted (See here for a list)
The solution hence is to do on the C++ side.

In its simplest form, the problem is about overriding the default locale, used by JavaScript without affecting the browser UI. Recent versions of Firefox are relying on ICU for internationalization, a C++ library. Say hello to XPConnect. The localization of JavaScript is done via the bool xpc_LocalizeContext(JSContext* cx) method (available here), overriding the default locale is as simple as inserting this code at the beginning of function:

char* overrideLocale = std::getenv("OVERRIDE_LOCALE");
if (overrideLocale != NULL) {
    return JS_SetDefaultLocale(rt, overrideLocale);
}

This code overrides the default locale via environment variable, but it's easily changeable.

Comments