def test_hostname_labels_valid_idn(self, label): # type: (Text) -> None """ hostname_labels() generates IDN host name labels. """ try: check_label(label) idna_encode(label) except UnicodeError: # pragma: no cover raise AssertionError("Invalid IDN label: {!r}".format(label))
def test_hostname_labels_valid_ascii(self, label): # type: (Text) -> None """ hostname_labels() generates a ASCII host name labels. """ try: check_label(label) label.encode("ascii") except UnicodeError: # pragma: no cover raise AssertionError("Invalid ASCII label: {!r}".format(label))
def test_hostnames_ascii(self, hostname): # type: (Text) -> None """ hostnames() generates a ASCII host names. """ try: for label in hostname.split(u"."): check_label(label) hostname.encode("ascii") except UnicodeError: # pragma: no cover raise AssertionError( "Invalid ASCII host name: {!r}".format(hostname))
def test_hostnames_idn(self, hostname): # type: (Text) -> None """ hostnames() generates a IDN host names. """ try: for label in hostname.split(u"."): check_label(label) idna_encode(hostname) except UnicodeError: # pragma: no cover raise AssertionError( "Invalid IDN host name: {!r}".format(hostname))
def hostname_labels(draw, allow_idn=True): # pragma: no cover # type: (DrawCallable, bool) -> Text """ A strategy which generates host name labels. @param allow_idn: Whether to allow non-ASCII characters as allowed by internationalized domain names (IDNs). """ if allow_idn: label = cast(Text, draw(idna_text(min_size=1, max_size=63))) try: label.encode("ascii") except UnicodeEncodeError: # If the label doesn't encode to ASCII, then we need to check the # length of the label after encoding to punycode and adding the # xn-- prefix. while len(label.encode("punycode")) > 63 - len("xn--"): # Rather than bombing out, just trim from the end until it is # short enough, so hypothesis doesn't have to generate new # data. label = label[:-1] else: label = cast( Text, draw( text( min_size=1, max_size=63, alphabet=unicode(ascii_letters + digits + "-"), ) ), ) # Filter invalid labels. # It would be better not to generate bogus labels in the first place... but # that's not trivial. try: check_label(label) except UnicodeError: assume(False) return label
def hostname_labels(draw, allow_idn=True): # pragma: no cover # type: (DrawCallable, bool) -> Text """ A strategy which generates host name labels. @param allow_idn: Whether to allow non-ASCII characters as allowed by internationalized domain names (IDNs). """ if allow_idn: label = draw(idna_text(min_size=1, max_size=63)) try: label.encode("ascii") except UnicodeEncodeError: # If the label doesn't encode to ASCII, then we need to check the # length of the label after encoding to punycode and adding the # xn-- prefix. while len(label.encode("punycode")) > 63 - len("xn--"): # Rather than bombing out, just trim from the end until it is # short enough, so hypothesis doesn't have to generate new # data. label = label[:-1] else: label = draw(text( min_size=1, max_size=63, alphabet=unicode(ascii_letters + digits + u"-") )) # Filter invalid labels. # It would be better not to generate bogus labels in the first place... but # that's not trivial. try: check_label(label) except UnicodeError: assume(False) return label
def test_hostname_labels_long_idn_punycode(self, data): # type: (SearchStrategy) -> None """ hostname_labels() handles case where idna_text() generates text that encoded to punycode ends up as longer than allowed. """ @composite def mock_idna_text(draw, min_size, max_size): # type: (DrawCallable, int, int) -> Text # We want a string that does not exceed max_size, but when # encoded to punycode, does exceed max_size. # So use a unicode character that is larger when encoded, # "รก" being a great example, and use it max_size times, which # will be max_size * 3 in size when encoded. return u"\N{LATIN SMALL LETTER A WITH ACUTE}" * max_size with patch("hyperlink.hypothesis.idna_text", mock_idna_text): label = data.draw(hostname_labels()) try: check_label(label) idna_encode(label) except UnicodeError: # pragma: no cover raise AssertionError( "Invalid IDN label: {!r}".format(label))
def to_string(proto, buf): string = buf.decode("utf-8") for label in string.split("."): idna.check_label(label) return string