From 9c0ca38dc9828e2e2b0da048add55242ccc58209 Mon Sep 17 00:00:00 2001 From: oussama seffai Date: Wed, 6 Nov 2024 18:59:43 +0100 Subject: [PATCH 1/3] fix(serveStatic): add guard to prevent reading empty folders --- src/adapter/deno/deno.d.ts | 8 ++++++++ src/adapter/deno/serve-static.ts | 7 ++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/adapter/deno/deno.d.ts b/src/adapter/deno/deno.d.ts index 38eaf3203..a03d5f667 100644 --- a/src/adapter/deno/deno.d.ts +++ b/src/adapter/deno/deno.d.ts @@ -76,4 +76,12 @@ declare namespace Deno { */ idleTimeout?: number } + + /** + * Get stats asynchronously for the specified path. + * + * @param path The path to get stats. + * @returns A promise that resolves to Stats object. + */ + export function stat(path: string): Promise } diff --git a/src/adapter/deno/serve-static.ts b/src/adapter/deno/serve-static.ts index 0e28424d9..b38ddb599 100644 --- a/src/adapter/deno/serve-static.ts +++ b/src/adapter/deno/serve-static.ts @@ -2,7 +2,7 @@ import type { ServeStaticOptions } from '../../middleware/serve-static' import { serveStatic as baseServeStatic } from '../../middleware/serve-static' import type { Env, MiddlewareHandler } from '../../types' -const { open, lstatSync, errors } = Deno +const { open, lstatSync, errors, stat } = Deno export const serveStatic = ( options: ServeStaticOptions @@ -10,6 +10,11 @@ export const serveStatic = ( return async function serveStatic(c, next) { const getContent = async (path: string) => { try { + const fileInfo = await stat(path) + if (fileInfo.isDirectory) { + return null + } + const file = await open(path) return file.readable } catch (e) { From a5e4269c32d012ae36866a1a6bd404a6af132b60 Mon Sep 17 00:00:00 2001 From: oussama seffai Date: Thu, 7 Nov 2024 10:24:33 +0100 Subject: [PATCH 2/3] fix(serveStatic): remove unnecessary Deno.stat --- src/adapter/deno/deno.d.ts | 8 -------- src/adapter/deno/serve-static.ts | 6 +++--- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/src/adapter/deno/deno.d.ts b/src/adapter/deno/deno.d.ts index a03d5f667..38eaf3203 100644 --- a/src/adapter/deno/deno.d.ts +++ b/src/adapter/deno/deno.d.ts @@ -76,12 +76,4 @@ declare namespace Deno { */ idleTimeout?: number } - - /** - * Get stats asynchronously for the specified path. - * - * @param path The path to get stats. - * @returns A promise that resolves to Stats object. - */ - export function stat(path: string): Promise } diff --git a/src/adapter/deno/serve-static.ts b/src/adapter/deno/serve-static.ts index b38ddb599..867f6f9ea 100644 --- a/src/adapter/deno/serve-static.ts +++ b/src/adapter/deno/serve-static.ts @@ -2,7 +2,7 @@ import type { ServeStaticOptions } from '../../middleware/serve-static' import { serveStatic as baseServeStatic } from '../../middleware/serve-static' import type { Env, MiddlewareHandler } from '../../types' -const { open, lstatSync, errors, stat } = Deno +const { open, lstatSync, errors } = Deno export const serveStatic = ( options: ServeStaticOptions @@ -10,8 +10,7 @@ export const serveStatic = ( return async function serveStatic(c, next) { const getContent = async (path: string) => { try { - const fileInfo = await stat(path) - if (fileInfo.isDirectory) { + if (isDir(path)) { return null } @@ -35,6 +34,7 @@ export const serveStatic = ( } catch {} return isDir } + return baseServeStatic({ ...options, getContent, From 7d4561d29a6c1102401ee5ff61742874b3d0516b Mon Sep 17 00:00:00 2001 From: oussama seffai Date: Thu, 7 Nov 2024 11:05:54 +0100 Subject: [PATCH 3/3] test(serveStatic): add test cases related to isDir guard --- runtime-tests/deno/middleware.test.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/runtime-tests/deno/middleware.test.tsx b/runtime-tests/deno/middleware.test.tsx index 1ad4569f5..9ca6f9bf4 100644 --- a/runtime-tests/deno/middleware.test.tsx +++ b/runtime-tests/deno/middleware.test.tsx @@ -139,6 +139,22 @@ Deno.test('Serve Static middleware', async () => { res = await app.request('http://localhost/static-absolute-root/plain.txt') assertEquals(res.status, 200) assertEquals(await res.text(), 'Deno!') + + res = await app.request('http://localhost/static') + assertEquals(res.status, 404) + assertEquals(await res.text(), '404 Not Found') + + res = await app.request('http://localhost/static/dir') + assertEquals(res.status, 404) + assertEquals(await res.text(), '404 Not Found') + + res = await app.request('http://localhost/static/helloworld/nested') + assertEquals(res.status, 404) + assertEquals(await res.text(), '404 Not Found') + + res = await app.request('http://localhost/static/helloworld/../') + assertEquals(res.status, 404) + assertEquals(await res.text(), '404 Not Found') }) Deno.test('JWT Authentication middleware', async () => {