@@ -266,26 +266,29 @@ pub const RoutingTrie = struct {
266
266
267
267
var duped = try std .ArrayListUnmanaged ([]const u8 ).initCapacity (allocator , 0 );
268
268
defer duped .deinit (allocator );
269
+ errdefer for (duped .items ) | d | allocator .free (d );
269
270
270
271
if (query_pos ) | pos | {
271
272
if (path .len > pos + 1 ) {
272
273
var query_iter = std .mem .tokenizeScalar (u8 , path [pos + 1 .. ], '&' );
273
274
274
275
while (query_iter .next ()) | chunk | {
275
- const field_idx = std .mem .indexOfScalar (u8 , chunk , '=' ) orelse break ;
276
- if (chunk .len < field_idx + 1 ) break ;
276
+ const field_idx = std .mem .indexOfScalar (u8 , chunk , '=' ) orelse return error . QueryMissingValue ;
277
+ if (chunk .len < field_idx + 2 ) return error . QueryMissingValue ;
277
278
278
279
const key = chunk [0.. field_idx ];
279
280
const value = chunk [(field_idx + 1 ).. ];
280
281
281
- assert (std .mem .indexOfScalar (u8 , key , '=' ) == null );
282
- assert (std .mem .indexOfScalar (u8 , value , '=' ) == null );
282
+ if (std .mem .indexOfScalar (u8 , key , '=' ) != null ) return error . MalformedQueryKey ;
283
+ if (std .mem .indexOfScalar (u8 , value , '=' ) != null ) return error . MalformedQueryValue ;
283
284
284
285
const decoded_key = try decode_alloc (allocator , key );
285
286
try duped .append (allocator , decoded_key );
286
287
287
288
const decoded_value = try decode_alloc (allocator , value );
288
289
try duped .append (allocator , decoded_value );
290
+
291
+ // Later values will clobber earlier ones.
289
292
try queries .put (decoded_key , decoded_value );
290
293
}
291
294
}
@@ -519,17 +522,26 @@ test "Routing with Queries" {
519
522
{
520
523
q .clearRetainingCapacity ();
521
524
// Purposefully bad format with incomplete key/value pair.
522
- const captured = (try s .get_bundle (
525
+ const captured = s .get_bundle (testing .allocator , "/item/100/price/283.21?help" , captures [0.. ], & q );
526
+ try testing .expectError (error .QueryMissingValue , captured );
527
+ }
528
+
529
+ {
530
+ q .clearRetainingCapacity ();
531
+ // Purposefully bad format with incomplete key/value pair.
532
+ const captured = s .get_bundle (testing .allocator , "/item/100/price/283.21?help=" , captures [0.. ], & q );
533
+ try testing .expectError (error .QueryMissingValue , captured );
534
+ }
535
+
536
+ {
537
+ q .clearRetainingCapacity ();
538
+ // Purposefully bad format with invalid charactes.
539
+ const captured = s .get_bundle (
523
540
testing .allocator ,
524
- "/item/100 /price/283.21?help " ,
541
+ "/item/999 /price/100.221?page_count=pages=2020&abc=200 " ,
525
542
captures [0.. ],
526
543
& q ,
527
- )).? ;
528
- defer testing .allocator .free (captured .duped );
529
- defer for (captured .duped ) | dupe | testing .allocator .free (dupe );
530
- try testing .expectEqual (Route .init ("/item/%i/price/%f" ), captured .route );
531
- try testing .expectEqual (100 , captured .captures [0 ].signed );
532
- try testing .expectEqual (283.21 , captured .captures [1 ].float );
533
- try testing .expectEqual (0 , q .count ());
544
+ );
545
+ try testing .expectError (error .MalformedQueryValue , captured );
534
546
}
535
547
}
0 commit comments