Correctly handle trailing slashes in URITemplateRouter#2464
Conversation
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
🤖 Augment PR SummarySummary: This PR makes trailing slashes a first-class, distinct part of route matching for Changes:
Technical Notes: The approach preserves strictness for internal empty segments (double slashes) while enabling distinct route registrations for 🤖 Was this summary useful? React with 👍 or 👎 |
There was a problem hiding this comment.
1 issue found across 4 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/core/uritemplate/uritemplate_router.cc">
<violation number="1" location="src/core/uritemplate/uritemplate_router.cc:494">
P2: Templates consisting only of slashes (e.g. `"////"`) will leave `current == nullptr` after the parsing loop, causing both this trailing-slash block and the final registration block to be skipped. The `add()` call silently does nothing—no route is registered and no error is raised. Consider normalizing slash-only templates to the existing `"/"` root handling or explicitly rejecting them to avoid surprising no-op registrations.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| current = &find_or_create_literal_child(literals, ""); | ||
| } | ||
|
|
||
| if (!absorbed && current != nullptr && current != base_path_end && |
There was a problem hiding this comment.
P2: Templates consisting only of slashes (e.g. "////") will leave current == nullptr after the parsing loop, causing both this trailing-slash block and the final registration block to be skipped. The add() call silently does nothing—no route is registered and no error is raised. Consider normalizing slash-only templates to the existing "/" root handling or explicitly rejecting them to avoid surprising no-op registrations.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/core/uritemplate/uritemplate_router.cc, line 494:
<comment>Templates consisting only of slashes (e.g. `"////"`) will leave `current == nullptr` after the parsing loop, causing both this trailing-slash block and the final registration block to be skipped. The `add()` call silently does nothing—no route is registered and no error is raised. Consider normalizing slash-only templates to the existing `"/"` root handling or explicitly rejecting them to avoid surprising no-op registrations.</comment>
<file context>
@@ -491,6 +491,11 @@ auto URITemplateRouter::add(const std::string_view uri_template,
current = &find_or_create_literal_child(literals, "");
}
+ if (!absorbed && current != nullptr && current != base_path_end &&
+ uri_template.size() > 1 && uri_template.back() == '/') {
+ current = &find_or_create_literal_child(current->literals, "");
</file context>
There was a problem hiding this comment.
Benchmark (macos/llvm)
Details
| Benchmark suite | Current: fe58667 | Previous: ec3ab52 | Ratio |
|---|---|---|---|
Regex_Lower_S_Or_Upper_S_Asterisk |
2.023008927224815 ns/iter |
2.024502094778693 ns/iter |
1.00 |
Regex_Caret_Lower_S_Or_Upper_S_Asterisk_Dollar |
1.7661190441047656 ns/iter |
1.6226946302130283 ns/iter |
1.09 |
Regex_Period_Asterisk |
1.699431746937724 ns/iter |
1.6580394489985497 ns/iter |
1.02 |
Regex_Group_Period_Asterisk_Group |
1.7041911377307704 ns/iter |
1.658989262174867 ns/iter |
1.03 |
Regex_Period_Plus |
2.0396430433685344 ns/iter |
2.020224328612864 ns/iter |
1.01 |
Regex_Period |
2.105180646541632 ns/iter |
1.9961204882865218 ns/iter |
1.05 |
Regex_Caret_Period_Plus_Dollar |
2.0456668919574366 ns/iter |
1.9791187122442282 ns/iter |
1.03 |
Regex_Caret_Group_Period_Plus_Group_Dollar |
2.103878436879067 ns/iter |
2.0273622891664287 ns/iter |
1.04 |
Regex_Caret_Period_Asterisk_Dollar |
1.7327891046745372 ns/iter |
1.6525958240776746 ns/iter |
1.05 |
Regex_Caret_Group_Period_Asterisk_Group_Dollar |
1.8006522328361179 ns/iter |
1.6587680795419664 ns/iter |
1.09 |
Regex_Caret_X_Hyphen |
6.249767841218333 ns/iter |
5.77392345407608 ns/iter |
1.08 |
Regex_Period_Md_Dollar |
18.102403983783482 ns/iter |
15.932790853667324 ns/iter |
1.14 |
Regex_Caret_Slash_Period_Asterisk |
4.878141143336687 ns/iter |
4.08445048290761 ns/iter |
1.19 |
Regex_Caret_Period_Range_Dollar |
2.0726259501424433 ns/iter |
1.9292850326935878 ns/iter |
1.07 |
Regex_Nested_Backtrack |
25.25843390412393 ns/iter |
24.44234500873663 ns/iter |
1.03 |
JSON_Array_Of_Objects_Unique |
434.62103532893866 ns/iter |
415.0942589656784 ns/iter |
1.05 |
JSON_Parse_1 |
4876.104303214185 ns/iter |
5260.747110241713 ns/iter |
0.93 |
JSON_Parse_Real |
7269.621522288123 ns/iter |
7398.416019487728 ns/iter |
0.98 |
JSON_Parse_Decimal |
8350.659232277312 ns/iter |
8984.807549811656 ns/iter |
0.93 |
JSON_Parse_Schema_ISO_Language |
3218706.986111194 ns/iter |
3335873.2328045256 ns/iter |
0.96 |
JSON_Fast_Hash_Helm_Chart_Lock |
60.431038467954245 ns/iter |
58.14016170613144 ns/iter |
1.04 |
JSON_Equality_Helm_Chart_Lock |
140.95724412628405 ns/iter |
131.4450696727289 ns/iter |
1.07 |
JSON_Divisible_By_Decimal |
178.8456898837942 ns/iter |
164.32875094178561 ns/iter |
1.09 |
JSON_String_Equal/10 |
6.8881782950220485 ns/iter |
6.482598528223076 ns/iter |
1.06 |
JSON_String_Equal/100 |
6.617389147723418 ns/iter |
6.031828840060782 ns/iter |
1.10 |
JSON_String_Equal_Small_By_Perfect_Hash/10 |
0.7729710341586941 ns/iter |
0.7241673428200286 ns/iter |
1.07 |
JSON_String_Equal_Small_By_Runtime_Perfect_Hash/10 |
3.3959001655985257 ns/iter |
3.1572893132010726 ns/iter |
1.08 |
JSON_String_Fast_Hash/10 |
2.481380038007788 ns/iter |
2.2520024413241675 ns/iter |
1.10 |
JSON_String_Fast_Hash/100 |
2.0308805591250914 ns/iter |
1.9296559995851663 ns/iter |
1.05 |
JSON_String_Key_Hash/10 |
1.3488899997919535 ns/iter |
1.4072655347764071 ns/iter |
0.96 |
JSON_String_Key_Hash/100 |
2.158549042199146 ns/iter |
2.1426865554239862 ns/iter |
1.01 |
JSON_Object_Defines_Miss_Same_Length |
2.3797213949498697 ns/iter |
2.380285213979885 ns/iter |
1.00 |
JSON_Object_Defines_Miss_Too_Small |
2.379841484752044 ns/iter |
2.243377851821152 ns/iter |
1.06 |
JSON_Object_Defines_Miss_Too_Large |
2.437302950919509 ns/iter |
2.3524393517390756 ns/iter |
1.04 |
Pointer_Object_Traverse |
14.810218799781264 ns/iter |
13.756642717500945 ns/iter |
1.08 |
Pointer_Object_Try_Traverse |
23.473641206482988 ns/iter |
23.646351813764905 ns/iter |
0.99 |
Pointer_Push_Back_Pointer_To_Weak_Pointer |
151.81994761424954 ns/iter |
150.99408941770733 ns/iter |
1.01 |
Pointer_Walker_Schema_ISO_Language |
4036240.1271675806 ns/iter |
4886306.352564163 ns/iter |
0.83 |
Pointer_Maybe_Tracked_Deeply_Nested/0 |
985364.3009985187 ns/iter |
1019254.6159527024 ns/iter |
0.97 |
Pointer_Maybe_Tracked_Deeply_Nested/1 |
1350775.4237287708 ns/iter |
1512906.539525727 ns/iter |
0.89 |
Pointer_Position_Tracker_Get_Deeply_Nested |
348.4564696225236 ns/iter |
362.9705765035049 ns/iter |
0.96 |
URITemplateRouter_Create |
25255.021007547068 ns/iter |
23522.33159509132 ns/iter |
1.07 |
URITemplateRouter_Match |
194.81059879585123 ns/iter |
165.3221143854459 ns/iter |
1.18 |
URITemplateRouter_Match_BasePath |
212.23707241819008 ns/iter |
186.12963869089097 ns/iter |
1.14 |
URITemplateRouterView_Restore |
9899.488582991575 ns/iter |
8885.733453117817 ns/iter |
1.11 |
URITemplateRouterView_Match |
131.04342738511133 ns/iter |
122.70000628756182 ns/iter |
1.07 |
URITemplateRouterView_Match_BasePath |
158.97165816559607 ns/iter |
139.91648613721765 ns/iter |
1.14 |
URITemplateRouterView_Arguments |
409.241523009635 ns/iter |
396.6329213574847 ns/iter |
1.03 |
JSONL_Parse_Large |
13601824.519230813 ns/iter |
12415846.982758561 ns/iter |
1.10 |
JSONL_Parse_Large_GZIP |
14316691.130434461 ns/iter |
13328737.415094418 ns/iter |
1.07 |
HTML_Build_Table_100000 |
79428109.37500155 ns/iter |
63142602.272726186 ns/iter |
1.26 |
HTML_Render_Table_100000 |
3639106.3953490546 ns/iter |
3078560.1660230765 ns/iter |
1.18 |
GZIP_Compress_ISO_Language_Set_3_Locations |
30531503.458332073 ns/iter |
26489899.703704026 ns/iter |
1.15 |
GZIP_Decompress_ISO_Language_Set_3_Locations |
5829206.451128152 ns/iter |
6008124.1776319565 ns/iter |
0.97 |
GZIP_Compress_ISO_Language_Set_3_Schema |
1590704.09930711 ns/iter |
1446627.6101010675 ns/iter |
1.10 |
GZIP_Decompress_ISO_Language_Set_3_Schema |
299158.6121437219 ns/iter |
262888.79688713275 ns/iter |
1.14 |
This comment was automatically generated by workflow using github-action-benchmark.
There was a problem hiding this comment.
Benchmark (linux/llvm)
Details
| Benchmark suite | Current: fe58667 | Previous: ec3ab52 | Ratio |
|---|---|---|---|
Regex_Lower_S_Or_Upper_S_Asterisk |
2.4616517971175127 ns/iter |
2.1818951985205097 ns/iter |
1.13 |
Regex_Caret_Lower_S_Or_Upper_S_Asterisk_Dollar |
2.4659491035933434 ns/iter |
2.180159705101779 ns/iter |
1.13 |
Regex_Period_Asterisk |
2.4634833217136625 ns/iter |
2.1789166576770462 ns/iter |
1.13 |
Regex_Group_Period_Asterisk_Group |
2.4626111077406914 ns/iter |
2.179685384743455 ns/iter |
1.13 |
Regex_Period_Plus |
3.8678756251777027 ns/iter |
2.805794336181445 ns/iter |
1.38 |
Regex_Period |
3.8703167487425194 ns/iter |
2.802327882070371 ns/iter |
1.38 |
Regex_Caret_Period_Plus_Dollar |
3.5173727022926022 ns/iter |
2.491886400660958 ns/iter |
1.41 |
Regex_Caret_Group_Period_Plus_Group_Dollar |
3.5186582300692986 ns/iter |
2.5019042786307346 ns/iter |
1.41 |
Regex_Caret_Period_Asterisk_Dollar |
2.814702697980883 ns/iter |
3.425730659514792 ns/iter |
0.82 |
Regex_Caret_Group_Period_Asterisk_Group_Dollar |
2.8582897500759983 ns/iter |
3.4268878127565765 ns/iter |
0.83 |
Regex_Caret_X_Hyphen |
6.6876904425255566 ns/iter |
6.542778493195267 ns/iter |
1.02 |
Regex_Period_Md_Dollar |
27.45088442848014 ns/iter |
27.712061374264024 ns/iter |
0.99 |
Regex_Caret_Slash_Period_Asterisk |
7.384502036732324 ns/iter |
5.916157770375355 ns/iter |
1.25 |
Regex_Caret_Period_Range_Dollar |
3.8686855856057196 ns/iter |
2.8213124758063928 ns/iter |
1.37 |
Regex_Nested_Backtrack |
37.56783931849595 ns/iter |
36.84158463997745 ns/iter |
1.02 |
JSON_Array_Of_Objects_Unique |
476.194560197109 ns/iter |
441.91341432627377 ns/iter |
1.08 |
JSON_Parse_1 |
6825.46640027289 ns/iter |
6880.783280729001 ns/iter |
0.99 |
JSON_Parse_Real |
11090.89828503016 ns/iter |
11743.223119899401 ns/iter |
0.94 |
JSON_Parse_Decimal |
11889.738962817944 ns/iter |
11867.479096082561 ns/iter |
1.00 |
JSON_Parse_Schema_ISO_Language |
4028159.8735634424 ns/iter |
3846928.4780225093 ns/iter |
1.05 |
JSON_Fast_Hash_Helm_Chart_Lock |
79.17632229549399 ns/iter |
71.69389344398105 ns/iter |
1.10 |
JSON_Equality_Helm_Chart_Lock |
190.29790022019586 ns/iter |
168.03592973849243 ns/iter |
1.13 |
JSON_Divisible_By_Decimal |
251.69539010157786 ns/iter |
249.37015070516483 ns/iter |
1.01 |
JSON_String_Equal/10 |
6.3309699463966815 ns/iter |
6.5510270876904 ns/iter |
0.97 |
JSON_String_Equal/100 |
7.038424830080263 ns/iter |
7.168424252824143 ns/iter |
0.98 |
JSON_String_Equal_Small_By_Perfect_Hash/10 |
1.0554625684248085 ns/iter |
0.9403617507063093 ns/iter |
1.12 |
JSON_String_Equal_Small_By_Runtime_Perfect_Hash/10 |
12.491342872672552 ns/iter |
15.003911381573829 ns/iter |
0.83 |
JSON_String_Fast_Hash/10 |
3.168123551171244 ns/iter |
3.1156291865137034 ns/iter |
1.02 |
JSON_String_Fast_Hash/100 |
3.1674530826069764 ns/iter |
3.118740196207803 ns/iter |
1.02 |
JSON_String_Key_Hash/10 |
2.463646888604096 ns/iter |
2.254980018655048 ns/iter |
1.09 |
JSON_String_Key_Hash/100 |
8.088166383047378 ns/iter |
9.048933205941642 ns/iter |
0.89 |
JSON_Object_Defines_Miss_Same_Length |
2.9210692380190473 ns/iter |
2.675792387882199 ns/iter |
1.09 |
JSON_Object_Defines_Miss_Too_Small |
2.908943290261587 ns/iter |
2.648693070376156 ns/iter |
1.10 |
JSON_Object_Defines_Miss_Too_Large |
4.222746551728957 ns/iter |
3.737377815996358 ns/iter |
1.13 |
Pointer_Object_Traverse |
25.773276145031915 ns/iter |
24.66593928466631 ns/iter |
1.04 |
Pointer_Object_Try_Traverse |
29.231296547160262 ns/iter |
28.30878387289857 ns/iter |
1.03 |
Pointer_Push_Back_Pointer_To_Weak_Pointer |
182.2520086494951 ns/iter |
172.30818320331724 ns/iter |
1.06 |
Pointer_Walker_Schema_ISO_Language |
3108106.320175402 ns/iter |
3017873.151898686 ns/iter |
1.03 |
Pointer_Maybe_Tracked_Deeply_Nested/0 |
1465229.2748414613 ns/iter |
1494415.7505330597 ns/iter |
0.98 |
Pointer_Maybe_Tracked_Deeply_Nested/1 |
1799818.6640625726 ns/iter |
1947394.326315601 ns/iter |
0.92 |
Pointer_Position_Tracker_Get_Deeply_Nested |
720.6474530790379 ns/iter |
655.9889671869884 ns/iter |
1.10 |
URITemplateRouter_Create |
30744.3058582535 ns/iter |
31454.410426370177 ns/iter |
0.98 |
URITemplateRouter_Match |
184.16422305504128 ns/iter |
163.73479041536572 ns/iter |
1.12 |
URITemplateRouter_Match_BasePath |
218.79821128283652 ns/iter |
187.1280947848351 ns/iter |
1.17 |
URITemplateRouterView_Restore |
8757.026009248033 ns/iter |
7908.522688161386 ns/iter |
1.11 |
URITemplateRouterView_Match |
143.46762890497112 ns/iter |
155.73423409923737 ns/iter |
0.92 |
URITemplateRouterView_Match_BasePath |
161.87153811950262 ns/iter |
176.15727852075324 ns/iter |
0.92 |
URITemplateRouterView_Arguments |
455.2045666731441 ns/iter |
443.3892682741375 ns/iter |
1.03 |
JSONL_Parse_Large |
11440337.709678538 ns/iter |
12069510.189654654 ns/iter |
0.95 |
JSONL_Parse_Large_GZIP |
12753129.054544844 ns/iter |
13318760.788461776 ns/iter |
0.96 |
HTML_Build_Table_100000 |
91365886.37500153 ns/iter |
67705282.18181549 ns/iter |
1.35 |
HTML_Render_Table_100000 |
5342339.558139901 ns/iter |
5144098.251851877 ns/iter |
1.04 |
GZIP_Compress_ISO_Language_Set_3_Locations |
36472759.15789363 ns/iter |
34554012.949996606 ns/iter |
1.06 |
GZIP_Decompress_ISO_Language_Set_3_Locations |
4769470.904761875 ns/iter |
4975955.789854711 ns/iter |
0.96 |
GZIP_Compress_ISO_Language_Set_3_Schema |
2106164.563253038 ns/iter |
1908724.585830881 ns/iter |
1.10 |
GZIP_Decompress_ISO_Language_Set_3_Schema |
290569.2495847289 ns/iter |
376834.0080385769 ns/iter |
0.77 |
This comment was automatically generated by workflow using github-action-benchmark.
There was a problem hiding this comment.
Benchmark (windows/msvc)
Details
| Benchmark suite | Current: fe58667 | Previous: ec3ab52 | Ratio |
|---|---|---|---|
Regex_Lower_S_Or_Upper_S_Asterisk |
2.495573435271703 ns/iter |
5.063208928571531 ns/iter |
0.49 |
Regex_Caret_Lower_S_Or_Upper_S_Asterisk_Dollar |
2.557992052429353 ns/iter |
5.018043749999939 ns/iter |
0.51 |
Regex_Period_Asterisk |
2.6703641717230178 ns/iter |
5.026991999999382 ns/iter |
0.53 |
Regex_Group_Period_Asterisk_Group |
2.619128570259878 ns/iter |
5.016498885048308 ns/iter |
0.52 |
Regex_Period_Plus |
2.577010645020891 ns/iter |
4.7049401890738025 ns/iter |
0.55 |
Regex_Period |
2.617123214285552 ns/iter |
4.702228805138945 ns/iter |
0.56 |
Regex_Caret_Period_Plus_Dollar |
2.684839285714296 ns/iter |
4.704632443805418 ns/iter |
0.57 |
Regex_Caret_Group_Period_Plus_Group_Dollar |
2.5726974999997765 ns/iter |
4.705631260767012 ns/iter |
0.55 |
Regex_Caret_Period_Asterisk_Dollar |
2.628303211939169 ns/iter |
5.016071000000011 ns/iter |
0.52 |
Regex_Caret_Group_Period_Asterisk_Group_Dollar |
2.6437514285711523 ns/iter |
5.014747999999827 ns/iter |
0.53 |
Regex_Caret_X_Hyphen |
5.987791071429375 ns/iter |
8.468091926481174 ns/iter |
0.71 |
Regex_Period_Md_Dollar |
31.632956297837715 ns/iter |
46.13673986912622 ns/iter |
0.69 |
Regex_Caret_Slash_Period_Asterisk |
5.680167857144219 ns/iter |
8.168189732141887 ns/iter |
0.70 |
Regex_Caret_Period_Range_Dollar |
2.7827455357142736 ns/iter |
5.6485410714271564 ns/iter |
0.49 |
Regex_Nested_Backtrack |
42.806679687501514 ns/iter |
58.52987500000089 ns/iter |
0.73 |
JSON_Array_Of_Objects_Unique |
414.6517813072986 ns/iter |
515.5798000000686 ns/iter |
0.80 |
JSON_Parse_1 |
9583.955428770772 ns/iter |
11607.44821428596 ns/iter |
0.83 |
JSON_Parse_Real |
15223.502232143257 ns/iter |
18473.67102904597 ns/iter |
0.82 |
JSON_Parse_Decimal |
16200.964285713684 ns/iter |
17803.889311758787 ns/iter |
0.91 |
JSON_Parse_Schema_ISO_Language |
7633602.22222218 ns/iter |
7610902.222222649 ns/iter |
1.00 |
JSON_Fast_Hash_Helm_Chart_Lock |
50.671200000010685 ns/iter |
70.41036607142408 ns/iter |
0.72 |
JSON_Equality_Helm_Chart_Lock |
255.01321428570074 ns/iter |
312.60468750003514 ns/iter |
0.82 |
JSON_Divisible_By_Decimal |
289.8148531332651 ns/iter |
303.3738567663102 ns/iter |
0.96 |
JSON_String_Equal/10 |
11.26375781250033 ns/iter |
16.920099217055018 ns/iter |
0.67 |
JSON_String_Equal/100 |
13.869439893437994 ns/iter |
16.798853682151705 ns/iter |
0.83 |
JSON_String_Equal_Small_By_Perfect_Hash/10 |
1.530919285030708 ns/iter |
2.5110009352583216 ns/iter |
0.61 |
JSON_String_Equal_Small_By_Runtime_Perfect_Hash/10 |
9.638899510538042 ns/iter |
15.025214665063157 ns/iter |
0.64 |
JSON_String_Fast_Hash/10 |
2.915562719309471 ns/iter |
5.016791071428527 ns/iter |
0.58 |
JSON_String_Fast_Hash/100 |
2.914691784413245 ns/iter |
5.011173000000326 ns/iter |
0.58 |
JSON_String_Key_Hash/10 |
2.927149150478493 ns/iter |
5.7839289999992625 ns/iter |
0.51 |
JSON_String_Key_Hash/100 |
13.731305965484836 ns/iter |
16.7350389504326 ns/iter |
0.82 |
JSON_Object_Defines_Miss_Same_Length |
4.077635221394044 ns/iter |
4.324309149854141 ns/iter |
0.94 |
JSON_Object_Defines_Miss_Too_Small |
3.5867257971666437 ns/iter |
4.296978961166617 ns/iter |
0.83 |
JSON_Object_Defines_Miss_Too_Large |
3.8492857142864114 ns/iter |
4.839793749998274 ns/iter |
0.80 |
Pointer_Object_Traverse |
41.406517956541066 ns/iter |
61.10502678570892 ns/iter |
0.68 |
Pointer_Object_Try_Traverse |
53.14658647446765 ns/iter |
71.14410714285566 ns/iter |
0.75 |
Pointer_Push_Back_Pointer_To_Weak_Pointer |
184.66359272302267 ns/iter |
165.50857142857262 ns/iter |
1.12 |
Pointer_Walker_Schema_ISO_Language |
12902472.00000067 ns/iter |
12333135.714283928 ns/iter |
1.05 |
Pointer_Maybe_Tracked_Deeply_Nested/0 |
2382795.1807227265 ns/iter |
2283674.621211999 ns/iter |
1.04 |
Pointer_Maybe_Tracked_Deeply_Nested/1 |
4406499.374999839 ns/iter |
3791164.245810083 ns/iter |
1.16 |
Pointer_Position_Tracker_Get_Deeply_Nested |
538.9665331906822 ns/iter |
671.2837181770008 ns/iter |
0.80 |
URITemplateRouter_Create |
40315.17613603621 ns/iter |
43414.74999999662 ns/iter |
0.93 |
URITemplateRouter_Match |
246.49912427464486 ns/iter |
238.32827697231284 ns/iter |
1.03 |
URITemplateRouter_Match_BasePath |
269.9245325926454 ns/iter |
274.0080413389215 ns/iter |
0.99 |
URITemplateRouterView_Restore |
24558.35537550405 ns/iter |
32968.05803571041 ns/iter |
0.74 |
URITemplateRouterView_Match |
159.22397321429366 ns/iter |
184.3962753925438 ns/iter |
0.86 |
URITemplateRouterView_Match_BasePath |
172.31346466386603 ns/iter |
208.81019826740183 ns/iter |
0.83 |
URITemplateRouterView_Arguments |
417.31067904408565 ns/iter |
519.9370535714414 ns/iter |
0.80 |
JSONL_Parse_Large |
28702474.999998152 ns/iter |
35947726.31578579 ns/iter |
0.80 |
JSONL_Parse_Large_GZIP |
28260188.000003837 ns/iter |
35531604.99999421 ns/iter |
0.80 |
HTML_Build_Table_100000 |
94764557.14285032 ns/iter |
92168128.57143201 ns/iter |
1.03 |
HTML_Render_Table_100000 |
12161615.624997068 ns/iter |
7685578.888890632 ns/iter |
1.58 |
GZIP_Compress_ISO_Language_Set_3_Locations |
40483988.235283665 ns/iter |
41013641.176465064 ns/iter |
0.99 |
GZIP_Decompress_ISO_Language_Set_3_Locations |
13149614.000003567 ns/iter |
10780146.87499973 ns/iter |
1.22 |
GZIP_Compress_ISO_Language_Set_3_Schema |
2290301.003344467 ns/iter |
2299320.4013376674 ns/iter |
1.00 |
GZIP_Decompress_ISO_Language_Set_3_Schema |
740201.0714287143 ns/iter |
683295.7142857967 ns/iter |
1.08 |
This comment was automatically generated by workflow using github-action-benchmark.
There was a problem hiding this comment.
2 issues found across 4 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/core/uritemplate/uritemplate_router.cc">
<violation number="1" location="src/core/uritemplate/uritemplate_router.cc:494">
P2: Templates consisting only of slashes (e.g. `"////"`) will leave `current == nullptr` after the parsing loop, causing both this trailing-slash block and the final registration block to be skipped. The `add()` call silently does nothing—no route is registered and no error is raised. Consider normalizing slash-only templates to the existing `"/"` root handling or explicitly rejecting them to avoid surprising no-op registrations.</violation>
</file>
<file name="src/core/uritemplate/uritemplate_router_view.cc">
<violation number="1" location="src/core/uritemplate/uritemplate_router_view.cc:505">
P2: This introduces a behavioral regression by rejecting non-leading-slash paths that were previously matchable. Keep optional leading-slash handling unless the API contract was intentionally tightened.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| if (path.front() != '/') { | ||
| return finalize_match(otherwise_context, 0, 0); | ||
| } | ||
|
|
||
| // Walk the trie, matching each path segment | ||
| std::uint32_t current_node = 0; | ||
| const char *position = path.data(); | ||
| const char *const path_end = position + path.size(); | ||
| const char *position = path.data() + 1; | ||
| const char *const path_end = path.data() + path.size(); |
There was a problem hiding this comment.
P2: This introduces a behavioral regression by rejecting non-leading-slash paths that were previously matchable. Keep optional leading-slash handling unless the API contract was intentionally tightened.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At src/core/uritemplate/uritemplate_router_view.cc, line 505:
<comment>This introduces a behavioral regression by rejecting non-leading-slash paths that were previously matchable. Keep optional leading-slash handling unless the API contract was intentionally tightened.</comment>
<file context>
@@ -497,102 +497,46 @@ auto URITemplateRouterView::match(
- }
- return finalize_match(otherwise_context, nodes[match].identifier,
- nodes[match].context);
+ if (path.front() != '/') {
+ return finalize_match(otherwise_context, 0, 0);
}
</file context>
| if (path.front() != '/') { | |
| return finalize_match(otherwise_context, 0, 0); | |
| } | |
| // Walk the trie, matching each path segment | |
| std::uint32_t current_node = 0; | |
| const char *position = path.data(); | |
| const char *const path_end = position + path.size(); | |
| const char *position = path.data() + 1; | |
| const char *const path_end = path.data() + path.size(); | |
| const char *position = path.data(); | |
| const char *const path_end = path.data() + path.size(); | |
| if (position < path_end && *position == '/') { | |
| ++position; | |
| } | |
| std::uint32_t current_node = 0; |
There was a problem hiding this comment.
Benchmark (linux/gcc)
Details
| Benchmark suite | Current: fe58667 | Previous: ec3ab52 | Ratio |
|---|---|---|---|
GZIP_Compress_ISO_Language_Set_3_Locations |
40978874.529407546 ns/iter |
40246850.99999956 ns/iter |
1.02 |
GZIP_Decompress_ISO_Language_Set_3_Locations |
4545778.168831434 ns/iter |
4469827.700636936 ns/iter |
1.02 |
GZIP_Compress_ISO_Language_Set_3_Schema |
2298935.9703945853 ns/iter |
2287643.9444444836 ns/iter |
1.00 |
GZIP_Decompress_ISO_Language_Set_3_Schema |
325861.3465804065 ns/iter |
290978.5305105796 ns/iter |
1.12 |
HTML_Build_Table_100000 |
72220575.4000015 ns/iter |
70553887.40000126 ns/iter |
1.02 |
HTML_Render_Table_100000 |
2093078.8411212412 ns/iter |
1980060.355113525 ns/iter |
1.06 |
JSONL_Parse_Large |
14784540.39583473 ns/iter |
14514723.000000358 ns/iter |
1.02 |
JSONL_Parse_Large_GZIP |
16090292.930230556 ns/iter |
15828424.545454502 ns/iter |
1.02 |
URITemplateRouter_Create |
29632.323889382635 ns/iter |
30373.505374945646 ns/iter |
0.98 |
URITemplateRouter_Match |
158.8795923901786 ns/iter |
164.2702134483191 ns/iter |
0.97 |
URITemplateRouter_Match_BasePath |
191.48694657732196 ns/iter |
186.3998845964014 ns/iter |
1.03 |
URITemplateRouterView_Restore |
8809.67715137081 ns/iter |
8330.095001784768 ns/iter |
1.06 |
URITemplateRouterView_Match |
124.56188710853715 ns/iter |
136.35611286556787 ns/iter |
0.91 |
URITemplateRouterView_Match_BasePath |
143.68711894200177 ns/iter |
161.28537396352758 ns/iter |
0.89 |
URITemplateRouterView_Arguments |
450.3365378925255 ns/iter |
459.94505475722065 ns/iter |
0.98 |
Pointer_Object_Traverse |
34.22177292537214 ns/iter |
33.69345384623382 ns/iter |
1.02 |
Pointer_Object_Try_Traverse |
22.254433462974525 ns/iter |
22.129552990360715 ns/iter |
1.01 |
Pointer_Push_Back_Pointer_To_Weak_Pointer |
151.43738805572866 ns/iter |
165.71726425943783 ns/iter |
0.91 |
Pointer_Walker_Schema_ISO_Language |
3516966.05527659 ns/iter |
3505436.3283582767 ns/iter |
1.00 |
Pointer_Maybe_Tracked_Deeply_Nested/0 |
1869393.4545454762 ns/iter |
1815058.758530138 ns/iter |
1.03 |
Pointer_Maybe_Tracked_Deeply_Nested/1 |
1868548.1443852305 ns/iter |
1825935.0779221205 ns/iter |
1.02 |
Pointer_Position_Tracker_Get_Deeply_Nested |
547.8528765068098 ns/iter |
586.6141219893663 ns/iter |
0.93 |
JSON_Array_Of_Objects_Unique |
428.0450220395496 ns/iter |
400.76779037386865 ns/iter |
1.07 |
JSON_Parse_1 |
9685.083944275877 ns/iter |
9531.357068416528 ns/iter |
1.02 |
JSON_Parse_Real |
13146.649595483763 ns/iter |
13280.779165092867 ns/iter |
0.99 |
JSON_Parse_Decimal |
16960.177144520345 ns/iter |
17189.772510918243 ns/iter |
0.99 |
JSON_Parse_Schema_ISO_Language |
5650549.000000037 ns/iter |
5797468.688524811 ns/iter |
0.97 |
JSON_Fast_Hash_Helm_Chart_Lock |
61.319224807579666 ns/iter |
53.13013618205252 ns/iter |
1.15 |
JSON_Equality_Helm_Chart_Lock |
168.62962920141896 ns/iter |
183.89519302402385 ns/iter |
0.92 |
JSON_Divisible_By_Decimal |
229.4377315853291 ns/iter |
228.16325305900105 ns/iter |
1.01 |
JSON_String_Equal/10 |
6.113855980974136 ns/iter |
6.0304009538638175 ns/iter |
1.01 |
JSON_String_Equal/100 |
6.847805779373822 ns/iter |
6.786013520193552 ns/iter |
1.01 |
JSON_String_Equal_Small_By_Perfect_Hash/10 |
0.7145542004214187 ns/iter |
0.7153038266415845 ns/iter |
1.00 |
JSON_String_Equal_Small_By_Runtime_Perfect_Hash/10 |
21.937511118960394 ns/iter |
21.936884587443792 ns/iter |
1.00 |
JSON_String_Fast_Hash/10 |
1.7581439500227796 ns/iter |
1.05550368558879 ns/iter |
1.67 |
JSON_String_Fast_Hash/100 |
1.7599247939571605 ns/iter |
1.055418255797365 ns/iter |
1.67 |
JSON_String_Key_Hash/10 |
1.0852052890673884 ns/iter |
1.759972436258043 ns/iter |
0.62 |
JSON_String_Key_Hash/100 |
15.027115821109158 ns/iter |
14.759185388944937 ns/iter |
1.02 |
JSON_Object_Defines_Miss_Same_Length |
3.8683673544801507 ns/iter |
3.867522214179814 ns/iter |
1.00 |
JSON_Object_Defines_Miss_Too_Small |
3.521837861039072 ns/iter |
4.221635906068492 ns/iter |
0.83 |
JSON_Object_Defines_Miss_Too_Large |
4.21980136992231 ns/iter |
3.5158405047285846 ns/iter |
1.20 |
Regex_Lower_S_Or_Upper_S_Asterisk |
0.7034950943446739 ns/iter |
1.0554518104611355 ns/iter |
0.67 |
Regex_Caret_Lower_S_Or_Upper_S_Asterisk_Dollar |
0.7038226686346973 ns/iter |
1.055285192614705 ns/iter |
0.67 |
Regex_Period_Asterisk |
1.0700053981630546 ns/iter |
0.7040351512679569 ns/iter |
1.52 |
Regex_Group_Period_Asterisk_Group |
1.055114891206321 ns/iter |
0.7038081104183351 ns/iter |
1.50 |
Regex_Period_Plus |
0.7031149443758484 ns/iter |
1.0551777434566731 ns/iter |
0.67 |
Regex_Period |
0.7036028877253467 ns/iter |
1.0547646148031877 ns/iter |
0.67 |
Regex_Caret_Period_Plus_Dollar |
1.055940190639057 ns/iter |
0.7039143857172082 ns/iter |
1.50 |
Regex_Caret_Group_Period_Plus_Group_Dollar |
1.0549237365434883 ns/iter |
0.7039966788338103 ns/iter |
1.50 |
Regex_Caret_Period_Asterisk_Dollar |
0.704063867873698 ns/iter |
1.056056810604562 ns/iter |
0.67 |
Regex_Caret_Group_Period_Asterisk_Group_Dollar |
0.705200095901354 ns/iter |
1.0549441861634414 ns/iter |
0.67 |
Regex_Caret_X_Hyphen |
3.5163730389181826 ns/iter |
4.221110498975404 ns/iter |
0.83 |
Regex_Period_Md_Dollar |
32.64964685247311 ns/iter |
33.897866710576984 ns/iter |
0.96 |
Regex_Caret_Slash_Period_Asterisk |
4.570761948170884 ns/iter |
3.872040830043942 ns/iter |
1.18 |
Regex_Caret_Period_Range_Dollar |
0.8393593346442372 ns/iter |
1.0581146405032162 ns/iter |
0.79 |
Regex_Nested_Backtrack |
42.91636745864303 ns/iter |
43.906220248947314 ns/iter |
0.98 |
This comment was automatically generated by workflow using github-action-benchmark.
Signed-off-by: Juan Cruz Viotti jv@jviotti.com