FIX: Escape $ in translations before interpolating (#8100)

FIX: Escape $ in translations before interpolating (#8100)

The dollar sign ($) is a special replace pattern, and $& inserts the matched string. Thus dollars signs need to be escaped with the special pattern $$, which inserts a single $.

diff --git a/app/assets/javascripts/locales/i18n.js b/app/assets/javascripts/locales/i18n.js
index cffc2e2..68657e2 100644
--- a/app/assets/javascripts/locales/i18n.js
+++ b/app/assets/javascripts/locales/i18n.js
@@ -116,7 +116,15 @@ I18n.interpolate = function(message, options) {
   for (var i = 0; placeholder = matches[i]; i++) {
     name = placeholder.replace(this.PLACEHOLDER, "$1");
 
-    value = options[name];
+    if (typeof options[name] === "string") {
+      // The dollar sign (`$`) is a special replace pattern, and `$&` inserts
+      // the matched string. Thus dollars signs need to be escaped with the
+      // special pattern `$$`, which inserts a single `$`.
+      // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#Specifying_a_string_as_a_parameter
+      value = options[name].replace(/\$/g, "$$$$");
+    } else {
+      value = options[name];
+    }
 
     if (!this.isValidNode(options, name)) {
       value = "[missing " + placeholder + " value]";
diff --git a/test/javascripts/lib/i18n-test.js.es6 b/test/javascripts/lib/i18n-test.js.es6
index f1c628a..9655f44 100644
--- a/test/javascripts/lib/i18n-test.js.es6
+++ b/test/javascripts/lib/i18n-test.js.es6
@@ -60,7 +60,8 @@ QUnit.module("lib:i18n", {
           days: {
             one: "%{count} day",
             other: "%{count} days"
-          }
+          },
+          dollar_sign: "Hi {{description}}"
         }
       }
     };
@@ -223,3 +224,12 @@ QUnit.test("fallback", assert => {
     "falls back to English translations"
   );
 });
+
+QUnit.test("Dollar signs are properly escaped", assert => {
+  assert.equal(
+    I18n.t("dollar_sign", {
+      description: "$& $&"
+    }),
+    "Hi $& $&"
+  );
+});

GitHub sha: fb200e30

1 Like