@@ -426,7 +426,7 @@ static size_t url_match_prefix(const char *url,
426
426
427
427
static int match_urls (const struct url_info * url ,
428
428
const struct url_info * url_prefix ,
429
- int * exactusermatch )
429
+ struct urlmatch_item * match )
430
430
{
431
431
/*
432
432
* url_prefix matches url if the scheme, host and port of url_prefix
@@ -445,8 +445,8 @@ static int match_urls(const struct url_info *url,
445
445
* contained a user name or false if url_prefix did not have a
446
446
* user name. If there is no match *exactusermatch is left untouched.
447
447
*/
448
- int usermatched = 0 ;
449
- int pathmatchlen ;
448
+ char usermatched = 0 ;
449
+ size_t pathmatchlen ;
450
450
451
451
if (!url || !url_prefix || !url -> url || !url_prefix -> url )
452
452
return 0 ;
@@ -483,22 +483,38 @@ static int match_urls(const struct url_info *url,
483
483
url -> url + url -> path_off ,
484
484
url_prefix -> url + url_prefix -> path_off ,
485
485
url_prefix -> url_len - url_prefix -> path_off );
486
+ if (!pathmatchlen )
487
+ return 0 ; /* paths do not match */
486
488
487
- if (pathmatchlen && exactusermatch )
488
- * exactusermatch = usermatched ;
489
- return pathmatchlen ;
489
+ if (match ) {
490
+ match -> hostmatch_len = url_prefix -> host_len ;
491
+ match -> pathmatch_len = pathmatchlen ;
492
+ match -> user_matched = usermatched ;
493
+ }
494
+
495
+ return 1 ;
496
+ }
497
+
498
+ static int cmp_matches (const struct urlmatch_item * a ,
499
+ const struct urlmatch_item * b )
500
+ {
501
+ if (a -> hostmatch_len != b -> hostmatch_len )
502
+ return a -> hostmatch_len < b -> hostmatch_len ? -1 : 1 ;
503
+ if (a -> pathmatch_len != b -> pathmatch_len )
504
+ return a -> pathmatch_len < b -> pathmatch_len ? -1 : 1 ;
505
+ if (a -> user_matched != b -> user_matched )
506
+ return b -> user_matched ? -1 : 1 ;
507
+ return 0 ;
490
508
}
491
509
492
510
int urlmatch_config_entry (const char * var , const char * value , void * cb )
493
511
{
494
512
struct string_list_item * item ;
495
513
struct urlmatch_config * collect = cb ;
496
- struct urlmatch_item * matched ;
514
+ struct urlmatch_item matched = { 0 } ;
497
515
struct url_info * url = & collect -> url ;
498
516
const char * key , * dot ;
499
517
struct strbuf synthkey = STRBUF_INIT ;
500
- size_t matched_len = 0 ;
501
- int user_matched = 0 ;
502
518
int retval ;
503
519
504
520
if (!skip_prefix (var , collect -> section , & key ) || * (key ++ ) != '.' ) {
@@ -516,9 +532,9 @@ int urlmatch_config_entry(const char *var, const char *value, void *cb)
516
532
free (config_url );
517
533
if (!norm_url )
518
534
return 0 ;
519
- matched_len = match_urls (url , & norm_info , & user_matched );
535
+ retval = match_urls (url , & norm_info , & matched );
520
536
free (norm_url );
521
- if (!matched_len )
537
+ if (!retval )
522
538
return 0 ;
523
539
key = dot + 1 ;
524
540
}
@@ -528,24 +544,18 @@ int urlmatch_config_entry(const char *var, const char *value, void *cb)
528
544
529
545
item = string_list_insert (& collect -> vars , key );
530
546
if (!item -> util ) {
531
- matched = xcalloc (1 , sizeof (* matched ));
532
- item -> util = matched ;
547
+ item -> util = xcalloc (1 , sizeof (matched ));
533
548
} else {
534
- matched = item -> util ;
535
- /*
536
- * Is our match shorter? Is our match the same
537
- * length, and without user while the current
538
- * candidate is with user? Then we cannot use it.
539
- */
540
- if (matched_len < matched -> matched_len ||
541
- ((matched_len == matched -> matched_len ) &&
542
- (!user_matched && matched -> user_matched )))
549
+ if (cmp_matches (& matched , item -> util ) < 0 )
550
+ /*
551
+ * Our match is worse than the old one,
552
+ * we cannot use it.
553
+ */
543
554
return 0 ;
544
555
/* Otherwise, replace it with this one. */
545
556
}
546
557
547
- matched -> matched_len = matched_len ;
548
- matched -> user_matched = user_matched ;
558
+ memcpy (item -> util , & matched , sizeof (matched ));
549
559
strbuf_addstr (& synthkey , collect -> section );
550
560
strbuf_addch (& synthkey , '.' );
551
561
strbuf_addstr (& synthkey , key );
0 commit comments