Skip to content

fix(metro): vendor image dimension parsing - #1860

Closed
robhogan wants to merge 1 commit into
mainfrom
fix/vendor-image-size
Closed

robhogan wants to merge 1 commit into
mainfrom
fix/vendor-image-size

Conversation

@robhogan

Copy link
Copy Markdown
Collaborator

Summary

  • replace the image-size dependency with an in-tree parser for the image formats Metro supports
  • dispatch by the declared asset type rather than running unrelated format detectors
  • preserve CgBI PNG, SVG units/viewBox, TIFF endianness, WebP variants, and KTX1/KTX2 support
  • reuse the first asset buffer already read for hashing
  • reject truncated, mismatched, non-positive, and non-advancing malformed inputs

This removes image-size and its queue dependency without introducing a new third-party package. The parser is derived from the MIT-licensed image-size format support, with its notice retained inline and bounds/forward-progress checks added throughout.

Refs #1762
Refs #1800

Test plan

  • yarn flow check
  • yarn typecheck-ts
  • yarn lint
  • yarn build
  • node node_modules/jest/bin/jest.js packages/metro/src/lib/__tests__/imageSize-test.js packages/metro/src/__tests__/Assets-test.js --runInBand --no-watchman
  • full Jest run: 141 suites passed; the two Watchman integration suites failed because the local environment cannot chmod the shared Watchman state directory
  • checked all applicable fixtures from the upstream image-size corpus
  • exercised 100,000 randomized malformed buffers across all parsers

Changelog: [Fix] Remove the image-size dependency and parse supported image dimensions within Metro.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 16, 2026
@robhogan
robhogan force-pushed the fix/vendor-image-size branch from 9f96097 to dfcb2d4 Compare August 16, 2026 21:11
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Aug 16, 2026
@meta-codesync

meta-codesync Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

@javache has imported this pull request. If you are a Meta employee, you can view this in D116437966.

@meta-codesync meta-codesync Bot closed this in ab65fa3 Aug 18, 2026
@meta-codesync meta-codesync Bot added the Merged label Aug 18, 2026
@meta-codesync

meta-codesync Bot commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

@javache merged this pull request in ab65fa3.

@robhogan
robhogan deleted the fix/vendor-image-size branch August 19, 2026 13:22
robhogan pushed a commit that referenced this pull request Aug 19, 2026
Summary:
- replace the `image-size` dependency with an in-tree parser for the image formats Metro supports
- dispatch by the declared asset type rather than running unrelated format detectors
- preserve CgBI PNG, SVG units/viewBox, TIFF endianness, WebP variants, and KTX1/KTX2 support
- reuse the first asset buffer already read for hashing
- reject truncated, mismatched, non-positive, and non-advancing malformed inputs

This removes `image-size` and its `queue` dependency without introducing a new third-party package. The parser is derived from the MIT-licensed `image-size` format support, with its notice retained inline and bounds/forward-progress checks added throughout.

Refs #1762
Refs #1800

Pull Request resolved: #1860

Test Plan:
- `yarn flow check`
- `yarn typecheck-ts`
- `yarn lint`
- `yarn build`
- `node node_modules/jest/bin/jest.js packages/metro/src/lib/__tests__/imageSize-test.js packages/metro/src/__tests__/Assets-test.js --runInBand --no-watchman`
- full Jest run: 141 suites passed; the two Watchman integration suites failed because the local environment cannot chmod the shared Watchman state directory
- checked all applicable fixtures from the upstream `image-size` corpus
- exercised 100,000 randomized malformed buffers across all parsers

Changelog: [Fix] Remove the image-size dependency and parse supported image dimensions within Metro.

Reviewed By: huntie

Differential Revision: D116437966

Pulled By: javache

fbshipit-source-id: 9f88b14668ae863b22a4aaf91b1298967c7f07c1
robhogan added a commit that referenced this pull request Aug 19, 2026
Summary:
- replace the `image-size` dependency with an in-tree parser for the image formats Metro supports
- dispatch by the declared asset type rather than running unrelated format detectors
- preserve CgBI PNG, SVG units/viewBox, TIFF endianness, WebP variants, and KTX1/KTX2 support
- reuse the first asset buffer already read for hashing
- reject truncated, mismatched, non-positive, and non-advancing malformed inputs

This removes `image-size` and its `queue` dependency without introducing a new third-party package. The parser is derived from the MIT-licensed `image-size` format support, with its notice retained inline and bounds/forward-progress checks added throughout.

Refs #1762
Refs #1800

Pull Request resolved: #1860

Test Plan:
- `yarn flow check`
- `yarn typecheck-ts`
- `yarn lint`
- `yarn build`
- `node node_modules/jest/bin/jest.js packages/metro/src/lib/__tests__/imageSize-test.js packages/metro/src/__tests__/Assets-test.js --runInBand --no-watchman`
- full Jest run: 141 suites passed; the two Watchman integration suites failed because the local environment cannot chmod the shared Watchman state directory
- checked all applicable fixtures from the upstream `image-size` corpus
- exercised 100,000 randomized malformed buffers across all parsers

Changelog: [Fix] Remove the image-size dependency and parse supported image dimensions within Metro.

Reviewed By: huntie

Differential Revision: D116437966

Pulled By: javache

fbshipit-source-id: 9f88b14668ae863b22a4aaf91b1298967c7f07c1
This was referenced Aug 19, 2026
azchohfi added a commit to microsoft/microsoft-ui-reactor that referenced this pull request Sep 1, 2026
…1169)

* Clear the fixable Component Governance alerts in the RN harness lockfiles

The React Native comparison harnesses under tests/ carry committed
package-lock.json files, so an upstream advisory fix never reaches us
until the lockfile is updated. 11 of the 17 open alerts are fixable by
version bump; this does all 11.

  brace-expansion   1.1.14 -> 1.1.18  GHSA-3jxr-9vmj-r5cp, GHSA-mh99-v99m-4gvg,
                                      GHSA-rgw5-rvv9-x895  (6 nested copies each
                                      in StocksGrid and VirtualList)
  brace-expansion   5.0.6  -> 5.0.9   GHSA-3jxr-9vmj-r5cp
  launch-editor     2.13.2 -> 2.14.1  GHSA-v6wh-96g9-6wx3
  @babel/plugin-transform-modules-systemjs
                    7.29.0 -> 7.29.4  GHSA-fv7c-fp4j-7gwp
  @babel/core       7.29.0 -> 7.29.6  GHSA-4x5r-pxfx-6jf8

@babel/core 7.29.6 requires generator ^7.29.6, which requires parser and
types ^7.29.7, which require the two 7.29.7 helpers; BlankRNW therefore
also moves generator 7.29.1 -> 7.29.7, parser 7.29.3 -> 7.29.7, types
7.29.0 -> 7.29.7, helper-string-parser 7.27.1 -> 7.29.7 and
helper-validator-identifier 7.28.5 -> 7.29.7. The chain terminates there
(both helpers have no dependencies). Every declaring range on the chain
is a caret range, so all are satisfied.

None of these are direct dependencies, and every declaring range already
permitted the patched version (brace-expansion ^1.1.7 and ^5.0.5,
launch-editor ^2.9.1, systemjs plugin ^7.29.0, @babel/core ^7.25.2) -
only the lockfile held the vulnerable versions, so no package.json changes.

The remaining 6 alerts are image-size (GHSA-w3rx-r6r6-pgpr,
GHSA-5p2g-fcmc-qvqq), which have no fix available: both cover <= 2.0.2 and
2.0.2 is the latest published release. It arrives via metro's ^1.0.2, which
would not take a 2.x fix anyway. Not reachable here - metro reads image
dimensions at bundle time from first-party assets, the vulnerable parsers
are ICNS/JXL/HEIF, and the only images in all three harnesses are MSIX
package PNGs consumed by the Windows packaging pipeline, not metro; no JS
source imports an image at all. These need a risk-accepted dismissal in the
CG portal rather than a code change.

