Skip to content

Commit 4868df4

Browse files
committed
Handle strings by code point
Fixes jmespath#88
1 parent 0928621 commit 4868df4

File tree

1 file changed

+33
-9
lines changed

1 file changed

+33
-9
lines changed

jmespath.js

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,26 @@
129129
};
130130
}
131131

132+
function compareStringsByCodePoints(a, b) {
133+
var ia = 0;
134+
var ib = 0;
135+
while (true) {
136+
// Offset each code point by 1, leaving 0 for end of string.
137+
var aCodePoint = (a.codePointAt(ia) + 1) || 0;
138+
var bCodePoint = (b.codePointAt(ib) + 1) || 0;
139+
var result = aCodePoint - bCodePoint;
140+
if (result) {
141+
return result;
142+
} else if (!aCodePoint) {
143+
// Having reached the end of both strings, they must be equal.
144+
return 0;
145+
}
146+
// Increment each index by the right amount.
147+
ia += aCodePoint <= 0xFFFF ? 1 : 2;
148+
ib += bCodePoint <= 0xFFFF ? 1 : 2;
149+
}
150+
}
151+
132152
// Type constants used to define functions.
133153
var TYPE_NUMBER = 0;
134154
var TYPE_ANY = 1;
@@ -1334,12 +1354,7 @@
13341354
_functionReverse: function(resolvedArgs) {
13351355
var typeName = this._getTypeName(resolvedArgs[0]);
13361356
if (typeName === TYPE_STRING) {
1337-
var originalStr = resolvedArgs[0];
1338-
var reversedStr = "";
1339-
for (var i = originalStr.length - 1; i >= 0; i--) {
1340-
reversedStr += originalStr[i];
1341-
}
1342-
return reversedStr;
1357+
return Array.from(resolvedArgs[0]).reverse().join("");
13431358
} else {
13441359
var reversedArray = resolvedArgs[0].slice(0);
13451360
reversedArray.reverse();
@@ -1374,7 +1389,7 @@
13741389

13751390
_functionLength: function(resolvedArgs) {
13761391
if (!isObject(resolvedArgs[0])) {
1377-
return resolvedArgs[0].length;
1392+
return Array.from(resolvedArgs[0]).length;
13781393
} else {
13791394
// As far as I can tell, there's no way to get the length
13801395
// of an object without O(n) iteration through the object.
@@ -1533,7 +1548,14 @@
15331548

15341549
_functionSort: function(resolvedArgs) {
15351550
var sortedArray = resolvedArgs[0].slice(0);
1536-
sortedArray.sort();
1551+
if (sortedArray.length === 0) {
1552+
return sortedArray;
1553+
}
1554+
if (this._getTypeName(sortedArray[0]) === TYPE_STRING) {
1555+
sortedArray.sort(compareStringsByCodePoints);
1556+
} else {
1557+
sortedArray.sort();
1558+
}
15371559
return sortedArray;
15381560
},
15391561

@@ -1573,7 +1595,9 @@
15731595
"TypeError: expected " + requiredType + ", received " +
15741596
that._getTypeName(exprB));
15751597
}
1576-
if (exprA > exprB) {
1598+
if (requiredType === TYPE_STRING) {
1599+
return compareStringsByCodePoints(exprA, exprB) || a[0] - b[0];
1600+
} else if (exprA > exprB) {
15771601
return 1;
15781602
} else if (exprA < exprB) {
15791603
return -1;

0 commit comments

Comments
 (0)