hono icon indicating copy to clipboard operation
hono copied to clipboard

Built-in validator formData parsing

Open HugeLetters opened this issue 1 year ago • 4 comments

What version of Hono are you using?

4.46

What runtime/platform is your app running on?

Nodejs

What steps can reproduce the bug?

Is there a reason at this you use arrayBuffer to construct formData record? https://github.com/honojs/hono/blob/d21f8eb27aa43da9cd9d5b6f666692c4e92a0344/src/validator/validator.ts#L92

Hono has a built-in for that already c.req.parseBody()

This causes a bug if there's middleware which uses .parseBody() before validator - this populates c.req.bodyCache.parsedBody AND c.req.bodyCache.formData. And since your validator tries to check the cache for formData(not parsedBody) - it gets a hit which contains FormData, not a Record.

It seems this issue would be mitigated if either hono used c.req.bodyCache.parsedBody with a fallback to arrayBuffer or would just use parseBody() directly since it already checks the cache.

So is there some reason for the current behavior? Apologies that the issue isn't properly filled in but I hope my explanation is clear enough.

What is the expected behavior?

No response

What do you see instead?

No response

Additional information

No response

HugeLetters avatar Jun 25 '24 18:06 HugeLetters

Hi @HugeLetters

This causes a bug if there's middleware which uses .parseBody() before validator - this populates c.req.bodyCache.parsedBody AND c.req.bodyCache.formData.

Can you provide the concrete steps to reproduce that bug first?

yusukebe avatar Jun 27 '24 01:06 yusukebe

@yusukebe hi, here's small demo https://github.com/HugeLetters/formdata-hono-demo

Just run a dev script and it should provide logs which showcase the bug.

HugeLetters avatar Jun 27 '24 08:06 HugeLetters

@HugeLetters Thanks! I'll check it later.

yusukebe avatar Jun 27 '24 08:06 yusukebe

@HugeLetters Sorry for the late reply.

I'm investigating it now. I've created a minimal code to reproduce it:

import assert from 'assert'
import { Hono } from 'hono'
import { validator } from 'hono/validator'

const app = new Hono().post(
  '/',
  async (c, next) => {
    await c.req.parseBody()
    await next()
  },
  validator('form', (value) => {
    console.log('validator - value:', value)
    assert(!(value instanceof FormData), 'Value has to be a Record, not FormData')
    return value
  }),
  (c) => {
    return c.text('Hello Hono!')
  }
)

const form = new FormData()
form.append('foo', 'bar')

await app.request('/', {
  method: 'POST',
  body: form
})

yusukebe avatar Jul 01 '24 01:07 yusukebe