1
1
/* TLD library -- TLD, domain name, and sub-domain extraction
2
- * Copyright (c) 2011-2019 Made to Order Software Corp. All Rights Reserved
2
+ * Copyright (c) 2011-2021 Made to Order Software Corp. All Rights Reserved
3
3
*
4
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
5
* copy of this software and associated documentation files (the
327
327
*/
328
328
static int cmp (const char * a , const char * b , int n )
329
329
{
330
- /* if `a == "*"` then it always a match! */
330
+ /* if `a == "*"` then we have a bug in the table
331
331
if(a[0] == '*'
332
332
&& a[1] == '\0')
333
333
{
334
334
return 0;
335
335
}
336
+ */
336
337
337
338
/* n represents the maximum number of characters to check in b */
338
339
while (n > 0 && * a != '\0' )
@@ -395,32 +396,43 @@ static int cmp(const char *a, const char *b, int n)
395
396
*/
396
397
int search (int i , int j , const char * domain , int n )
397
398
{
398
- int p , r ;
399
+ int auto_match = -1 , p , r ;
399
400
const struct tld_description * tld ;
400
401
401
- while (i < j )
402
+ if (i < j )
402
403
{
403
- p = (j - i ) / 2 + i ;
404
- tld = tld_descriptions + p ;
405
- r = cmp (tld -> f_tld , domain , n );
406
- if (r < 0 )
404
+ /* the "*" breaks the binary search, we have to handle it specially */
405
+ tld = tld_descriptions + i ;
406
+ if (tld -> f_tld [0 ] == '*' && tld -> f_tld [1 ] == '\0' )
407
407
{
408
- /* eliminate the first half */
409
- i = p + 1 ;
408
+ auto_match = i ;
409
+ ++ i ;
410
410
}
411
- else if (r > 0 )
412
- {
413
- /* eliminate the second half */
414
- j = p ;
415
- }
416
- else
411
+
412
+ while (i < j )
417
413
{
418
- /* match */
419
- return p ;
414
+ p = (j - i ) / 2 + i ;
415
+ tld = tld_descriptions + p ;
416
+ r = cmp (tld -> f_tld , domain , n );
417
+ if (r < 0 )
418
+ {
419
+ /* eliminate the first half */
420
+ i = p + 1 ;
421
+ }
422
+ else if (r > 0 )
423
+ {
424
+ /* eliminate the second half */
425
+ j = p ;
426
+ }
427
+ else
428
+ {
429
+ /* match */
430
+ return p ;
431
+ }
420
432
}
421
433
}
422
434
423
- return -1 ;
435
+ return auto_match ;
424
436
}
425
437
426
438
@@ -556,7 +568,7 @@ enum tld_result tld(const char *uri, struct tld_info *info)
556
568
{
557
569
const char * end = uri ;
558
570
const char * * level_ptr ;
559
- int level = 0 , start_level , i , r , p ;
571
+ int level = 0 , start_level , i , r , p , offset ;
560
572
enum tld_result result ;
561
573
562
574
/* set defaults in the info structure */
@@ -598,7 +610,7 @@ enum tld_result tld(const char *uri, struct tld_info *info)
598
610
}
599
611
++ end ;
600
612
}
601
- /* if level is not at least 1 then there are no period */
613
+ /* if level is not at least 1 then there are no periods */
602
614
if (level == 0 )
603
615
{
604
616
/* no TLD */
@@ -633,6 +645,7 @@ enum tld_result tld(const char *uri, struct tld_info *info)
633
645
p = r ;
634
646
-- level ;
635
647
}
648
+ offset = (int ) (level_ptr [level ] - uri );
636
649
637
650
/* if there are exceptions we may need to search those now if level is 0 */
638
651
if (level == 0 )
@@ -644,29 +657,39 @@ enum tld_result tld(const char *uri, struct tld_info *info)
644
657
if (r != -1 )
645
658
{
646
659
p = r ;
660
+ offset = 0 ;
647
661
}
648
662
}
649
663
650
664
info -> f_status = tld_descriptions [p ].f_status ;
651
- result = info -> f_status == TLD_STATUS_VALID
652
- ? TLD_RESULT_SUCCESS
653
- : TLD_RESULT_INVALID ;
654
-
655
- /* did we hit an exception? */
656
- if (tld_descriptions [p ].f_status == TLD_STATUS_EXCEPTION )
665
+ switch (info -> f_status )
657
666
{
658
- /* return the actual TLD and not the exception */
667
+ case TLD_STATUS_VALID :
668
+ result = TLD_RESULT_SUCCESS ;
669
+ break ;
670
+
671
+ case TLD_STATUS_EXCEPTION :
672
+ /* return the actual TLD and not the exception
673
+ * i.e. "nacion.ar" is valid and the TLD is just ".ar"
674
+ * even though top level ".ar" is forbidden by default
675
+ */
659
676
p = tld_descriptions [p ].f_exception_apply_to ;
660
677
level = start_level - tld_descriptions [p ].f_exception_level ;
678
+ offset = (int ) (level_ptr [level ] - uri );
661
679
info -> f_status = TLD_STATUS_VALID ;
662
680
result = TLD_RESULT_SUCCESS ;
681
+ break ;
682
+
683
+ default :
684
+ result = TLD_RESULT_INVALID ;
685
+ break ;
686
+
663
687
}
664
688
665
- /* return a valid result */
666
689
info -> f_category = tld_descriptions [p ].f_category ;
667
690
info -> f_country = tld_descriptions [p ].f_country ;
668
691
info -> f_tld = level_ptr [level ];
669
- info -> f_offset = ( int ) ( level_ptr [ level ] - uri ) ;
692
+ info -> f_offset = offset ;
670
693
671
694
free (level_ptr );
672
695
0 commit comments