Skip to content

[steps] Safely index build step inputs and outputs - #4066

Open
sjchmiela wants to merge 7 commits into
mainfrom
stanley/use-map-for-build-step-outputs
Open

[steps] Safely index build step inputs and outputs#4066
sjchmiela wants to merge 7 commits into
mainfrom
stanley/use-map-for-build-step-outputs

Conversation

@sjchmiela

@sjchmiela sjchmiela commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Why

Build step input and output collections were indexed with ordinary JavaScript objects. An identifier such as __proto__ would interact with the object's prototype instead of behaving like an ordinary own property. Call-input presence checks also treated inherited property names as supplied inputs.

How

  • Create internally owned input/output dictionaries with a null prototype.
  • Keep the existing object-shaped public interfaces, including runtime-loaded custom functions.
  • Use Object.hasOwn when reading externally supplied call inputs.
  • Apply the same safe dictionary representation to condition evaluation and command interpolation.
  • Keep conversion only at explicit serialization boundaries.

Test Plan

Added regressions for __proto__ identifiers in:

  • input and output indexes
  • direct build functions
  • build function groups
  • command interpolation
  • if conditions
  • runtime-loaded custom functions

Validated locally with the steps and build-tools tests and typechecks, formatting, and lint.

@sjchmiela sjchmiela added the no changelog PR that doesn't require a changelog entry label Jul 23, 2026 — with ChatGPT Codex Connector
@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.56%. Comparing base (adab984) to head (11b4800).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4066      +/-   ##
==========================================
+ Coverage   61.54%   61.56%   +0.02%     
==========================================
  Files         980      981       +1     
  Lines       43952    43957       +5     
  Branches     9226     9225       -1     
==========================================
+ Hits        27047    27056       +9     
+ Misses      15457    15453       -4     
  Partials     1448     1448              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@sjchmiela
sjchmiela marked this pull request as ready for review July 24, 2026 08:15

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

This repository is configured for manual code reviews. Comment @claude review for a one-time review, or @claude review always to subscribe this PR to a review on every future push.

Tip: disable this comment in your organization's Code Review settings.

@sjchmiela
sjchmiela requested a review from sswrk July 24, 2026 08:15

@sswrk sswrk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😮

Should we do something in this vein for inputs too?

@sjchmiela sjchmiela changed the title [steps] Store build step outputs in a Map [steps] Store build step inputs and outputs in Maps Jul 24, 2026
@sjchmiela
sjchmiela force-pushed the stanley/use-map-for-build-step-outputs branch from 852b12c to bf1779d Compare July 24, 2026 19:20
@sjchmiela sjchmiela changed the title [steps] Store build step inputs and outputs in Maps [steps] Safely index build step inputs and outputs Jul 24, 2026
@github-actions

Copy link
Copy Markdown

⏩ The changelog entry check has been skipped since the "no changelog" label is present.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Hardens the @expo/steps runtime against prototype-pollution edge cases by ensuring build-step inputs/outputs and related dictionaries safely support arbitrary identifiers like __proto__, while keeping the public object-shaped interfaces used by step functions.

Changes:

  • Introduces a createEmptyRecord() helper to build null-prototype dictionaries and applies it to input/output indexing and function input evaluation.
  • Replaces in checks with Object.hasOwn when reading externally supplied callInputs to avoid inherited-property confusion.
  • Adds targeted regression coverage (including __proto__) across direct functions, function groups, interpolation, if conditions, and runtime-loaded custom functions.

Reviewed changes

Copilot reviewed 17 out of 17 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/steps/src/utils/record.ts Adds createEmptyRecord() to create null-prototype dictionaries.
packages/steps/src/utils/tests/record-test.ts Tests the null-prototype record helper.
packages/steps/src/scripts/tests/runCustomFunction-test.ts Expands coverage to ensure __proto__ inputs/outputs work through custom-function execution.
packages/steps/src/BuildStepOutput.ts Uses null-prototype indexing for outputs via createEmptyRecord().
packages/steps/src/BuildStepInput.ts Uses null-prototype indexing for inputs via createEmptyRecord().
packages/steps/src/BuildStep.ts Switches ownership checks to Object.hasOwn and ensures evaluated/input dictionaries use null prototypes.
packages/steps/src/BuildFunctionGroup.ts Uses Object.hasOwn to read callInputs safely and updates input indexing helper usage.
packages/steps/src/BuildFunction.ts Uses Object.hasOwn to read callInputs safely.
packages/steps/src/tests/StepsConfigParser-test.ts Updates assertions for empty null-prototype output dictionaries.
packages/steps/src/tests/fixtures/my-custom-ts-function/src/index.ts Extends fixture custom function to use __proto__ inputs/outputs.
packages/steps/src/tests/fixtures/my-custom-ts-function/build/index.js Updates built fixture output for __proto__ handling.
packages/steps/src/tests/BuildStepOutput-test.ts Updates and expands tests for null-prototype output indexing and special keys.
packages/steps/src/tests/BuildStepInput-test.ts Updates and expands tests for null-prototype input indexing and special keys.
packages/steps/src/tests/BuildStep-test.ts Adds regression tests for __proto__ in interpolation, function inputs, deserialization, and if evaluation.
packages/steps/src/tests/BuildFunctionGroup-test.ts Adds coverage for __proto__ call inputs in function groups.
packages/steps/src/tests/BuildFunction-test.ts Adds coverage for __proto__ call inputs in direct build functions.
AGENTS.md Documents the repository convention to use null-prototype records for user-controlled keys.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@sjchmiela
sjchmiela requested a review from sswrk July 24, 2026 21:10
@sjchmiela

Copy link
Copy Markdown
Contributor Author

changed it a bit so re-requesting review

@sjchmiela

Copy link
Copy Markdown
Contributor Author

thank you for thinking of inputs when reviewing!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no changelog PR that doesn't require a changelog entry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants