[PR #894] [MERGED] fix(plist): report omitted __proto__ entries in signatures and Interface Builder #2326

Closed
opened 2026-10-16 21:17:19 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/894
Author: @kaoru0822-kitauji
Created: 10/7/2026
Status: ✅ Merged
Merged: 10/7/2026
Merged by: @kaoru0822-kitauji

Base: main ← Head: fix/plist-prototype-key-reporting


📝 Commits (2)

  • 6729ee7 fix(plist): report omitted proto entries in signatures and Interface Builder
  • 5afd8a8 fix(plist): keep character references beyond Unicode literal

📊 Changes

6 files changed (+157 additions, -23 deletions)

View changed files

📝 src/application/InterfaceBuilderAnalysis.ts (+36 -12)
📝 src/domain/propertyListKeys.test.ts (+20 -0)
📝 src/domain/propertyListKeys.ts (+18 -4)
📝 src/native/NativeMacOSProvider.ts (+20 -7)
📝 tests/boundary/filesystem/interfaceBuilderBundle.test.ts (+28 -0)
📝 tests/boundary/providers/native/nativeProvider.test.ts (+35 -0)

📄 Description

Summary

Follow-up to #885, which merged before its three review comments were addressed.

#885 decodes XML plists containing a legal __proto__ key by omitting those entries and counting them. inspect_plist and inspect_keyed_archive report the count, but two sites dropped it:

  • inspect_signature: an entitlements plist with a __proto__ entry returned the remaining entitlements with no limitation, so the set looked complete. It now adds Entitlements: 1 dictionary entry keyed __proto__ was omitted because REA results cannot represent that key.
  • Interface Builder XML plists (decode_interface_builder): the document decoded and archive_decode stayed complete. It is now partial with reason dictionary_entries_omitted, graph.truncated is true, and a per-document limitation names the archive path, e.g. Contents/Resources/Prototype.nib: 1 dictionary entry keyed __proto__ was omitted …. Asset catalog analysis reads graph.truncated, so its resource-key joins now also say they may be incomplete.

Placeholder collision. Before decoding, each __proto__ key is replaced with a placeholder. The placeholder was checked only against the raw XML, so <key>&#95;&#95;rea_prototype_key__</key> did not match, but it decoded to the placeholder. That unrelated entry was then dropped and counted as __proto__. The placeholder is now checked against the entity-decoded text. Literal spellings appear there unchanged, because the placeholder contains no & or ;.

No schema or catalog change. The archive_decode reason is a free-form string, and the new value sits beside one_or_more_archives_invalid.

Verification

New cases (each fails on main):

  • src/domain/propertyListKeys.test.ts: an entity-encoded key that decodes to the placeholder is kept, while the real __proto__ entry is still omitted.
  • tests/boundary/providers/native/nativeProvider.test.ts: inspect_signature with __proto__ in the codesign entitlements output keeps the other entitlements and reports the limitation.
  • tests/boundary/filesystem/interfaceBuilderBundle.test.ts: an XML NIB plist with __proto__ reports archive_decode partial (dictionary_entries_omitted), a truncated graph, and the per-document limitation.

npm run check:changed (22 files, 165 tests) and npm run docs:check pass. So do the native signature CLI, native inventory golden, binary target, and plist prototype-key CLI boundary tests. The ibtool-compiled NIB tests (nibNativeHierarchy, the compiled storyboard case) fail the same way on main on this host, because it has only the Command Line Tools and no ibtool.

No Hopper/Ghidra/IDA verification is needed.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/894 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/7/2026 **Status:** ✅ Merged **Merged:** 10/7/2026 **Merged by:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Base:** `main` ← **Head:** `fix/plist-prototype-key-reporting` --- ### 📝 Commits (2) - [`6729ee7`](https://github.com/morluto/rea/commit/6729ee7636889a0a2ebc9fca8e35860476f8ca34) fix(plist): report omitted __proto__ entries in signatures and Interface Builder - [`5afd8a8`](https://github.com/morluto/rea/commit/5afd8a850b2ebd62e3400a5e2ece1a1cfa98bab6) fix(plist): keep character references beyond Unicode literal ### 📊 Changes **6 files changed** (+157 additions, -23 deletions) <details> <summary>View changed files</summary> 📝 `src/application/InterfaceBuilderAnalysis.ts` (+36 -12) 📝 `src/domain/propertyListKeys.test.ts` (+20 -0) 📝 `src/domain/propertyListKeys.ts` (+18 -4) 📝 `src/native/NativeMacOSProvider.ts` (+20 -7) 📝 `tests/boundary/filesystem/interfaceBuilderBundle.test.ts` (+28 -0) 📝 `tests/boundary/providers/native/nativeProvider.test.ts` (+35 -0) </details> ### 📄 Description ## Summary Follow-up to #885, which merged before its three review comments were addressed. #885 decodes XML plists containing a legal `__proto__` key by omitting those entries and counting them. `inspect_plist` and `inspect_keyed_archive` report the count, but two sites dropped it: - **`inspect_signature`**: an entitlements plist with a `__proto__` entry returned the remaining entitlements with no limitation, so the set looked complete. It now adds `Entitlements: 1 dictionary entry keyed __proto__ was omitted because REA results cannot represent that key.` - **Interface Builder XML plists** (`decode_interface_builder`): the document decoded and `archive_decode` stayed `complete`. It is now `partial` with reason `dictionary_entries_omitted`, `graph.truncated` is true, and a per-document limitation names the archive path, e.g. `Contents/Resources/Prototype.nib: 1 dictionary entry keyed __proto__ was omitted …`. Asset catalog analysis reads `graph.truncated`, so its resource-key joins now also say they may be incomplete. **Placeholder collision.** Before decoding, each `__proto__` key is replaced with a placeholder. The placeholder was checked only against the raw XML, so `<key>&#95;&#95;rea_prototype_key__</key>` did not match, but it decoded to the placeholder. That unrelated entry was then dropped and counted as `__proto__`. The placeholder is now checked against the entity-decoded text. Literal spellings appear there unchanged, because the placeholder contains no `&` or `;`. No schema or catalog change. The `archive_decode` reason is a free-form string, and the new value sits beside `one_or_more_archives_invalid`. ## Verification New cases (each fails on `main`): - `src/domain/propertyListKeys.test.ts`: an entity-encoded key that decodes to the placeholder is kept, while the real `__proto__` entry is still omitted. - `tests/boundary/providers/native/nativeProvider.test.ts`: `inspect_signature` with `__proto__` in the codesign entitlements output keeps the other entitlements and reports the limitation. - `tests/boundary/filesystem/interfaceBuilderBundle.test.ts`: an XML NIB plist with `__proto__` reports `archive_decode` partial (`dictionary_entries_omitted`), a truncated graph, and the per-document limitation. `npm run check:changed` (22 files, 165 tests) and `npm run docs:check` pass. So do the native signature CLI, native inventory golden, binary target, and plist prototype-key CLI boundary tests. The ibtool-compiled NIB tests (`nibNativeHierarchy`, the compiled storyboard case) fail the same way on `main` on this host, because it has only the Command Line Tools and no `ibtool`. No Hopper/Ghidra/IDA verification is needed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-16 21:17:19 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2326
No description provided.