Skip to content

Commit

Permalink
Merge pull request #29392 from colemanw/jsEncode
Browse files Browse the repository at this point in the history
CRM_Utils_JS - Improve encoding of object keys
  • Loading branch information
mlutfy authored Feb 15, 2024
2 parents e5b8b9b + 1aa2a19 commit 7e2d00f
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 15 deletions.
19 changes: 8 additions & 11 deletions CRM/Utils/JS.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,18 +163,15 @@ public static function decode($js, $throwException = FALSE) {
public static function convertSingleQuoteString(string $str, $throwException) {
// json_decode can only handle double quotes around strings, so convert single-quoted strings
$backslash = chr(0) . 'backslash' . chr(0);
$str = str_replace(['\\\\', '\\"', '"', '\\&', '\\/', $backslash], [$backslash, '"', '\\"', '&', '/', '\\'], substr($str, 1, -1));
$str = str_replace(['\\\\', '\\"', '"', '\\&', '\\/'], [$backslash, '"', '\\"', '&', '/'], substr($str, 1, -1));
// Ensure the string doesn't terminate early by checking that all single quotes are escaped
$pos = -1;
while (($pos = strpos($str, "'", $pos + 1)) !== FALSE) {
if (($pos - strlen(rtrim(substr($str, 0, $pos)))) % 2) {
if ($throwException) {
throw new CRM_Core_Exception('Invalid string passed to CRM_Utils_JS::decode');
}
return NULL;
if (preg_match("/[^\\\\]'/", $str)) {
if ($throwException) {
throw new CRM_Core_Exception('Invalid string passed to CRM_Utils_JS::decode');
}
return NULL;
}
return '"' . $str . '"';
return '"' . str_replace(["\\'", $backslash], ["'", '\\\\'], $str) . '"';
}

/**
Expand Down Expand Up @@ -310,8 +307,8 @@ public static function writeObject($obj, $encodeValues = FALSE) {
if ($brackets[0] == '{') {
// Enclose the key in quotes unless it is purely alphanumeric
if (preg_match('/\W/', $key)) {
// Prefer single quotes
$key = preg_match('/^[\w "]+$/', $key) ? "'" . $key . "'" : json_encode($key, JSON_UNESCAPED_SLASHES);
// Prefer single quotes around keys
$key = self::encode($key);
}
$js[] = "$key: $val";
}
Expand Down
8 changes: 4 additions & 4 deletions tests/phpunit/CRM/Utils/JSTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,8 @@ public static function encodeExamples() {
"{a: 'Apple', b: 'Banana', c: [0, -2, 3.15]}",
],
[
['a' => ['foo', 'bar'], 'b' => ["'a'" => ['foo/bar&', 'bar(foo)'], 'b' => ['a' => ["fo\\'oo", '"bar"'], 'b' => []]]],
"{a: ['foo', 'bar'], b: {\"'a'\": ['foo/bar&', 'bar(foo)'], b: {a: ['fo\\\\\\'oo', '\"bar\"'], b: {}}}}",
['a.b-c' => ['foo', 'bar'], 'b' => ["'a'" => ['foo/bar&', 'bar(foo)'], 'b' => ["'a'" => ["fo\\'oo", '"bar"'], 'b' => []]]],
"{'a.b-c': ['foo', 'bar'], b: {'\'a\'': ['foo/bar&', 'bar(foo)'], b: {'\'a\'': ['fo\\\\\\'oo', '\"bar\"'], b: {}}}}",
],
[TRUE, 'true'],
[' ', "' '"],
Expand Down Expand Up @@ -313,12 +313,12 @@ public static function objectExamples() {
[
'{status: /^http:\/\/civicrm\.com/.test(url) ? \'good\' : \'bad\' , \'foo\&\': getFoo("Some \"quoted\" thing"), "ba\'[(r": function() {return "bar"}}',
['status' => '/^http:\/\/civicrm\.com/.test(url) ? \'good\' : \'bad\'', 'foo&' => 'getFoo("Some \"quoted\" thing")', "ba'[(r" => 'function() {return "bar"}'],
'{status: /^http:\/\/civicrm\.com/.test(url) ? \'good\' : \'bad\', "foo&": getFoo("Some \"quoted\" thing"), "ba\'[(r": function() {return "bar"}}',
'{status: /^http:\/\/civicrm\.com/.test(url) ? \'good\' : \'bad\', \'foo&\': getFoo("Some \"quoted\" thing"), \'ba\\\'[(r\': function() {return "bar"}}',
],
[
'{"some\"key": typeof foo === \'number\' ? true : false , "O\'Really?": ",((,", \'A"quote"\': 1 + 1 , "\\\\&\\/" : 0}',
['some"key' => 'typeof foo === \'number\' ? true : false', "O'Really?" => '",((,"', 'A"quote"' => '1 + 1', '\\&/' => '0'],
'{\'some"key\': typeof foo === \'number\' ? true : false, "O\'Really?": ",((,", \'A"quote"\': 1 + 1, "\\\\&/": 0}',
'{\'some"key\': typeof foo === \'number\' ? true : false, \'O\\\'Really?\': ",((,", \'A"quote"\': 1 + 1, \'\\\\&/\': 0}',
],
[
'[foo ? 1 : 2 , 3 , function() {return 1 + 1;}, /^http:\/\/civicrm\.com/.test(url) ? \'good\' : \'bad\' , 3.14 ]',
Expand Down

0 comments on commit 7e2d00f

Please sign in to comment.