From 79eccc9c7f4088507e4a44dc0028908a6e045586 Mon Sep 17 00:00:00 2001 From: ale-adobe Date: Wed, 13 May 2026 22:45:24 -0700 Subject: [PATCH 1/3] Check for null and non-array case in snakeCaseify --- packages/c2pa-web/src/lib/settings.spec.ts | 34 ++++++++++++++++++++++ packages/c2pa-web/src/lib/settings.ts | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/packages/c2pa-web/src/lib/settings.spec.ts b/packages/c2pa-web/src/lib/settings.spec.ts index 47c131f..65db7b3 100644 --- a/packages/c2pa-web/src/lib/settings.spec.ts +++ b/packages/c2pa-web/src/lib/settings.spec.ts @@ -21,6 +21,40 @@ describe('settings', () => { JSON.stringify({ builder: { generate_c2pa_archive: true } }) ); }); + + test('should not throw when a settings value is null', async () => { + // typeof null === 'object' in JS — without a null guard this crashes + const settingsString = await settingsToWasmJson({ + verify: null as any + }); + + expect(settingsString).toEqual( + JSON.stringify({ builder: { generate_c2pa_archive: true }, verify: null }) + ); + }); + + test('should not throw when a nested settings value is null', async () => { + const settingsString = await settingsToWasmJson({ + trust: { userAnchors: null as any } + }); + + expect(settingsString).toEqual( + JSON.stringify({ + builder: { generate_c2pa_archive: true }, + trust: { user_anchors: null } + }) + ); + }); + + test('should not recurse into array values', async () => { + // Arrays satisfy typeof val === 'object'; they should be passed through, not iterated + const settingsString = await settingsToWasmJson({ + trust: { userAnchors: ['a', 'b'] as any } + }); + + const parsed = JSON.parse(settingsString); + expect(parsed.trust.user_anchors).toEqual(['a', 'b']); + }); }); describe('trust', () => { diff --git a/packages/c2pa-web/src/lib/settings.ts b/packages/c2pa-web/src/lib/settings.ts index 360984a..0a6bc85 100644 --- a/packages/c2pa-web/src/lib/settings.ts +++ b/packages/c2pa-web/src/lib/settings.ts @@ -141,7 +141,7 @@ function snakeCaseify(object: SettingsObjectType): SettingsObjectType { const formattedObject = Object.entries(object).reduce( (formattedObject, [key, val]) => { formattedObject[snakeCase(key)] = - typeof val === 'object' ? snakeCaseify(val) : val; + typeof val === 'object' && val !== null && !Array.isArray(val) ? snakeCaseify(val) : val; return formattedObject; }, {} as SettingsObjectType From 2bde864f2aa2b54ef4178d435e5dd80819f71e94 Mon Sep 17 00:00:00 2001 From: ale-adobe Date: Thu, 14 May 2026 11:11:33 -0700 Subject: [PATCH 2/3] Remove unreachable array guard --- packages/c2pa-web/src/lib/settings.spec.ts | 10 ---------- packages/c2pa-web/src/lib/settings.ts | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/packages/c2pa-web/src/lib/settings.spec.ts b/packages/c2pa-web/src/lib/settings.spec.ts index 65db7b3..b99293e 100644 --- a/packages/c2pa-web/src/lib/settings.spec.ts +++ b/packages/c2pa-web/src/lib/settings.spec.ts @@ -45,16 +45,6 @@ describe('settings', () => { }) ); }); - - test('should not recurse into array values', async () => { - // Arrays satisfy typeof val === 'object'; they should be passed through, not iterated - const settingsString = await settingsToWasmJson({ - trust: { userAnchors: ['a', 'b'] as any } - }); - - const parsed = JSON.parse(settingsString); - expect(parsed.trust.user_anchors).toEqual(['a', 'b']); - }); }); describe('trust', () => { diff --git a/packages/c2pa-web/src/lib/settings.ts b/packages/c2pa-web/src/lib/settings.ts index 0a6bc85..a018ad2 100644 --- a/packages/c2pa-web/src/lib/settings.ts +++ b/packages/c2pa-web/src/lib/settings.ts @@ -141,7 +141,7 @@ function snakeCaseify(object: SettingsObjectType): SettingsObjectType { const formattedObject = Object.entries(object).reduce( (formattedObject, [key, val]) => { formattedObject[snakeCase(key)] = - typeof val === 'object' && val !== null && !Array.isArray(val) ? snakeCaseify(val) : val; + typeof val === 'object' && val !== null ? snakeCaseify(val) : val; return formattedObject; }, {} as SettingsObjectType From 53b3c7bc95d583382a1923ffc994bbb276d37fde Mon Sep 17 00:00:00 2001 From: ale-adobe Date: Thu, 14 May 2026 11:15:04 -0700 Subject: [PATCH 3/3] Add changeset --- .changeset/seven-moons-crash.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/seven-moons-crash.md diff --git a/.changeset/seven-moons-crash.md b/.changeset/seven-moons-crash.md new file mode 100644 index 0000000..73a06dc --- /dev/null +++ b/.changeset/seven-moons-crash.md @@ -0,0 +1,5 @@ +--- +'@contentauth/c2pa-web': patch +--- + +Add null check to avoid potential crashes.