fix(translation): only read own dictionary entries

Draft
KN
2d ago
+102-3

Confirmed defect

Translation lookup reads inherited Object.prototype properties as dictionary entries. Missing text such as constructor, toString, or __proto__ returns a function/object instead of the original text, and the sampled debug logging can throw. In full mode, a valid JSON translation named hasOwnProperty shadows the method and makes substring matching throw.

Change

  • Check own properties for exact and trimmed lookups.
  • Use Object.prototype.hasOwnProperty.call for full-mode enumeration, so translation text cannot shadow the method.
  • Preserve explicitly declared special-name keys, empty-string translations, ordinary lookups, and the existing substring strategy.

Only the translation function and a new offline test file change. No dependencies, lockfiles, workflows, installer, credentials, or permissions change. Existing #5, #6, and #7 remain independent and untouched.

Validation

Base: 83ceac969392e7ea1948652d0b2dd6d06233ddeb.
Head: dae56749947263101955bddeb46640c208eda406.
Published tree: fe862b2d43ab39e29ecb7a9f4bd84bfb45008825, identical to the locally tested tree.

  • All 15 baseline files verified against their Git blob IDs; the baseline tree matches the remote main tree.
  • Unchanged baseline: 68 Jest tests passed.
  • New regression/control suite on unchanged source: 18 failed, 7 passed. Fixed source: all 25 passed.
  • Final locked npm ci --ignore-scripts and full Jest suite: 93 tests passed on Node 24.22.1 / npm 11.9.0.
  • Python installer suite: 27 tests passed on Python 3.12.14 / pytest 9.0.2.
  • JavaScript syntax, Python compileall, pip check, and git diff --cached --check passed. No separate build or lint command is declared.
  • Independent read-only review found no blocker and independently reran all 93 Jest tests.

Hosted CI for the published head passed, as recorded below. Existing development-dependency warnings remain unchanged; #6 tracks the independent dependency refresh. Tests use synthetic JSON/XHR and mocked RPG Maker globals, not a real game or browser acceptance test. This is dictionary lookup correctness, not a general schema validation or security audit. No live game files, user computer, merge, deployment, or release was used.

Summary by Sourcery

Restrict translation resolution to own dictionary entries while preserving existing exact, trimmed, and substring lookup behavior.

Bug Fixes:

  • Prevent translation lookups from treating inherited Object.prototype properties as dictionary entries, including for trimmed and substring-based matching.
  • Preserve correct behavior for explicitly translated special-name keys, empty translations, and dictionaries containing a hasOwnProperty entry.

Tests:

  • Add regression coverage for inherited property names, prototype pollution cases, special-name translations, empty strings, trimmed lookups, and full-mode substring matching.

Summary by cubic

Fixes translation dictionary lookups so inherited Object.prototype entries like constructor or toString are no longer returned as translations, and a translation named hasOwnProperty no longer breaks full-mode substring matching.

  • Uses Object.prototype.hasOwnProperty.call for exact, trimmed, and full-mode lookups.
  • Preserves explicitly declared special-name keys, empty-string translations, and the existing substring strategy.
  • Adds an offline test suite covering inherited names, prototype-named translations, and edge cases like whitespace-padded lookups.

Hosted verification

CI run 42345844514 completed successfully for head dae56749947263101955bddeb46640c208eda406. Node 18.20.8 and 20.20.2 each passed all 93 tests; Python 3.11.18 / pytest 9.2.0 passed all 27 installer tests.

All three checkout logs confirm merge ref 687f54a9663e58a934f8f721d4f187f351c1200b. Its parents are the unchanged base and published head, and its tree equals the locally tested/published tree fe862b2d43ab39e29ecb7a9f4bd84bfb45008825. This is verified merge-ref CI, not a bare-head checkout. Both changed remote files were read back and matched the tested files byte-for-byte.

CommitCheck passed. CodeRabbit skipped the Draft, which is not a review pass; no inline review threads were present. The unchanged npm lockfile still reports 11 development-dependency findings (7 low, 1 moderate, 3 high) in hosted installation output; the independent dependency refresh remains in #6. Existing action-runtime deprecation/cache warnings did not fail the jobs. The PR remains Draft, with no merge or deployment.