-
Notifications
You must be signed in to change notification settings - Fork 80
Description
Environment
Node --version -> 22.19.0
npm -version -> 10.9.3
Reproduction
Here are the package.json and server.js to reproduce the error:
It is a simple express hello-world application. If one starts it via node server.js and opens browser in http://localhost:3000 then in console.log at Node server one can see the modifiers object is wrong.
It has only w property with wrong value 75&q=10
Describe the bug
Hi everyone,
If we use %26 or %2C URLs in IPX Module, then we parameters are not processed properly.
/w_75%26f_webp/example.jpg- processes path as one parameter:w=75&f_webp-> wrong/w_75&f_webp/example.jpg- processes path with two parametersw=75andf=webp-> correct
According to URL specification both of the paths should actually give the same result since & and , are reserved characters.
Here is the simple express application that takes a code from server.ts (https://github.com/unjs/ipx/blob/main/src/server.ts#L35 to https://github.com/unjs/ipx/blob/main/src/server.ts#L62) and confirms the error:
const express = require('express');
const { decode } = require("ufo");
// Next initialize the application
const app = express();
function safeString(input) {
return JSON.stringify(input)
.replace(/^"|"$/g, "")
.replace(/\\+/g, "\\")
.replace(/\\"/g, '"');
}
// routing path
app.get('/', (req, res) => {
let url = '/w_75%26q_10/example.jpg';
const [modifiersString = "", ...idSegments] = url
.slice(1 /* leading slash */)
.split("/");
const MODIFIER_SEP = /[&,]/g;
const MODIFIER_VAL_SEP = /[:=_]/;
const modifiers = Object.create(null);
// Read modifiers from first segment
if (modifiersString !== "_") {
// correct version -> replaces %26 with & so that MODIFIER_SEP can properly separate parameters
// for (const p of modifiersString.replace(/%26/gi, "&").split(MODIFIER_SEP)) {
// wrong: does no account for %26
// https://github.com/unjs/ipx/blob/main/src/server.ts#L62
for (const p of modifiersString.split(MODIFIER_SEP)) {
const [key, ...values] = p.split(MODIFIER_VAL_SEP);
modifiers[safeString(key)] = values
.map((v) => safeString(decode(v)))
.join("_");
}
}
console.log(modifiers);
});
// Start the server
app.listen(3000, () => {
console.log('Server started on port 3000');
});One possible solution would e.g. be a hard-replace separators at the line: https://github.com/unjs/ipx/blob/main/src/server.ts#L62 but may be you have better ideas or other considerations:
for (const p of modifiersString.replace(/%26/gi, "&").split(MODIFIER_SEP)) {
...
}Could you confirm the bug, or do you need any additional information?
Additional context
No response
Logs
Server started on port 3000 -> server.js:49
{w: '75&q_10'} -> server.js:43