Repository: ember-cli/ember-cli
Pull request #6867 (2017-03-17 19:55:26)

Use `encode/decodeURIComponent()` for `meta` tag config
Issue: #6598

raido: Any updates on this?
raido: Rebased on master.

Patch:
diff --git a/lib/broccoli/app-config-from-meta.js b/lib/broccoli/app-config-from-meta.js
index 20f19570b..08c4bd639 100644
--- a/lib/broccoli/app-config-from-meta.js
+++ b/lib/broccoli/app-config-from-meta.js
@@ -1,7 +1,7 @@
 try {
   var metaName = prefix + '/config/environment';
   var rawConfig = document.querySelector('meta[name="' + metaName + '"]').getAttribute('content');
-  var config = JSON.parse(unescape(rawConfig));
+  var config = JSON.parse(decodeURIComponent(rawConfig));
 
   var exports = { 'default': config };
 
diff --git a/lib/broccoli/ember-app.js b/lib/broccoli/ember-app.js
index 90de86138..553d5b65a 100644
--- a/lib/broccoli/ember-app.js
+++ b/lib/broccoli/ember-app.js
@@ -1,4 +1,4 @@
-/* global require, module, escape */
+/* global require, module */
 'use strict';
 
 /**
diff --git a/lib/utilities/ember-app-utils.js b/lib/utilities/ember-app-utils.js
index 703fc6bcd..1a413f4dc 100644
--- a/lib/utilities/ember-app-utils.js
+++ b/lib/utilities/ember-app-utils.js
@@ -95,7 +95,7 @@ function contentFor(config, match, type, options) {
       content.push(calculateBaseTag(config.baseURL, config.locationType));
 
       if (options.storeConfigInMeta) {
-        content.push(`<meta name="${config.modulePrefix}/config/environment" content="${escape(JSON.stringify(config))}" />`);
+        content.push(`<meta name="${config.modulePrefix}/config/environment" content="${encodeURIComponent(JSON.stringify(config))}" />`);
       }
 
       break;


Test patch:
diff --git a/tests/unit/broccoli/default-packager/ember-cli-internal-test.js b/tests/unit/broccoli/default-packager/ember-cli-internal-test.js
index cba3e5999..c623ff707 100644
--- a/tests/unit/broccoli/default-packager/ember-cli-internal-test.js
+++ b/tests/unit/broccoli/default-packager/ember-cli-internal-test.js
@@ -163,7 +163,7 @@ describe('Default Packager: Ember CLI Internal', function() {
     let appConfigFileContent = emberCliFiles['app-config.js'].trim();
 
     expect(appConfigFileContent).to.contain(`var rawConfig = document.querySelector(`);
-    expect(appConfigFileContent).to.contain(`var config = JSON.parse(unescape(rawConfig));`);
+    expect(appConfigFileContent).to.contain(`var config = JSON.parse(decodeURIComponent(rawConfig));`);
   }));
 
   it('populates the contents of internal files correctly, including content from add-ons', co.wrap(function *() {
diff --git a/tests/unit/broccoli/ember-app-test.js b/tests/unit/broccoli/ember-app-test.js
index 4c156210f..30a2f43d6 100644
--- a/tests/unit/broccoli/ember-app-test.js
+++ b/tests/unit/broccoli/ember-app-test.js
@@ -1,5 +1,3 @@
-/* global escape */
-
 'use strict';
 
 const co = require('co');
diff --git a/tests/unit/utilities/ember-app-utils-test.js b/tests/unit/utilities/ember-app-utils-test.js
index 7f2a9ff65..480d04f82 100644
--- a/tests/unit/utilities/ember-app-utils-test.js
+++ b/tests/unit/utilities/ember-app-utils-test.js
@@ -18,7 +18,7 @@ describe('ember-app-utils', function() {
     };
 
     let defaultMatch = '{{content-for \'head\'}}';
-    let escapedConfig = escape(JSON.stringify(config));
+    let escapedConfig = encodeURIComponent(JSON.stringify(config));
     let defaultOptions = {
       storeConfigInMeta: true,
       autoRun: true,
@@ -43,6 +43,18 @@ describe('ember-app-utils', function() {
         ).to.contain(expected);
       });
 
+      it('handles multibyte characters in `<meta>` tag', function() {
+        let configWithMultibyteChars = { modulePrefix: 'cool-å' };
+        let actual = contentFor(configWithMultibyteChars, defaultMatch, 'head', defaultOptions);
+        let escapedConfig = encodeURIComponent(JSON.stringify(configWithMultibyteChars));
+        let expected = `<meta name="cool-å/config/environment" content="${escapedConfig}" />`;
+
+        expect(
+          actual,
+          '`<meta>` tag was included with multibyte characters'
+        ).to.contain(expected);
+      });
+
       it('omits `<meta>` tag if `storeConfigInMeta` is false', function() {
         let options = Object.assign({}, defaultOptions, { storeConfigInMeta: false });