Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: vitejs/vite
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v5.4.14
Choose a base ref
...
head repository: vitejs/vite
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v5.4.15
Choose a head ref
  • 3 commits
  • 6 files changed
  • 2 contributors

Commits on Jan 23, 2025

  1. Copy the full SHA
    3ccbdbe View commit details

Commits on Mar 24, 2025

  1. fix: backport #19702, fs raw query with query separators (#19703)

    sapphi-red authored Mar 24, 2025
    Copy the full SHA
    807d7f0 View commit details
  2. release: v5.4.15

    sapphi-red committed Mar 24, 2025
    Copy the full SHA
    9b0f4c8 View commit details
4 changes: 3 additions & 1 deletion docs/config/preview-options.md
Original file line number Diff line number Diff line change
@@ -85,7 +85,9 @@ Uses [`http-proxy`](https://github.com/http-party/node-http-proxy). Full options
- **Type:** `boolean | CorsOptions`
- **Default:** [`server.cors`](./server-options#server-cors)

Configure CORS for the preview server. This is enabled by default and allows any origin. Pass an [options object](https://github.com/expressjs/cors#configuration-options) to fine tune the behavior or `false` to disable.
Configure CORS for the preview server.

See [`server.cors`](./server-options#server-cors) for more details.

## preview.headers

6 changes: 6 additions & 0 deletions packages/vite/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## <small>5.4.15 (2025-03-24)</small>

* fix: backport #19702, fs raw query with query separators (#19703) ([807d7f0](https://github.com/vitejs/vite/commit/807d7f06d33ab49c48a2a3501da3eea1906c0d41)), closes [#19702](https://github.com/vitejs/vite/issues/19702) [#19703](https://github.com/vitejs/vite/issues/19703)



## <small>5.4.14 (2025-01-21)</small>

* fix: `preview.allowedHosts` with specific values was not respected (#19246) ([9df6e6b](https://github.com/vitejs/vite/commit/9df6e6beabf0d18988ec13b8b742d2aba29662f9)), closes [#19246](https://github.com/vitejs/vite/issues/19246)
2 changes: 1 addition & 1 deletion packages/vite/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vite",
"version": "5.4.14",
"version": "5.4.15",
"type": "module",
"license": "MIT",
"author": "Evan You",
15 changes: 13 additions & 2 deletions packages/vite/src/node/server/middlewares/transform.ts
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ import { ensureServingAccess } from './static'
const debugCache = createDebugger('vite:cache')

const knownIgnoreList = new Set(['/', '/favicon.ico'])
const trailingQuerySeparatorsRE = /[?&]+$/

/**
* A middleware that short-circuits the middleware chain to serve cached transformed modules
@@ -163,9 +164,19 @@ export function transformMiddleware(
warnAboutExplicitPublicPathInUrl(url)
}

const urlWithoutTrailingQuerySeparators = url.replace(
trailingQuerySeparatorsRE,
'',
)
if (
(rawRE.test(url) || urlRE.test(url)) &&
!ensureServingAccess(url, server, res, next)
(rawRE.test(urlWithoutTrailingQuerySeparators) ||
urlRE.test(urlWithoutTrailingQuerySeparators)) &&
!ensureServingAccess(
urlWithoutTrailingQuerySeparators,
server,
res,
next,
)
) {
return
}
14 changes: 14 additions & 0 deletions playground/fs-serve/__tests__/fs-serve.spec.ts
Original file line number Diff line number Diff line change
@@ -96,6 +96,20 @@ describe.runIf(isServe)('main', () => {
expect(await page.textContent('.unsafe-fs-fetch-raw-status')).toBe('403')
})

test('unsafe fs fetch query 1', async () => {
expect(await page.textContent('.unsafe-fs-fetch-raw-query1')).toBe('')
expect(await page.textContent('.unsafe-fs-fetch-raw-query1-status')).toBe(
'403',
)
})

test('unsafe fs fetch query 2', async () => {
expect(await page.textContent('.unsafe-fs-fetch-raw-query2')).toBe('')
expect(await page.textContent('.unsafe-fs-fetch-raw-query2-status')).toBe(
'403',
)
})

test('unsafe fs fetch with special characters (#8498)', async () => {
expect(await page.textContent('.unsafe-fs-fetch-8498')).toBe('')
expect(await page.textContent('.unsafe-fs-fetch-8498-status')).toBe('404')
38 changes: 38 additions & 0 deletions playground/fs-serve/root/src/index.html
Original file line number Diff line number Diff line change
@@ -37,6 +37,10 @@ <h2>Unsafe /@fs/ Fetch</h2>
<pre class="unsafe-fs-fetch"></pre>
<pre class="unsafe-fs-fetch-raw-status"></pre>
<pre class="unsafe-fs-fetch-raw"></pre>
<pre class="unsafe-fs-fetch-raw-query1-status"></pre>
<pre class="unsafe-fs-fetch-raw-query1"></pre>
<pre class="unsafe-fs-fetch-raw-query2-status"></pre>
<pre class="unsafe-fs-fetch-raw-query2"></pre>
<pre class="unsafe-fs-fetch-8498-status"></pre>
<pre class="unsafe-fs-fetch-8498"></pre>
<pre class="unsafe-fs-fetch-8498-2-status"></pre>
@@ -209,6 +213,40 @@ <h2>Denied</h2>
console.error(e)
})

fetch(
joinUrlSegments(
base,
joinUrlSegments('/@fs/', ROOT) + '/unsafe.json?import&raw??',
),
)
.then((r) => {
text('.unsafe-fs-fetch-raw-query1-status', r.status)
return r.json()
})
.then((data) => {
text('.unsafe-fs-fetch-raw-query1', JSON.stringify(data))
})
.catch((e) => {
console.error(e)
})

fetch(
joinUrlSegments(
base,
joinUrlSegments('/@fs/', ROOT) + '/unsafe.json?import&raw?&',
),
)
.then((r) => {
text('.unsafe-fs-fetch-raw-query2-status', r.status)
return r.json()
})
.then((data) => {
text('.unsafe-fs-fetch-raw-query2', JSON.stringify(data))
})
.catch((e) => {
console.error(e)
})

// outside root with special characters #8498
fetch(
joinUrlSegments(