Skip to content

Commit

Permalink
Fix unexpected object mutation while resolving Open Graph
Browse files Browse the repository at this point in the history
Modifying an object passed from external sources can unintentionally lead to unpredictable behavior.

By changing the implementation from in-place object modification to returning a new object, we can make the method more predictable.

fixes #49501
  • Loading branch information
runjuu committed May 9, 2023
1 parent d6c83a4 commit a182f79
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 9 deletions.
23 changes: 23 additions & 0 deletions packages/next/src/lib/metadata/resolvers/resolve-opengraph.test.ts
@@ -0,0 +1,23 @@
import { resolveImages } from './resolve-opengraph'

describe('resolveImages', () => {
const image1 = 'https://www.example.com/image1.jpg'
const image2 = 'https://www.example.com/image2.jpg'

it(`should resolve images`, () => {
const images = [image1, { url: image2, alt: 'Image2' }]

expect(resolveImages(images, null)).toEqual([
{ url: new URL(image1) },
{ url: new URL(image2), alt: 'Image2' },
])
})

it('should not mutate passed images', () => {
const images = [image1, { url: image2, alt: 'Image2' }]

resolveImages(images, null)

expect(images).toEqual([image1, { url: image2, alt: 'Image2' }])
})
})
19 changes: 10 additions & 9 deletions packages/next/src/lib/metadata/resolvers/resolve-opengraph.ts
Expand Up @@ -29,32 +29,33 @@ const OgTypeFields = {
],
} as const

function resolveImages(
export function resolveImages(
images: Twitter['images'],
metadataBase: ResolvedMetadata['metadataBase']
): NonNullable<ResolvedMetadata['twitter']>['images']
function resolveImages(
export function resolveImages(
images: OpenGraph['images'],
metadataBase: ResolvedMetadata['metadataBase']
): NonNullable<ResolvedMetadata['openGraph']>['images']
function resolveImages(
export function resolveImages(
images: OpenGraph['images'] | Twitter['images'],
metadataBase: ResolvedMetadata['metadataBase']
):
| NonNullable<ResolvedMetadata['twitter']>['images']
| NonNullable<ResolvedMetadata['openGraph']>['images'] {
const resolvedImages = resolveAsArrayOrUndefined(images)
resolvedImages?.forEach((item, index, array) => {
return resolveAsArrayOrUndefined(images)?.map((item, index) => {

Check warning on line 46 in packages/next/src/lib/metadata/resolvers/resolve-opengraph.ts

View workflow job for this annotation

GitHub Actions / lint

'index' is defined but never used. Allowed unused args must match /^_/u
if (isStringOrURL(item)) {
array[index] = {
return {
url: resolveUrl(item, metadataBase)!,
}
} else {
// Update image descriptor url
item.url = resolveUrl(item.url, metadataBase)!
return {
...item,
// Update image descriptor url
url: resolveUrl(item.url, metadataBase)!,
}
}
})
return resolvedImages
}

function getFieldsByOgType(ogType: OpenGraphType | undefined) {
Expand Down

0 comments on commit a182f79

Please sign in to comment.