Edited surgically rather than regenerated, per the precedent in #1089:
resolving through the proxy registry strips dist.integrity and silently
downgrades entries from sha512 to sha1. Only version, resolved and
integrity are touched, plus the four metadata fields that genuinely changed
upstream (brace-expansion 5.0.9 engines "18 || 20 || >=22" -> "20 || >=22",
launch-editor shell-quote ^1.8.3 -> ^1.8.4, and the @babel/core and
generator/parser/types dependency ranges). 77 changed lines total, and a
filter over the diff confirms every one of the 154 changed lines is an
intended field - verified non-vacuous by feeding it license/dev/funding
lines, which it flags.

Verified: all 10 introduced integrity values were confirmed by downloading
the published tarballs and recomputing sha512, with the method first
validated by reproducing four pre-existing untouched integrity values
(balanced-match, concat-map, picocolors, jsesc) exactly - so the proxy is
not rewriting tarball bytes - and a negative control confirming the checker
detects a corrupted hash. `npm ci` then succeeds in all three harnesses
(789/860/860 packages, exit 0) and leaves the lockfiles unmodified, which
independently confirms every integrity value validates and every range is
satisfiable. No vulnerable version remains in any resulting tree; that scan
is non-vacuous - run against the pre-change tree the same checker flags
@babel/core 7.29.0.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

* Drop image-size by taking metro 0.83.8 in the RN harness lockfiles

Clears the remaining 6 Component Governance alerts - image-size
GHSA-w3rx-r6r6-pgpr / CVE-2025-71330 (ICNS parser infinite loop) and
GHSA-5p2g-fcmc-qvqq / CVE-2025-71329 (JXL and HEIF parser infinite loops),
one pair per harness.

There is no fixed image-size to upgrade to: both advisories cover <= 2.0.2,
2.0.2 is the latest release, and image-size/image-size was archived on
2026-06-03 with issues and pull requests disabled - which is why both
advisories can only cite PR 439 through a web.archive.org snapshot.

The fix came from the consumer side instead. metro vendored its own image
dimension parsing (react/metro#1860, cherry-picked as #1870 and #1871) and
released it in 0.83.8 and 0.84.5, dropping the image-size dependency
outright. These harnesses were pinned at metro 0.83.7. Tracking issues
upstream are react/metro#1607 and #1762.

metro-config and metro-transform-worker pin `metro` to an exact version, so
the whole family moves in lockstep: 15 entries per lockfile (the 14 metro-*
packages plus ob1) go 0.83.7 -> 0.83.8. Removing image-size also orphans
`queue`, its only dependant, so that entry goes too - 17 entries changed per
lockfile, 173 lines. No package.json changes: @react-native/community-cli-plugin
already declares metro ^0.83.1, which admits 0.83.8.

Note this is not fixed on metro 0.85+ - 0.85.0, 0.86.0 and 0.87.0 all still
declare image-size ^1.0.2, so a future React Native upgrade will reintroduce
it until that is forward-ported upstream.

Applied surgically, for a sharper reason than last time. npm's own resolution
was used as the source of truth for versions and dependency ranges (run in a
scratch directory with an `overrides` pin), but this environment's proxy
registry rewrites both fields that identify the artifact: `resolved` becomes an
ms-feed-N.pkgs.visualstudio.com URL and `integrity` is downgraded to sha1. A
fresh resolve here corrupts 791 of 791 entries that way, so its output cannot
be committed. Only entries whose version actually changed were taken; the
~20 entries where the proxy rewrote resolved/integrity while the version stood
still are noise and were excluded, as was a spurious typescript
devOptional -> dev flip. `resolved` was rewritten back to registry.npmjs.org
and `integrity` recomputed as sha512 from the real tarball bytes.

Verified: 0 non-sha512 integrity values and 0 non-registry.npmjs.org resolved
URLs remain in any of the three lockfiles. `npm ci` succeeds in all three
(787/858/858 packages, exit 0) and leaves the lockfiles unmodified, which
confirms every recomputed integrity validates against the real tarball and
every range is satisfiable; each tree installs exactly 2 packages fewer than
before, matching image-size and queue. metro on disk is 0.83.8 and image-size
is absent. Sweeping the installed trees for every package named in all 17
original alerts finds 30 copies and 0 vulnerable - and that sweep is not
vacuous: run against the pre-change tree the same check flags image-size 1.2.1.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
robhogan added a commit that referenced this pull request Sep 7, 2026
Summary:
- replace the `image-size` dependency with an in-tree parser for the image formats Metro supports
- dispatch by the declared asset type rather than running unrelated format detectors
- preserve CgBI PNG, SVG units/viewBox, TIFF endianness, WebP variants, and KTX1/KTX2 support
- reuse the first asset buffer already read for hashing
- reject truncated, mismatched, non-positive, and non-advancing malformed inputs

This removes `image-size` and its `queue` dependency without introducing a new third-party package. The parser is derived from the MIT-licensed `image-size` format support, with its notice retained inline and bounds/forward-progress checks added throughout.

Refs #1762
Refs #1800

Pull Request resolved: #1860

Test Plan:
- `yarn flow check`
- `yarn typecheck-ts`
- `yarn lint`
- `yarn build`
- `node node_modules/jest/bin/jest.js packages/metro/src/lib/__tests__/imageSize-test.js packages/metro/src/__tests__/Assets-test.js --runInBand --no-watchman`
- full Jest run: 141 suites passed; the two Watchman integration suites failed because the local environment cannot chmod the shared Watchman state directory
- checked all applicable fixtures from the upstream `image-size` corpus
- exercised 100,000 randomized malformed buffers across all parsers

Changelog: [Fix] Remove the image-size dependency and parse supported image dimensions within Metro.

Reviewed By: huntie

Differential Revision: D116437966

Pulled By: javache

fbshipit-source-id: 9f88b14668ae863b22a4aaf91b1298967c7f07c1
tung2744 added a commit to tung2744/authgear-sdk-js that referenced this pull request Sep 8, 2026
- browserslist: bump to 4.28.8 in root, example/capacitor, and website
  (GHSA-c83g-rgw3-j3cx, GHSA-73wf-gq98-2v4g)
- qs: bump to 6.16.0 in root, example/reactnative, and website, adding
  an override in website since express/body-parser pin qs via tilde
  ranges that exclude the patch (GHSA-q8mj-m7cp-5q26, GHSA-x5fp-wj9c-mxmx,
  GHSA-4mjr-xmp4-gh2g)
- image-size (GHSA-w3rx-r6r6-pgpr, GHSA-5p2g-fcmc-qvqq, DoS via infinite
  loop): upstream image-size is archived with no fix for any published
  version.
  - root and example/reactnative: metro dropped its image-size
    dependency entirely in 0.84.5 (react/metro#1860), so override
    metro/metro-config/metro-transform-worker to that patched version
    instead of depending on any image-size replacement.
  - website: @docusaurus/mdx-loader still requires image-size with no
    upstream fix yet (facebook/docusaurus#12231, fix pending in #12388).
    Override to a git-pinned fork at tung2744/image-size-next instead of
    the community image-size-next npm package, whose maintainer account
    was flagged for supply-chain-risk-like promotional behavior. Pinned
    to an exact commit SHA with a "prepare" build step for reproducible,
    review-gated installs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
meta-codesync Bot pushed a commit that referenced this pull request Sep 11, 2026
Summary:
Publish Metro 0.87.1 from `main`.

Changelog: [Internal]

Pull Request resolved: #1926

Test Plan:
```
node scripts/updateVersion.js 0.87.1
sl diff --stat
```

Only the 17 `packages/*/package.json` manifests change, and every `0.87.0` reference is replaced.

Draft release notes (from the 91 commits in v0.87.0...main - reverted and internal-only changes omitted):

```
 - **[Feature]**: Add `resolver.schemeResolvers` to resolve URI-scheme-prefixed specifiers (eg `foo:bar`) with custom resolvers (#1804 by robhogan)
 - **[Feature]**: Resolve `metro:babel-runtime/<path>` imports to Metro's own `babel/runtime` dependency (8388f71 by robhogan)
 - **[Feature]**: `metro-file-map`: Add `crawlerFactory` to optionally replace the built-in Watchman / Node crawlers (68022f0 by vzaidman)
 - **[Feature]**: `metro-babel-transformer`: Pass `inlinePlatform` to Babel presets via `caller` (6bbe095 by robhogan)
 - **[Fix]**: Replace `image-size` dependency with vendored parsers, fix CVE alerts (#1860 by robhogan)
 - **[Fix]**: Include `charset=utf-8` in the `Content-Type` of text assets and source files served by the dev server (#1888 by robhogan)
 - **[Fix]**: Preserve `Platform.OS` write targets during constant inlining (#1890 by OskarEichler)
 - **[Fix]**: Inline the last duplicate key from static `Platform.select` object literals (#1889 by OskarEichler)
 - **[Fix]**: `FallbackWatcher` no longer misses files written to a directory while it is being crawled (#1907 by robhogan)
 - **[Fix]**: `HttpStore`: Handle socket errors during writes, so they're retried rather than crashing the process (fad3b88)
 - **[Fix]**: Treat `CI=false` and `CI=0` as not-CI when defaulting `watch`. CI is now detected from `process.env.CI` only, dropping the `ci-info` dependency (61e4592 by robhogan)
 - **[Fix]**: Fix Fast Refresh hitting undefined modules when using lazy (segmented) bundles in dev (c70d0ae by robhogan)
 - **[Performance]**: `FallbackWatcher`: Drop `walker` dependency, reduce crawl RSS by ~34% and peak heap by ~41% (#1906 by robhogan)
 - **[Performance]**: Don't emit redundant empty dependency map arrays for modules with no dependencies (#1858 by robhogan)
 - **[Types]**: Restore publishing of private (underscore-prefixed) fields in TypeScript declarations (#1876 by robhogan)
 - **[Types]**: Fix async functions being inferred as returning `void` (not `Promise<void>`), eg `MetroServer#end` (#1909 by robhogan)
 - **[Types]**: Tidy up generated types, allow nullable props to be omitted in more places (#1885 by robhogan)

> NOTE: Experimental features are not covered by semver and can change at any time.

 - **[Experimental]**: Add `serializer.unstable_inlineDependencyMap` to inline module IDs at serialisation time (#1786 by robhogan)
 - **[Experimental]**: Add `serializer.unstable_getAsyncDependencyPath` to supply custom `paths` to framework-defined `__loadBundleAsync` (#1855 by robhogan)
 - **[Experimental]**: Remove `transformer.unstable_renameRequire` - `require` is never renamed (42577f7 by robhogan)
 - **[Experimental]**: `experimentalImportSupport`: Fix `export * from` re-exporting the source module's default export (#1777 by robhogan)

 **Full Changelog**: v0.87.0...v0.87.1
```

Reviewed By: zeyap

Differential Revision: D119675927

Pulled By: GijsWeterings

fbshipit-source-id: daf17f3501b4725c21c39b4dfd5c82b95e01dca5
cursor Bot pushed a commit to armstrongj2001/hunt-map that referenced this pull request Sep 12, 2026
…ency

Expo SDK 54 (@expo/metro 54.2.0) pins metro to exactly 0.83.3, which
depends on image-size <=2.0.2. image-size has two open DoS advisories
(GHSA-w3rx-r6r6-pgpr, GHSA-5p2g-fcmc-qvqq) and no patched release; the
upstream fix is metro 0.83.8, which vendors its own image parsers and
removes the dependency entirely (react/metro#1860).

0.83.4-0.83.8 are bug-fix patch releases on the stable 0.83.x branch
that ships with React Native 0.81, and react-native's own
@react-native/community-cli-plugin already accepts ^0.83.1. All
metro-* workspace packages are pinned together so a single consistent
version is installed.

Verified on this branch:
- `expo export --platform all` builds web, iOS and Android bundles
- `expo start` serves web and iOS dev bundles
- image-size is no longer present in node_modules

This is the one override that touches Expo's exact pin; revert this
commit alone if `expo start` misbehaves. It becomes unnecessary once
the app moves to a newer Expo SDK.

npm audit: 15 vulns (8 high) -> 7 moderate, all in the
decode-uri-component chain under @react-navigation.

Co-authored-by: Jobi Armstrong <armstrongj2001@users.noreply.github.com>
armstrongj2001 added a commit to armstrongj2001/hunt-map that referenced this pull request Sep 12, 2026
…y handling (#2)

* chore(deps): refresh mobile lockfile with non-breaking security fixes

Run `npm audit fix` (no --force) in HuntMapMobile so transitive
dependencies move to patched releases within their existing semver
ranges. No package.json changes; Expo stays on SDK 54.

Notable bumps: axios 1.15.1->1.20.0, expo 54.0.33->54.0.37,
@xmldom/xmldom, brace-expansion, nanoid, browserslist, js-yaml,
undici, tar, shell-quote, ws, form-data, baseline-browser-mapping.

npm audit: 39 vulns (2 critical, 20 high) -> 26 (0 critical, 11 high).

Co-authored-by: Jobi Armstrong <armstrongj2001@users.noreply.github.com>

* chore(deps): override postcss, markdown-it, and xcode's uuid to patched versions

These transitive deps are pinned by their parents to vulnerable ranges
that `npm audit fix` cannot move on its own:

- postcss ~8.4.32 (via @expo/metro-config) -> ^8.5.28
  Fixes 4 advisories (sourceMappingURL file disclosure, </style> XSS).
  Minor bump within 8.x; dev/build-time only.
- markdown-it ^10 (via react-native-markdown-display) -> ^14.3.2
  Fixes 2 markdown-it + 2 linkify-it DoS advisories. 14.x still ships a
  CommonJS build; the library's parser pipeline produces an identical AST
  on 10.0.0 and 14.3.2 for headings, lists, tables, links, fences, etc.
- uuid ^7 (via xcode <- @expo/config-plugins) -> ^11.1.1
  Fixes buffer bounds check advisory. Only used by `expo prebuild`
  tooling on Node; xcode's generateUuid() verified working.

Scoped as nested overrides so nothing else in the tree is affected.

npm audit: 26 vulns (11 high) -> 15 (8 high). Remaining are the
image-size (metro) and decode-uri-component (@react-navigation) chains.

Co-authored-by: Jobi Armstrong <armstrongj2001@users.noreply.github.com>

* chore(deps): pin metro to 0.83.8 to drop vulnerable image-size dependency

Expo SDK 54 (@expo/metro 54.2.0) pins metro to exactly 0.83.3, which
depends on image-size <=2.0.2. image-size has two open DoS advisories
(GHSA-w3rx-r6r6-pgpr, GHSA-5p2g-fcmc-qvqq) and no patched release; the
upstream fix is metro 0.83.8, which vendors its own image parsers and
removes the dependency entirely (react/metro#1860).

0.83.4-0.83.8 are bug-fix patch releases on the stable 0.83.x branch
that ships with React Native 0.81, and react-native's own
@react-native/community-cli-plugin already accepts ^0.83.1. All
metro-* workspace packages are pinned together so a single consistent
version is installed.

Verified on this branch:
- `expo export --platform all` builds web, iOS and Android bundles
- `expo start` serves web and iOS dev bundles
- image-size is no longer present in node_modules

This is the one override that touches Expo's exact pin; revert this
commit alone if `expo start` misbehaves. It becomes unnecessary once
the app moves to a newer Expo SDK.

npm audit: 15 vulns (8 high) -> 7 moderate, all in the
decode-uri-component chain under @react-navigation.

Co-authored-by: Jobi Armstrong <armstrongj2001@users.noreply.github.com>

* security: harden Google Maps key handling and document restrictions

The Google Maps key was committed in HuntMapMobile/.env (removed from
tracking in ab9b32b) and is still present in git history, so GitHub
secret scanning flags it. The app already reads the key from
EXPO_PUBLIC_GOOGLE_MAPS_API_KEY; this change makes that path safer:

- HuntMap.web.js: warn clearly in the console when the key is missing
  instead of silently failing to load Google Maps.
- landmarks.js: skip the Google Places request when no key is set so
  the OSM and Wikipedia results still come back.
- .env.example: explain that EXPO_PUBLIC_ values ship in the client
  bundle and must be restricted in Google Cloud Console (HTTP referrer
  + API restrictions), and that EAS builds should use EAS env vars.

No secret values are introduced; .env files at every level are already
covered by .gitignore.

Co-authored-by: Jobi Armstrong <armstrongj2001@users.noreply.github.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Jobi Armstrong <armstrongj2001@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Merged Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant