From f427b1ac68598206de41da4f7584fbc41d510b8a Mon Sep 17 00:00:00 2001 From: Shunya Shishido Date: Fri, 31 Jan 2025 00:18:22 +0900 Subject: [PATCH] Check router rule recursion depth --- docs/index.bs | 66 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/docs/index.bs b/docs/index.bs index 0a280725..538e2e94 100644 --- a/docs/index.bs +++ b/docs/index.bs @@ -212,10 +212,6 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ A [=/service worker=] has an associated list of router rules (a [=list=] of {{RouterRule}}s). It is initially an empty [=list=]. - A [=/service worker=] has an associated router rule count (the number of registered {{RouterRule}}s). It is initially set to zero. - - Note: [=router rule count=] is defined as the limit of the total number of registered router rules. This prevents the user agent from spending much resources by evaluating too many router rules. The limit is 1024. - A [=/service worker=] is said to be running if its [=event loop=] is running.
@@ -1604,7 +1600,9 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ }; - Note: {{RouterCondition/_or}} and {{RouterCondition/not}} might have the other {{RouterCondition/_or}} or {{RouterCondition/not}} inside. To avoid spending much resources by the nested condition or performance penalty on evaluation, depth of such nested conditions can be limited. + A count router condition result is a [=struct=] that consists of: + * A total count (a number). + * A depth (a number).

{{InstallEvent/addRoutes(rules)|event.addRoutes(rules)}}

@@ -1620,6 +1618,7 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If running the [=Verify Router Condition=] algorithm with |rule|["{{RouterRule/condition}}"] and |serviceWorker| returns false, return [=a promise rejected with=] a {{TypeError}}. 1. Append |rule| to |routerRules|. 1. If |routerRules| [=list/contains=] a {{RouterRule}} whose {{RouterRule/source}} is either of "{{RouterSourceEnum/fetch-event}}" or "{{RouterSourceEnum/race-network-and-fetch-handler}}", and |serviceWorker|'s [=set of event types to handle=] does not [=set/contain=] {{ServiceWorkerGlobalScope/fetch!!event}}, return [=a promise rejected with=] a {{TypeError}}. + 1. If running the [=Check Router Registration Limit=] with |serviceWorker| returns false, return [=a promise rejected with=] a {{TypeError}}. 1. Set |serviceWorker|'s [=service worker/list of router rules=] to |routerRules|. 1. Return [=a promise resolved with=] undefined. @@ -3405,9 +3404,6 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ Note: For ease of understanding the router rule, the "or" condition is mutually exclusive with other conditions. 1. Let |orConditions| be |condition|["{{RouterCondition/_or}}"]. - - Note: To limit the resource usage and a condition evaluation time, |orConditions|'s [=list/size=] can be limited. - 1. For each |orCondition| of |orConditions|: 1. If running the [=Verify Router Condition=] algorithm with |orCondition| and |serviceWorker| returns false, return false. 1. Set |hasCondition| to true. @@ -3418,9 +3414,6 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. If running the [=Verify Router Condition=] algorithm with |condition|["{{RouterCondition/not}}"] and |serviceWorker| returns false, return false. 1. Set |hasCondition| to true. - 1. If |hasCondition| is true, then: - 1. Increament |serviceWorker|'s [=service worker/router rule count=] by one. - 1. If |serviceWorker|'s [=service worker/router rule count=] exceeds 1024, which is the limit of registered router rules, return false. 1. Return |hasCondition|.
@@ -3468,6 +3461,57 @@ spec: storage; urlPrefix: https://storage.spec.whatwg.org/ 1. Return true.
+
+

Check Router Registration Limit

+ + : Input + :: |serviceWorker|, a [=/service worker=] + : Output + :: a boolean + + Note: Router conditions can be complex and nested using {{RouterCondition/_or}} and {{RouterCondition/not}}. To prevent excessive processing, this algorithm introduces two limits. First, the total number of conditions, counting all nested conditions, cannot exceed 1024. Second, the nesting depth is limited to 10 levels to avoid exponential computation. + + 1. Let |result| be a [=count router condition result=]. + 1. Set |result|'s [=count router condition result/total count=] to 0. + 1. Set |result|'s [=count router condition result/depth=] to 1. + 1. Let |maxCount| be 1024. + 1. Let |maxDepth| be 10. + 1. [=list/For each=] |rule| of |serviceWorker|'s [=service worker/list of router rules=]: + 1. Let |currentResult| be the result of running [=Count Router Inner Conditions=] with |rule|["{{RouterRule/condition}}"], |result|, |maxCount|, and |maxDepth|. + 1. If |currentResult|'s [=count router condition result/total count=] exceeds |maxCount|, return false. + 1. If |currentResult|'s [=count router condition result/depth=] exceeds |maxDepth|, return false. + 1. Set |result|'s [=count router condition result/total count=] to |currentResult|'s [=count router condition result/total count=]. + 1. return true. +
+ +
+

Count Router Inner Conditions

+ + : Input + :: |condition|, a {{RouterCondition}} + :: |result|, a [=count router condition result=] + :: |maxCount|, a number + :: |maxDepth|, a number + : Output + :: |result|, a [=count router condition result=] + + 1. Increment |result|'s [=count router condition result/total count=] by one. + 1. If |result|'s [=count router condition result/total count=] exceeds |maxCount|, return |result|. + 1. If |result|'s [=count router condition result/depth=] exceeds |maxDepth|, return |result|. + 1. If |condition|["{{RouterCondition/_or}}"] [=map/exists=], then: + 1. Increment |result|'s [=count router condition result/depth=] by one. + 1. For each |orCondition| of |condition|["{{RouterCondition/_or}}"]: + 1. Set |result| to be the result of running [=Count Router Inner Conditions=] with |orCondition|, |result|, |maxCount|, and |maxDepth|. + 1. If |result|'s [=count router condition result/total count=] exceeds |maxCount|, return |result|. + 1. If |result|'s [=count router condition result/depth=] exceeds |maxDepth|, return |result|. + 1. Else if |condition|["{{RouterCondition/not}}"] [=map/exists=], then: + 1. Increment |result|'s [=count router condition result/depth=] by one. + 1. Set |result| to be the result of running [=Count Router Inner Conditions=] with |condition|["{{RouterCondition/not}}"], |result|, |maxCount|, and |maxDepth|. + 1. If |result|'s [=count router condition result/total count=] exceeds |maxCount|, return |result|. + 1. If |result|'s [=count router condition result/depth=] exceeds |maxDepth|, return |result|. + 1. Return |result|. +
+

Get Router Source

: Input