diff --git a/packages/@aws-cdk/cloudformation-diff/lib/diff/util.ts b/packages/@aws-cdk/cloudformation-diff/lib/diff/util.ts index 1cbd4b1a111d7..b1e6146cf8afd 100644 --- a/packages/@aws-cdk/cloudformation-diff/lib/diff/util.ts +++ b/packages/@aws-cdk/cloudformation-diff/lib/diff/util.ts @@ -27,6 +27,13 @@ export function deepEqual(lvalue: any, rvalue: any): boolean { safeParseFloat(lvalue) === safeParseFloat(rvalue)) { return true; } + // GetStackTemplate flattens any codepoint greater than "\u7f" to "?". This + // is true even for codepoints in the supplemental planes which are + // represented in JS as surrogate pairs, all the way up to "\u{10ffff}". + if (typeof lvalue === 'string' && typeof rvalue === 'string' && + lvalue === rvalue.replace(/[\u{80}-\u{10ffff}]/gu, '?')) { + return true; + } if (typeof lvalue !== typeof rvalue) { return false; } if (Array.isArray(lvalue) !== Array.isArray(rvalue)) { return false; } if (Array.isArray(lvalue) /* && Array.isArray(rvalue) */) { diff --git a/packages/@aws-cdk/cloudformation-diff/test/deep-equal.test.ts b/packages/@aws-cdk/cloudformation-diff/test/deep-equal.test.ts new file mode 100644 index 0000000000000..59df74fa37552 --- /dev/null +++ b/packages/@aws-cdk/cloudformation-diff/test/deep-equal.test.ts @@ -0,0 +1,11 @@ +import { deepEqual } from '../lib/diff/util'; + +test('mangled strings', () => { + expect(deepEqual('foo', 'foo')).toBeTruthy(); + expect(deepEqual('????', '文字化け')).toBeTruthy(); + expect(deepEqual('?????', '🤦🏻‍♂️')).toBeTruthy(); + expect(deepEqual('?', '\u{10ffff}')).toBeTruthy(); + expect(deepEqual('\u007f', '\u007f')).toBeTruthy(); + expect(deepEqual('?', '\u007f')).toBeFalsy(); + expect(deepEqual('?', '\u0080')).toBeTruthy(); +});