Skip to content

Commit

Permalink
Fix: Prevent Errors in Header Processing and Encode URLs Properly (#6…
Browse files Browse the repository at this point in the history
…7780)


Unlinked contributors: mafiayemakhfi.

Co-authored-by: Juzar10 <juzar@git.wordpress.org>
Co-authored-by: ellatrix <ellatrix@git.wordpress.org>
Co-authored-by: Mamaduka <mamaduka@git.wordpress.org>
Co-authored-by: SainathPoojary <sainathpoojary@git.wordpress.org>
Co-authored-by: himanshupathak95 <abcd95@git.wordpress.org>
Co-authored-by: t-hamano <wildworks@git.wordpress.org>
  • Loading branch information
7 people authored Feb 6, 2025
1 parent 8b64cb1 commit d01a09e
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 9 deletions.
43 changes: 34 additions & 9 deletions packages/api-fetch/src/middlewares/preloading.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,40 @@ function createPreloadingMiddleware( preloadedData ) {
* @return {Promise<any>} Promise with the response.
*/
function prepareResponse( responseData, parse ) {
return Promise.resolve(
parse
? responseData.body
: new window.Response( JSON.stringify( responseData.body ), {
status: 200,
statusText: 'OK',
headers: responseData.headers,
} )
);
if ( parse ) {
return Promise.resolve( responseData.body );
}

try {
return Promise.resolve(
new window.Response( JSON.stringify( responseData.body ), {
status: 200,
statusText: 'OK',
headers: responseData.headers,
} )
);
} catch {
// See: https://github.com/WordPress/gutenberg/issues/67358#issuecomment-2621163926.
Object.entries( responseData.headers ).forEach( ( [ key, value ] ) => {
if ( key.toLowerCase() === 'link' ) {
responseData.headers[ key ] = value.replace(
/<([^>]+)>/,
( /** @type {any} */ _, /** @type {string} */ url ) =>
`<${ encodeURI( url ) }>`
);
}
} );

return Promise.resolve(
parse
? responseData.body
: new window.Response( JSON.stringify( responseData.body ), {
status: 200,
statusText: 'OK',
headers: responseData.headers,
} )
);
}
}

export default createPreloadingMiddleware;
51 changes: 51 additions & 0 deletions packages/api-fetch/src/middlewares/test/preloading.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,57 @@ describe( 'Preloading Middleware', () => {
expect( secondMiddleware ).toHaveBeenCalledTimes( 1 );
} );

it( 'should not throw an error when non-ASCII headers are present', async () => {
const noResponseMock = 'undefined' === typeof window.Response;
if ( noResponseMock ) {
window.Response = class {
constructor( body, options ) {
this.body = JSON.parse( body );
this.headers = options.headers;

// Check for non-ASCII characters in headers
for ( const [ key, value ] of Object.entries(
this.headers || {}
) ) {
if ( /[^\x00-\x7F]/.test( value ) ) {
throw new Error(
`Invalid non-ASCII character found in header: ${ key }`
);
}
}
}
};
}

const data = {
body: 'Hello',
headers: {
Link: '<http://example.com/ویدیو/example>; rel="alternate"; type=text/html',
},
};

const preloadedData = {
'wp/v2/example': data,
};

const preloadingMiddleware =
createPreloadingMiddleware( preloadedData );

const requestOptions = {
method: 'GET',
path: 'wp/v2/example',
parse: false,
};

await expect(
preloadingMiddleware( requestOptions, () => {} )
).resolves.not.toThrow();

if ( noResponseMock ) {
delete window.Response;
}
} );

describe.each( [ [ 'GET' ], [ 'OPTIONS' ] ] )( '%s', ( method ) => {
describe.each( [
[ 'all empty', {} ],
Expand Down

0 comments on commit d01a09e

Please sign in to comment.