domain_name 0.6.20260921 → 0.7.20261007

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0a0b71ccec77c247036b76c91780e64f983cea260cdf0584e72ebe2347c3ec9d
4
- data.tar.gz: 8e1a83de91eb9fc6dd5dd9b413adc76fba858cff20612d126f697de6c72501e7
3
+ metadata.gz: 476a417bd69f97cbcbc78fd5c5b558b64be4dccebaf4faa2f423cbda38f16f2a
4
+ data.tar.gz: d85b95635ab78654fabfbfeecf5e1177ac9dca1675cf6eb373da497525f9371f
5
5
  SHA512:
6
- metadata.gz: c68b7731ff6ebcdb3ec40ad7a608b57f4ed5190e2aff81305374348d44b7c6c3e66924fc85fcba0787483178f0d5640f31f1319c9393b92c7e9fc77b412b335f
7
- data.tar.gz: 2b0b189d98a2dc22be7ed33d8a1826bdf75ba485262a37f1dc12cb3009644b348ee751ce04ef581b797019ad5990c27c336e2f795fc29b494a7c3f7c815ddd03
6
+ metadata.gz: 352e4f73563ddc78ca350026b87c4b785e7bc84747e076f48c15f8521936cb180778849f04c9179183352c9980078b8644ee3214f809ac97f655c4a24d7f161b
7
+ data.tar.gz: 5c0f30985880e573684bf2ac7357c3696654cd2538d0bd988b419383d1343c906fb3389cb171e7c8ef66a867bcc001d6beac4c166292c977903ae4276e339f66
@@ -11,9 +11,7 @@
11
11
  schedule: ["after 9am on friday", "before 6pm on friday"],
12
12
  rebaseWhen: "behind-base-branch",
13
13
  lockFileMaintenance: {
14
- enabled: true,
15
- labels: ["dependencies"],
16
- schedule: ["after 9am on friday", "before 6pm on friday"],
14
+ enabled: false,
17
15
  },
