⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 201850 in webkit


Ignore:
Timestamp:
Jun 8, 2016, 10:07:24 PM (10 years ago)
Author:
Brent Fulgham
Message:

Perform IDNA encoding on parameters for setHostAndPort and setHost
https://bugs.webkit.org/show_bug.cgi?id=158371
<rdar://problem/16869342>

Patch by John Wilander <wilander@apple.com> on 2016-06-08
Reviewed by Brent Fulgham.

Source/WebCore:

Tests: fast/dom/set-document-location-host-to-unaccepted-values.html

fast/dom/set-document-location-hostname-to-unaccepted-values.html
http/tests/dom/set-document-location-host-to-accepted-values.html
http/tests/dom/set-document-location-hostname-to-accepted-values.html

  • platform/URL.cpp:

(WebCore::containsOnlyASCII):

Moved up to enable usage in URL::setHost and URL::setHostAndPort.

(WebCore::appendEncodedHostname):

Moved up to enable usage in URL::setHost and URL::setHostAndPort.

(WebCore::URL::setHost):

Now disallows the colon character, does IDNA encoding, and uses StringBuilder.

(WebCore::URL::setHostAndPort):

Now disallows multiple colons, disallows non-numeric ports, disallows the empty
string, does IDNA encoding, and uses StringBuilder.

LayoutTests:

  • fast/dom/resources/set-document-location-iframe.html: Added.
  • fast/dom/set-document-location-host-to-unaccepted-values-expected.txt: Added.
  • fast/dom/set-document-location-host-to-unaccepted-values.html: Added.
  • fast/dom/set-document-location-hostname-to-unaccepted-values-expected.txt: Added.
  • fast/dom/set-document-location-hostname-to-unaccepted-values.html: Added.
  • http/tests/dom/resources/set-document-location-iframe.html: Added.
  • http/tests/dom/set-document-location-host-to-accepted-values-expected.txt: Added.
  • http/tests/dom/set-document-location-host-to-accepted-values.html: Added.
  • http/tests/dom/set-document-location-hostname-to-accepted-values-expected.txt: Added.
  • http/tests/dom/set-document-location-hostname-to-accepted-values.html: Added.
