hono 4.12.3 → 4.12.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -34,6 +34,11 @@ class SSEStreamingApi extends import_stream.StreamingApi {
34
34
  const dataLines = data.split(/\r\n|\r|\n/).map((line) => {
35
35
  return `data: ${line}`;
36
36
  }).join("\n");
37
+ for (const key of ["event", "id", "retry"]) {
38
+ if (message[key] && /[\r\n]/.test(message[key])) {
39
+ throw new Error(`${key} must not contain "\\r" or "\\n"`);
40
+ }
41
+ }
37
42
  const sseData = [
38
43
  message.event && `event: ${message.event}`,
39
44
  dataLines,
@@ -23,6 +23,7 @@ __export(serve_static_exports, {
23
23
  module.exports = __toCommonJS(serve_static_exports);
24
24
  var import_compress = require("../../utils/compress");
25
25
  var import_mime = require("../../utils/mime");
26
+ var import_url = require("../../utils/url");
26
27
  var import_path = require("./path");
27
28
  const ENCODINGS = {
28
29
  br: ".br",
@@ -44,7 +45,7 @@ const serveStatic = (options) => {
44
45
  filename = options.path;
45
46
  } else {
46
47
  try {
47
- filename = decodeURIComponent(c.req.path);
48
+ filename = (0, import_url.tryDecodeURI)(c.req.path);
48
49
  if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
49
50
  throw new Error();
50
51
  }
@@ -112,6 +112,11 @@ const _serialize = (name, value, opt = {}) => {
112
112
  throw new Error("__Host- Cookie must not have Domain attributes");
113
113
  }
114
114
  }
115
+ for (const key of ["domain", "path"]) {
116
+ if (opt[key] && /[;\r\n]/.test(opt[key])) {
117
+ throw new Error(`${key} must not contain ";", "\\r", or "\\n"`);
118
+ }
119
+ }
115
120
  if (opt && typeof opt.maxAge === "number" && opt.maxAge >= 0) {
116
121
  if (opt.maxAge > 3456e4) {
117
122
  throw new Error(
@@ -29,7 +29,8 @@ __export(url_exports, {
29
29
  mergePath: () => mergePath,
30
30
  splitPath: () => splitPath,
31
31
  splitRoutingPath: () => splitRoutingPath,
32
- tryDecode: () => tryDecode
32
+ tryDecode: () => tryDecode,
33
+ tryDecodeURI: () => tryDecodeURI
33
34
  });
34
35
  module.exports = __toCommonJS(url_exports);
35
36
  const splitPath = (path) => {
@@ -251,5 +252,6 @@ const decodeURIComponent_ = decodeURIComponent;
251
252
  mergePath,
252
253
  splitPath,
253
254
  splitRoutingPath,
254
- tryDecode
255
+ tryDecode,
256
+ tryDecodeURI
255
257
  });
@@ -11,6 +11,11 @@ var SSEStreamingApi = class extends StreamingApi {
11
11
  const dataLines = data.split(/\r\n|\r|\n/).map((line) => {
12
12
  return `data: ${line}`;
13
13
  }).join("\n");
14
+ for (const key of ["event", "id", "retry"]) {
15
+ if (message[key] && /[\r\n]/.test(message[key])) {
16
+ throw new Error(`${key} must not contain "\\r" or "\\n"`);
17
+ }
18
+ }
14
19
  const sseData = [
15
20
  message.event && `event: ${message.event}`,
16
21
  dataLines,
@@ -1,6 +1,7 @@
1
1
  // src/middleware/serve-static/index.ts
2
2
  import { COMPRESSIBLE_CONTENT_TYPE_REGEX } from "../../utils/compress.js";
3
3
  import { getMimeType } from "../../utils/mime.js";
4
+ import { tryDecodeURI } from "../../utils/url.js";
4
5
  import { defaultJoin } from "./path.js";
5
6
  var ENCODINGS = {
6
7
  br: ".br",
@@ -22,7 +23,7 @@ var serveStatic = (options) => {
22
23
  filename = options.path;
23
24
  } else {
24
25
  try {
25
- filename = decodeURIComponent(c.req.path);
26
+ filename = tryDecodeURI(c.req.path);
26
27
  if (/(?:^|[\/\\])\.\.(?:$|[\/\\])/.test(filename)) {
27
28
  throw new Error();
28
29
  }
@@ -1,7 +1,7 @@
1
1
  import type { Hono } from '../hono';
2
2
  import type { HonoBase } from '../hono-base';
3
3
  import type { METHODS, METHOD_NAME_ALL_LOWERCASE } from '../router';
4
- import type { Endpoint, KnownResponseFormat, ResponseFormat, Schema } from '../types';
4
+ import type { Endpoint, ExtractSchema, KnownResponseFormat, ResponseFormat, Schema } from '../types';
5
5
  import type { StatusCode, SuccessStatusCode } from '../utils/http-status';
6
6
  import type { HasRequiredKeys } from '../utils/types';
7
7
  /**
@@ -205,5 +205,5 @@ type ModSchema<D, Def extends GlobalResponseDefinition> = {
205
205
  [M in keyof D[K]]: ModRoute<D[K][M], Def>;
206
206
  };
207
207
  };
208
- export type ApplyGlobalResponse<App, Def extends GlobalResponseDefinition> = App extends HonoBase<infer E, infer D extends Schema, infer B> ? Hono<E, ModSchema<D, Def> extends Schema ? ModSchema<D, Def> : never, B> : never;
208
+ export type ApplyGlobalResponse<App, Def extends GlobalResponseDefinition> = App extends HonoBase<infer E, infer _ extends Schema, infer B> ? ModSchema<ExtractSchema<App>, Def> extends infer S extends Schema ? Hono<E, S, B> : never : never;
209
209
  export {};
@@ -8,6 +8,16 @@ export declare const splitRoutingPath: (routePath: string) => string[];
8
8
  export declare const getPattern: (label: string, next?: string) => Pattern | null;
9
9
  type Decoder = (str: string) => string;
10
10
  export declare const tryDecode: (str: string, decoder: Decoder) => string;
11
+ /**
12
+ * Try to apply decodeURI() to given string.
13
+ * If it fails, skip invalid percent encoding or invalid UTF-8 sequences, and apply decodeURI() to the rest as much as possible.
14
+ * @param str The string to decode.
15
+ * @returns The decoded string that sometimes contains undecodable percent encoding.
16
+ * @example
17
+ * tryDecodeURI('Hello%20World') // 'Hello World'
18
+ * tryDecodeURI('Hello%20World/%A4%A2') // 'Hello World/%A4%A2'
19
+ */
20
+ export declare const tryDecodeURI: (str: string) => string;
11
21
  export declare const getPath: (request: Request) => string;
12
22
  export declare const getQueryStrings: (url: string) => string;
13
23
  export declare const getPathNoStrict: (request: Request) => string;
@@ -87,6 +87,11 @@ var _serialize = (name, value, opt = {}) => {
87
87
  throw new Error("__Host- Cookie must not have Domain attributes");
88
88
  }
89
89
  }
90
+ for (const key of ["domain", "path"]) {
91
+ if (opt[key] && /[;\r\n]/.test(opt[key])) {
92
+ throw new Error(`${key} must not contain ";", "\\r", or "\\n"`);
93
+ }
94
+ }
90
95
  if (opt && typeof opt.maxAge === "number" && opt.maxAge >= 0) {
91
96
  if (opt.maxAge > 3456e4) {
92
97
  throw new Error(
package/dist/utils/url.js CHANGED
@@ -217,5 +217,6 @@ export {
217
217
  mergePath,
218
218
  splitPath,
219
219
  splitRoutingPath,
220
- tryDecode
220
+ tryDecode,
221
+ tryDecodeURI
221
222
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hono",
3
- "version": "4.12.3",
3
+ "version": "4.12.4",
4
4
  "description": "Web framework built on Web Standards",
5
5
  "main": "dist/cjs/index.js",
6
6
  "type": "module",