18
16
  vulnerabilityAlerts: {
19
17
  enabled: true,
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.7.20261007](https://github.com/knu/ruby-domain_name/tree/v0.7.20261007) (2026-10-13)
4
+ [Full Changelog](https://github.com/knu/ruby-domain_name/compare/v0.6.20260921...v0.7.20261007)
5
+
6
+ - Update the eTLD database to 2026-10-07 07:28:30 UTC
7
+ - Reject IDN labels longer than 63 characters in `DomainName::Punycode.encode_hostname` and `decode_hostname`, and thus in `DomainName.new`, to avoid quadratic Punycode processing time
8
+ - Classify a rooted IPv4 address such as `127.0.0.1.` as an IP address instead of a domain name
9
+ - Make `DomainName#==` return false and `DomainName#<=>` return nil for objects that are not strings, instead of raising `TypeError`
10
+
11
+ **Merged pull requests:**
12
+
13
+ - Return conventional results for unrelated comparisons [\#35](https://github.com/knu/ruby-domain_name/pull/35) ([OskarEichler](https://github.com/OskarEichler))
14
+ - Classify rooted IPs and bound hostname normalization [\#41](https://github.com/knu/ruby-domain_name/pull/41) ([OskarEichler](https://github.com/OskarEichler))
15
+
3
16
  ## [v0.6.20260921](https://github.com/knu/ruby-domain_name/tree/v0.6.20260921) (2026-09-24)
4
17
  [Full Changelog](https://github.com/knu/ruby-domain_name/compare/v0.6.20260907...v0.6.20260921)
5
18
 
@@ -5,8 +5,8 @@
5
5
  // Please pull this list from, and only from https://publicsuffix.org/list/public_suffix_list.dat,
6
6
  // rather than any other VCS sites. Pulling from any other URL is not guaranteed to be supported.
7
7
 
8
- // VERSION: 2026-09-21_18-50-07_UTC
9
- // COMMIT: 728555a30ef4d40e42a82d5678e5fbad2ad17b26
8
+ // VERSION: 2026-10-07_07-28-19_UTC
9
+ // COMMIT: 3929462652695bad04f0a27afb600974014a3c8b
10
10
 
11
11
  // Instructions on pulling and using this list can be found at https://publicsuffix.org/list/.
12
12
 
@@ -6812,7 +6812,7 @@ org.zw
6812
6812
 
6813
6813
  // newGTLDs
6814
6814
 
6815
- // List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2026-07-24T16:40:16Z
6815
+ // List of new gTLDs imported from https://www.icann.org/resources/registries/gtlds/v2/gtlds.json on 2026-10-01T20:07:38Z
6816
6816
  // This list is auto-generated, don't edit it manually.
6817
6817
  // aaa : American Automobile Association, Inc.
6818
6818
  // https://www.iana.org/domains/root/db/aaa.html
@@ -7630,7 +7630,7 @@ coffee
7630
7630
  // https://www.iana.org/domains/root/db/college.html
7631
7631
  college
7632
7632
 
7633
- // cologne : dotKoeln GmbH
7633
+ // cologne : domainworx Service & Management GmbH
7634
7634
  // https://www.iana.org/domains/root/db/cologne.html
7635
7635
  cologne
7636
7636
 
@@ -8798,10 +8798,6 @@ jprs
8798
8798
  // https://www.iana.org/domains/root/db/juegos.html
8799
8799
  juegos
8800
8800
 
8801
- // juniper : JUNIPER NETWORKS, INC.
8802
- // https://www.iana.org/domains/root/db/juniper.html
8803
- juniper
8804
-
8805
8801
  // kaufen : Dog Beach, LLC
8806
8802
  // https://www.iana.org/domains/root/db/kaufen.html
8807
8803
  kaufen
@@ -8846,7 +8842,7 @@ kitchen
8846
8842
  // https://www.iana.org/domains/root/db/kiwi.html
8847
8843
  kiwi
8848
8844
 
8849
- // koeln : dotKoeln GmbH
8845
+ // koeln : domainworx Service & Management GmbH
8850
8846
  // https://www.iana.org/domains/root/db/koeln.html
8851
8847
  koeln
8852
8848
 
@@ -11421,9 +11417,10 @@ cloudfront.net
11421
11417
 
11422
11418
  // Amazon Cognito
11423
11419
  // Submitted by AWS Security <psl-maintainers@amazon.com>
11424
- // Reference: d7d4a954-976e-403e-a010-de9ed0cfbbd1
11420
+ // Reference: dd7b1be3-c336-4750-8e69-85d381b572dd
11425
11421
  auth.af-south-1.amazoncognito.com
11426
11422
  auth.ap-east-1.amazoncognito.com
11423
+ auth.ap-east-2.amazoncognito.com
11427
11424
  auth.ap-northeast-1.amazoncognito.com
11428
11425
  auth.ap-northeast-2.amazoncognito.com
11429
11426
  auth.ap-northeast-3.amazoncognito.com
@@ -11434,6 +11431,7 @@ auth.ap-southeast-2.amazoncognito.com
11434
11431
  auth.ap-southeast-3.amazoncognito.com
11435
11432
  auth.ap-southeast-4.amazoncognito.com
11436
11433
  auth.ap-southeast-5.amazoncognito.com
11434
+ auth.ap-southeast-6.amazoncognito.com
11437
11435
  auth.ap-southeast-7.amazoncognito.com
11438
11436
  auth.ca-central-1.amazoncognito.com
11439
11437
  auth.ca-west-1.amazoncognito.com
@@ -11573,6 +11571,30 @@ emrappui-prod.us-west-2.amazonaws.com
11573
11571
  emrnotebooks-prod.us-west-2.amazonaws.com
11574
11572
  emrstudio-prod.us-west-2.amazonaws.com
11575
11573
 
11574
+ // Amazon Lightsail
11575
+ // Submitted by AWS Security <psl-maintainers@amazon.com>
11576
+ // Reference: _BNEF4RCADXL7ELNLFZHYJMSMW4
11577
+ amazonlightsail.com
11578
+ *.ap-east-1.cs.amazonlightsail.com
11579
+ *.ap-northeast-1.cs.amazonlightsail.com
11580
+ *.ap-northeast-2.cs.amazonlightsail.com
11581
+ *.ap-south-1.cs.amazonlightsail.com
11582
+ *.ap-southeast-1.cs.amazonlightsail.com
11583
+ *.ap-southeast-2.cs.amazonlightsail.com
11584
+ *.ap-southeast-3.cs.amazonlightsail.com
11585
+ *.ap-southeast-5.cs.amazonlightsail.com
11586
+ *.ca-central-1.cs.amazonlightsail.com
11587
+ *.eu-central-1.cs.amazonlightsail.com
11588
+ *.eu-north-1.cs.amazonlightsail.com
11589
+ *.eu-south-2.cs.amazonlightsail.com
11590
+ *.eu-west-1.cs.amazonlightsail.com
11591
+ *.eu-west-2.cs.amazonlightsail.com
11592
+ *.eu-west-3.cs.amazonlightsail.com
11593
+ *.sa-east-1.cs.amazonlightsail.com
11594
+ *.us-east-1.cs.amazonlightsail.com
11595
+ *.us-east-2.cs.amazonlightsail.com
11596
+ *.us-west-2.cs.amazonlightsail.com
11597
+
11576
11598
  // Amazon Managed Workflows for Apache Airflow
11577
11599
  // Submitted by AWS Security <psl-maintainers@amazon.com>
11578
11600
  // Reference: bfd043cc-2816-451d-894e-612c6b61a438
@@ -12194,7 +12216,7 @@ awsapps.com
12194
12216
 
12195
12217
  // AWS Elastic Beanstalk
12196
12218
  // Submitted by AWS Security <psl-maintainers@amazon.com>
12197
- // Reference: e4e02a54-eaf9-4fe7-b662-39ccbc011a04
12219
+ // Reference: _CCBN322SBHBCSUGB7BBDVTREDI
12198
12220
  cn-north-1.eb.amazonaws.com.cn
12199
12221
  cn-northwest-1.eb.amazonaws.com.cn
12200
12222
  elasticbeanstalk.com
@@ -12204,13 +12226,18 @@ ap-northeast-1.elasticbeanstalk.com
12204
12226
  ap-northeast-2.elasticbeanstalk.com
12205
12227
  ap-northeast-3.elasticbeanstalk.com
12206
12228
  ap-south-1.elasticbeanstalk.com
12229
+ ap-south-2.elasticbeanstalk.com
12207
12230
  ap-southeast-1.elasticbeanstalk.com
12208
12231
  ap-southeast-2.elasticbeanstalk.com
12209
12232
  ap-southeast-3.elasticbeanstalk.com
12233
+ ap-southeast-4.elasticbeanstalk.com
12210
12234
  ap-southeast-5.elasticbeanstalk.com
12235
+ ap-southeast-6.elasticbeanstalk.com
12211
12236
  ap-southeast-7.elasticbeanstalk.com
12212
12237
  ca-central-1.elasticbeanstalk.com
12238
+ ca-west-1.elasticbeanstalk.com
12213
12239
  eu-central-1.elasticbeanstalk.com
12240
+ eu-central-2.elasticbeanstalk.com
12214
12241
  eu-north-1.elasticbeanstalk.com
12215
12242
  eu-south-1.elasticbeanstalk.com
12216
12243
  eu-south-2.elasticbeanstalk.com
@@ -12769,8 +12796,10 @@ co.no
12769
12796
  // Combell.com : https://www.combell.com
12770
12797
  // Submitted by Combell Team <support@combell.com>
12771
12798
  webhosting.be
12799
+ site.webhosting.be
12772
12800
  prvw.eu
12773
12801
  hosting-cluster.nl
12802
+ site.hosting-cluster.nl
12774
12803
 
12775
12804
  // Contentful GmbH : https://www.contentful.com
12776
12805
  // Submitted by Contentful Developer Experience Team <prd-ecosystem-dx@contentful.com>
@@ -13785,6 +13814,10 @@ gitlab.io
13785
13814
  gitapp.si
13786
13815
  gitpage.si
13787
13816
 
13817
+ // Glide : https://www.glideapps.com
13818
+ // Submitted by Glide Engineering <engineering@heyglide.com>
13819
+ glideos.app
13820
+
13788
13821
  // Global NOG Alliance : https://nogalliance.org/
13789
13822
  // Submitted by Sander Steffann <sander@nogalliance.org>
13790
13823
  nog.community
@@ -14236,6 +14269,10 @@ home64.de
14236
14269
  ipv64.de
14237
14270
  ipv64.net
14238
14271
 
14272
+ // IQHost / IQ Group : https://iqhost.pl/
14273
+ // Submitted by Adam Buhl <admin@iqhost.pl>
14274
+ iqhs.pl
14275
+
14239
14276
  // ir.md : https://nic.ir.md
14240
14277
  // Submitted by Ali Soizi <info@nic.ir.md>
14241
14278
  ir.md
@@ -15475,33 +15512,8 @@ firewalledreplit.co
15475
15512
  id.firewalledreplit.co
15476
15513
  repl.co
15477
15514
  id.repl.co
15478
- replit.dev
15479
- archer.replit.dev
15480
- bones.replit.dev
15481
- canary.replit.dev
15482
- global.replit.dev
15483
- hacker.replit.dev
15484
- id.replit.dev
15485
- janeway.replit.dev
15486
- kim.replit.dev
15487
- kira.replit.dev
15488
- kirk.replit.dev
15489
- odo.replit.dev
15490
- paris.replit.dev
15491
- picard.replit.dev
15492
- pike.replit.dev
15493
- prerelease.replit.dev
15494
- reed.replit.dev
15495
- riker.replit.dev
15496
- sisko.replit.dev
15497
- spock.replit.dev
15498
- staging.replit.dev
15499
- sulu.replit.dev
15500
- tarpit.replit.dev
15501
- teams.replit.dev
15502
- tucker.replit.dev
15503
- wesley.replit.dev
15504
- worf.replit.dev
15515
+ *.replit.dev
15516
+ *.teams.replit.dev
15505
15517
  repl.run
15506
15518
 
15507
15519
  // Resin.io : https://resin.io
@@ -15509,6 +15521,10 @@ repl.run
15509
15521
  resindevice.io
15510
15522
  devices.resinstaging.io
15511
15523
 
15524
+ // Retool : https://retool.com
15525
+ // Submitted by Andrew Guan <security@retool.com>
15526
+ retool.app
15527
+
15512
15528
  // Rico Developments Limited : https://adimo.co
15513
15529
  // Submitted by Colin Brown <hello@adimo.co>
15514
15530
  adimo.co.uk
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class DomainName
4
- ETLD_DATA_DATE = '2026-09-21T18:50:24Z'
4
+ ETLD_DATA_DATE = '2026-10-07T07:28:30Z'
5
5
 
6
6
  ETLD_DATA = {
7
7
  "ac" => 0,
@@ -6343,7 +6343,6 @@ class DomainName
6343
6343
  "jpmorgan" => 0,
6344
6344
  "jprs" => 0,
6345
6345
  "juegos" => 0,
6346
- "juniper" => 0,
6347
6346
  "kaufen" => 0,
6348
6347
  "kddi" => 0,
6349
6348
  "kerryhotels" => 0,
@@ -7052,6 +7051,7 @@ class DomainName
7052
7051
  "cloudfront.net" => 0,
7053
7052
  "auth.af-south-1.amazoncognito.com" => 0,
7054
7053
  "auth.ap-east-1.amazoncognito.com" => 0,
7054
+ "auth.ap-east-2.amazoncognito.com" => 0,
7055
7055
  "auth.ap-northeast-1.amazoncognito.com" => 0,
7056
7056
  "auth.ap-northeast-2.amazoncognito.com" => 0,
7057
7057
  "auth.ap-northeast-3.amazoncognito.com" => 0,
@@ -7062,6 +7062,7 @@ class DomainName
7062
7062
  "auth.ap-southeast-3.amazoncognito.com" => 0,
7063
7063
  "auth.ap-southeast-4.amazoncognito.com" => 0,
7064
7064
  "auth.ap-southeast-5.amazoncognito.com" => 0,
7065
+ "auth.ap-southeast-6.amazoncognito.com" => 0,
7065
7066
  "auth.ap-southeast-7.amazoncognito.com" => 0,
7066
7067
  "auth.ca-central-1.amazoncognito.com" => 0,
7067
7068
  "auth.ca-west-1.amazoncognito.com" => 0,
@@ -7192,6 +7193,26 @@ class DomainName
7192
7193
  "emrappui-prod.us-west-2.amazonaws.com" => 0,
7193
7194
  "emrnotebooks-prod.us-west-2.amazonaws.com" => 0,
7194
7195
  "emrstudio-prod.us-west-2.amazonaws.com" => 0,
7196
+ "amazonlightsail.com" => 0,
7197
+ "ap-east-1.cs.amazonlightsail.com" => -1,
7198
+ "ap-northeast-1.cs.amazonlightsail.com" => -1,
7199
+ "ap-northeast-2.cs.amazonlightsail.com" => -1,
7200
+ "ap-south-1.cs.amazonlightsail.com" => -1,
7201
+ "ap-southeast-1.cs.amazonlightsail.com" => -1,
7202
+ "ap-southeast-2.cs.amazonlightsail.com" => -1,
7203
+ "ap-southeast-3.cs.amazonlightsail.com" => -1,
7204
+ "ap-southeast-5.cs.amazonlightsail.com" => -1,
7205
+ "ca-central-1.cs.amazonlightsail.com" => -1,
7206
+ "eu-central-1.cs.amazonlightsail.com" => -1,
7207
+ "eu-north-1.cs.amazonlightsail.com" => -1,
7208
+ "eu-south-2.cs.amazonlightsail.com" => -1,
7209
+ "eu-west-1.cs.amazonlightsail.com" => -1,
7210
+ "eu-west-2.cs.amazonlightsail.com" => -1,
7211
+ "eu-west-3.cs.amazonlightsail.com" => -1,
7212
+ "sa-east-1.cs.amazonlightsail.com" => -1,
7213
+ "us-east-1.cs.amazonlightsail.com" => -1,
7214
+ "us-east-2.cs.amazonlightsail.com" => -1,
7215
+ "us-west-2.cs.amazonlightsail.com" => -1,
7195
7216
  "airflow.af-south-1.on.aws" => -1,
7196
7217
  "airflow.ap-east-1.on.aws" => -1,
7197
7218
  "airflow.ap-northeast-1.on.aws" => -1,
@@ -7772,13 +7793,18 @@ class DomainName
7772
7793
  "ap-northeast-2.elasticbeanstalk.com" => 0,
7773
7794
  "ap-northeast-3.elasticbeanstalk.com" => 0,
7774
7795
  "ap-south-1.elasticbeanstalk.com" => 0,
7796
+ "ap-south-2.elasticbeanstalk.com" => 0,
7775
7797
  "ap-southeast-1.elasticbeanstalk.com" => 0,
7776
7798
  "ap-southeast-2.elasticbeanstalk.com" => 0,
7777
7799
  "ap-southeast-3.elasticbeanstalk.com" => 0,
7800
+ "ap-southeast-4.elasticbeanstalk.com" => 0,
7778
7801
  "ap-southeast-5.elasticbeanstalk.com" => 0,
7802
+ "ap-southeast-6.elasticbeanstalk.com" => 0,
7779
7803
  "ap-southeast-7.elasticbeanstalk.com" => 0,
7780
7804
  "ca-central-1.elasticbeanstalk.com" => 0,
7805
+ "ca-west-1.elasticbeanstalk.com" => 0,
7781
7806
  "eu-central-1.elasticbeanstalk.com" => 0,
7807
+ "eu-central-2.elasticbeanstalk.com" => 0,
7782
7808
  "eu-north-1.elasticbeanstalk.com" => 0,
7783
7809
  "eu-south-1.elasticbeanstalk.com" => 0,
7784
7810
  "eu-south-2.elasticbeanstalk.com" => 0,
@@ -8088,8 +8114,10 @@ class DomainName
8088
8114
  "co.no" => 0,
8089
8115
  "devinapps.com" => -1,
8090
8116
  "webhosting.be" => 0,
8117
+ "site.webhosting.be" => 0,
8091
8118
  "prvw.eu" => 0,
8092
8119
  "hosting-cluster.nl" => 0,
8120
+ "site.hosting-cluster.nl" => 0,
8093
8121
  "ctfcloud.net" => 0,
8094
8122
  "convex.app" => 0,
8095
8123
  "convex.cloud" => 0,
@@ -8806,6 +8834,7 @@ class DomainName
8806
8834
  "gitlab.io" => 0,
8807
8835
  "gitapp.si" => 0,
8808
8836
  "gitpage.si" => 0,
8837
+ "glideos.app" => 0,
8809
8838
  "nog.community" => 0,
8810
8839
  "co.ro" => 0,
8811
8840
  "shop.ro" => 0,
@@ -9081,6 +9110,7 @@ class DomainName
9081
9110
  "home64.de" => 0,
9082
9111
  "ipv64.de" => 0,
9083
9112
  "ipv64.net" => 0,
9113
+ "iqhs.pl" => 0,
9084
9114
  "ir.md" => 0,
9085
9115
  "is-a-good.dev" => 0,
9086
9116
  "iservschule.de" => 0,
@@ -9798,36 +9828,12 @@ class DomainName
9798
9828
  "id.firewalledreplit.co" => 0,
9799
9829
  "repl.co" => 0,
9800
9830
  "id.repl.co" => 0,
9801
- "replit.dev" => 0,
9802
- "archer.replit.dev" => 0,
9803
- "bones.replit.dev" => 0,
9804
- "canary.replit.dev" => 0,
9805
- "global.replit.dev" => 0,
9806
- "hacker.replit.dev" => 0,
9807
- "id.replit.dev" => 0,
9808
- "janeway.replit.dev" => 0,
9809
- "kim.replit.dev" => 0,
9810
- "kira.replit.dev" => 0,
9811
- "kirk.replit.dev" => 0,
9812
- "odo.replit.dev" => 0,
9813
- "paris.replit.dev" => 0,
9814
- "picard.replit.dev" => 0,
9815
- "pike.replit.dev" => 0,
9816
- "prerelease.replit.dev" => 0,
9817
- "reed.replit.dev" => 0,
9818
- "riker.replit.dev" => 0,
9819
- "sisko.replit.dev" => 0,
9820
- "spock.replit.dev" => 0,
9821
- "staging.replit.dev" => 0,
9822
- "sulu.replit.dev" => 0,
9823
- "tarpit.replit.dev" => 0,
9824
- "teams.replit.dev" => 0,
9825
- "tucker.replit.dev" => 0,
9826
- "wesley.replit.dev" => 0,
9827
- "worf.replit.dev" => 0,
9831
+ "replit.dev" => -1,
9832
+ "teams.replit.dev" => -1,
9828
9833
  "repl.run" => 0,
9829
9834
  "resindevice.io" => 0,
9830
9835
  "devices.resinstaging.io" => 0,
9836
+ "retool.app" => 0,
9831
9837
  "adimo.co.uk" => 0,
9832
9838
  "itcouldbewor.se" => 0,
9833
9839
  "aus.basketball" => 0,
@@ -92,6 +92,9 @@ class DomainName
92
92
  DOT = '.'
93
93
  PREFIX = 'xn--'
94
94
 
95
+ # The maximum length of a label in a hostname (RFC 1035)
96
+ MAX_LABEL_LENGTH = 63
97
+
95
98
  # Most errors we raise are basically kind of ArgumentError.
96
99
  class ArgumentError < ::ArgumentError; end
97
100
  class BufferOverflowError < ArgumentError; end
@@ -177,13 +180,22 @@ class DomainName
177
180
  output
178
181
  end
179
182
 
180
- # Encode a hostname using IDN/Punycode algorithms
183
+ # Encode a hostname using IDN/Punycode algorithms. Raises
184
+ # ArgumentError if an encoded label would exceed
185
+ # MAX_LABEL_LENGTH.
181
186
  def encode_hostname(hostname)
182
187
  hostname.match(RE_NONBASIC) or return hostname
183
188
 
184
189
  hostname.split(DOT).map { |name|
185
190
  if name.match(RE_NONBASIC)
186
- PREFIX + encode(name)
191
+ # Encoding takes quadratic time, and the encoded label is
192
+ # always longer than the input by at least the prefix
193
+ name.length + PREFIX.length > MAX_LABEL_LENGTH and
194
+ raise ArgumentError, "Label is too long: #{name.length} characters"
195
+ label = PREFIX + encode(name)
196
+ label.length > MAX_LABEL_LENGTH and
197
+ raise ArgumentError, "Encoded label is too long: #{label.length} characters"
198
+ label
187
199
  else
188
200
  name
189
201
  end
@@ -272,9 +284,13 @@ class DomainName
272
284
  output.pack('U*')
273
285
  end
274
286
 
275
- # Decode a hostname using IDN/Punycode algorithms
287
+ # Decode a hostname using IDN/Punycode algorithms. Raises
288
+ # ArgumentError if an encoded label exceeds MAX_LABEL_LENGTH.
276
289
  def decode_hostname(hostname)
277
290
  hostname.gsub(/(\A|#{Regexp.quote(DOT)})#{Regexp.quote(PREFIX)}([^#{Regexp.quote(DOT)}]*)/o) {
291
+ length = PREFIX.length + $2.length
292
+ length > MAX_LABEL_LENGTH and
293
+ raise ArgumentError, "Encoded label is too long: #{length} characters"
278
294
  $1 + decode($2)
279
295
  }
280
296
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class DomainName
4
- VERSION = '0.6.20260921'
4
+ VERSION = '0.7.20261007'
5
5
  end
data/lib/domain_name.rb CHANGED
@@ -82,7 +82,7 @@ class DomainName
82
82
  raise ArgumentError, "domain name must not start with a dot: #{hostname}"
83
83
  end
84
84
  case hostname
85
- when /\A([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\z/
85
+ when /\A([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\.?\z/
86
86
  @ipaddr = IPAddr.new($1)
87
87
  @uri_host = @hostname = @ipaddr.to_s
88
88
  @domain = @tld = nil
@@ -171,12 +171,20 @@ class DomainName
171
171
  end
172
172
 
173
173
  def ==(other)
174
- other = DomainName.new(other) unless DomainName === other
174
+ unless DomainName === other
175
+ other = String.try_convert(other)
176
+ return false unless other
177
+ other = DomainName.new(other)
178
+ end
175
179
  other.hostname == @hostname
176
180
  end
177
181
 
178
182
  def <=>(other)
179
- other = DomainName.new(other) unless DomainName === other
183
+ unless DomainName === other
184
+ other = String.try_convert(other)
185
+ return nil unless other
186
+ other = DomainName.new(other)
187
+ end
180
188
  othername = other.hostname
181
189
  if othername == @hostname
182
190
  0
@@ -96,4 +96,36 @@ class TestDomainName < Test::Unit::TestCase
96
96
  assert_equal cps.pack('U*').unicode_normalize(:nfc), DomainName::Punycode.decode(punycode), title
97
97
  }
98
98
  end
99
+
100
+ test "limit the length of encoded labels in a hostname" do
101
+ longest = 'a' * 55 + "ü"
102
+ encoded = 'xn--' + 'a' * 55 + '-8yf'
103
+ assert_equal 63, encoded.length
104
+ assert_equal "#{encoded}.com", DomainName::Punycode.encode_hostname("#{longest}.com")
105
+ assert_equal "#{longest}.com", DomainName::Punycode.decode_hostname("#{encoded}.com")
106
+
107
+ assert_raises(DomainName::Punycode::ArgumentError) {
108
+ DomainName::Punycode.encode_hostname("a#{longest}.com")
109
+ }
110
+ assert_raises(DomainName::Punycode::ArgumentError) {
111
+ DomainName::Punycode.decode_hostname("xn--a#{encoded[4..-1]}.com")
112
+ }
113
+
114
+ ascii = 'a' * 64
115
+ assert_equal "#{ascii}.com", DomainName::Punycode.encode_hostname("#{ascii}.com")
116
+ assert_equal "#{ascii}.com", DomainName::Punycode.decode_hostname("#{ascii}.com")
117
+ end
118
+
119
+ test "reject long labels before encoding or decoding them" do
120
+ unicode = (0x4E00...0x4E00 + 10_000).to_a.pack('U*')
121
+ assert_raises(DomainName::Punycode::ArgumentError) {
122
+ DomainName::Punycode.encode_hostname("#{unicode}.com")
123
+ }
124
+ assert_raise_kind_of(ArgumentError) { DomainName.new("#{unicode}.com") }
125
+
126
+ punycode = 'xn--' + '9' * 10_000
127
+ assert_raises(DomainName::Punycode::ArgumentError) {
128
+ DomainName::Punycode.decode_hostname("#{punycode}.com")
129
+ }
130
+ end
99
131
  end
@@ -184,6 +184,24 @@ class TestDomainName < Test::Unit::TestCase
184
184
  }
185
185
  end
186
186
 
187
+ test "compare with objects that are not strings" do
188
+ dn = DomainName('foo.com')
189
+ [nil, 1, :'foo.com', Object.new].each { |other|
190
+ assert_equal(false, dn == other)
191
+ assert_equal(true, dn != other)
192
+ assert_equal(nil, dn <=> other)
193
+ assert_equal(nil, dn < other)
194
+ assert_equal(nil, dn >= other)
195
+ }
196
+
197
+ str = Object.new
198
+ def str.to_str
199
+ 'www.foo.com'
200
+ end
201
+ assert_equal(false, dn == str)
202
+ assert_equal(1, dn <=> str)
203
+ end
204
+
187
205
  test "check cookie domain correctly" do
188
206
  {
189
207
  'com' => [
@@ -272,6 +290,13 @@ class TestDomainName < Test::Unit::TestCase
272
290
  assert_equal(false, dn.cookie_domain?('168.10.20'))
273
291
  assert_equal(false, dn.cookie_domain?('20'))
274
292
  assert_equal(nil, dn.superdomain)
293
+
294
+ dn = DomainName("#{a}.")
295
+ assert_equal(a, dn.hostname)
296
+ assert_equal(true, dn.ipaddr?)
297
+ assert_equal(nil, dn.domain)
298
+ assert_equal(true, dn.cookie_domain?(a))
299
+ assert_equal(false, dn.cookie_domain?('10.20'))
275
300
  end
276
301
 
277
302
  test "parse IPv6 addresseses" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: domain_name
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.20260921
4
+ version: 0.7.20261007
5
5
  platform: ruby
6
6
  authors:
7
7
  - Akinori MUSHA