Changeset 206337 in webkit


Ignore:
Timestamp:
Sep 23, 2016, 4:40:46 PM (9 years ago)
Author:
achristensen@apple.com
Message:

Refactor URLParser
https://bugs.webkit.org/show_bug.cgi?id=162518

Reviewed by Brady Eidson.

Use a helper function to determine the currentPosition instead of always determining position based on the
size of the buffer. Soon there will be nothing in the buffer in the common case where there are no syntax errors.
Also make more static functions into methods. Give IPv6Addresses and IPv4Addresses names. Start adding syntaxError stubs.

No change in behavior. Covered by API tests.

  • platform/URLParser.cpp:

(WebCore::URLParser::incrementIteratorSkippingTabAndNewLine):
(WebCore::URLParser::isWindowsDriveLetter):
(WebCore::URLParser::appendToASCIIBuffer):
(WebCore::URLParser::syntaxError):
(WebCore::URLParser::currentPosition):
(WebCore::URLParser::URLParser):
(WebCore::URLParser::parse):
(WebCore::URLParser::parseAuthority):
(WebCore::URLParser::appendNumberToASCIIBuffer):
(WebCore::URLParser::serializeIPv4):
(WebCore::URLParser::serializeIPv6Piece):
(WebCore::URLParser::serializeIPv6):
(WebCore::URLParser::parseIPv4Host):
(WebCore::URLParser::parseIPv6Host):
(WebCore::URLParser::parsePort):
(WebCore::URLParser::parseHostAndPort):
(WebCore::append): Deleted.
(WebCore::serializeIPv4): Deleted.
(WebCore::serializeIPv6Piece): Deleted.
(WebCore::serializeIPv6): Deleted.
(WebCore::parseIPv4Host): Deleted.
(WebCore::parseIPv6Host): Deleted.

  • platform/URLParser.h:
Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r206334 r206337  
     12016-09-23  Alex Christensen  <achristensen@webkit.org>
     2
     3        Refactor URLParser
     4        https://bugs.webkit.org/show_bug.cgi?id=162518
     5
     6        Reviewed by Brady Eidson.
     7
     8        Use a helper function to determine the currentPosition instead of always determining position based on the
     9        size of the buffer.  Soon there will be nothing in the buffer in the common case where there are no syntax errors.
     10        Also make more static functions into methods.  Give IPv6Addresses and IPv4Addresses names.  Start adding syntaxError stubs.
     11
     12        No change in behavior.  Covered by API tests.
     13
     14        * platform/URLParser.cpp:
     15        (WebCore::URLParser::incrementIteratorSkippingTabAndNewLine):
     16        (WebCore::URLParser::isWindowsDriveLetter):
     17        (WebCore::URLParser::appendToASCIIBuffer):
     18        (WebCore::URLParser::syntaxError):
     19        (WebCore::URLParser::currentPosition):
     20        (WebCore::URLParser::URLParser):
     21        (WebCore::URLParser::parse):
     22        (WebCore::URLParser::parseAuthority):
     23        (WebCore::URLParser::appendNumberToASCIIBuffer):
     24        (WebCore::URLParser::serializeIPv4):
     25        (WebCore::URLParser::serializeIPv6Piece):
     26        (WebCore::URLParser::serializeIPv6):
     27        (WebCore::URLParser::parseIPv4Host):
     28        (WebCore::URLParser::parseIPv6Host):
     29        (WebCore::URLParser::parsePort):
     30        (WebCore::URLParser::parseHostAndPort):
     31        (WebCore::append): Deleted.
     32        (WebCore::serializeIPv4): Deleted.
     33        (WebCore::serializeIPv6Piece): Deleted.
     34        (WebCore::serializeIPv6): Deleted.
     35        (WebCore::parseIPv4Host): Deleted.
     36        (WebCore::parseIPv6Host): Deleted.
     37        * platform/URLParser.h:
     38
    1392016-09-23  Alex Christensen  <achristensen@webkit.org>
    240
  • trunk/Source/WebCore/platform/URLParser.cpp

    r206334 r206337  
    414414{
    415415    ++iterator;
    416     while (!iterator.atEnd() && isTabOrNewline(*iterator))
     416    while (!iterator.atEnd() && isTabOrNewline(*iterator)) {
     417        syntaxError(iterator);
    417418        ++iterator;
     419    }
    418420}
    419421
     
    428430    if (*iterator == ':')
    429431        return true;
    430     if (*iterator == '|')
     432    if (*iterator == '|') {
     433        syntaxError(iterator);
    431434        return true;
     435    }
    432436    return false;
    433437}
     
    444448    ASSERT(m_unicodeFragmentBuffer.isEmpty());
    445449    ASSERT(isASCII(codePoint));
    446     m_asciiBuffer.append(codePoint);
     450    if (m_seenSyntaxError)
     451        m_asciiBuffer.append(codePoint);
    447452}
    448453
     
    450455{
    451456    ASSERT(m_unicodeFragmentBuffer.isEmpty());
    452     m_asciiBuffer.append(characters, length);
     457    if (m_seenSyntaxError)
     458        m_asciiBuffer.append(characters, length);
    453459}
    454460
     
    927933}
    928934
     935template<typename CharacterType>
     936void URLParser::syntaxError(const CodePointIterator<CharacterType>&)
     937{
     938    // FIXME: Implement.
     939}
     940
    929941void URLParser::failure()
    930942{
     
    933945}
    934946
     947template<typename CharacterType>
     948size_t URLParser::currentPosition(const CodePointIterator<CharacterType>& iterator)
     949{
     950    if (m_seenSyntaxError)
     951        return m_asciiBuffer.size();
     952   
     953    return iterator.codeUnitsSince(reinterpret_cast<const CharacterType*>(m_inputBegin));
     954}
     955
    935956URLParser::URLParser(const String& input, const URL& base, const TextEncoding& encoding)
    936957    : m_inputString(input)
     
    939960        return;
    940961
    941     if (input.is8Bit())
     962    if (input.is8Bit()) {
     963        m_inputBegin = input.characters8();
    942964        parse(input.characters8(), input.length(), base, encoding);
    943     else
     965    } else {
     966        m_inputBegin = input.characters16();
    944967        parse(input.characters16(), input.length(), base, encoding);
     968    }
    945969}
    946970
     
    9881012    };
    9891013
    990 #define LOG_STATE(x) LOG(URLParser, "State %s, code point %c, asciiBuffer size %zu", x, *c, m_asciiBuffer.size())
     1014#define LOG_STATE(x) LOG(URLParser, "State %s, code point %c, asciiBuffer size %zu", x, *c, currentPosition(c))
    9911015#define LOG_FINAL_STATE(x) LOG(URLParser, "Final State: %s", x)
    9921016
     
    9941018    while (!c.atEnd()) {
    9951019        if (isTabOrNewline(*c)) {
     1020            syntaxError(c);
    9961021            ++c;
    9971022            continue;
     
    10021027            LOG_STATE("SchemeStart");
    10031028            if (isASCIIAlpha(*c)) {
    1004                 m_asciiBuffer.uncheckedAppend(toASCIILower(*c));
     1029                appendToASCIIBuffer(toASCIILower(*c));
    10051030                incrementIteratorSkippingTabAndNewLine(c);
    10061031                if (c.atEnd()) {
     
    10181043                appendToASCIIBuffer(toASCIILower(*c));
    10191044            else if (*c == ':') {
    1020                 m_url.m_schemeEnd = m_asciiBuffer.size();
     1045                m_url.m_schemeEnd = currentPosition(c);
    10211046                StringView urlScheme = StringView(m_asciiBuffer.data(), m_url.m_schemeEnd);
    10221047                m_url.m_protocolIsInHTTPFamily = urlScheme == "http" || urlScheme == "https";
     
    10311056                if (isSpecialScheme(urlScheme)) {
    10321057                    m_urlIsSpecial = true;
    1033                     if (base.protocolIs(m_asciiBuffer.data(), m_asciiBuffer.size() - 1))
     1058                    if (base.protocolIs(m_asciiBuffer.data(), currentPosition(c) - 1))
    10341059                        state = State::SpecialRelativeOrAuthority;
    10351060                    else
     
    10401065                    if (!maybeSlash.atEnd() && *maybeSlash == '/') {
    10411066                        appendToASCIIBuffer('/');
    1042                         m_url.m_userStart = m_asciiBuffer.size();
     1067                        m_url.m_userStart = currentPosition(c);
    10431068                        state = State::PathOrAuthority;
    10441069                        c = maybeSlash;
    10451070                        ASSERT(*c == '/');
    10461071                    } else {
    1047                         m_url.m_userStart = m_asciiBuffer.size();
     1072                        m_url.m_userStart = currentPosition(c);
    10481073                        m_url.m_userEnd = m_url.m_userStart;
    10491074                        m_url.m_passwordEnd = m_url.m_userStart;
     
    11131138            if (*c == '/') {
    11141139                appendToASCIIBuffer('/');
    1115                 m_url.m_userStart = m_asciiBuffer.size();
     1140                m_url.m_userStart = currentPosition(c);
    11161141                state = State::AuthorityOrHost;
    11171142                ++c;
     
    11191144            } else {
    11201145                ASSERT(m_asciiBuffer.last() == '/');
    1121                 m_url.m_userStart = m_asciiBuffer.size() - 1;
     1146                m_url.m_userStart = currentPosition(c) - 1;
    11221147                m_url.m_userEnd = m_url.m_userStart;
    11231148                m_url.m_passwordEnd = m_url.m_userStart;
     
    11841209                ++c;
    11851210            }
    1186             m_url.m_userStart = m_asciiBuffer.size();
     1211            m_url.m_userStart = currentPosition(c);
    11871212            state = State::AuthorityOrHost;
    11881213            authorityOrHostBegin = c;
     
    12091234                bool isSlash = *c == '/' || (m_urlIsSpecial && *c == '\\');
    12101235                if (isSlash || *c == '?' || *c == '#') {
    1211                     m_url.m_userEnd = m_asciiBuffer.size();
     1236                    m_url.m_userEnd = currentPosition(c);
    12121237                    m_url.m_passwordEnd = m_url.m_userEnd;
    12131238                    if (!parseHostAndPort(CodePointIterator<CharacterType>(authorityOrHostBegin, c))) {
     
    12171242                    if (!isSlash) {
    12181243                        appendToASCIIBuffer('/');
    1219                         m_url.m_pathAfterLastSlash = m_asciiBuffer.size();
     1244                        m_url.m_pathAfterLastSlash = currentPosition(c);
    12201245                    }
    12211246                    state = State::Path;
     
    12541279                    copyURLPartsUntil(base, URLPart::PathEnd);
    12551280                appendToASCIIBuffer("///?", 4);
    1256                 m_url.m_userStart = m_asciiBuffer.size() - 2;
     1281                m_url.m_userStart = currentPosition(c) - 2;
    12571282                m_url.m_userEnd = m_url.m_userStart;
    12581283                m_url.m_passwordEnd = m_url.m_userStart;
     
    12681293                    copyURLPartsUntil(base, URLPart::QueryEnd);
    12691294                appendToASCIIBuffer("///#", 4);
    1270                 m_url.m_userStart = m_asciiBuffer.size() - 2;
     1295                m_url.m_userStart = currentPosition(c) - 2;
    12711296                m_url.m_userEnd = m_url.m_userStart;
    12721297                m_url.m_passwordEnd = m_url.m_userStart;
     
    12841309                else {
    12851310                    appendToASCIIBuffer("///", 3);
    1286                     m_url.m_userStart = m_asciiBuffer.size() - 1;
     1311                    m_url.m_userStart = currentPosition(c) - 1;
    12871312                    m_url.m_userEnd = m_url.m_userStart;
    12881313                    m_url.m_passwordEnd = m_url.m_userStart;
     
    13011326                ++c;
    13021327                appendToASCIIBuffer('/');
    1303                 m_url.m_userStart = m_asciiBuffer.size();
     1328                m_url.m_userStart = currentPosition(c);
    13041329                m_url.m_userEnd = m_url.m_userStart;
    13051330                m_url.m_passwordEnd = m_url.m_userStart;
     
    13241349            }
    13251350            appendToASCIIBuffer("//", 2);
    1326             m_url.m_userStart = m_asciiBuffer.size() - 1;
     1351            m_url.m_userStart = currentPosition(c) - 1;
    13271352            m_url.m_userEnd = m_url.m_userStart;
    13281353            m_url.m_passwordEnd = m_url.m_userStart;
     
    13411366                }
    13421367                if (authorityOrHostBegin == c) {
    1343                     ASSERT(m_asciiBuffer[m_asciiBuffer.size() - 1] == '/');
     1368                    ASSERT(m_asciiBuffer[currentPosition(c) - 1] == '/');
    13441369                    if (*c == '?') {
    13451370                        appendToASCIIBuffer("/?", 2);
    1346                         m_url.m_pathAfterLastSlash = m_asciiBuffer.size() - 1;
     1371                        m_url.m_pathAfterLastSlash = currentPosition(c) - 1;
    13471372                        m_url.m_pathEnd = m_url.m_pathAfterLastSlash;
    13481373                        state = State::Query;
     
    13521377                    if (*c == '#') {
    13531378                        appendToASCIIBuffer("/#", 2);
    1354                         m_url.m_pathAfterLastSlash = m_asciiBuffer.size() - 1;
     1379                        m_url.m_pathAfterLastSlash = currentPosition(c) - 1;
    13551380                        m_url.m_pathEnd = m_url.m_pathAfterLastSlash;
    13561381                        m_url.m_queryEnd = m_url.m_pathAfterLastSlash;
     
    13671392                }
    13681393               
    1369                 if (StringView(m_asciiBuffer.data() + m_url.m_passwordEnd, m_asciiBuffer.size() - m_url.m_passwordEnd) == "localhost")  {
     1394                if (StringView(m_asciiBuffer.data() + m_url.m_passwordEnd, currentPosition(c) - m_url.m_passwordEnd) == "localhost")  {
    13701395                    m_asciiBuffer.shrink(m_url.m_passwordEnd);
    1371                     m_url.m_hostEnd = m_asciiBuffer.size();
     1396                    m_url.m_hostEnd = currentPosition(c);
    13721397                    m_url.m_portEnd = m_url.m_hostEnd;
    13731398                }
     
    13901415            if (*c == '/' || (m_urlIsSpecial && *c == '\\')) {
    13911416                appendToASCIIBuffer('/');
    1392                 m_url.m_pathAfterLastSlash = m_asciiBuffer.size();
     1417                m_url.m_pathAfterLastSlash = currentPosition(c);
    13931418                ++c;
    13941419                break;
    13951420            }
    1396             if (m_asciiBuffer.size() && m_asciiBuffer[m_asciiBuffer.size() - 1] == '/') {
     1421            if (currentPosition(c) && m_asciiBuffer[currentPosition(c) - 1] == '/') {
    13971422                if (isDoubleDotPathSegment(c)) {
    13981423                    consumeDoubleDotPathSegment(c);
     
    14001425                    break;
    14011426                }
    1402                 if (m_asciiBuffer[m_asciiBuffer.size() - 1] == '/' && isSingleDotPathSegment(c)) {
     1427                if (m_asciiBuffer[currentPosition(c) - 1] == '/' && isSingleDotPathSegment(c)) {
    14031428                    consumeSingleDotPathSegment(c);
    14041429                    break;
     
    14061431            }
    14071432            if (*c == '?') {
    1408                 m_url.m_pathEnd = m_asciiBuffer.size();
     1433                m_url.m_pathEnd = currentPosition(c);
    14091434                state = State::Query;
    14101435                break;
    14111436            }
    14121437            if (*c == '#') {
    1413                 m_url.m_pathEnd = m_asciiBuffer.size();
     1438                m_url.m_pathEnd = currentPosition(c);
    14141439                m_url.m_queryEnd = m_url.m_pathEnd;
    14151440                state = State::Fragment;
     
    14321457            LOG_STATE("CannotBeABaseURLPath");
    14331458            if (*c == '?') {
    1434                 m_url.m_pathEnd = m_asciiBuffer.size();
     1459                m_url.m_pathEnd = currentPosition(c);
    14351460                state = State::Query;
    14361461            } else if (*c == '#') {
    1437                 m_url.m_pathEnd = m_asciiBuffer.size();
     1462                m_url.m_pathEnd = currentPosition(c);
    14381463                m_url.m_queryEnd = m_url.m_pathEnd;
    14391464                state = State::Fragment;
    14401465            } else if (*c == '/') {
    14411466                appendToASCIIBuffer('/');
    1442                 m_url.m_pathAfterLastSlash = m_asciiBuffer.size();
     1467                m_url.m_pathAfterLastSlash = currentPosition(c);
    14431468                ++c;
    14441469            } else {
     
    14521477                if (!isUTF8Encoding)
    14531478                    encodeQuery(queryBuffer, encoding);
    1454                 m_url.m_queryEnd = m_asciiBuffer.size();
     1479                m_url.m_queryEnd = currentPosition(c);
    14551480                state = State::Fragment;
    14561481                break;
     
    14761501    case State::SchemeStart:
    14771502        LOG_FINAL_STATE("SchemeStart");
    1478         if (!m_asciiBuffer.size() && base.isValid()) {
     1503        if (!currentPosition(c) && base.isValid()) {
    14791504            m_url = base;
    14801505            return;
     
    14971522        LOG_FINAL_STATE("PathOrAuthority");
    14981523        ASSERT(m_url.m_userStart);
    1499         ASSERT(m_url.m_userStart == m_asciiBuffer.size());
     1524        ASSERT(m_url.m_userStart == currentPosition(c));
    15001525        ASSERT(m_asciiBuffer.last() == '/');
    15011526        m_url.m_userStart--;
     
    15241549    case State::SpecialAuthoritySlashes:
    15251550        LOG_FINAL_STATE("SpecialAuthoritySlashes");
    1526         m_url.m_userStart = m_asciiBuffer.size();
     1551        m_url.m_userStart = currentPosition(c);
    15271552        m_url.m_userEnd = m_url.m_userStart;
    15281553        m_url.m_passwordEnd = m_url.m_userStart;
     
    15411566    case State::AuthorityOrHost:
    15421567        LOG_FINAL_STATE("AuthorityOrHost");
    1543         m_url.m_userEnd = m_asciiBuffer.size();
     1568        m_url.m_userEnd = currentPosition(c);
    15441569        m_url.m_passwordEnd = m_url.m_userEnd;
    15451570        if (authorityOrHostBegin.atEnd()) {
     
    15751600        }
    15761601        appendToASCIIBuffer("///", 3);
    1577         m_url.m_userStart = m_asciiBuffer.size() - 1;
     1602        m_url.m_userStart = currentPosition(c) - 1;
    15781603        m_url.m_userEnd = m_url.m_userStart;
    15791604        m_url.m_passwordEnd = m_url.m_userStart;
     
    15881613        LOG_FINAL_STATE("FileSlash");
    15891614        appendToASCIIBuffer("//", 2);
    1590         m_url.m_userStart = m_asciiBuffer.size() - 1;
     1615        m_url.m_userStart = currentPosition(c) - 1;
    15911616        m_url.m_userEnd = m_url.m_userStart;
    15921617        m_url.m_passwordEnd = m_url.m_userStart;
     
    16021627        if (authorityOrHostBegin == c) {
    16031628            appendToASCIIBuffer('/');
    1604             m_url.m_userStart = m_asciiBuffer.size() - 1;
     1629            m_url.m_userStart = currentPosition(c) - 1;
    16051630            m_url.m_userEnd = m_url.m_userStart;
    16061631            m_url.m_passwordEnd = m_url.m_userStart;
     
    16191644        }
    16201645
    1621         if (StringView(m_asciiBuffer.data() + m_url.m_passwordEnd, m_asciiBuffer.size() - m_url.m_passwordEnd) == "localhost")  {
     1646        if (StringView(m_asciiBuffer.data() + m_url.m_passwordEnd, currentPosition(c) - m_url.m_passwordEnd) == "localhost")  {
    16221647            m_asciiBuffer.shrink(m_url.m_passwordEnd);
    1623             m_url.m_hostEnd = m_asciiBuffer.size();
     1648            m_url.m_hostEnd = currentPosition(c);
    16241649            m_url.m_portEnd = m_url.m_hostEnd;
    16251650        }
     
    16351660    case State::Path:
    16361661        LOG_FINAL_STATE("Path");
    1637         m_url.m_pathEnd = m_asciiBuffer.size();
     1662        m_url.m_pathEnd = currentPosition(c);
    16381663        m_url.m_queryEnd = m_url.m_pathEnd;
    16391664        m_url.m_fragmentEnd = m_url.m_pathEnd;
     
    16411666    case State::CannotBeABaseURLPath:
    16421667        LOG_FINAL_STATE("CannotBeABaseURLPath");
    1643         m_url.m_pathEnd = m_asciiBuffer.size();
     1668        m_url.m_pathEnd = currentPosition(c);
    16441669        m_url.m_queryEnd = m_url.m_pathEnd;
    16451670        m_url.m_fragmentEnd = m_url.m_pathEnd;
     
    16491674        if (!isUTF8Encoding)
    16501675            encodeQuery(queryBuffer, encoding);
    1651         m_url.m_queryEnd = m_asciiBuffer.size();
     1676        m_url.m_queryEnd = currentPosition(c);
    16521677        m_url.m_fragmentEnd = m_url.m_queryEnd;
    16531678        break;
    16541679    case State::Fragment:
    16551680        LOG_FINAL_STATE("Fragment");
    1656         m_url.m_fragmentEnd = m_asciiBuffer.size() + m_unicodeFragmentBuffer.size();
     1681        m_url.m_fragmentEnd = currentPosition(c) + m_unicodeFragmentBuffer.size();
    16571682        break;
    16581683    }
    16591684
    1660     if (m_unicodeFragmentBuffer.isEmpty())
     1685    if (!m_seenSyntaxError) {
     1686        m_url.m_string = m_inputString;
     1687        ASSERT(m_asciiBuffer.isEmpty());
     1688        ASSERT(m_unicodeFragmentBuffer.isEmpty());
     1689    } else if (m_unicodeFragmentBuffer.isEmpty())
    16611690        m_url.m_string = String::adopt(WTFMove(m_asciiBuffer));
    16621691    else {
    16631692        Vector<UChar> buffer;
    1664         buffer.reserveInitialCapacity(m_asciiBuffer.size() + m_unicodeFragmentBuffer.size());
     1693        buffer.reserveInitialCapacity(currentPosition(c) + m_unicodeFragmentBuffer.size());
    16651694        buffer.appendVector(m_asciiBuffer);
    16661695        buffer.appendVector(m_unicodeFragmentBuffer);
     
    16761705{
    16771706    if (iterator.atEnd()) {
    1678         m_url.m_userEnd = m_asciiBuffer.size();
     1707        m_url.m_userEnd = currentPosition(iterator);
    16791708        m_url.m_passwordEnd = m_url.m_userEnd;
    16801709        return;
     
    16831712        if (*iterator == ':') {
    16841713            ++iterator;
    1685             m_url.m_userEnd = m_asciiBuffer.size();
     1714            m_url.m_userEnd = currentPosition(iterator);
    16861715            if (iterator.atEnd()) {
    16871716                m_url.m_passwordEnd = m_url.m_userEnd;
     
    16971726    for (; !iterator.atEnd(); ++iterator)
    16981727        utf8PercentEncode<isInUserInfoEncodeSet>(*iterator);
    1699     m_url.m_passwordEnd = m_asciiBuffer.size();
     1728    m_url.m_passwordEnd = currentPosition(iterator);
    17001729    if (!m_url.m_userEnd)
    17011730        m_url.m_userEnd = m_url.m_passwordEnd;
     
    17041733
    17051734template<typename UnsignedIntegerType>
    1706 void append(Vector<LChar>& destination, UnsignedIntegerType number)
     1735void URLParser::appendNumberToASCIIBuffer(UnsignedIntegerType number)
    17071736{
    17081737    LChar buf[sizeof(UnsignedIntegerType) * 3 + 1];
     
    17131742        number /= 10;
    17141743    } while (number);
    1715     destination.append(p, end - p);
    1716 }
    1717 
    1718 inline static void serializeIPv4(uint32_t address, Vector<LChar>& buffer)
    1719 {
    1720     append<uint8_t>(buffer, address >> 24);
    1721     buffer.append('.');
    1722     append<uint8_t>(buffer, address >> 16);
    1723     buffer.append('.');
    1724     append<uint8_t>(buffer, address >> 8);
    1725     buffer.append('.');
    1726     append<uint8_t>(buffer, address);
     1744    appendToASCIIBuffer(p, end - p);
     1745}
     1746
     1747void URLParser::serializeIPv4(IPv4Address address)
     1748{
     1749    appendNumberToASCIIBuffer<uint8_t>(address >> 24);
     1750    appendToASCIIBuffer('.');
     1751    appendNumberToASCIIBuffer<uint8_t>(address >> 16);
     1752    appendToASCIIBuffer('.');
     1753    appendNumberToASCIIBuffer<uint8_t>(address >> 8);
     1754    appendToASCIIBuffer('.');
     1755    appendNumberToASCIIBuffer<uint8_t>(address);
    17271756}
    17281757   
     
    17531782    return longest;
    17541783}
    1755    
    1756 inline static void serializeIPv6Piece(uint16_t piece, Vector<LChar>& buffer)
     1784
     1785void URLParser::serializeIPv6Piece(uint16_t piece)
    17571786{
    17581787    bool printed = false;
    17591788    if (auto nibble0 = piece >> 12) {
    1760         buffer.append(lowerNibbleToLowercaseASCIIHexDigit(nibble0));
     1789        appendToASCIIBuffer(lowerNibbleToLowercaseASCIIHexDigit(nibble0));
    17611790        printed = true;
    17621791    }
    17631792    auto nibble1 = piece >> 8 & 0xF;
    17641793    if (printed || nibble1) {
    1765         buffer.append(lowerNibbleToLowercaseASCIIHexDigit(nibble1));
     1794        appendToASCIIBuffer(lowerNibbleToLowercaseASCIIHexDigit(nibble1));
    17661795        printed = true;
    17671796    }
    17681797    auto nibble2 = piece >> 4 & 0xF;
    17691798    if (printed || nibble2)
    1770         buffer.append(lowerNibbleToLowercaseASCIIHexDigit(nibble2));
    1771     buffer.append(lowerNibbleToLowercaseASCIIHexDigit(piece & 0xF));
    1772 }
    1773 
    1774 inline static void serializeIPv6(std::array<uint16_t, 8> address, Vector<LChar>& buffer)
    1775 {
    1776     buffer.append('[');
     1799        appendToASCIIBuffer(lowerNibbleToLowercaseASCIIHexDigit(nibble2));
     1800    appendToASCIIBuffer(lowerNibbleToLowercaseASCIIHexDigit(piece & 0xF));
     1801}
     1802
     1803void URLParser::serializeIPv6(URLParser::IPv6Address address)
     1804{
     1805    appendToASCIIBuffer('[');
    17771806    auto compressPointer = findLongestZeroSequence(address);
    17781807    for (size_t piece = 0; piece < 8; piece++) {
     
    17801809            ASSERT(!address[piece]);
    17811810            if (piece)
    1782                 buffer.append(':');
     1811                appendToASCIIBuffer(':');
    17831812            else
    1784                 buffer.append("::", 2);
     1813                appendToASCIIBuffer("::", 2);
    17851814            while (piece < 8 && !address[piece])
    17861815                piece++;
     
    17881817                break;
    17891818        }
    1790         serializeIPv6Piece(address[piece], buffer);
     1819        serializeIPv6Piece(address[piece]);
    17911820        if (piece < 7)
    1792             buffer.append(':');
    1793     }
    1794     buffer.append(']');
     1821            appendToASCIIBuffer(':');
     1822    }
     1823    appendToASCIIBuffer(']');
    17951824}
    17961825
     
    18641893
    18651894template<typename CharacterType>
    1866 inline static Optional<uint32_t> parseIPv4Host(CodePointIterator<CharacterType> iterator)
     1895Optional<URLParser::IPv4Address> URLParser::parseIPv4Host(CodePointIterator<CharacterType> iterator)
    18671896{
    18681897    Vector<uint32_t, 4> items;
     
    18901919            return Nullopt;
    18911920    }
    1892     uint32_t ipv4 = items.takeLast();
     1921    IPv4Address ipv4 = items.takeLast();
    18931922    for (size_t counter = 0; counter < items.size(); ++counter)
    18941923        ipv4 += items[counter] * pow256(3 - counter);
     
    18971926   
    18981927template<typename CharacterType>
    1899 inline static Optional<std::array<uint16_t, 8>> parseIPv6Host(CodePointIterator<CharacterType> c)
     1928Optional<URLParser::IPv6Address> URLParser::parseIPv6Host(CodePointIterator<CharacterType> c)
    19001929{
    19011930    if (c.atEnd())
    19021931        return Nullopt;
    19031932
    1904     std::array<uint16_t, 8> address = {{0, 0, 0, 0, 0, 0, 0, 0}};
     1933    IPv6Address address = {{0, 0, 0, 0, 0, 0, 0, 0}};
    19051934    size_t piecePointer = 0;
    19061935    Optional<size_t> compressPointer;
     
    20792108    uint32_t port = 0;
    20802109    if (iterator.atEnd()) {
    2081         m_url.m_portEnd = m_asciiBuffer.size();
     2110        m_url.m_portEnd = currentPosition(iterator);
    20822111        return true;
    20832112    }
     
    20962125    if (isDefaultPort(StringView(m_asciiBuffer.data(), m_url.m_schemeEnd), port)) {
    20972126        ASSERT(m_asciiBuffer.last() == ':');
    2098         m_asciiBuffer.shrink(m_asciiBuffer.size() - 1);
    2099     } else
    2100         append<uint16_t>(m_asciiBuffer, static_cast<uint16_t>(port));
    2101 
    2102     m_url.m_portEnd = m_asciiBuffer.size();
     2127        m_asciiBuffer.shrink(currentPosition(iterator) - 1);
     2128    } else {
     2129        ASSERT(port <= std::numeric_limits<uint16_t>::max());
     2130        appendNumberToASCIIBuffer<uint16_t>(static_cast<uint16_t>(port));
     2131    }
     2132
     2133    m_url.m_portEnd = currentPosition(iterator);
    21032134    return true;
    21042135}
     
    21152146            ++ipv6End;
    21162147        if (auto address = parseIPv6Host(CodePointIterator<CharacterType>(iterator, ipv6End))) {
    2117             serializeIPv6(address.value(), m_asciiBuffer);
    2118             m_url.m_hostEnd = m_asciiBuffer.size();
     2148            serializeIPv6(address.value());
     2149            m_url.m_hostEnd = currentPosition(iterator);
    21192150            if (!ipv6End.atEnd()) {
    21202151                ++ipv6End;
     
    21232154                    return parsePort(ipv6End);
    21242155                }
    2125                 m_url.m_portEnd = m_asciiBuffer.size();
     2156                m_url.m_portEnd = currentPosition(iterator);
    21262157                return true;
    21272158            }
     
    21412172        }
    21422173        if (auto address = parseIPv4Host(CodePointIterator<CharacterType>(hostIterator, iterator))) {
    2143             serializeIPv4(address.value(), m_asciiBuffer);
    2144             m_url.m_hostEnd = m_asciiBuffer.size();
     2174            serializeIPv4(address.value());
     2175            m_url.m_hostEnd = currentPosition(iterator);
    21452176            if (iterator.atEnd()) {
    2146                 m_url.m_portEnd = m_asciiBuffer.size();
     2177                m_url.m_portEnd = currentPosition(iterator);
    21472178                return true;
    21482179            }
     
    21542185                appendToASCIIBuffer(toASCIILower(*hostIterator));
    21552186        }
    2156         m_url.m_hostEnd = m_asciiBuffer.size();
     2187        m_url.m_hostEnd = currentPosition(iterator);
    21572188        if (!hostIterator.atEnd()) {
    21582189            ASSERT(*hostIterator == ':');
     
    21602191            return parsePort(hostIterator);
    21612192        }
    2162         m_url.m_portEnd = m_asciiBuffer.size();
     2193        m_url.m_portEnd = currentPosition(iterator);
    21632194        return true;
    21642195    }
     
    21872218
    21882219    if (auto address = parseIPv4Host(CodePointIterator<LChar>(asciiDomainValue.begin(), asciiDomainValue.end()))) {
    2189         serializeIPv4(address.value(), m_asciiBuffer);
    2190         m_url.m_hostEnd = m_asciiBuffer.size();
     2220        serializeIPv4(address.value());
     2221        m_url.m_hostEnd = currentPosition(iterator);
    21912222        if (iterator.atEnd()) {
    2192             m_url.m_portEnd = m_asciiBuffer.size();
     2223            m_url.m_portEnd = currentPosition(iterator);
    21932224            return true;
    21942225        }
     
    21982229
    21992230    appendToASCIIBuffer(asciiDomainCharacters, asciiDomainValue.size());
    2200     m_url.m_hostEnd = m_asciiBuffer.size();
     2231    m_url.m_hostEnd = currentPosition(iterator);
    22012232    if (!iterator.atEnd()) {
    22022233        ASSERT(*iterator == ':');
     
    22042235        return parsePort(iterator);
    22052236    }
    2206     m_url.m_portEnd = m_asciiBuffer.size();
     2237    m_url.m_portEnd = currentPosition(iterator);
    22072238    return true;
    22082239}
  • trunk/Source/WebCore/platform/URLParser.h

    r206334 r206337  
    5757    bool m_hostHasPercentOrNonASCII { false };
    5858    String m_inputString;
     59    const void* m_inputBegin { nullptr };
     60
     61    // FIXME: This should start out as false and only change to true when we see a syntax error once syntax error handling is implemented.
     62    bool m_seenSyntaxError { true };
    5963
    6064    template<typename CharacterType> void parse(const CharacterType*, const unsigned length, const URL&, const TextEncoding&);
     
    6973    template<typename CharacterType> bool shouldCopyFileURL(CodePointIterator<CharacterType>);
    7074    template<typename CharacterType> void checkWindowsDriveLetter(CodePointIterator<CharacterType>&);
     75    template<typename CharacterType> size_t currentPosition(const CodePointIterator<CharacterType>&);
     76    template<typename UnsignedIntegerType> void appendNumberToASCIIBuffer(UnsignedIntegerType);
    7177    template<bool(*isInCodeSet)(UChar32)> void utf8PercentEncode(UChar32);
    7278    void utf8QueryEncode(UChar32);
     
    7884    void copyASCIIStringUntil(const String&, size_t lengthIf8Bit, size_t lengthIf16Bit);
    7985
     86    using IPv4Address = uint32_t;
     87    void serializeIPv4(IPv4Address);
     88    template<typename CharacterType> Optional<IPv4Address> parseIPv4Host(CodePointIterator<CharacterType>);
     89    using IPv6Address = std::array<uint16_t, 8>;
     90    template<typename CharacterType> Optional<IPv6Address> parseIPv6Host(CodePointIterator<CharacterType>);
     91    void serializeIPv6Piece(uint16_t piece);
     92    void serializeIPv6(URLParser::IPv6Address);
     93
    8094    enum class URLPart;
    8195    void copyURLPartsUntil(const URL& base, URLPart);
Note: See TracChangeset for help on using the changeset viewer.