Home | History | Annotate | Line # | Download | only in idna
      1   1.1.1.8  christos #!/bin/sh
      2   1.1.1.8  christos 
      3       1.1  christos # Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      4       1.1  christos #
      5   1.1.1.7  christos # SPDX-License-Identifier: MPL-2.0
      6   1.1.1.7  christos #
      7       1.1  christos # This Source Code Form is subject to the terms of the Mozilla Public
      8   1.1.1.7  christos # License, v. 2.0.  If a copy of the MPL was not distributed with this
      9   1.1.1.6  christos # file, you can obtain one at https://mozilla.org/MPL/2.0/.
     10       1.1  christos #
     11       1.1  christos # See the COPYRIGHT file distributed with this work for additional
     12       1.1  christos # information regarding copyright ownership.
     13       1.1  christos 
     14   1.1.1.9  christos set -e
     15   1.1.1.9  christos 
     16   1.1.1.9  christos . ../conf.sh
     17       1.1  christos 
     18       1.1  christos # Set known locale for the tests
     19       1.1  christos 
     20       1.1  christos if locale -a | grep -qE "^C\\.(UTF-8|utf8)"; then
     21   1.1.1.9  christos   LC_ALL="C.UTF-8"
     22       1.1  christos elif locale -a | grep -qE "^en_US\\.(UTF-8|utf8)"; then
     23   1.1.1.9  christos   LC_ALL="en_US.UTF-8"
     24       1.1  christos fi
     25       1.1  christos export LC_ALL
     26       1.1  christos 
     27       1.1  christos # This set of tests check the behavior of the IDNA options in "dig".
     28       1.1  christos #
     29       1.1  christos # The tests run "dig" against an authoritative server configured with a minimal
     30       1.1  christos # root zone and nothing else.  As a result, all queries will result in an
     31       1.1  christos # NXDOMAIN.  The server will return the qname sent, which "dig" will display
     32       1.1  christos # according to the options selected.  This returned string is compared with
     33       1.1  christos # the qname originally sent.
     34       1.1  christos #
     35       1.1  christos # In the comments below, the following nomenclature (taken from RFC 5890) is
     36       1.1  christos # used:
     37       1.1  christos #
     38       1.1  christos # A-label: Label comprising ASCII characters that starts xn-- and whose
     39       1.1  christos #          characters after the xn-- are a valid output of the Punycode
     40       1.1  christos #          algorithm.
     41       1.1  christos #
     42       1.1  christos # Fake A-label: An A-label whose characters after the xn-- are not valid
     43       1.1  christos #          Punycode output.
     44       1.1  christos #
     45       1.1  christos # U-label: Unicode (native character) form of a label.
     46       1.1  christos #
     47       1.1  christos # For the purpose of this test script, U-labels do not include labels that
     48       1.1  christos # comprise purely ASCII characters, which are referred to as "ASCII-labels"
     49       1.1  christos # here. Valid ASCII-labels comprise letters, digits and hyphens and do not
     50       1.1  christos # start with a hyphen.
     51       1.1  christos #
     52       1.1  christos # References:
     53       1.1  christos # 1. http://www.unicode.org/reports/tr46/#Deviations
     54       1.1  christos # 2. http://www.unicode.org/reports/tr46/#IDNAComparison
     55       1.1  christos 
     56  1.1.1.10  christos DIGCMD="$DIG -p ${PORT} @10.53.0.1"
     57       1.1  christos 
     58       1.1  christos # Initialize test count and status return
     59       1.1  christos n=0
     60       1.1  christos status=0
     61       1.1  christos 
     62       1.1  christos # Function for extracting the qname from the response
     63       1.1  christos #
     64       1.1  christos # This is the first field in the line after the line starting
     65       1.1  christos # ";; QUESTION SECTION:".
     66       1.1  christos #
     67       1.1  christos # The string returned includes the trailing period.
     68       1.1  christos 
     69       1.1  christos qname() {
     70   1.1.1.9  christos   awk 'BEGIN { qs = 0; } \
     71       1.1  christos         /;; QUESTION SECTION:/ { qs = 1; next; } \
     72       1.1  christos         qs == 1 {sub(";", "", $1) ; print $1; exit 0; }' \
     73   1.1.1.9  christos     $1
     74       1.1  christos }
     75       1.1  christos 
     76       1.1  christos # Function for performing a test where "dig" is expected to succeed.
     77       1.1  christos #
     78       1.1  christos #   $1 - Description of the test
     79       1.1  christos #   $2 - Dig command additional options
     80       1.1  christos #   $3 - Name being queried
     81       1.1  christos #   $4 - The name that is expected to be displayed by "dig".  Note that names
     82       1.1  christos #        displayed by "dig" will always have a trailing period, so this
     83       1.1  christos #        parameter should have that period as well.
     84       1.1  christos 
     85       1.1  christos idna_test() {
     86   1.1.1.9  christos   n=$((n + 1))
     87   1.1.1.9  christos   description=$1
     88   1.1.1.9  christos   if [ "$2" != "" ]; then
     89   1.1.1.9  christos     description="${description}: $2"
     90   1.1.1.9  christos   fi
     91   1.1.1.9  christos   echo_i "$description ($n)"
     92   1.1.1.9  christos 
     93   1.1.1.9  christos   ret=0
     94   1.1.1.9  christos   {
     95   1.1.1.9  christos     $DIGCMD $2 $3 >dig.out.$n 2>&1
     96   1.1.1.9  christos     rc=$?
     97   1.1.1.9  christos   } || true
     98   1.1.1.9  christos   if [ $rc -ne 0 ]; then
     99   1.1.1.9  christos     echo_i "failed: dig command returned non-zero status"
    100   1.1.1.9  christos     ret=1
    101   1.1.1.9  christos   else
    102   1.1.1.9  christos     actual=$(qname dig.out.$n)
    103   1.1.1.9  christos     if [ "$4" != "$actual" ]; then
    104   1.1.1.9  christos       echo_i "failed: expected answer $4, actual result $actual"
    105   1.1.1.9  christos       ret=1
    106       1.1  christos     fi
    107   1.1.1.9  christos   fi
    108   1.1.1.9  christos   status=$((status + ret))
    109       1.1  christos }
    110       1.1  christos 
    111       1.1  christos # Function for performing a test where "dig" is expected to fail
    112       1.1  christos #
    113       1.1  christos #   $1 - Description of the test
    114       1.1  christos #   $2 - Dig command additional options
    115       1.1  christos #   $3 - Name being queried
    116       1.1  christos 
    117       1.1  christos idna_fail() {
    118   1.1.1.9  christos   n=$((n + 1))
    119   1.1.1.9  christos   description=$1
    120   1.1.1.9  christos   if [ "$2" != "" ]; then
    121   1.1.1.9  christos     description="${description}: $2"
    122   1.1.1.9  christos   fi
    123   1.1.1.9  christos   echo_i "$description ($n)"
    124   1.1.1.9  christos 
    125   1.1.1.9  christos   ret=0
    126   1.1.1.9  christos   {
    127   1.1.1.9  christos     $DIGCMD $2 $3 >dig.out.$n 2>&1
    128   1.1.1.9  christos     rc=$?
    129   1.1.1.9  christos   } || true
    130   1.1.1.9  christos   if [ $rc -eq 0 ]; then
    131   1.1.1.9  christos     echo_i "failed: dig command unexpectedly succeeded"
    132   1.1.1.9  christos     ret=1
    133   1.1.1.9  christos   fi
    134   1.1.1.9  christos   status=$((status + ret))
    135       1.1  christos }
    136       1.1  christos 
    137       1.1  christos # Function to check that case is preserved for an all-ASCII label.
    138       1.1  christos #
    139       1.1  christos # Without IDNA support, case-preservation is the expected behavior.
    140       1.1  christos #
    141       1.1  christos # With IDNA support... not really.  IDNA maps uppercase ASCII characters to
    142       1.1  christos # their lower-case equivalent.  When IDNA support in "dig" was updated to
    143       1.1  christos # non-transitional IDNA 2008, the switch "+idnin" was added and made the default
    144       1.1  christos # behaviour. This meant that the command "dig LocalhosT" (no command switches)
    145       1.1  christos # sends the qname "localhost", a change in behavior from earlier versions.
    146       1.1  christos #
    147       1.1  christos # This was felt to be confusing to the significant number of users who are
    148       1.1  christos # not interested in IDNA. For this reason, after "dig" passes the input qname
    149       1.1  christos # through the IDNA conversion, is does a case-insensitive comparison with the
    150       1.1  christos # result.  If the two are the same, "dig" can conclude that the qname is
    151       1.1  christos # entirely ASCII and is uses the entered string instead of the converted string
    152       1.1  christos # as the qname.
    153       1.1  christos 
    154       1.1  christos ascii_case_preservation_test() {
    155   1.1.1.9  christos   text="Checking valid ASCII label"
    156  1.1.1.10  christos   idna_test "$text" "+noidn" LocalhosT LocalhosT.
    157   1.1.1.9  christos   idna_test "$text" "+noidnin +noidnout" LocalhosT LocalhosT.
    158   1.1.1.9  christos   idna_test "$text" "+noidnin +idnout" LocalhosT LocalhosT.
    159   1.1.1.9  christos   idna_test "$text" "+idnin   +noidnout" LocalhosT LocalhosT.
    160   1.1.1.9  christos   idna_test "$text" "+idnin   +idnout" LocalhosT LocalhosT.
    161  1.1.1.10  christos   idna_test "$text" "+idn" LocalhosT LocalhosT.
    162       1.1  christos }
    163       1.1  christos 
    164       1.1  christos # Function to perform the tests if IDNA is enabled.
    165       1.1  christos 
    166       1.1  christos idna_enabled_test() {
    167   1.1.1.9  christos   echo_i "IDNA is enabled, all IDNA tests will be performed"
    168   1.1.1.9  christos   # Check that case is preserved on an ASCII label.
    169       1.1  christos 
    170   1.1.1.9  christos   ascii_case_preservation_test
    171       1.1  christos 
    172   1.1.1.9  christos   # Test of a valid U-label
    173   1.1.1.9  christos   #
    174   1.1.1.9  christos   # +noidnin +noidnout: The label is sent as a unicode octet stream and dig
    175   1.1.1.9  christos   #                     will display the string in the \nnn format.
    176   1.1.1.9  christos   # +noidnin +idnout:   As for the previous case.
    177   1.1.1.9  christos   # +idnin   +noidnout: The label is converted to the xn-- format.  "dig"
    178   1.1.1.9  christos   #                     displays the returned xn-- text.
    179   1.1.1.9  christos   # +idnin   +idnout:   The label is converted to the xn-- format.  "dig"
    180   1.1.1.9  christos   #                     converts the returned xn-- string back to the original
    181   1.1.1.9  christos   #                     unicode text.
    182   1.1.1.9  christos   #
    183   1.1.1.9  christos   # Note that ASCII characters are converted to lower-case.
    184   1.1.1.9  christos 
    185   1.1.1.9  christos   text="Checking valid non-ASCII label"
    186  1.1.1.10  christos   idna_test "$text" "+noidn" "Mnchen" "M\195\188nchen."
    187   1.1.1.9  christos   idna_test "$text" "+noidnin +noidnout" "Mnchen" "M\195\188nchen."
    188   1.1.1.9  christos   idna_test "$text" "+noidnin +idnout" "Mnchen" "M\195\188nchen."
    189   1.1.1.9  christos   idna_test "$text" "+idnin   +noidnout" "Mnchen" "xn--mnchen-3ya."
    190   1.1.1.9  christos   idna_test "$text" "+idnin   +idnout" "Mnchen" "mnchen."
    191  1.1.1.10  christos   idna_test "$text" "+idn" "Mnchen" "mnchen."
    192   1.1.1.9  christos 
    193   1.1.1.9  christos   # Tests of transitional processing of a valid U-label
    194   1.1.1.9  christos   #
    195   1.1.1.9  christos   # IDNA2003 introduced national character sets but, unfortunately, didn't
    196   1.1.1.9  christos   # support several characters properly.  One of those was the German
    197   1.1.1.9  christos   # character "" (the "Eszett" or "sharp s"), which was interpreted as "ss".
    198   1.1.1.9  christos   # So the domain fa.de domain (for example) was processed as fass.de.
    199   1.1.1.9  christos   #
    200   1.1.1.9  christos   # This was corrected in IDNA2008, although some vendors that adopted this
    201   1.1.1.9  christos   # standard chose to keep the existing IDNA2003 translation for this
    202   1.1.1.9  christos   # character to prevent problems (e.g. people visiting www.fa.example would,
    203   1.1.1.9  christos   # under IDNA2003, go to www.fass.example but under IDNA2008 would end up at
    204   1.1.1.9  christos   # www.fa\195\159.example - a different web site).
    205   1.1.1.9  christos   #
    206  1.1.1.10  christos   # BIND has adopted a (mostly) hard transition, so this test checks that
    207  1.1.1.10  christos   # the transitional mapping is not used for characters that are valid in
    208  1.1.1.10  christos   # IDNA2008. The tests are essentially the same as for the valid U-label.
    209   1.1.1.9  christos 
    210   1.1.1.9  christos   text="Checking that non-transitional IDNA processing is used"
    211  1.1.1.10  christos   idna_test "$text" "+noidn" "fa.de" "fa\195\159.de."
    212   1.1.1.9  christos   idna_test "$text" "+noidnin +noidnout" "fa.de" "fa\195\159.de."
    213   1.1.1.9  christos   idna_test "$text" "+noidnin +idnout" "fa.de" "fa\195\159.de."
    214   1.1.1.9  christos   idna_test "$text" "+idnin   +noidnout" "fa.de" "xn--fa-hia.de."
    215   1.1.1.9  christos   idna_test "$text" "+idnin   +idnout" "fa.de" "fa.de."
    216  1.1.1.10  christos   idna_test "$text" "+idn" "fa.de" "fa.de."
    217   1.1.1.9  christos 
    218   1.1.1.9  christos   # Another problem character.  The final character in the first label mapped
    219   1.1.1.9  christos   # onto the Greek sigma character ("") in IDNA2003.
    220   1.1.1.9  christos 
    221   1.1.1.9  christos   text="Second check that non-transitional IDNA processing is used"
    222  1.1.1.10  christos   idna_test "$text" "+noidn" ".com" "\206\178\207\140\206\187\206\191\207\130.com."
    223   1.1.1.9  christos   idna_test "$text" "+noidnin +noidnout" ".com" "\206\178\207\140\206\187\206\191\207\130.com."
    224   1.1.1.9  christos   idna_test "$text" "+noidnin +idnout" ".com" "\206\178\207\140\206\187\206\191\207\130.com."
    225   1.1.1.9  christos   idna_test "$text" "+idnin   +noidnout" ".com" "xn--nxasmm1c.com."
    226   1.1.1.9  christos   idna_test "$text" "+idnin   +idnout" ".com" ".com."
    227  1.1.1.10  christos   idna_test "$text" "+idn" ".com" ".com."
    228   1.1.1.9  christos 
    229   1.1.1.9  christos   # Tests of a valid A-label (i.e. starting xn--)
    230   1.1.1.9  christos   #
    231   1.1.1.9  christos   # +noidnout: The string is sent as-is to the server and the returned qname
    232   1.1.1.9  christos   #            is displayed in the same form.
    233   1.1.1.9  christos   # +idnout:   The string is sent as-is to the server and the returned qname
    234   1.1.1.9  christos   #            is displayed as the corresponding U-label.
    235   1.1.1.9  christos   #
    236   1.1.1.9  christos   # The "+[no]idnin" flag has no effect in these cases.
    237   1.1.1.9  christos 
    238   1.1.1.9  christos   text="Checking valid A-label"
    239  1.1.1.10  christos   idna_test "$text" "+noidn" "xn--nxasmq6b.com" "xn--nxasmq6b.com."
    240   1.1.1.9  christos   idna_test "$text" "+noidnin +noidnout" "xn--nxasmq6b.com" "xn--nxasmq6b.com."
    241   1.1.1.9  christos   idna_test "$text" "+noidnin +idnout" "xn--nxasmq6b.com" ".com."
    242   1.1.1.9  christos   idna_test "$text" "+idnin +noidnout" "xn--nxasmq6b.com" "xn--nxasmq6b.com."
    243   1.1.1.9  christos   idna_test "$text" "+idnin +idnout" "xn--nxasmq6b.com" ".com."
    244  1.1.1.10  christos   idna_test "$text" "+idn" "xn--nxasmq6b.com" ".com."
    245   1.1.1.9  christos 
    246   1.1.1.9  christos   # Test of valid A-label in locale that cannot display it
    247   1.1.1.9  christos   #
    248   1.1.1.9  christos   # +noidnout: The string is sent as-is to the server and the returned qname
    249   1.1.1.9  christos   #            is displayed in the same form.
    250   1.1.1.9  christos   # +idnout:   The string is sent as-is to the server and the returned qname
    251   1.1.1.9  christos   #            is displayed as the corresponding A-label.
    252   1.1.1.9  christos   #
    253   1.1.1.9  christos   # The "+[no]idnout" flag has no effect in these cases.
    254   1.1.1.9  christos   saved_LC_ALL="${LC_ALL}"
    255   1.1.1.9  christos   LC_ALL="C"
    256   1.1.1.9  christos   text="Checking valid A-label in C locale"
    257   1.1.1.9  christos   label="xn--nxasmq6b.com"
    258   1.1.1.9  christos   if command -v idn2 >/dev/null && ! idn2 -d "$label" >/dev/null 2>/dev/null; then
    259  1.1.1.10  christos     idna_test "$text" "+noidn" "$label" "$label."
    260   1.1.1.9  christos     idna_test "$text" "+noidnin +noidnout" "$label" "$label."
    261   1.1.1.9  christos     idna_test "$text" "+noidnin +idnout" "$label" "$label."
    262   1.1.1.9  christos     idna_test "$text" "+idnin +noidnout" "$label" "$label."
    263   1.1.1.9  christos     idna_test "$text" "+idnin +idnout" "$label" "$label."
    264   1.1.1.9  christos     idna_test "$text" "+noidnin +idnout" "$label" "$label."
    265  1.1.1.10  christos     idna_test "$text" "+idn" "$label" "$label."
    266   1.1.1.9  christos   fi
    267   1.1.1.9  christos   LC_ALL="${saved_LC_ALL}"
    268   1.1.1.9  christos 
    269   1.1.1.9  christos   # Tests of invalid A-labels
    270   1.1.1.9  christos   #
    271   1.1.1.9  christos   # +noidnin: The label is sent as-is to the server and dig will display the
    272   1.1.1.9  christos   #           returned fake A-label in the same form.
    273   1.1.1.9  christos   # +idnin:   "dig" should report that the label is not correct.
    274   1.1.1.9  christos   #
    275   1.1.1.9  christos   # +[no]idnout: If the label makes it to the server (via +noidnin), "dig"
    276   1.1.1.9  christos   #           should report an error if +idnout is specified.
    277  1.1.1.10  christos   #
    278  1.1.1.10  christos   # +idn=lax: The label is sent and printed as-is.
    279   1.1.1.9  christos 
    280   1.1.1.9  christos   # The minimum length of a punycode A-label is 7 characters.  Check that
    281   1.1.1.9  christos   # a shorter label is detected and rejected.
    282   1.1.1.9  christos 
    283   1.1.1.9  christos   text="Checking punycode label shorter than minimum valid length"
    284  1.1.1.10  christos   idna_test "$text" "+noidn" "xn--xx" "xn--xx."
    285   1.1.1.9  christos   idna_test "$text" "+noidnin +noidnout" "xn--xx" "xn--xx."
    286  1.1.1.10  christos   idna_test "$text" "+noidnin   +idnout" "xn--xx" "xn--xx."
    287  1.1.1.10  christos   idna_test "$text" "+idnin   +noidnout" "xn--xx" "xn--xx."
    288  1.1.1.10  christos   idna_test "$text" "+idnin     +idnout" "xn--xx" "xn--xx."
    289  1.1.1.10  christos   idna_test "$text" "+idn" "xn--xx" "xn--xx."
    290   1.1.1.9  christos 
    291   1.1.1.9  christos   # Fake A-label - the string does not translate to anything.
    292  1.1.1.10  christos   # "xn--0000h" decodes to a single "code point" value of U+127252
    293  1.1.1.10  christos   # (1,208,914) which is not a legal Unicode code point.
    294  1.1.1.10  christos   # (https://www.farsightsecurity.com/blog/txt-record/punycode-20180711/)
    295   1.1.1.9  christos 
    296   1.1.1.9  christos   text="Checking fake A-label"
    297  1.1.1.10  christos   idna_test "$text" "+noidn" "xn--0000h" "xn--0000h."
    298  1.1.1.10  christos   idna_test "$text" "+noidnin +noidnout" "xn--0000h" "xn--0000h."
    299  1.1.1.10  christos   idna_test "$text" "+noidnin   +idnout" "xn--0000h" "xn--0000h."
    300  1.1.1.10  christos   idna_test "$text" "+idnin   +noidnout" "xn--0000h" "xn--0000h."
    301  1.1.1.10  christos   idna_test "$text" "+idnin     +idnout" "xn--0000h" "xn--0000h."
    302  1.1.1.10  christos   idna_test "$text" "+idn" "xn--0000h" "xn--0000h."
    303   1.1.1.9  christos 
    304   1.1.1.9  christos   # Too long a label. The punycode string is too long (at 64 characters).
    305   1.1.1.9  christos   # BIND rejects such labels: with +idnin
    306   1.1.1.9  christos 
    307   1.1.1.9  christos   label="xn--xflod18hstflod18hstflod18hstflod18hstflod18hstflod18-1iejjjj"
    308   1.1.1.9  christos   text="Checking punycode label longer than maximum valid length"
    309  1.1.1.10  christos   idna_fail "$text" "+noidn" "$label"
    310   1.1.1.9  christos   idna_fail "$text" "+noidnin +noidnout" "$label"
    311   1.1.1.9  christos   idna_fail "$text" "+noidnin   +idnout" "$label"
    312   1.1.1.9  christos   idna_fail "$text" "+idnin   +noidnout" "$label"
    313   1.1.1.9  christos   idna_fail "$text" "+idnin     +idnout" "$label"
    314  1.1.1.10  christos   idna_fail "$text" "+idn" "$label"
    315   1.1.1.9  christos 
    316   1.1.1.9  christos   # Tests of a valid unicode string but an invalid U-label (input)
    317   1.1.1.9  christos   #
    318  1.1.1.10  christos   # Symbols are not valid IDNA2008 names, but are allowed by IDNA2003.
    319   1.1.1.9  christos   #
    320   1.1.1.9  christos   # +noidnin: "dig" should send unicode octets to the server and display the
    321   1.1.1.9  christos   #           returned qname in the same form.
    322   1.1.1.9  christos   # +idnin:   "dig" should generate an error.
    323   1.1.1.9  christos   #
    324   1.1.1.9  christos   # The +[no]idnout options should not have any effect on the test.
    325   1.1.1.9  christos 
    326   1.1.1.9  christos   text="Checking invalid input U-label"
    327  1.1.1.10  christos   idna_test "$text" "+noidn" ".com" "\226\136\154.com."
    328   1.1.1.9  christos   idna_test "$text" "+noidnin +noidnout" ".com" "\226\136\154.com."
    329   1.1.1.9  christos   idna_test "$text" "+noidnin +idnout" ".com" "\226\136\154.com."
    330   1.1.1.9  christos   idna_test "$text" "+idnin   +noidnout" ".com" "xn--19g.com."
    331   1.1.1.9  christos   idna_test "$text" "+idnin   +idnout" ".com" ".com."
    332  1.1.1.10  christos   idna_test "$text" "+idn" ".com" ".com."
    333   1.1.1.9  christos 
    334   1.1.1.9  christos   # Tests of a valid unicode string but an invalid U-label (output)
    335   1.1.1.9  christos   #
    336  1.1.1.10  christos   # Symbols are not valid IDNA2008 names, but are allowed by IDNA2003.
    337   1.1.1.9  christos   #
    338   1.1.1.9  christos   # +noidnout: "dig" should send the ACE string to the server and display the
    339   1.1.1.9  christos   #            returned qname.
    340   1.1.1.9  christos   # +idnout:   "dig" should generate an error.
    341   1.1.1.9  christos   #
    342   1.1.1.9  christos   # The +[no]idnin options should not have any effect on the test.
    343   1.1.1.9  christos 
    344   1.1.1.9  christos   text="Checking invalid output U-label"
    345  1.1.1.10  christos   idna_test "$text" "+noidn" "xn--19g" "xn--19g."
    346   1.1.1.9  christos   idna_test "$text" "+noidnin +noidnout" "xn--19g" "xn--19g."
    347   1.1.1.9  christos   idna_test "$text" "+noidnin +idnout" "xn--19g" "."
    348  1.1.1.10  christos   idna_test "$text" "+idnin   +noidnout" "xn--19g" "xn--19g."
    349   1.1.1.9  christos   idna_test "$text" "+idnin   +idnout" "xn--19g" "."
    350  1.1.1.10  christos   idna_test "$text" "+idn" "xn--19g" "."
    351   1.1.1.9  christos 
    352   1.1.1.9  christos   # Test that non-letter characters are preserved in the output.  When
    353   1.1.1.9  christos   # UseSTD3ASCIIRules are enabled, it would mangle non-letter characters like
    354   1.1.1.9  christos   # `_` (underscore) and `*` (wildcard.
    355   1.1.1.9  christos 
    356   1.1.1.9  christos   text="Checking valid non-letter characters"
    357  1.1.1.10  christos   idna_test "$text" "+noidn" "*.xn--nxasmq6b.com" "*.xn--nxasmq6b.com."
    358   1.1.1.9  christos   idna_test "$text" "+noidnin +noidnout" "*.xn--nxasmq6b.com" "*.xn--nxasmq6b.com."
    359   1.1.1.9  christos   idna_test "$text" "+noidnin +idnout" "*.xn--nxasmq6b.com" "*..com."
    360   1.1.1.9  christos   idna_test "$text" "+idnin +noidnout" "*.xn--nxasmq6b.com" "*.xn--nxasmq6b.com."
    361   1.1.1.9  christos   idna_test "$text" "+idnin +idnout" "*.xn--nxasmq6b.com" "*..com."
    362  1.1.1.10  christos   idna_test "$text" "+idn" "*.xn--nxasmq6b.com" "*..com."
    363   1.1.1.9  christos 
    364  1.1.1.10  christos   idna_test "$text" "+noidn" "_tcp.xn--nxasmq6b.com" "_tcp.xn--nxasmq6b.com."
    365   1.1.1.9  christos   idna_test "$text" "+noidnin +noidnout" "_tcp.xn--nxasmq6b.com" "_tcp.xn--nxasmq6b.com."
    366   1.1.1.9  christos   idna_test "$text" "+noidnin +idnout" "_tcp.xn--nxasmq6b.com" "_tcp..com."
    367   1.1.1.9  christos   idna_test "$text" "+idnin +noidnout" "_tcp.xn--nxasmq6b.com" "_tcp.xn--nxasmq6b.com."
    368   1.1.1.9  christos   idna_test "$text" "+idnin +idnout" "_tcp.xn--nxasmq6b.com" "_tcp..com."
    369  1.1.1.10  christos   idna_test "$text" "+idn=strict" "_tcp.xn--nxasmq6b.com" "_tcp..com."
    370  1.1.1.10  christos   idna_test "$text" "+idn=lax" "_tcp.xn--nxasmq6b.com" "_tcp..com."
    371       1.1  christos }
    372       1.1  christos 
    373       1.1  christos # Function to perform tests if IDNA is not enabled.
    374       1.1  christos 
    375       1.1  christos idna_disabled_test() {
    376   1.1.1.9  christos   echo_i "IDNA is disabled, only case mapping tests will be performed"
    377   1.1.1.9  christos   ascii_case_preservation_test
    378       1.1  christos }
    379       1.1  christos 
    380       1.1  christos # Main test begins here
    381       1.1  christos 
    382   1.1.1.9  christos if $FEATURETEST --with-libidn2; then
    383   1.1.1.9  christos   idna_enabled_test
    384       1.1  christos else
    385   1.1.1.9  christos   idna_disabled_test
    386       1.1  christos fi
    387       1.1  christos 
    388       1.1  christos exit $status
    389