Skip to content

Inconsistent handling of IDN vs non-IDN hosts in URL() #1560

@nreilly

Description

@nreilly

Describe the bug
URLs created with long hostnames has inconsistent behaviour between IDN and non-IDN hostnames. For hostnames longer than 63 characters, non-IDN hostnames work fine, but IDNs result in URL returning Nil.

To Reproduce
Here's some sample code to show the issue:

import Foundation

func letters(_ count: Int) -> String {
  return String(repeating: "a", count: count)
}

func extraLetters(_ count: Int) -> String {
  let face = "🧐"  //  = xn--9u9h
  switch count {
  case 8: return face
  case 0...12: return letters(count)
  case 13...36: return letters(count - 10) + face
  default: return letters(count - 11) + face
  }
}

func host(_ host: String) -> String {
  return URL(string: "https://\(host)/")?.host(percentEncoded: false)
    ?? "<No URL>"
}

func printComparison(_ count: Int) {
  let prefix = String(format: "%03d: ", count)
  print("\(prefix)\(host(letters(count)))")
  print("\(prefix)\(host(extraLetters(count)))")
}

for comparison in [8, 30, 63, 64, 128, 256] {
  printComparison(comparison)
}

And here's the output:

008: aaaaaaaa
008: xn--9u9h
030: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
030: xn--aaaaaaaaaaaaaaaaaaaa-uv13t
063: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
063: xn--aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-r3017c
064: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
064: <No URL>
128: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
128: <No URL>
256: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
256: <No URL>

Expected behavior
Consistency between IDN and non-IDN handling. I realise each section in a hostname is meant to be up to 63 octets (characters) (RFC1123), so I can understand that URL returns nil for IDN names, but I don't know why it then works for non-IDN.

Configuration (please complete the following information):

  • Version 26.0 (17A321) / 26.0.1 (25A362) / swift-driver version: 1.127.14.1 Apple Swift version 6.2 (swiftlang-6.2.0.19.9 clang-1700.3.19.1)
  • Swift 6.2-Nightly via SwiftFiddle

Additional context
Also posted on the swift forums

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions