Skip to content

LinearRouter matches an empty path segment and returns an empty param #5372

Description

@harshit-d3v

LinearRouter matches a path with an empty segment and hands the handler an empty param. The other three routers return 404.

import { Hono } from 'hono'
import { LinearRouter } from 'hono/router/linear-router'

const app = new Hono({ router: new LinearRouter() })
app.get('/u/:id/posts', (c) => c.json({ id: c.req.param('id') }))

await app.request('http://localhost/u/42/posts')  // 200 { id: "42" }
await app.request('http://localhost/u//posts')    // 200 { id: "" }   <- expected 404
Router /u//posts
RegExpRouter 404
TrieRouter 404
PatternRouter 404
LinearRouter 200, id is ""

A handler that expects an id to be present gets an empty string instead.

Cause

In match(), the plain label branch already rejects an empty segment at the end of the path but not one in the middle:

let endValuePos = path.indexOf('/', pos + 1)
if (endValuePos === -1) {
  if (pos + 1 === path.length) {
    continue ROUTES_LOOP      // trailing empty segment, rejected
  }
  endValuePos = path.length
}
value = path.slice(pos + 1, endValuePos)

For /u//posts the indexOf returns pos + 1, so value is '' and the match carries on. That is why /a/:p correctly 404s on /a/ but /u/:id/posts matches /u//posts.

Fix is to reject endValuePos === pos + 1 the same way. Full suite passes and I added the case to common.case.test.ts, where all four routers pass it. Happy to open the PR.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions