Skip to content

Commit 6530b83

Browse files
Fix: 'fromGlobalId' trowing on invalide UTF code points (#374)
Fixes #358 Note: it's temporary workaround until we design a better API
1 parent d4c533f commit 6530b83

File tree

2 files changed

+29
-8
lines changed

2 files changed

+29
-8
lines changed

src/connection/__tests__/arrayConnection-test.ts

+12-4
Original file line numberDiff line numberDiff line change
@@ -274,11 +274,19 @@ describe('connectionFromArray()', () => {
274274
});
275275

276276
it('returns all elements if cursors are invalid', () => {
277-
const c = connectionFromArray(arrayABCDE, {
278-
before: 'invalid',
279-
after: 'invalid',
277+
const c1 = connectionFromArray(arrayABCDE, {
278+
before: 'InvalidBase64',
279+
after: 'InvalidBase64',
280280
});
281-
expect(c).to.deep.equal({
281+
282+
const invalidUnicodeInBase64 = '9JCAgA=='; // U+110000
283+
const c2 = connectionFromArray(arrayABCDE, {
284+
before: invalidUnicodeInBase64,
285+
after: invalidUnicodeInBase64,
286+
});
287+
288+
expect(c1).to.deep.equal(c2);
289+
expect(c1).to.deep.equal({
282290
edges: [edgeA, edgeB, edgeC, edgeD, edgeE],
283291
pageInfo: {
284292
startCursor: cursorA,

src/utils/base64.ts

+17-4
Original file line numberDiff line numberDiff line change
@@ -126,29 +126,42 @@ function utf8ArrayToString(input: Array<number>) {
126126
for (let i = 0; i < input.length; ) {
127127
const a = input[i++];
128128
if ((a & 0x80) === 0) {
129-
result += String.fromCodePoint(a);
129+
result += fromCodePoint(a);
130130
continue;
131131
}
132132

133133
const b = input[i++];
134134
if ((a & 0xe0) === 0xc0) {
135-
result += String.fromCodePoint(((a & 0x1f) << 6) | (b & 0x3f));
135+
result += fromCodePoint(((a & 0x1f) << 6) | (b & 0x3f));
136136
continue;
137137
}
138138

139139
const c = input[i++];
140140
if ((a & 0xf0) === 0xe0) {
141-
result += String.fromCodePoint(
141+
result += fromCodePoint(
142142
((a & 0x0f) << 12) | ((b & 0x3f) << 6) | (c & 0x3f),
143143
);
144144
continue;
145145
}
146146

147147
const d = input[i++];
148-
result += String.fromCodePoint(
148+
result += fromCodePoint(
149149
((a & 0x07) << 18) | ((b & 0x3f) << 12) | ((c & 0x3f) << 6) | (d & 0x3f),
150150
);
151151
}
152152

153153
return result;
154154
}
155+
156+
function fromCodePoint(code: number): string {
157+
if (code > 0x10ffff) {
158+
/*
159+
* Previously we used Node's API for parsing Base64 and following code
160+
* Buffer.from(i, 'base64').toString('utf8')
161+
* That silently ignored incorrect input and returned empty string instead
162+
* Let's keep this behaviour for a time being and hopefully fix it in the future.
163+
*/
164+
return '';
165+
}
166+
return String.fromCodePoint(code);
167+
}

0 commit comments

Comments
 (0)