Location:
trunk
Files:
10 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r201842 r201850  
     12016-06-08  John Wilander  <wilander@apple.com>
     2
     3        Perform IDNA encoding on parameters for setHostAndPort and setHost
     4        https://bugs.webkit.org/show_bug.cgi?id=158371
     5        <rdar://problem/16869342>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        * fast/dom/resources/set-document-location-iframe.html: Added.
     10        * fast/dom/set-document-location-host-to-unaccepted-values-expected.txt: Added.
     11        * fast/dom/set-document-location-host-to-unaccepted-values.html: Added.
     12        * fast/dom/set-document-location-hostname-to-unaccepted-values-expected.txt: Added.
     13        * fast/dom/set-document-location-hostname-to-unaccepted-values.html: Added.
     14        * http/tests/dom/resources/set-document-location-iframe.html: Added.
     15        * http/tests/dom/set-document-location-host-to-accepted-values-expected.txt: Added.
     16        * http/tests/dom/set-document-location-host-to-accepted-values.html: Added.
     17        * http/tests/dom/set-document-location-hostname-to-accepted-values-expected.txt: Added.
     18        * http/tests/dom/set-document-location-hostname-to-accepted-values.html: Added.
     19
    1202016-06-08  Ryan Haddad  <ryanhaddad@apple.com>
    221
  • trunk/Source/WebCore/ChangeLog

    r201846 r201850  
     12016-06-08  John Wilander  <wilander@apple.com>
     2
     3        Perform IDNA encoding on parameters for setHostAndPort and setHost
     4        https://bugs.webkit.org/show_bug.cgi?id=158371
     5        <rdar://problem/16869342>
     6
     7        Reviewed by Brent Fulgham.
     8
     9        Tests: fast/dom/set-document-location-host-to-unaccepted-values.html
     10               fast/dom/set-document-location-hostname-to-unaccepted-values.html
     11               http/tests/dom/set-document-location-host-to-accepted-values.html
     12               http/tests/dom/set-document-location-hostname-to-accepted-values.html
     13
     14        * platform/URL.cpp:
     15        (WebCore::containsOnlyASCII):
     16            Moved up to enable usage in URL::setHost and URL::setHostAndPort.
     17        (WebCore::appendEncodedHostname):
     18            Moved up to enable usage in URL::setHost and URL::setHostAndPort.
     19        (WebCore::URL::setHost):
     20            Now disallows the colon character, does IDNA encoding, and uses StringBuilder.
     21        (WebCore::URL::setHostAndPort):
     22            Now disallows multiple colons, disallows non-numeric ports, disallows the empty
     23            string, does IDNA encoding, and uses StringBuilder.
     24
    1252016-06-08  Alex Christensen  <achristensen@webkit.org>
    226
  • trunk/Source/WebCore/platform/URL.cpp

    r201740 r201850  
    837837}
    838838
     839static bool containsOnlyASCII(StringView string)
     840{
     841    if (string.is8Bit())
     842        return charactersAreAllASCII(string.characters8(), string.length());
     843    return charactersAreAllASCII(string.characters16(), string.length());
     844}
     845   
     846// Appends the punycoded hostname identified by the given string and length to
     847// the output buffer. The result will not be null terminated.
     848// Return value of false means error in encoding.
     849static bool appendEncodedHostname(UCharBuffer& buffer, StringView string)
     850{
     851    // Needs to be big enough to hold an IDN-encoded name.
     852    // For host names bigger than this, we won't do IDN encoding, which is almost certainly OK.
     853    const unsigned hostnameBufferLength = 2048;
     854   
     855    if (string.length() > hostnameBufferLength || containsOnlyASCII(string)) {
     856        append(buffer, string);
     857        return true;
     858    }
     859   
     860    UChar hostnameBuffer[hostnameBufferLength];
     861    UErrorCode error = U_ZERO_ERROR;
     862   
     863#if COMPILER(GCC_OR_CLANG)
     864#pragma GCC diagnostic push
     865#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     866#endif
     867    int32_t numCharactersConverted = uidna_IDNToASCII(string.upconvertedCharacters(), string.length(), hostnameBuffer,
     868        hostnameBufferLength, UIDNA_ALLOW_UNASSIGNED, 0, &error);
     869#if COMPILER(GCC_OR_CLANG)
     870#pragma GCC diagnostic pop
     871#endif
     872   
     873    if (error == U_ZERO_ERROR) {
     874        buffer.append(hostnameBuffer, numCharactersConverted);
     875        return true;
     876    }
     877    return false;
     878}
     879   
    839880void URL::setHost(const String& s)
    840881{
     
    842883        return;
    843884
    844     // FIXME: Non-ASCII characters must be encoded and escaped to match parse() expectations,
    845     // and to avoid changing more than just the host.
    846 
     885    auto colonIndex = s.find(':');
     886    if (colonIndex != notFound)
     887        return;
     888
     889    UCharBuffer encodedHostName;
     890    if (!appendEncodedHostname(encodedHostName, s))
     891        return;
     892   
    847893    bool slashSlashNeeded = m_userStart == m_schemeEnd + 1;
    848 
    849     parse(m_string.left(hostStart()) + (slashSlashNeeded ? "//" : "") + s + m_string.substring(m_hostEnd));
     894   
     895    StringBuilder builder;
     896    builder.append(m_string.left(hostStart()));
     897    if (slashSlashNeeded)
     898        builder.append("//");
     899    builder.append(StringView(encodedHostName.data(), encodedHostName.size()));
     900    builder.append(m_string.substring(m_hostEnd));
     901   
     902    parse(builder.toString());
    850903}
    851904
     
    873926        return;
    874927
    875     // FIXME: Non-ASCII characters must be encoded and escaped to match parse() expectations,
    876     // and to avoid changing more than just host and port.
     928    StringView hostName(hostAndPort);
     929    StringView port;
     930   
     931    auto colonIndex = hostName.find(':');
     932    if (colonIndex != notFound) {
     933        port = hostName.substring(colonIndex + 1);
     934        bool ok;
     935        int portInt = port.toIntStrict(ok);
     936        if (!ok || portInt < 0)
     937            return;
     938        hostName = hostName.substring(0, colonIndex);
     939    }
     940
     941    if (hostName.isEmpty())
     942        return;
     943
     944    UCharBuffer encodedHostName;
     945    if (!appendEncodedHostname(encodedHostName, hostName))
     946        return;
    877947
    878948    bool slashSlashNeeded = m_userStart == m_schemeEnd + 1;
    879949
    880     parse(m_string.left(hostStart()) + (slashSlashNeeded ? "//" : "") + hostAndPort + m_string.substring(m_portEnd));
     950    StringBuilder builder;
     951    builder.append(m_string.left(hostStart()));
     952    if (slashSlashNeeded)
     953        builder.append("//");
     954    builder.append(StringView(encodedHostName.data(), encodedHostName.size()));
     955    if (!port.isEmpty()) {
     956        builder.append(":");
     957        builder.append(port);
     958    }
     959    builder.append(m_string.substring(m_portEnd));
     960
     961    parse(builder.toString());
    881962}
    882963
     
    16651746}
    16661747
    1667 static bool containsOnlyASCII(StringView string)
    1668 {
    1669     if (string.is8Bit())
    1670         return charactersAreAllASCII(string.characters8(), string.length());
    1671     return charactersAreAllASCII(string.characters16(), string.length());
    1672 }
    1673 
    16741748static bool protocolIs(StringView stringURL, const char* protocol)
    16751749{
     
    16811755        if (!isLetterMatchIgnoringCase(stringURL[i], protocol[i]))
    16821756            return false;
    1683     }
    1684     return false;
    1685 }
    1686 
    1687 // Appends the punycoded hostname identified by the given string and length to
    1688 // the output buffer. The result will not be null terminated.
    1689 // Return value of false means error in encoding.
    1690 static bool appendEncodedHostname(UCharBuffer& buffer, StringView string)
    1691 {
    1692     // Needs to be big enough to hold an IDN-encoded name.
    1693     // For host names bigger than this, we won't do IDN encoding, which is almost certainly OK.
    1694     const unsigned hostnameBufferLength = 2048;
    1695 
    1696     if (string.length() > hostnameBufferLength || containsOnlyASCII(string)) {
    1697         append(buffer, string);
    1698         return true;
    1699     }
    1700 
    1701     UChar hostnameBuffer[hostnameBufferLength];
    1702     UErrorCode error = U_ZERO_ERROR;
    1703 
    1704 #if COMPILER(GCC_OR_CLANG)
    1705 #pragma GCC diagnostic push
    1706 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
    1707 #endif
    1708     int32_t numCharactersConverted = uidna_IDNToASCII(string.upconvertedCharacters(), string.length(), hostnameBuffer,
    1709         hostnameBufferLength, UIDNA_ALLOW_UNASSIGNED, 0, &error);
    1710 #if COMPILER(GCC_OR_CLANG)
    1711 #pragma GCC diagnostic pop
    1712 #endif
    1713 
    1714     if (error == U_ZERO_ERROR) {
    1715         buffer.append(hostnameBuffer, numCharactersConverted);
    1716         return true;
    17171757    }
    17181758    return false;
Note: See TracChangeset for help on using the changeset viewer.