Bug 44080 - String find/reverseFind methods need tidying up
authorbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Aug 2010 23:31:33 +0000 (23:31 +0000)
committerbarraclough@apple.com <barraclough@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 16 Aug 2010 23:31:33 +0000 (23:31 +0000)
These methods have a couple of problems with their interface, and implementation.

Reviewed by Sam Weinig

These methods take and int index, and return an int - however this is problematic
since on 64-bit string indices may have a full 32-bit range.  This spills out into
surrounding code, which unsafely casts string indices from unsigned to int. Code
checking the result of these methods check for a mix of "== -1", "< 0", and
"== notFound".  Clean this up by changing these methods to take an unsigned
starting index, and return a size_t. with a failed match indicated by notFound.
reverseFind also has a special meaning for the starting index argument, in that a
negative index is interpreted as an offset back from the end of the string. Remove
this functionality, in the (1!) case where it is used we should just calculate the
offset by subtracting from the string's length.

The implementation has a few problems too.  The code is not in webkit style, in
using assorted abbreviations in variable names, and implementations of similar
find methods with differing argument types were unnecessarily inconsistent. When
find is passed const char* data the string would be handled as latin1 (zero
extended to UTF-16) for all characters but the first; this is sign extended.
Case-insensitive find is broken for unicode strings; the hashing optimization is
not unicode safe, and could result in false negatives.

Unify UString find methods to match String.

JavaScriptCore:

* JavaScriptCore.exp:
* bytecode/CodeBlock.cpp:
(JSC::escapeQuotes):
* bytecompiler/NodesCodegen.cpp:
(JSC::substitute):
* runtime/JSString.cpp:
(JSC::JSString::replaceCharacter):
* runtime/RegExp.cpp:
(JSC::RegExp::RegExp):
* runtime/RegExpKey.h:
(JSC::RegExpKey::getFlagsValue):
* runtime/StringPrototype.cpp:
(JSC::substituteBackreferencesSlow):
(JSC::substituteBackreferences):
(JSC::stringProtoFuncReplace):
(JSC::stringProtoFuncIndexOf):
(JSC::stringProtoFuncLastIndexOf):
(JSC::stringProtoFuncSplit):
* runtime/UString.cpp:
* runtime/UString.h:
(JSC::UString::find):
(JSC::UString::reverseFind):
* wtf/text/AtomicString.h:
(WTF::AtomicString::find):
* wtf/text/StringImpl.cpp:
(WTF::StringImpl::find):
(WTF::StringImpl::findCaseInsensitive):
(WTF::StringImpl::reverseFind):
(WTF::StringImpl::reverseFindCaseInsensitive):
(WTF::StringImpl::endsWith):
(WTF::StringImpl::replace):
* wtf/text/StringImpl.h:
(WTF::StringImpl::startsWith):
* wtf/text/WTFString.cpp:
(WTF::String::split):
* wtf/text/WTFString.h:
(WTF::String::find):
(WTF::String::reverseFind):
(WTF::String::findCaseInsensitive):
(WTF::String::reverseFindCaseInsensitive):
(WTF::String::contains):
(WTF::find):
(WTF::reverseFind):

WebCore:

* css/CSSSelector.cpp:
(WebCore::CSSSelector::RareData::parseNth):
* css/CSSStyleDeclaration.cpp:
(WebCore::CSSStyleDeclaration::setProperty):
* css/CSSStyleSelector.cpp:
(WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
* dom/Document.cpp:
(WebCore::Document::getImageMap):
* editing/CompositeEditCommand.cpp:
(WebCore::CompositeEditCommand::inputText):
* editing/InsertTextCommand.cpp:
(WebCore::InsertTextCommand::input):
* editing/TextIterator.cpp:
(WebCore::TextIterator::handleTextBox):
* editing/TypingCommand.cpp:
(WebCore::TypingCommand::insertText):
* editing/markup.cpp:
(WebCore::fillContainerFromString):
(WebCore::createFragmentFromText):
* html/File.cpp:
(WebCore::File::Init):
* html/HTMLAnchorElement.cpp:
(WebCore::HTMLAnchorElement::setHost):
* html/HTMLEmbedElement.cpp:
(WebCore::HTMLEmbedElement::parseMappedAttribute):
* html/HTMLFormControlElement.cpp:
(WebCore::HTMLTextFormControlElement::isPlaceholderEmpty):
* html/HTMLObjectElement.cpp:
(WebCore::HTMLObjectElement::parseMappedAttribute):
* inspector/InspectorDOMAgent.cpp:
(WebCore::InspectorDOMAgent::performSearch):
* loader/CrossOriginPreflightResultCache.cpp:
(WebCore::parseAccessControlAllowList):
* loader/MainResourceLoader.cpp:
(WebCore::MainResourceLoader::substituteMIMETypeFromPluginDatabase):
* loader/appcache/ApplicationCacheStorage.cpp:
(WebCore::parseHeader):
(WebCore::parseHeaders):
* loader/icon/IconFetcher.cpp:
(WebCore::parseIconLink):
* page/DOMWindow.cpp:
(WebCore::DOMWindow::parseModalDialogFeatures):
* page/SecurityOrigin.cpp:
(WebCore::SecurityOrigin::createFromDatabaseIdentifier):
* page/UserContentURLPattern.cpp:
(WebCore::UserContentURLPattern::parse):
* page/XSSAuditor.cpp:
(WebCore::XSSAuditor::findInRequest):
* platform/ContentType.cpp:
(WebCore::ContentType::parameter):
(WebCore::ContentType::type):
* platform/KURL.cpp:
(WebCore::KURL::lastPathComponent):
(WebCore::KURL::setProtocol):
(WebCore::decodeURLEscapeSequences):
(WebCore::substituteBackslashes):
(WebCore::mimeTypeFromDataURL):
* platform/Length.cpp:
(WebCore::newCoordsArray):
(WebCore::newLengthArray):
* platform/LinkHash.cpp:
(WebCore::findSlashDotDotSlash):
(WebCore::findSlashSlash):
(WebCore::findSlashDotSlash):
(WebCore::cleanPath):
* platform/MIMETypeRegistry.cpp:
(WebCore::MIMETypeRegistry::getMIMETypeForPath):
* platform/SchemeRegistry.cpp:
(WebCore::SchemeRegistry::shouldTreatURLAsLocal):
* platform/graphics/MediaPlayer.cpp:
(WebCore::MediaPlayer::load):
* platform/mac/DragImageMac.mm:
(WebCore::createDragImageIconForCachedImage):
* platform/network/CredentialStorage.cpp:
(WebCore::protectionSpaceMapKeyFromURL):
(WebCore::findDefaultProtectionSpaceForURL):
* platform/network/HTTPParsers.cpp:
(WebCore::skipWhiteSpace):
(WebCore::skipToken):
(WebCore::parseHTTPRefresh):
(WebCore::filenameFromHTTPContentDisposition):
(WebCore::findCharsetInMediaType):
(WebCore::parseXSSProtectionHeader):
(WebCore::extractReasonPhraseFromHTTPStatusLine):
* platform/network/ResourceResponseBase.cpp:
(WebCore::ResourceResponseBase::isAttachment):
(WebCore::parseCacheHeader):
* rendering/RenderEmbeddedObject.cpp:
(WebCore::RenderEmbeddedObject::updateWidget):
* storage/Entry.cpp:
(WebCore::Entry::Entry):
* svg/SVGFont.cpp:
(WebCore::isCompatibleGlyph):
* svg/SVGURIReference.cpp:
(WebCore::SVGURIReference::getTarget):
* svg/animation/SVGSMILElement.cpp:
(WebCore::SVGSMILElement::parseClockValue):
(WebCore::SVGSMILElement::parseCondition):
* xml/XPathFunctions.cpp:
(WebCore::XPath::FunSubstringBefore::evaluate):
(WebCore::XPath::FunSubstringAfter::evaluate):
(WebCore::XPath::FunTranslate::evaluate):
(WebCore::XPath::FunLang::evaluate):
* xml/XPathParser.cpp:
(WebCore::XPath::Parser::expandQName):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@65468 268f45cc-cd09-0410-ab3c-d52691b4dbfc

58 files changed:
JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.exp
JavaScriptCore/bytecode/CodeBlock.cpp
JavaScriptCore/bytecompiler/NodesCodegen.cpp
JavaScriptCore/runtime/JSString.cpp
JavaScriptCore/runtime/RegExp.cpp
JavaScriptCore/runtime/RegExpKey.h
JavaScriptCore/runtime/StringPrototype.cpp
JavaScriptCore/runtime/UString.cpp
JavaScriptCore/runtime/UString.h
JavaScriptCore/wtf/text/AtomicString.h
JavaScriptCore/wtf/text/StringImpl.cpp
JavaScriptCore/wtf/text/StringImpl.h
JavaScriptCore/wtf/text/WTFString.cpp
JavaScriptCore/wtf/text/WTFString.h
WebCore/ChangeLog
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/css/CSSSelector.cpp
WebCore/css/CSSStyleDeclaration.cpp
WebCore/css/CSSStyleSelector.cpp
WebCore/dom/Document.cpp
WebCore/editing/CompositeEditCommand.cpp
WebCore/editing/InsertTextCommand.cpp
WebCore/editing/TextIterator.cpp
WebCore/editing/TypingCommand.cpp
WebCore/editing/markup.cpp
WebCore/html/File.cpp
WebCore/html/HTMLAnchorElement.cpp
WebCore/html/HTMLEmbedElement.cpp
WebCore/html/HTMLFormControlElement.cpp
WebCore/html/HTMLObjectElement.cpp
WebCore/inspector/InspectorDOMAgent.cpp
WebCore/loader/CrossOriginPreflightResultCache.cpp
WebCore/loader/MainResourceLoader.cpp
WebCore/loader/appcache/ApplicationCacheStorage.cpp
WebCore/loader/icon/IconFetcher.cpp
WebCore/page/DOMWindow.cpp
WebCore/page/SecurityOrigin.cpp
WebCore/page/UserContentURLPattern.cpp
WebCore/page/XSSAuditor.cpp
WebCore/platform/ContentType.cpp
WebCore/platform/KURL.cpp
WebCore/platform/Length.cpp
WebCore/platform/LinkHash.cpp
WebCore/platform/MIMETypeRegistry.cpp
WebCore/platform/SchemeRegistry.cpp
WebCore/platform/graphics/MediaPlayer.cpp
WebCore/platform/mac/DragImageMac.mm
WebCore/platform/network/CredentialStorage.cpp
WebCore/platform/network/HTTPParsers.cpp
WebCore/platform/network/ResourceResponseBase.cpp
WebCore/rendering/RenderEmbeddedObject.cpp
WebCore/storage/Entry.cpp
WebCore/svg/SVGFont.cpp
WebCore/svg/SVGURIReference.cpp
WebCore/svg/animation/SVGSMILElement.cpp
WebCore/xml/XPathFunctions.cpp
WebCore/xml/XPathParser.cpp

index 1b0a7ea..3eab5a7 100644 (file)
@@ -1,3 +1,75 @@
+2010-08-16  Gavin Barraclough  <barraclough@apple.com>
+
+        Reviewed by Sam Weinig
+
+        Bug 44080 - String find/reverseFind methods need tidying up
+        These methods have a couple of problems with their interface, and implementation.
+
+        These methods take and int index, and return an int - however this is problematic
+        since on 64-bit string indices may have a full 32-bit range.  This spills out into
+        surrounding code, which unsafely casts string indices from unsigned to int. Code
+        checking the result of these methods check for a mix of "== -1", "< 0", and
+        "== notFound".  Clean this up by changing these methods to take an unsigned
+        starting index, and return a size_t. with a failed match indicated by notFound.
+        reverseFind also has a special meaning for the starting index argument, in that a
+        negative index is interpreted as an offset back from the end of the string. Remove
+        this functionality, in the (1!) case where it is used we should just calculate the
+        offset by subtracting from the string's length.
+
+        The implementation has a few problems too.  The code is not in webkit style, in
+        using assorted abbreviations in variable names, and implementations of similar
+        find methods with differing argument types were unnecessarily inconsistent. When
+        find is passed const char* data the string would be handled as latin1 (zero
+        extended to UTF-16) for all characters but the first; this is sign extended.
+        Case-insensitive find is broken for unicode strings; the hashing optimization is
+        not unicode safe, and could result in false negatives.
+
+        Unify UString find methods to match String.
+
+        * JavaScriptCore.exp:
+        * bytecode/CodeBlock.cpp:
+        (JSC::escapeQuotes):
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::substitute):
+        * runtime/JSString.cpp:
+        (JSC::JSString::replaceCharacter):
+        * runtime/RegExp.cpp:
+        (JSC::RegExp::RegExp):
+        * runtime/RegExpKey.h:
+        (JSC::RegExpKey::getFlagsValue):
+        * runtime/StringPrototype.cpp:
+        (JSC::substituteBackreferencesSlow):
+        (JSC::substituteBackreferences):
+        (JSC::stringProtoFuncReplace):
+        (JSC::stringProtoFuncIndexOf):
+        (JSC::stringProtoFuncLastIndexOf):
+        (JSC::stringProtoFuncSplit):
+        * runtime/UString.cpp:
+        * runtime/UString.h:
+        (JSC::UString::find):
+        (JSC::UString::reverseFind):
+        * wtf/text/AtomicString.h:
+        (WTF::AtomicString::find):
+        * wtf/text/StringImpl.cpp:
+        (WTF::StringImpl::find):
+        (WTF::StringImpl::findCaseInsensitive):
+        (WTF::StringImpl::reverseFind):
+        (WTF::StringImpl::reverseFindCaseInsensitive):
+        (WTF::StringImpl::endsWith):
+        (WTF::StringImpl::replace):
+        * wtf/text/StringImpl.h:
+        (WTF::StringImpl::startsWith):
+        * wtf/text/WTFString.cpp:
+        (WTF::String::split):
+        * wtf/text/WTFString.h:
+        (WTF::String::find):
+        (WTF::String::reverseFind):
+        (WTF::String::findCaseInsensitive):
+        (WTF::String::reverseFindCaseInsensitive):
+        (WTF::String::contains):
+        (WTF::find):
+        (WTF::reverseFind):
+
 2010-08-16  Kevin Ollivier  <kevino@theolliviers.com>
 
         [wx] Build fix, do not build WebCore as a convenience library as this leads to
index d4ebae6..ffd1b93 100644 (file)
@@ -319,19 +319,22 @@ __ZN3JSC9constructEPNS_9ExecStateENS_7JSValueENS_13ConstructTypeERKNS_13Construc
 __ZN3JSCeqERKNS_7UStringEPKc
 __ZN3JSCgtERKNS_7UStringES2_
 __ZN3JSCltERKNS_7UStringES2_
-__ZN3WTF10StringImpl11reverseFindEPS0_ib
-__ZN3WTF10StringImpl11reverseFindEti
+__ZN3WTF10StringImpl11reverseFindEPS0_j
+__ZN3WTF10StringImpl11reverseFindEtj
 __ZN3WTF10StringImpl12sharedBufferEv
+__ZN3WTF10StringImpl16findIgnoringCaseEPKcj
+__ZN3WTF10StringImpl16findIgnoringCaseEPS0_j
 __ZN3WTF10StringImpl18simplifyWhiteSpaceEv
 __ZN3WTF10StringImpl19characterStartingAtEj
 __ZN3WTF10StringImpl19createUninitializedEjRPt
 __ZN3WTF10StringImpl22containsOnlyWhitespaceEv
 __ZN3WTF10StringImpl23defaultWritingDirectionEv
+__ZN3WTF10StringImpl23reverseFindIgnoringCaseEPS0_j
 __ZN3WTF10StringImpl37createStrippingNullCharactersSlowCaseEPKtj
-__ZN3WTF10StringImpl4findEPFbtEi
-__ZN3WTF10StringImpl4findEPKcib
-__ZN3WTF10StringImpl4findEPS0_ib
-__ZN3WTF10StringImpl4findEti
+__ZN3WTF10StringImpl4findEPFbtEj
+__ZN3WTF10StringImpl4findEPKcj
+__ZN3WTF10StringImpl4findEPS0_j
+__ZN3WTF10StringImpl4findEtj
 __ZN3WTF10StringImpl5adoptERNS_12StringBufferE
 __ZN3WTF10StringImpl5emptyEv
 __ZN3WTF10StringImpl5lowerEv
index 289ffed..b916595 100644 (file)
@@ -50,8 +50,8 @@ namespace JSC {
 static UString escapeQuotes(const UString& str)
 {
     UString result = str;
-    unsigned pos = 0;
-    while ((pos = result.find('\"', pos)) != UString::NotFound) {
+    size_t pos = 0;
+    while ((pos = result.find('\"', pos)) != notFound) {
         result = makeString(result.substr(0, pos), "\"\\\"\"", result.substr(pos + 1));
         pos += 4;
     }
index dadf3f7..5b5a908 100644 (file)
@@ -78,8 +78,8 @@ namespace JSC {
 
 static void substitute(UString& string, const UString& substring)
 {
-    unsigned position = string.find("%s");
-    ASSERT(position != UString::NotFound);
+    size_t position = string.find("%s");
+    ASSERT(position != notFound);
     string = makeString(string.substr(0, position), substring, string.substr(position + 2));
 }
 
index 4e6efc9..99e49b6 100644 (file)
@@ -108,8 +108,8 @@ void JSString::resolveRope(ExecState* exec) const
 JSValue JSString::replaceCharacter(ExecState* exec, UChar character, const UString& replacement)
 {
     if (!isRope()) {
-        unsigned matchPosition = m_value.find(character);
-        if (matchPosition == UString::NotFound)
+        size_t matchPosition = m_value.find(character);
+        if (matchPosition == notFound)
             return JSValue(this);
         return jsString(exec, m_value.substr(0, matchPosition), replacement, m_value.substr(matchPosition + 1));
     }
@@ -119,7 +119,7 @@ JSValue JSString::replaceCharacter(ExecState* exec, UChar character, const UStri
     // Count total fibers and find matching string.
     size_t fiberCount = 0;
     StringImpl* matchString = 0;
-    int matchPosition = -1;
+    size_t matchPosition = notFound;
     for (RopeIterator it(m_other.m_fibers.data(), m_fiberCount); it != end; ++it) {
         ++fiberCount;
         if (matchString)
@@ -127,7 +127,7 @@ JSValue JSString::replaceCharacter(ExecState* exec, UChar character, const UStri
 
         StringImpl* string = *it;
         matchPosition = string->find(character);
-        if (matchPosition == -1)
+        if (matchPosition == notFound)
             continue;
         matchString = string;
     }
index f0bb5bd..2b844c1 100644 (file)
@@ -56,11 +56,11 @@ inline RegExp::RegExp(JSGlobalData* globalData, const UString& pattern, const US
     // NOTE: The global flag is handled on a case-by-case basis by functions like
     // String::match and RegExpObject::match.
     if (!flags.isNull()) {
-        if (flags.find('g') != UString::NotFound)
+        if (flags.find('g') != notFound)
             m_flagBits |= Global;
-        if (flags.find('i') != UString::NotFound)
+        if (flags.find('i') != notFound)
             m_flagBits |= IgnoreCase;
-        if (flags.find('m') != UString::NotFound)
+        if (flags.find('m') != notFound)
             m_flagBits |= Multiline;
     }
     compile(globalData);
index e2ea100..1e34de4 100644 (file)
@@ -73,11 +73,11 @@ struct RegExpKey {
     int getFlagsValue(const UString flags) 
     {
         flagsValue = 0;
-        if (flags.find('g') != UString::NotFound)
+        if (flags.find('g') != notFound)
             flagsValue += 4;
-        if (flags.find('i') != UString::NotFound)
+        if (flags.find('i') != notFound)
             flagsValue += 2;
-        if (flags.find('m') != UString::NotFound)
+        if (flags.find('m') != notFound)
             flagsValue += 1;
         return flagsValue;
     }
index 7e9131e..ef5d137 100644 (file)
@@ -151,7 +151,7 @@ bool StringPrototype::getOwnPropertyDescriptor(ExecState* exec, const Identifier
 
 // ------------------------------ Functions --------------------------
 
-static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacement, const UString& source, const int* ovector, RegExp* reg, unsigned i)
+static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacement, const UString& source, const int* ovector, RegExp* reg, size_t i)
 {
     Vector<UChar> substitutedReplacement;
     int offset = 0;
@@ -207,7 +207,7 @@ static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacem
         i += 1 + advance;
         offset = i + 1;
         substitutedReplacement.append(source.characters() + backrefStart, backrefLength);
-    } while ((i = replacement.find('$', i + 1)) != UString::NotFound);
+    } while ((i = replacement.find('$', i + 1)) != notFound);
 
     if (replacement.length() - offset)
         substitutedReplacement.append(replacement.characters() + offset, replacement.length() - offset);
@@ -218,8 +218,8 @@ static NEVER_INLINE UString substituteBackreferencesSlow(const UString& replacem
 
 static inline UString substituteBackreferences(const UString& replacement, const UString& source, const int* ovector, RegExp* reg)
 {
-    unsigned i = replacement.find('$', 0);
-    if (UNLIKELY(i != UString::NotFound))
+    size_t i = replacement.find('$', 0);
+    if (UNLIKELY(i != notFound))
         return substituteBackreferencesSlow(replacement, source, ovector, reg, i);
     return replacement;
 }
@@ -429,9 +429,9 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncReplace(ExecState* exec)
         return JSValue::encode(sourceVal->replaceCharacter(exec, patternString[0], replacementString));
     
     const UString& source = sourceVal->value(exec);
-    unsigned matchPos = source.find(patternString);
+    size_t matchPos = source.find(patternString);
 
-    if (matchPos == UString::NotFound)
+    if (matchPos == notFound)
         return JSValue::encode(sourceVal);
 
     int matchLen = patternString.length();
@@ -542,8 +542,8 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncIndexOf(ExecState* exec)
         pos = static_cast<int>(dpos);
     }
 
-    unsigned result = s.find(u2, pos);
-    if (result == UString::NotFound)
+    size_t result = s.find(u2, pos);
+    if (result == notFound)
         return JSValue::encode(jsNumber(exec, -1));
     return JSValue::encode(jsNumber(exec, result));
 }
@@ -571,8 +571,8 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncLastIndexOf(ExecState* exec)
         dpos = len;
 #endif
 
-    unsigned result = s.rfind(u2, static_cast<unsigned>(dpos));
-    if (result == UString::NotFound)
+    size_t result = s.reverseFind(u2, static_cast<unsigned>(dpos));
+    if (result == notFound)
         return JSValue::encode(jsNumber(exec, -1));
     return JSValue::encode(jsNumber(exec, result));
 }
@@ -736,9 +736,8 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec)
             while (i != limit && p0 < s.length() - 1)
                 result->put(exec, i++, jsSingleCharacterSubstring(exec, s, p0++));
         } else {
-            unsigned pos;
-            
-            while (i != limit && (pos = s.find(u2, p0)) != UString::NotFound) {
+            size_t pos;
+            while (i != limit && (pos = s.find(u2, p0)) != notFound) {
                 result->put(exec, i++, jsSubstring(exec, s, p0, pos - p0));
                 p0 = pos + u2.length();
             }
index 86e1cbf..fecf4f1 100644 (file)
@@ -413,83 +413,6 @@ uint32_t UString::toStrictUInt32(bool* ok) const
     }
 }
 
-unsigned UString::find(const UString& f, unsigned pos) const
-{
-    unsigned fsz = f.length();
-
-    if (fsz == 1) {
-        UChar ch = f[0];
-        const UChar* end = characters() + length();
-        for (const UChar* c = characters() + pos; c < end; c++) {
-            if (*c == ch)
-                return static_cast<unsigned>(c - characters());
-        }
-        return NotFound;
-    }
-
-    unsigned sz = length();
-    if (sz < fsz)
-        return NotFound;
-    if (fsz == 0)
-        return pos;
-    const UChar* end = characters() + sz - fsz;
-    unsigned fsizeminusone = (fsz - 1) * sizeof(UChar);
-    const UChar* fdata = f.characters();
-    unsigned short fchar = fdata[0];
-    ++fdata;
-    for (const UChar* c = characters() + pos; c <= end; c++) {
-        if (c[0] == fchar && !memcmp(c + 1, fdata, fsizeminusone))
-            return static_cast<unsigned>(c - characters());
-    }
-
-    return NotFound;
-}
-
-unsigned UString::find(UChar ch, unsigned pos) const
-{
-    const UChar* end = characters() + length();
-    for (const UChar* c = characters() + pos; c < end; c++) {
-        if (*c == ch)
-            return static_cast<unsigned>(c - characters());
-    }
-
-    return NotFound;
-}
-
-unsigned UString::rfind(const UString& f, unsigned pos) const
-{
-    unsigned sz = length();
-    unsigned fsz = f.length();
-    if (sz < fsz)
-        return NotFound;
-    if (pos > sz - fsz)
-        pos = sz - fsz;
-    if (fsz == 0)
-        return pos;
-    unsigned fsizeminusone = (fsz - 1) * sizeof(UChar);
-    const UChar* fdata = f.characters();
-    for (const UChar* c = characters() + pos; c >= characters(); c--) {
-        if (*c == *fdata && !memcmp(c + 1, fdata + 1, fsizeminusone))
-            return static_cast<unsigned>(c - characters());
-    }
-
-    return NotFound;
-}
-
-unsigned UString::rfind(UChar ch, unsigned pos) const
-{
-    if (isEmpty())
-        return NotFound;
-    if (pos + 1 >= length())
-        pos = length() - 1;
-    for (const UChar* c = characters() + pos; c >= characters(); c--) {
-        if (*c == ch)
-            return static_cast<unsigned>(c - characters());
-    }
-
-    return NotFound;
-}
-
 UString UString::substr(unsigned pos, unsigned len) const
 {
     unsigned s = length();
index 6303baf..e8c135f 100644 (file)
@@ -104,7 +104,19 @@ public:
     static UString number(long long);
     static UString number(double);
 
-
+    // Find a single character or string, also with match function & latin1 forms.
+    size_t find(UChar c, unsigned start = 0) const
+        { return m_impl ? m_impl->find(c, start) : notFound; }
+    size_t find(const UString& str, unsigned start = 0) const
+        { return m_impl ? m_impl->find(str.impl(), start) : notFound; }
+    size_t find(const char* str, unsigned start = 0) const
+        { return m_impl ? m_impl->find(str, start) : notFound; }
+
+    // Find the last instance of a single character or string.
+    size_t reverseFind(UChar c, unsigned start = UINT_MAX) const
+        { return m_impl ? m_impl->reverseFind(c, start) : notFound; }
+    size_t reverseFind(const UString& str, unsigned start = UINT_MAX) const
+        { return m_impl ? m_impl->reverseFind(str.impl(), start) : notFound; }
 
     double toDouble(bool tolerateTrailingJunk, bool tolerateEmptyString) const;
     double toDouble(bool tolerateTrailingJunk) const;
@@ -114,13 +126,7 @@ public:
     uint32_t toUInt32(bool* ok, bool tolerateEmptyString) const;
     uint32_t toStrictUInt32(bool* ok = 0) const;
 
-    static const unsigned NotFound = 0xFFFFFFFFu;
-    unsigned find(const UString& f, unsigned pos = 0) const;
-    unsigned find(UChar, unsigned pos = 0) const;
-    unsigned rfind(const UString& f, unsigned pos) const;
-    unsigned rfind(UChar, unsigned pos) const;
-
-    UString substr(unsigned pos = 0, unsigned len = 0xFFFFFFFF) const;
+    UString substr(unsigned pos = 0, unsigned len = UINT_MAX) const;
 
 private:
     RefPtr<StringImpl> m_impl;
index 24c9ed1..cfabde7 100644 (file)
@@ -71,10 +71,10 @@ public:
     bool contains(const String& s, bool caseSensitive = true) const
         { return m_string.contains(s, caseSensitive); }
 
-    int find(UChar c, int start = 0) const { return m_string.find(c, start); }
-    int find(const char* s, int start = 0, bool caseSentitive = true) const
+    size_t find(UChar c, size_t start = 0) const { return m_string.find(c, start); }
+    size_t find(const char* s, size_t start = 0, bool caseSentitive = true) const
         { return m_string.find(s, start, caseSentitive); }
-    int find(const String& s, int start = 0, bool caseSentitive = true) const
+    size_t find(const String& s, size_t start = 0, bool caseSentitive = true) const
         { return m_string.find(s, start, caseSentitive); }
     
     bool startsWith(const String& s, bool caseSensitive = true) const
index a7f69df..a944470 100644 (file)
@@ -498,175 +498,234 @@ int codePointCompare(const StringImpl* s1, const StringImpl* s2)
     return (l1 > l2) ? 1 : -1;
 }
 
-int StringImpl::find(const char* chs, int index, bool caseSensitive)
+size_t StringImpl::find(UChar c, unsigned start)
 {
-    if (!chs || index < 0)
-        return -1;
+    return WTF::find(m_data, m_length, c, start);
+}
 
-    int chsLength = strlen(chs);
-    int n = m_length - index;
-    if (n < 0)
-        return -1;
-    n -= chsLength - 1;
-    if (n <= 0)
-        return -1;
+size_t StringImpl::find(CharacterMatchFunctionPtr matchFunction, unsigned start)
+{
+    return WTF::find(m_data, m_length, matchFunction, start);
+}
 
-    const char* chsPlusOne = chs + 1;
-    int chsLengthMinusOne = chsLength - 1;
-    
-    const UChar* ptr = m_data + index - 1;
-    if (caseSensitive) {
-        UChar c = *chs;
-        do {
-            if (*++ptr == c && equal(ptr + 1, chsPlusOne, chsLengthMinusOne))
-                return m_length - chsLength - n + 1;
-        } while (--n);
-    } else {
-        UChar lc = Unicode::foldCase(*chs);
-        do {
-            if (Unicode::foldCase(*++ptr) == lc && equalIgnoringCase(ptr + 1, chsPlusOne, chsLengthMinusOne))
-                return m_length - chsLength - n + 1;
-        } while (--n);
+size_t StringImpl::find(const char* matchString, unsigned index)
+{
+    // Check for null or empty string to match against
+    if (!matchString)
+        return notFound;
+    unsigned matchLength = strlen(matchString);
+    if (!matchLength)
+        return min(index, length());
+
+    // Optimization 1: fast case for strings of length 1.
+    if (matchLength == 1)
+        return WTF::find(characters(), length(), *(const unsigned char*)matchString, index);
+
+    // Check index & matchLength are in range.
+    if (index > length())
+        return notFound;
+    unsigned searchLength = length() - index;
+    if (matchLength > searchLength)
+        return notFound;
+    // delta is the number of additional times to test; delta == 0 means test only once.
+    unsigned delta = searchLength - matchLength;
+
+    const UChar* searchCharacters = characters() + index;
+    const unsigned char* matchCharacters = (const unsigned char*)matchString;
+
+    // Optimization 2: keep a running hash of the strings,
+    // only call memcmp if the hashes match.
+    unsigned searchHash = 0;
+    unsigned matchHash = 0;
+    for (unsigned i = 0; i < matchLength; ++i) {
+        searchHash += searchCharacters[i];
+        matchHash += matchCharacters[i];
     }
 
-    return -1;
+    for (unsigned i = 0; i <= delta; ++i) {
+        if (searchHash == matchHash && equal(searchCharacters + i, matchString, matchLength))
+            return index + i;
+        searchHash += searchCharacters[i + matchLength];
+        searchHash -= searchCharacters[i];
+    }
+    return notFound;
 }
 
-int StringImpl::find(UChar c, int start)
+size_t StringImpl::findIgnoringCase(const char* matchString, unsigned index)
 {
-    return WTF::find(m_data, m_length, c, start);
+    // Check for null or empty string to match against
+    if (!matchString)
+        return notFound;
+    unsigned matchLength = strlen(matchString);
+    if (!matchLength)
+        return min(index, length());
+
+    // Check index & matchLength are in range.
+    if (index > length())
+        return notFound;
+    unsigned searchLength = length() - index;
+    if (matchLength > searchLength)
+        return notFound;
+    // delta is the number of additional times to test; delta == 0 means test only once.
+    unsigned delta = searchLength - matchLength;
+
+    const UChar* searchCharacters = characters() + index;
+
+    for (unsigned i = 0; i <= delta; ++i) {
+        if (equalIgnoringCase(searchCharacters + i, matchString, matchLength))
+            return index + i;
+    }
+    return notFound;
+}
+
+size_t StringImpl::find(StringImpl* matchString, unsigned index)
+{
+    // Check for null or empty string to match against
+    if (!matchString)
+        return notFound;
+    unsigned matchLength = matchString->length();
+    if (!matchLength)
+        return min(index, length());
+
+    // Optimization 1: fast case for strings of length 1.
+    if (matchLength == 1)
+        return WTF::find(characters(), length(), matchString->characters()[0], index);
+
+    // Check index & matchLength are in range.
+    if (index > length())
+        return notFound;
+    unsigned searchLength = length() - index;
+    if (matchLength > searchLength)
+        return notFound;
+    // delta is the number of additional times to test; delta == 0 means test only once.
+    unsigned delta = searchLength - matchLength;
+
+    const UChar* searchCharacters = characters() + index;
+    const UChar* matchCharacters = matchString->characters();
+
+    // Optimization 2: keep a running hash of the strings,
+    // only call memcmp if the hashes match.
+    unsigned searchHash = 0;
+    unsigned matchHash = 0;
+    for (unsigned i = 0; i < matchLength; ++i) {
+        searchHash += searchCharacters[i];
+        matchHash += matchCharacters[i];
+    }
+
+    for (unsigned i = 0; i <= delta; ++i) {
+        if (searchHash == matchHash && memcmp(searchCharacters + i, matchCharacters, matchLength * sizeof(UChar)) == 0)
+            return index + i;
+        searchHash += searchCharacters[i + matchLength];
+        searchHash -= searchCharacters[i];
+    }
+    return notFound;
 }
 
-int StringImpl::find(CharacterMatchFunctionPtr matchFunction, int start)
+size_t StringImpl::findIgnoringCase(StringImpl* matchString, unsigned index)
 {
-    return WTF::find(m_data, m_length, matchFunction, start);
-}
+    // Check for null or empty string to match against
+    if (!matchString)
+        return notFound;
+    unsigned matchLength = matchString->length();
+    if (!matchLength)
+        return min(index, length());
 
-int StringImpl::find(StringImpl* str, int index, bool caseSensitive)
-{
-    /*
-      We use a simple trick for efficiency's sake. Instead of
-      comparing strings, we compare the sum of str with that of
-      a part of this string. Only if that matches, we call memcmp
-      or ucstrnicmp.
-    */
-    ASSERT(str);
-    if (index < 0)
-        index += m_length;
-    int lstr = str->m_length;
-    int lthis = m_length - index;
-    if ((unsigned)lthis > m_length)
-        return -1;
-    int delta = lthis - lstr;
-    if (delta < 0)
-        return -1;
-
-    const UChar* uthis = m_data + index;
-    const UChar* ustr = str->m_data;
-    unsigned hthis = 0;
-    unsigned hstr = 0;
-    if (caseSensitive) {
-        for (int i = 0; i < lstr; i++) {
-            hthis += uthis[i];
-            hstr += ustr[i];
-        }
-        int i = 0;
-        while (1) {
-            if (hthis == hstr && memcmp(uthis + i, ustr, lstr * sizeof(UChar)) == 0)
-                return index + i;
-            if (i == delta)
-                return -1;
-            hthis += uthis[i + lstr];
-            hthis -= uthis[i];
-            i++;
-        }
-    } else {
-        for (int i = 0; i < lstr; i++ ) {
-            hthis += toASCIILower(uthis[i]);
-            hstr += toASCIILower(ustr[i]);
-        }
-        int i = 0;
-        while (1) {
-            if (hthis == hstr && equalIgnoringCase(uthis + i, ustr, lstr))
-                return index + i;
-            if (i == delta)
-                return -1;
-            hthis += toASCIILower(uthis[i + lstr]);
-            hthis -= toASCIILower(uthis[i]);
-            i++;
-        }
+    // Check index & matchLength are in range.
+    if (index > length())
+        return notFound;
+    unsigned searchLength = length() - index;
+    if (matchLength > searchLength)
+        return notFound;
+    // delta is the number of additional times to test; delta == 0 means test only once.
+    unsigned delta = searchLength - matchLength;
+
+    const UChar* searchCharacters = characters() + index;
+    const UChar* matchCharacters = matchString->characters();
+
+    for (unsigned i = 0; i <= delta; ++i) {
+        if (equalIgnoringCase(searchCharacters + i, matchCharacters, matchLength))
+            return index + i;
     }
+    return notFound;
 }
 
-int StringImpl::reverseFind(UChar c, int index)
+size_t StringImpl::reverseFind(UChar c, unsigned index)
 {
     return WTF::reverseFind(m_data, m_length, c, index);
 }
 
-int StringImpl::reverseFind(StringImpl* str, int index, bool caseSensitive)
+size_t StringImpl::reverseFind(StringImpl* matchString, unsigned index)
 {
-    /*
-     See StringImpl::find() for explanations.
-     */
-    ASSERT(str);
-    int lthis = m_length;
-    if (index < 0)
-        index += lthis;
-    
-    int lstr = str->m_length;
-    int delta = lthis - lstr;
-    if ( index < 0 || index > lthis || delta < 0 )
-        return -1;
-    if ( index > delta )
-        index = delta;
-    
-    const UChar *uthis = m_data;
-    const UChar *ustr = str->m_data;
-    unsigned hthis = 0;
-    unsigned hstr = 0;
-    int i;
-    if (caseSensitive) {
-        for ( i = 0; i < lstr; i++ ) {
-            hthis += uthis[index + i];
-            hstr += ustr[i];
-        }
-        i = index;
-        while (1) {
-            if (hthis == hstr && memcmp(uthis + i, ustr, lstr * sizeof(UChar)) == 0)
-                return i;
-            if (i == 0)
-                return -1;
-            i--;
-            hthis -= uthis[i + lstr];
-            hthis += uthis[i];
-        }
-    } else {
-        for (i = 0; i < lstr; i++) {
-            hthis += toASCIILower(uthis[index + i]);
-            hstr += toASCIILower(ustr[i]);
-        }
-        i = index;
-        while (1) {
-            if (hthis == hstr && equalIgnoringCase(uthis + i, ustr, lstr) )
-                return i;
-            if (i == 0)
-                return -1;
-            i--;
-            hthis -= toASCIILower(uthis[i + lstr]);
-            hthis += toASCIILower(uthis[i]);
-        }
+    // Check for null or empty string to match against
+    if (!matchString)
+        return notFound;
+    unsigned matchLength = matchString->length();
+    if (!matchLength)
+        return min(index, length());
+
+    // Optimization 1: fast case for strings of length 1.
+    if (matchLength == 1)
+        return WTF::reverseFind(characters(), length(), matchString->characters()[0], index);
+
+    // Check index & matchLength are in range.
+    if (matchLength > length())
+        return notFound;
+    // delta is the number of additional times to test; delta == 0 means test only once.
+    unsigned delta = min(index, length() - matchLength);
+
+    const UChar *searchCharacters = characters();
+    const UChar *matchCharacters = matchString->characters();
+
+    // Optimization 2: keep a running hash of the strings,
+    // only call memcmp if the hashes match.
+    unsigned searchHash = 0;
+    unsigned matchHash = 0;
+    for (unsigned i = 0; i < matchLength; ++i) {
+        searchHash += searchCharacters[delta + i];
+        matchHash += matchCharacters[i];
+    }
+
+    while (searchHash != matchHash || memcmp(searchCharacters + delta, matchCharacters, matchLength * sizeof(UChar))) {
+        if (!delta--)
+            return notFound;
+        searchHash -= searchCharacters[delta + matchLength];
+        searchHash += searchCharacters[delta];
     }
+    return delta;
+}
+
+size_t StringImpl::reverseFindIgnoringCase(StringImpl* matchString, unsigned index)
+{
+    // Check for null or empty string to match against
+    if (!matchString)
+        return notFound;
+    unsigned matchLength = matchString->length();
+    if (!matchLength)
+        return min(index, length());
+
+    // Check index & matchLength are in range.
+    if (matchLength > length())
+        return notFound;
+    // delta is the number of additional times to test; delta == 0 means test only once.
+    unsigned delta = min(index, length() - matchLength);
     
-    // Should never get here.
-    return -1;
+    const UChar *searchCharacters = characters();
+    const UChar *matchCharacters = matchString->characters();
+
+    while (!equalIgnoringCase(searchCharacters + delta, matchCharacters, matchLength)) {
+        if (!delta--)
+            return notFound;
+    }
+    return delta;
 }
 
 bool StringImpl::endsWith(StringImpl* m_data, bool caseSensitive)
 {
     ASSERT(m_data);
-    int start = m_length - m_data->m_length;
-    if (start >= 0)
-        return (find(m_data, start, caseSensitive) == start);
+    if (m_length >= m_data->m_length) {
+        unsigned start = m_length - m_data->m_length;
+        return (caseSensitive ? find(m_data, start) : findIgnoringCase(m_data, start)) == start;
+    }
     return false;
 }
 
@@ -716,12 +775,12 @@ PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacemen
     if (!replacement)
         return this;
         
-    int repStrLength = replacement->length();
-    int srcSegmentStart = 0;
-    int matchCount = 0;
+    unsigned repStrLength = replacement->length();
+    size_t srcSegmentStart = 0;
+    unsigned matchCount = 0;
     
     // Count the matches
-    while ((srcSegmentStart = find(pattern, srcSegmentStart)) >= 0) {
+    while ((srcSegmentStart = find(pattern, srcSegmentStart)) != notFound) {
         ++matchCount;
         ++srcSegmentStart;
     }
@@ -735,12 +794,12 @@ PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacemen
         createUninitialized(m_length - matchCount + (matchCount * repStrLength), data);
 
     // Construct the new data
-    int srcSegmentEnd;
-    int srcSegmentLength;
+    size_t srcSegmentEnd;
+    unsigned srcSegmentLength;
     srcSegmentStart = 0;
-    int dstOffset = 0;
+    unsigned dstOffset = 0;
     
-    while ((srcSegmentEnd = find(pattern, srcSegmentStart)) >= 0) {
+    while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != notFound) {
         srcSegmentLength = srcSegmentEnd - srcSegmentStart;
         memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar));
         dstOffset += srcSegmentLength;
@@ -752,7 +811,7 @@ PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacemen
     srcSegmentLength = m_length - srcSegmentStart;
     memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar));
 
-    ASSERT(dstOffset + srcSegmentLength == static_cast<int>(newImpl->length()));
+    ASSERT(dstOffset + srcSegmentLength == newImpl->length());
 
     return newImpl;
 }
@@ -762,16 +821,16 @@ PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* repl
     if (!pattern || !replacement)
         return this;
 
-    int patternLength = pattern->length();
+    unsigned patternLength = pattern->length();
     if (!patternLength)
         return this;
         
-    int repStrLength = replacement->length();
-    int srcSegmentStart = 0;
-    int matchCount = 0;
+    unsigned repStrLength = replacement->length();
+    size_t srcSegmentStart = 0;
+    unsigned matchCount = 0;
     
     // Count the matches
-    while ((srcSegmentStart = find(pattern, srcSegmentStart)) >= 0) {
+    while ((srcSegmentStart = find(pattern, srcSegmentStart)) != notFound) {
         ++matchCount;
         srcSegmentStart += patternLength;
     }
@@ -785,12 +844,12 @@ PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* repl
         createUninitialized(m_length + matchCount * (repStrLength - patternLength), data);
     
     // Construct the new data
-    int srcSegmentEnd;
-    int srcSegmentLength;
+    size_t srcSegmentEnd;
+    unsigned srcSegmentLength;
     srcSegmentStart = 0;
-    int dstOffset = 0;
+    unsigned dstOffset = 0;
     
-    while ((srcSegmentEnd = find(pattern, srcSegmentStart)) >= 0) {
+    while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != notFound) {
         srcSegmentLength = srcSegmentEnd - srcSegmentStart;
         memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar));
         dstOffset += srcSegmentLength;
@@ -802,7 +861,7 @@ PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* repl
     srcSegmentLength = m_length - srcSegmentStart;
     memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar));
 
-    ASSERT(dstOffset + srcSegmentLength == static_cast<int>(newImpl->length()));
+    ASSERT(dstOffset + srcSegmentLength == newImpl->length());
 
     return newImpl;
 }
index acf9d66..cec0b80 100644 (file)
@@ -290,15 +290,18 @@ public:
 
     PassRefPtr<StringImpl> removeCharacters(CharacterMatchFunctionPtr);
 
-    int find(const char*, int index = 0, bool caseSensitive = true);
-    int find(UChar, int index = 0);
-    int find(CharacterMatchFunctionPtr, int index = 0);
-    int find(StringImpl*, int index, bool caseSensitive = true);
-
-    int reverseFind(UChar, int index);
-    int reverseFind(StringImpl*, int index, bool caseSensitive = true);
-    
-    bool startsWith(StringImpl* str, bool caseSensitive = true) { return reverseFind(str, 0, caseSensitive) == 0; }
+    size_t find(UChar, unsigned index = 0);
+    size_t find(CharacterMatchFunctionPtr, unsigned index = 0);
+    size_t find(const char*, unsigned index = 0);
+    size_t find(StringImpl*, unsigned index = 0);
+    size_t findIgnoringCase(const char*, unsigned index = 0);
+    size_t findIgnoringCase(StringImpl*, unsigned index = 0);
+
+    size_t reverseFind(UChar, unsigned index = UINT_MAX);
+    size_t reverseFind(StringImpl*, unsigned index = UINT_MAX);
+    size_t reverseFindIgnoringCase(StringImpl*, unsigned index = UINT_MAX);
+
+    bool startsWith(StringImpl* str, bool caseSensitive = true) { return (caseSensitive ? reverseFind(str, 0) : reverseFindIgnoringCase(str, 0)) == 0; }
     bool endsWith(StringImpl*, bool caseSensitive = true);
 
     PassRefPtr<StringImpl> replace(UChar, UChar);
index c632c4e..dd9ff94 100644 (file)
@@ -576,14 +576,14 @@ void String::split(const String& separator, bool allowEmptyEntries, Vector<Strin
 {
     result.clear();
 
-    int startPos = 0;
-    int endPos;
-    while ((endPos = find(separator, startPos)) != -1) {
+    unsigned startPos = 0;
+    size_t endPos;
+    while ((endPos = find(separator, startPos)) != notFound) {
         if (allowEmptyEntries || startPos != endPos)
             result.append(substring(startPos, endPos - startPos));
         startPos = endPos + separator.length();
     }
-    if (allowEmptyEntries || startPos != static_cast<int>(length()))
+    if (allowEmptyEntries || startPos != length())
         result.append(substring(startPos));
 }
 
@@ -596,14 +596,14 @@ void String::split(UChar separator, bool allowEmptyEntries, Vector<String>& resu
 {
     result.clear();
 
-    int startPos = 0;
-    int endPos;
-    while ((endPos = find(separator, startPos)) != -1) {
+    unsigned startPos = 0;
+    size_t endPos;
+    while ((endPos = find(separator, startPos)) != notFound) {
         if (allowEmptyEntries || startPos != endPos)
             result.append(substring(startPos, endPos - startPos));
         startPos = endPos + 1;
     }
-    if (allowEmptyEntries || startPos != static_cast<int>(length()))
+    if (allowEmptyEntries || startPos != length())
         result.append(substring(startPos));
 }
 
index 288468e..5b07b71 100644 (file)
@@ -72,9 +72,6 @@ intptr_t charactersToIntPtr(const UChar*, size_t, bool* ok = 0); // ignores trai
 double charactersToDouble(const UChar*, size_t, bool* ok = 0);
 float charactersToFloat(const UChar*, size_t, bool* ok = 0);
 
-int find(const UChar*, size_t, UChar, int startPosition = 0);
-int reverseFind(const UChar*, size_t, UChar, int startPosition = -1);
-
 class String {
 public:
     // Construct a null string, distinguishable from an empty string.
@@ -146,30 +143,46 @@ public:
     static String number(unsigned long long);
     static String number(double);
 
-
+    // Find a single character or string, also with match function & latin1 forms.
+    size_t find(UChar c, unsigned start = 0) const
+        { return m_impl ? m_impl->find(c, start) : notFound; }
+    size_t find(const String& str, unsigned start = 0) const
+        { return m_impl ? m_impl->find(str.impl(), start) : notFound; }
+    size_t find(CharacterMatchFunctionPtr matchFunction, unsigned start = 0) const
+        { return m_impl ? m_impl->find(matchFunction, start) : notFound; }
+    size_t find(const char* str, unsigned start = 0) const
+        { return m_impl ? m_impl->find(str, start) : notFound; }
+
+    // Find the last instance of a single character or string.
+    size_t reverseFind(UChar c, unsigned start = UINT_MAX) const
+        { return m_impl ? m_impl->reverseFind(c, start) : notFound; }
+    size_t reverseFind(const String& str, unsigned start = UINT_MAX) const
+        { return m_impl ? m_impl->reverseFind(str.impl(), start) : notFound; }
+
+    // Case insensitive string matching.
+    size_t findIgnoringCase(const char* str, unsigned start = 0) const
+        { return m_impl ? m_impl->findIgnoringCase(str, start) : notFound; }
+    size_t findIgnoringCase(const String& str, unsigned start = 0) const
+        { return m_impl ? m_impl->findIgnoringCase(str.impl(), start) : notFound; }
+    size_t reverseFindIgnoringCase(const String& str, unsigned start = UINT_MAX) const
+        { return m_impl ? m_impl->reverseFindIgnoringCase(str.impl(), start) : notFound; }
+
+    // Wrappers for find & reverseFind adding dynamic sensitivity check.
+    size_t find(const char* str, unsigned start, bool caseSensitive) const
+        { return caseSensitive ? find(str, start) : findIgnoringCase(str, start); }
+    size_t find(const String& str, unsigned start, bool caseSensitive) const
+        { return caseSensitive ? find(str, start) : findIgnoringCase(str, start); }
+    size_t reverseFind(const String& str, unsigned start, bool caseSensitive) const
+        { return caseSensitive ? reverseFind(str, start) : reverseFindIgnoringCase(str, start); }
 
     const UChar* charactersWithNullTermination();
     
     UChar32 characterStartingAt(unsigned) const; // Ditto.
     
-    bool contains(UChar c) const { return find(c) != -1; }
-    bool contains(const char* str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != -1; }
-    bool contains(const String& str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != -1; }
-
-    int find(UChar c, int start = 0) const
-        { return m_impl ? m_impl->find(c, start) : -1; }
-    int find(CharacterMatchFunctionPtr matchFunction, int start = 0) const
-        { return m_impl ? m_impl->find(matchFunction, start) : -1; }
-    int find(const char* str, int start = 0, bool caseSensitive = true) const
-        { return m_impl ? m_impl->find(str, start, caseSensitive) : -1; }
-    int find(const String& str, int start = 0, bool caseSensitive = true) const
-        { return m_impl ? m_impl->find(str.impl(), start, caseSensitive) : -1; }
-
-    int reverseFind(UChar c, int start = -1) const
-        { return m_impl ? m_impl->reverseFind(c, start) : -1; }
-    int reverseFind(const String& str, int start = -1, bool caseSensitive = true) const
-        { return m_impl ? m_impl->reverseFind(str.impl(), start, caseSensitive) : -1; }
-    
+    bool contains(UChar c) const { return find(c) != notFound; }
+    bool contains(const char* str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != notFound; }
+    bool contains(const String& str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != notFound; }
+
     bool startsWith(const String& s, bool caseSensitive = true) const
         { return m_impl ? m_impl->startsWith(s.impl(), caseSensitive) : s.isEmpty(); }
     bool endsWith(const String& s, bool caseSensitive = true) const
@@ -351,43 +364,37 @@ inline bool charactersAreAllASCII(const UChar* characters, size_t length)
 
 int codePointCompare(const String&, const String&);
 
-inline int find(const UChar* characters, size_t length, UChar character, int startPosition)
+inline size_t find(const UChar* characters, unsigned length, UChar matchCharacter, unsigned index = 0)
 {
-    if (startPosition >= static_cast<int>(length))
-        return -1;
-    for (size_t i = startPosition; i < length; ++i) {
-        if (characters[i] == character)
-            return static_cast<int>(i);
+    while (index < length) {
+        if (characters[index] == matchCharacter)
+            return index;
+        ++index;
     }
-    return -1;
+    return notFound;
 }
 
-inline int find(const UChar* characters, size_t length, CharacterMatchFunctionPtr matchFunction, int startPosition)
+inline size_t find(const UChar* characters, unsigned length, CharacterMatchFunctionPtr matchFunction, unsigned index = 0)
 {
-    if (startPosition >= static_cast<int>(length))
-        return -1;
-    for (size_t i = startPosition; i < length; ++i) {
-        if (matchFunction(characters[i]))
-            return static_cast<int>(i);
+    while (index < length) {
+        if (matchFunction(characters[index]))
+            return index;
+        ++index;
     }
-    return -1;
+    return notFound;
 }
 
-inline int reverseFind(const UChar* characters, size_t length, UChar character, int startPosition)
+inline size_t reverseFind(const UChar* characters, unsigned length, UChar matchCharacter, unsigned index = UINT_MAX)
 {
-    if (startPosition >= static_cast<int>(length) || !length)
-        return -1;
-    if (startPosition < 0)
-        startPosition += static_cast<int>(length);
-    while (true) {
-        if (characters[startPosition] == character)
-            return startPosition;
-        if (!startPosition)
-            return -1;
-        startPosition--;
+    if (!length)
+        return notFound;
+    if (index >= length)
+        index = length - 1;
+    while (characters[index] != matchCharacter) {
+        if (!index--)
+            return notFound;
     }
-    ASSERT_NOT_REACHED();
-    return -1;
+    return index;
 }
 
 inline void append(Vector<UChar>& vector, const String& string)
index 8de34d6..2c3acb1 100644 (file)
@@ -1,3 +1,137 @@
+2010-08-16  Gavin Barraclough  <barraclough@apple.com>
+
+        Reviewed by Sam Weinig
+
+        Bug 44080 - String find/reverseFind methods need tidying up
+        These methods have a couple of problems with their interface, and implementation.
+
+        These methods take and int index, and return an int - however this is problematic
+        since on 64-bit string indices may have a full 32-bit range.  This spills out into
+        surrounding code, which unsafely casts string indices from unsigned to int. Code
+        checking the result of these methods check for a mix of "== -1", "< 0", and
+        "== notFound".  Clean this up by changing these methods to take an unsigned
+        starting index, and return a size_t. with a failed match indicated by notFound.
+        reverseFind also has a special meaning for the starting index argument, in that a
+        negative index is interpreted as an offset back from the end of the string. Remove
+        this functionality, in the (1!) case where it is used we should just calculate the
+        offset by subtracting from the string's length.
+
+        The implementation has a few problems too.  The code is not in webkit style, in
+        using assorted abbreviations in variable names, and implementations of similar
+        find methods with differing argument types were unnecessarily inconsistent. When
+        find is passed const char* data the string would be handled as latin1 (zero
+        extended to UTF-16) for all characters but the first; this is sign extended.
+        Case-insensitive find is broken for unicode strings; the hashing optimization is
+        not unicode safe, and could result in false negatives.
+
+        Unify UString find methods to match String.
+
+        * css/CSSSelector.cpp:
+        (WebCore::CSSSelector::RareData::parseNth):
+        * css/CSSStyleDeclaration.cpp:
+        (WebCore::CSSStyleDeclaration::setProperty):
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::SelectorChecker::checkOneSelector):
+        * dom/Document.cpp:
+        (WebCore::Document::getImageMap):
+        * editing/CompositeEditCommand.cpp:
+        (WebCore::CompositeEditCommand::inputText):
+        * editing/InsertTextCommand.cpp:
+        (WebCore::InsertTextCommand::input):
+        * editing/TextIterator.cpp:
+        (WebCore::TextIterator::handleTextBox):
+        * editing/TypingCommand.cpp:
+        (WebCore::TypingCommand::insertText):
+        * editing/markup.cpp:
+        (WebCore::fillContainerFromString):
+        (WebCore::createFragmentFromText):
+        * html/File.cpp:
+        (WebCore::File::Init):
+        * html/HTMLAnchorElement.cpp:
+        (WebCore::HTMLAnchorElement::setHost):
+        * html/HTMLEmbedElement.cpp:
+        (WebCore::HTMLEmbedElement::parseMappedAttribute):
+        * html/HTMLFormControlElement.cpp:
+        (WebCore::HTMLTextFormControlElement::isPlaceholderEmpty):
+        * html/HTMLObjectElement.cpp:
+        (WebCore::HTMLObjectElement::parseMappedAttribute):
+        * inspector/InspectorDOMAgent.cpp:
+        (WebCore::InspectorDOMAgent::performSearch):
+        * loader/CrossOriginPreflightResultCache.cpp:
+        (WebCore::parseAccessControlAllowList):
+        * loader/MainResourceLoader.cpp:
+        (WebCore::MainResourceLoader::substituteMIMETypeFromPluginDatabase):
+        * loader/appcache/ApplicationCacheStorage.cpp:
+        (WebCore::parseHeader):
+        (WebCore::parseHeaders):
+        * loader/icon/IconFetcher.cpp:
+        (WebCore::parseIconLink):
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::parseModalDialogFeatures):
+        * page/SecurityOrigin.cpp:
+        (WebCore::SecurityOrigin::createFromDatabaseIdentifier):
+        * page/UserContentURLPattern.cpp:
+        (WebCore::UserContentURLPattern::parse):
+        * page/XSSAuditor.cpp:
+        (WebCore::XSSAuditor::findInRequest):
+        * platform/ContentType.cpp:
+        (WebCore::ContentType::parameter):
+        (WebCore::ContentType::type):
+        * platform/KURL.cpp:
+        (WebCore::KURL::lastPathComponent):
+        (WebCore::KURL::setProtocol):
+        (WebCore::decodeURLEscapeSequences):
+        (WebCore::substituteBackslashes):
+        (WebCore::mimeTypeFromDataURL):
+        * platform/Length.cpp:
+        (WebCore::newCoordsArray):
+        (WebCore::newLengthArray):
+        * platform/LinkHash.cpp:
+        (WebCore::findSlashDotDotSlash):
+        (WebCore::findSlashSlash):
+        (WebCore::findSlashDotSlash):
+        (WebCore::cleanPath):
+        * platform/MIMETypeRegistry.cpp:
+        (WebCore::MIMETypeRegistry::getMIMETypeForPath):
+        * platform/SchemeRegistry.cpp:
+        (WebCore::SchemeRegistry::shouldTreatURLAsLocal):
+        * platform/graphics/MediaPlayer.cpp:
+        (WebCore::MediaPlayer::load):
+        * platform/mac/DragImageMac.mm:
+        (WebCore::createDragImageIconForCachedImage):
+        * platform/network/CredentialStorage.cpp:
+        (WebCore::protectionSpaceMapKeyFromURL):
+        (WebCore::findDefaultProtectionSpaceForURL):
+        * platform/network/HTTPParsers.cpp:
+        (WebCore::skipWhiteSpace):
+        (WebCore::skipToken):
+        (WebCore::parseHTTPRefresh):
+        (WebCore::filenameFromHTTPContentDisposition):
+        (WebCore::findCharsetInMediaType):
+        (WebCore::parseXSSProtectionHeader):
+        (WebCore::extractReasonPhraseFromHTTPStatusLine):
+        * platform/network/ResourceResponseBase.cpp:
+        (WebCore::ResourceResponseBase::isAttachment):
+        (WebCore::parseCacheHeader):
+        * rendering/RenderEmbeddedObject.cpp:
+        (WebCore::RenderEmbeddedObject::updateWidget):
+        * storage/Entry.cpp:
+        (WebCore::Entry::Entry):
+        * svg/SVGFont.cpp:
+        (WebCore::isCompatibleGlyph):
+        * svg/SVGURIReference.cpp:
+        (WebCore::SVGURIReference::getTarget):
+        * svg/animation/SVGSMILElement.cpp:
+        (WebCore::SVGSMILElement::parseClockValue):
+        (WebCore::SVGSMILElement::parseCondition):
+        * xml/XPathFunctions.cpp:
+        (WebCore::XPath::FunSubstringBefore::evaluate):
+        (WebCore::XPath::FunSubstringAfter::evaluate):
+        (WebCore::XPath::FunTranslate::evaluate):
+        (WebCore::XPath::FunLang::evaluate):
+        * xml/XPathParser.cpp:
+        (WebCore::XPath::Parser::expandQName):
+
 2010-08-16  Ryosuke Niwa  <rniwa@webkit.org>
 
         Reviewed by Tony Chang.
index 02834d4..771fec3 100644 (file)
                        isa = PBXProject;
                        buildConfigurationList = 149C284308902B11008A9EFC /* Build configuration list for PBXProject "WebCore" */;
                        compatibilityVersion = "Xcode 2.4";
+                       developmentRegion = English;
                        hasScannedForEncodings = 1;
                        knownRegions = (
                                English,
index 3a6a448..1f336a2 100644 (file)
@@ -906,8 +906,8 @@ bool CSSSelector::RareData::parseNth()
         m_a = 2;
         m_b = 0;
     } else {
-        int n = argument.find('n');
-        if (n != -1) {
+        size_t n = argument.find('n');
+        if (n != notFound) {
             if (argument[0] == '-') {
                 if (n == 1)
                     m_a = -1; // -n == -1n
@@ -918,12 +918,12 @@ bool CSSSelector::RareData::parseNth()
             else
                 m_a = argument.substring(0, n).toInt();
             
-            int p = argument.find('+', n);
-            if (p != -1)
+            size_t p = argument.find('+', n);
+            if (p != notFound)
                 m_b = argument.substring(p + 1, argument.length() - p - 1).toInt();
             else {
                 p = argument.find('-', n);
-                if (p != -1)
+                if (p != notFound)
                     m_b = -argument.substring(p + 1, argument.length() - p - 1).toInt();
             }
         } else
index 404a978..996d573 100644 (file)
@@ -82,8 +82,8 @@ bool CSSStyleDeclaration::isPropertyImplicit(const String& propertyName)
 
 void CSSStyleDeclaration::setProperty(const String& propertyName, const String& value, ExceptionCode& ec)
 {
-    int important = value.find("!important", 0, false);
-    if (important == -1)
+    size_t important = value.find("!important", 0, false);
+    if (important == notFound)
         setProperty(propertyName, value, "", ec);
     else
         setProperty(propertyName, value.left(important - 1), "important", ec);
@@ -96,7 +96,7 @@ void CSSStyleDeclaration::setProperty(const String& propertyName, const String&
         // FIXME: Should we raise an exception here?
         return;
     }
-    bool important = priority.find("important", 0, false) != -1;
+    bool important = priority.find("important", 0, false) != notFound;
     setProperty(propID, value, important, ec);
 }
 
index 7575957..4ee49d0 100644 (file)
@@ -2119,18 +2119,18 @@ bool CSSStyleSelector::SelectorChecker::checkOneSelector(CSSSelector* sel, Eleme
             if (sel->m_value.contains(' ') || sel->m_value.isEmpty())
                 return false;
 
-            int startSearchAt = 0;
+            unsigned startSearchAt = 0;
             while (true) {
-                int foundPos = value.find(sel->m_value, startSearchAt, caseSensitive);
-                if (foundPos == -1)
+                size_t foundPos = value.find(sel->m_value, startSearchAt, caseSensitive);
+                if (foundPos == notFound)
                     return false;
-                if (foundPos == 0 || value[foundPos-1] == ' ') {
+                if (foundPos == 0 || value[foundPos - 1] == ' ') {
                     unsigned endStr = foundPos + sel->m_value.length();
                     if (endStr == value.length() || value[endStr] == ' ')
                         break; // We found a match.
                 }
                 
-                // No match.  Keep looking.
+                // No match. Keep looking.
                 startSearchAt = foundPos + 1;
             }
             break;
index e91a9ac..b86db5b 100644 (file)
@@ -3648,8 +3648,8 @@ HTMLMapElement* Document::getImageMap(const String& url) const
 {
     if (url.isNull())
         return 0;
-    int hashPos = url.find('#');
-    String name = (hashPos < 0 ? url : url.substring(hashPos + 1)).impl();
+    size_t hashPos = url.find('#');
+    String name = (hashPos == notFound ? url : url.substring(hashPos + 1)).impl();
     AtomicString mapName = isHTMLDocument() ? name.lower() : name;
     m_imageMapsByName.checkConsistency();
     return m_imageMapsByName.get(mapName.impl());
index 4216452..f50929a 100644 (file)
@@ -294,24 +294,24 @@ void CompositeEditCommand::joinTextNodes(PassRefPtr<Text> text1, PassRefPtr<Text
 
 void CompositeEditCommand::inputText(const String& text, bool selectInsertedText)
 {
-    int offset = 0;
-    int length = text.length();
+    unsigned offset = 0;
+    unsigned length = text.length();
     RefPtr<Range> startRange = Range::create(document(), Position(document()->documentElement(), 0), endingSelection().start());
-    int startIndex = TextIterator::rangeLength(startRange.get());
-    int newline;
+    unsigned startIndex = TextIterator::rangeLength(startRange.get());
+    size_t newline;
     do {
         newline = text.find('\n', offset);
         if (newline != offset) {
             RefPtr<InsertTextCommand> command = InsertTextCommand::create(document());
             applyCommandToComposite(command);
-            int substringLength = newline == -1 ? length - offset : newline - offset;
+            int substringLength = newline == notFound ? length - offset : newline - offset;
             command->input(text.substring(offset, substringLength), false);
         }
-        if (newline != -1)
+        if (newline != notFound)
             insertLineBreak();
             
         offset = newline + 1;
-    } while (newline != -1 && offset != length);
+    } while (newline != notFound && offset != length);
     
     if (selectInsertedText) {
         RefPtr<Range> selectedRange = TextIterator::rangeFromLocationAndLength(document()->documentElement(), startIndex, length);
index f10d71b..52eb12f 100644 (file)
@@ -109,7 +109,7 @@ bool InsertTextCommand::performTrivialReplace(const String& text, bool selectIns
 void InsertTextCommand::input(const String& text, bool selectInsertedText)
 {
     
-    ASSERT(text.find('\n') == -1);
+    ASSERT(text.find('\n') == notFound);
 
     if (endingSelection().isNone())
         return;
index 7226eba..39013c1 100644 (file)
@@ -521,11 +521,11 @@ void TextIterator::handleTextBox()
         return;
     }
     String str = renderer->text();
-    int start = m_offset;
-    int end = (m_node == m_endContainer) ? m_endOffset : INT_MAX;
+    unsigned start = m_offset;
+    unsigned end = (m_node == m_endContainer) ? m_endOffset : UINT_MAX;
     while (m_textBox) {
-        int textBoxStart = m_textBox->start();
-        int runStart = max(textBoxStart, start);
+        unsigned textBoxStart = m_textBox->start();
+        unsigned runStart = max(textBoxStart, start);
 
         // Check for collapsed space at the start of this run.
         InlineTextBox* firstTextBox = renderer->containsReversedText() ? m_sortedTextBoxes[0] : renderer->firstTextBox();
@@ -541,8 +541,8 @@ void TextIterator::handleTextBox()
                 emitCharacter(' ', m_node, 0, runStart, runStart);
             return;
         }
-        int textBoxEnd = textBoxStart + m_textBox->len();
-        int runEnd = min(textBoxEnd, end);
+        unsigned textBoxEnd = textBoxStart + m_textBox->len();
+        unsigned runEnd = min(textBoxEnd, end);
         
         // Determine what the next text box will be, but don't advance yet
         InlineTextBox* nextTextBox = 0;
@@ -560,8 +560,8 @@ void TextIterator::handleTextBox()
                 emitCharacter(' ', m_node, 0, runStart, runStart + 1);
                 m_offset = runStart + 1;
             } else {
-                int subrunEnd = str.find('\n', runStart);
-                if (subrunEnd == -1 || subrunEnd > runEnd)
+                size_t subrunEnd = str.find('\n', runStart);
+                if (subrunEnd == notFound || subrunEnd > runEnd)
                     subrunEnd = runEnd;
     
                 m_offset = subrunEnd;
@@ -570,11 +570,11 @@ void TextIterator::handleTextBox()
 
             // If we are doing a subrun that doesn't go to the end of the text box,
             // come back again to finish handling this text box; don't advance to the next one.
-            if (m_positionEndOffset < textBoxEnd)
+            if (static_cast<unsigned>(m_positionEndOffset) < textBoxEnd)
                 return;
 
             // Advance and return
-            int nextRunStart = nextTextBox ? nextTextBox->start() : str.length();
+            unsigned nextRunStart = nextTextBox ? nextTextBox->start() : str.length();
             if (nextRunStart > runEnd)
                 m_lastTextNodeEndedWithCollapsedSpace = true; // collapsed space between runs or at the end
             m_textBox = nextTextBox;
index 7680084..bab3111 100644 (file)
@@ -332,9 +332,9 @@ void TypingCommand::insertText(const String &text, bool selectInsertedText)
     // an existing selection; at the moment they can either put the caret after what's inserted or
     // select what's inserted, but there's no way to "extend selection" to include both an old selection
     // that ends just before where we want to insert text and the newly inserted text.
-    int offset = 0;
-    int newline;
-    while ((newline = text.find('\n', offset)) != -1) {
+    unsigned offset = 0;
+    size_t newline;
+    while ((newline = text.find('\n', offset)) != notFound) {
         if (newline != offset)
             insertTextRunWithoutNewlines(text.substring(offset, newline - offset), false);
         insertParagraphSeparator();
@@ -343,7 +343,7 @@ void TypingCommand::insertText(const String &text, bool selectInsertedText)
     if (!offset)
         insertTextRunWithoutNewlines(text, selectInsertedText);
     else {
-        int length = text.length();
+        unsigned length = text.length();
         if (length != offset)
             insertTextRunWithoutNewlines(text.substring(offset, length - offset), selectInsertedText);
     }
index f9eeb38..b1ec07c 100644 (file)
@@ -1101,7 +1101,7 @@ static void fillContainerFromString(ContainerNode* paragraph, const String& stri
         return;
     }
 
-    ASSERT(string.find('\n') == -1);
+    ASSERT(string.find('\n') == notFound);
 
     Vector<String> tabList;
     string.split('\t', true, tabList);
@@ -1184,7 +1184,7 @@ PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String
     }
 
     // A string with no newlines gets added inline, rather than being put into a paragraph.
-    if (string.find('\n') == -1) {
+    if (string.find('\n') == notFound) {
         fillContainerFromString(fragment.get(), string);
         return fragment.release();
     }
index c804f34..253cb4d 100644 (file)
@@ -57,8 +57,8 @@ void File::Init()
 {
     // We don't use MIMETypeRegistry::getMIMETypeForPath() because it returns "application/octet-stream" upon failure.
     const String& fileName = name();
-    int index = fileName.reverseFind('.');
-    if (index != -1)
+    size_t index = fileName.reverseFind('.');
+    if (index != notFound)
         m_type = MIMETypeRegistry::getMIMETypeForExtension(fileName.substring(index + 1));
 }
 
index 0d2e92d..e1ee86a 100644 (file)
@@ -381,11 +381,11 @@ void HTMLAnchorElement::setHost(const String& value)
     if (!url.canSetHostOrPort())
         return;
 
-    int separator = value.find(':');
+    size_t separator = value.find(':');
     if (!separator)
         return;
 
-    if (separator == -1)
+    if (separator == notFound)
         url.setHostAndPort(value);
     else {
         unsigned portEnd;
index 3f700ef..afa56d4 100644 (file)
@@ -89,8 +89,8 @@ void HTMLEmbedElement::parseMappedAttribute(Attribute* attr)
   
     if (attr->name() == typeAttr) {
         m_serviceType = value.string().lower();
-        int pos = m_serviceType.find(";");
-        if (pos != -1)
+        size_t pos = m_serviceType.find(";");
+        if (pos != notFound)
             m_serviceType = m_serviceType.left(pos);
         if (!isImageType() && m_imageLoader)
             m_imageLoader.clear();
index 7d4cb00..ae1ac62 100644 (file)
@@ -526,7 +526,7 @@ static bool isNotLineBreak(UChar ch) { return ch != newlineCharacter && ch != ca
 bool HTMLTextFormControlElement::isPlaceholderEmpty() const
 {
     const AtomicString& attributeValue = getAttribute(placeholderAttr);
-    return attributeValue.string().find(isNotLineBreak) == -1;
+    return attributeValue.string().find(isNotLineBreak) == notFound;
 }
 
 bool HTMLTextFormControlElement::placeholderShouldBeVisible() const
index d4bccc3..5989ec7 100644 (file)
@@ -70,11 +70,11 @@ RenderWidget* HTMLObjectElement::renderWidgetForJSBindings() const
 void HTMLObjectElement::parseMappedAttribute(Attribute* attr)
 {
     String val = attr->value();
-    int pos;
+    size_t pos;
     if (attr->name() == typeAttr) {
         m_serviceType = val.lower();
         pos = m_serviceType.find(";");
-        if (pos != -1)
+        if (pos != notFound)
           m_serviceType = m_serviceType.left(pos);
         if (renderer())
           m_needWidgetUpdate = true;
index 074aab8..6243299 100644 (file)
@@ -630,7 +630,7 @@ void InspectorDOMAgent::performSearch(const String& whitespaceTrimmedQuery, bool
     // 2) There is no need to push all search results to the front-end at a time, pushing next / previous result
     //    is sufficient.
 
-    int queryLength = whitespaceTrimmedQuery.length();
+    unsigned queryLength = whitespaceTrimmedQuery.length();
     bool startTagFound = !whitespaceTrimmedQuery.find('<');
     bool endTagFound = whitespaceTrimmedQuery.reverseFind('>') + 1 == queryLength;
 
index 51874d1..18e4be2 100644 (file)
@@ -74,16 +74,16 @@ static void addToAccessControlAllowList(const String& string, unsigned start, un
 template<class HashType>
 static bool parseAccessControlAllowList(const String& string, HashSet<String, HashType>& set)
 {
-    int start = 0;
-    int end;
-    while ((end = string.find(',', start)) != -1) {
+    unsigned start = 0;
+    size_t end;
+    while ((end = string.find(',', start)) != notFound) {
         if (start == end)
             return false;
 
         addToAccessControlAllowList(string, start, end - 1, set);
         start = end + 1;
     }
-    if (start != static_cast<int>(string.length()))
+    if (start != string.length())
         addToAccessControlAllowList(string, start, string.length() - 1, set);
 
     return true;
index c03f9ca..a7a5968 100644 (file)
@@ -305,8 +305,8 @@ void MainResourceLoader::substituteMIMETypeFromPluginDatabase(const ResourceResp
     if (filename.endsWith("/"))
         return;
 
-    int extensionPos = filename.reverseFind('.');
-    if (extensionPos == -1)
+    size_t extensionPos = filename.reverseFind('.');
+    if (extensionPos == notFound)
         return;
 
     String extension = filename.substring(extensionPos + 1);
index 5624809..5a82d6e 100644 (file)
@@ -968,8 +968,8 @@ bool ApplicationCacheStorage::storeNewestCache(ApplicationCacheGroup* group)
 
 static inline void parseHeader(const UChar* header, size_t headerLength, ResourceResponse& response)
 {
-    int pos = find(header, headerLength, ':');
-    ASSERT(pos != -1);
+    size_t pos = find(header, headerLength, ':');
+    ASSERT(pos != notFound);
     
     AtomicString headerName = AtomicString(header, pos);
     String headerValue = String(header + pos + 1, headerLength - pos - 1);
@@ -979,9 +979,9 @@ static inline void parseHeader(const UChar* header, size_t headerLength, Resourc
 
 static inline void parseHeaders(const String& headers, ResourceResponse& response)
 {
-    int startPos = 0;
-    int endPos;
-    while ((endPos = headers.find('\n', startPos)) != -1) {
+    unsigned startPos = 0;
+    size_t endPos;
+    while ((endPos = headers.find('\n', startPos)) != notFound) {
         ASSERT(startPos != endPos);
 
         parseHeader(headers.characters() + startPos, endPos - startPos, response);
@@ -989,7 +989,7 @@ static inline void parseHeaders(const String& headers, ResourceResponse& respons
         startPos = endPos + 1;
     }
     
-    if (startPos != static_cast<int>(headers.length()))
+    if (startPos != headers.length())
         parseHeader(headers.characters(), headers.length(), response);
 }
     
index 3d3df39..1107d7b 100644 (file)
@@ -87,8 +87,8 @@ static void parseIconLink(HTMLLinkElement* link, Vector<IconLinkEntry>& entries)
     // Try to determine the file type.
     String path = url.path();
     
-    int pos = path.reverseFind('.');
-    if (pos >= 0) {
+    size_t pos = path.reverseFind('.');
+    if (pos != notFound) {
         String extension = path.substring(pos + 1);
         if (equalIgnoringCase(extension, "icns"))
             type = IconLinkEntry::ICNS;
index b4789e3..af43a55 100644 (file)
@@ -331,20 +331,20 @@ void DOMWindow::parseModalDialogFeatures(const String& featuresArg, HashMap<Stri
     Vector<String>::const_iterator end = features.end();
     for (Vector<String>::const_iterator it = features.begin(); it != end; ++it) {
         String s = *it;
-        int pos = s.find('=');
-        int colonPos = s.find(':');
-        if (pos >= 0 && colonPos >= 0)
+        size_t pos = s.find('=');
+        size_t colonPos = s.find(':');
+        if (pos != notFound && colonPos != notFound)
             continue; // ignore any strings that have both = and :
-        if (pos < 0)
+        if (pos == notFound)
             pos = colonPos;
-        if (pos < 0) {
+        if (pos == notFound) {
             // null string for value means key without value
             map.set(s.stripWhiteSpace().lower(), String());
         } else {
             String key = s.left(pos).stripWhiteSpace().lower();
             String val = s.substring(pos + 1).stripWhiteSpace().lower();
-            int spacePos = val.find(' ');
-            if (spacePos != -1)
+            size_t spacePos = val.find(' ');
+            if (spacePos != notFound)
                 val = val.left(spacePos);
             map.set(key, val);
         }
index 87b3ed2..e306486 100644 (file)
@@ -367,13 +367,13 @@ static const char SeparatorCharacter = '_';
 PassRefPtr<SecurityOrigin> SecurityOrigin::createFromDatabaseIdentifier(const String& databaseIdentifier)
 { 
     // Make sure there's a first separator
-    int separator1 = databaseIdentifier.find(SeparatorCharacter);
-    if (separator1 == -1)
+    size_t separator1 = databaseIdentifier.find(SeparatorCharacter);
+    if (separator1 == notFound)
         return create(KURL());
         
     // Make sure there's a second separator
-    int separator2 = databaseIdentifier.reverseFind(SeparatorCharacter);
-    if (separator2 == -1)
+    size_t separator2 = databaseIdentifier.reverseFind(SeparatorCharacter);
+    if (separator2 == notFound)
         return create(KURL());
         
     // Ensure there were at least 2 separator characters. Some hostnames on intranets have
@@ -384,7 +384,7 @@ PassRefPtr<SecurityOrigin> SecurityOrigin::createFromDatabaseIdentifier(const St
     // Make sure the port section is a valid port number or doesn't exist
     bool portOkay;
     int port = databaseIdentifier.right(databaseIdentifier.length() - separator2 - 1).toInt(&portOkay);
-    bool portAbsent = (separator2 == static_cast<int>(databaseIdentifier.length()) - 1);
+    bool portAbsent = (separator2 == databaseIdentifier.length() - 1);
     if (!(portOkay || portAbsent))
         return create(KURL());
     
index 09eb678..272284a 100644 (file)
@@ -63,14 +63,14 @@ bool UserContentURLPattern::parse(const String& pattern)
 {
     DEFINE_STATIC_LOCAL(const String, schemeSeparator, ("://"));
 
-    int schemeEndPos = pattern.find(schemeSeparator);
-    if (schemeEndPos == -1)
+    size_t schemeEndPos = pattern.find(schemeSeparator);
+    if (schemeEndPos == notFound)
         return false;
 
     m_scheme = pattern.left(schemeEndPos);
 
-    int hostStartPos = schemeEndPos + schemeSeparator.length();
-    if (hostStartPos >= static_cast<int>(pattern.length()))
+    unsigned hostStartPos = schemeEndPos + schemeSeparator.length();
+    if (hostStartPos >= pattern.length())
         return false;
 
     int pathStartPos = 0;
@@ -78,8 +78,8 @@ bool UserContentURLPattern::parse(const String& pattern)
     if (equalIgnoringCase(m_scheme, "file"))
         pathStartPos = hostStartPos;
     else {
-        int hostEndPos = pattern.find("/", hostStartPos);
-        if (hostEndPos == -1)
+        size_t hostEndPos = pattern.find("/", hostStartPos);
+        if (hostEndPos == notFound)
             return false;
 
         m_host = pattern.substring(hostStartPos, hostEndPos - hostStartPos);
@@ -96,7 +96,7 @@ bool UserContentURLPattern::parse(const String& pattern)
         }
 
         // No other '*' can occur in the host.
-        if (m_host.find("*") != -1)
+        if (m_host.find("*") != notFound)
             return false;
 
         pathStartPos = hostEndPos;
index b2764f9..fb0e1c0 100644 (file)
@@ -405,10 +405,10 @@ bool XSSAuditor::findInRequest(Frame* frame, const FindTask& task) const
 
     String decodedPageURL = m_pageURLCache.canonicalizeURL(pageURL, frame->document()->decoder()->encoding(), task.decodeEntities, task.decodeURLEscapeSequencesTwice);
 
-    if (task.allowRequestIfNoIllegalURICharacters && !hasFormData && decodedPageURL.find(&isIllegalURICharacter, 0) == -1)
+    if (task.allowRequestIfNoIllegalURICharacters && !hasFormData && decodedPageURL.find(&isIllegalURICharacter, 0) == notFound)
         return false; // Injection is impossible because the request does not contain any illegal URI characters.
 
-    if (decodedPageURL.find(canonicalizedString, 0, false) != -1)
+    if (decodedPageURL.find(canonicalizedString, 0, false) != notFound)
         return true; // We've found the string in the GET data.
 
     if (hasFormData) {
@@ -423,7 +423,7 @@ bool XSSAuditor::findInRequest(Frame* frame, const FindTask& task) const
         if (m_formDataSuffixTree && !m_formDataSuffixTree->mightContain(canonicalizedString))
             return false;
 
-        if (decodedFormData.find(canonicalizedString, 0, false) != -1)
+        if (decodedFormData.find(canonicalizedString, 0, false) != notFound)
             return true; // We found the string in the POST data.
     }
 
index 3dce7b5..c094d54 100644 (file)
@@ -41,14 +41,14 @@ String ContentType::parameter(const String& parameterName) const
     String strippedType = m_type.stripWhiteSpace();
 
     // a MIME type can have one or more "param=value" after a semi-colon, and separated from each other by semi-colons
-    int semi = strippedType.find(';');
-    if (semi != -1) {
-        int start = strippedType.find(parameterName, semi + 1, false);
-        if (start != -1) {
+    size_t semi = strippedType.find(';');
+    if (semi != notFound) {
+        size_t start = strippedType.find(parameterName, semi + 1, false);
+        if (start != notFound) {
             start = strippedType.find('=', start + 6);
-            if (start != -1) {
-                int end = strippedType.find(';', start + 6);
-                if (end == -1)
+            if (start != notFound) {
+                size_t end = strippedType.find(';', start + 6);
+                if (end == notFound)
                     end = strippedType.length();
                 parameterValue = strippedType.substring(start + 1, end - (start + 1)).stripWhiteSpace();
             }
@@ -63,8 +63,8 @@ String ContentType::type() const
     String strippedType = m_type.stripWhiteSpace();
 
     // "type" can have parameters after a semi-colon, strip them
-    int semi = strippedType.find(';');
-    if (semi != -1)
+    size_t semi = strippedType.find(';');
+    if (semi != notFound)
         strippedType = strippedType.left(semi).stripWhiteSpace();
 
     return strippedType;
index 8c845b0..16b84b5 100644 (file)
@@ -551,12 +551,12 @@ String KURL::lastPathComponent() const
     if (!hasPath())
         return String();
 
-    int end = m_pathEnd - 1;
+    unsigned end = m_pathEnd - 1;
     if (m_string[end] == '/')
         --end;
 
-    int start = m_string.reverseFind('/', end);
-    if (start < m_portEnd)
+    size_t start = m_string.reverseFind('/', end);
+    if (start < static_cast<unsigned>(m_portEnd))
         return String();
     ++start;
 
@@ -675,7 +675,7 @@ String KURL::path() const
 bool KURL::setProtocol(const String& s)
 {
     // Firefox and IE remove everything after the first ':'.
-    int separatorPosition = s.find(':');
+    size_t separatorPosition = s.find(':');
     String newProtocol = s.substring(0, separatorPosition);
 
     if (!isValidProtocol(newProtocol))
@@ -882,13 +882,13 @@ String decodeURLEscapeSequences(const String& str, const TextEncoding& encoding)
 
     CharBuffer buffer;
 
-    int length = str.length();
-    int decodedPosition = 0;
-    int searchPosition = 0;
-    int encodedRunPosition;
-    while ((encodedRunPosition = str.find('%', searchPosition)) >= 0) {
+    unsigned length = str.length();
+    unsigned decodedPosition = 0;
+    unsigned searchPosition = 0;
+    size_t encodedRunPosition;
+    while ((encodedRunPosition = str.find('%', searchPosition)) != notFound) {
         // Find the sequence of %-escape codes.
-        int encodedRunEnd = encodedRunPosition;
+        unsigned encodedRunEnd = encodedRunPosition;
         while (length - encodedRunEnd >= 3
                 && str[encodedRunEnd] == '%'
                 && isASCIIHexDigit(str[encodedRunEnd + 1])
@@ -1614,13 +1614,13 @@ static void encodeRelativeString(const String& rel, const TextEncoding& encoding
 
 static String substituteBackslashes(const String& string)
 {
-    int questionPos = string.find('?');
-    int hashPos = string.find('#');
-    int pathEnd;
+    size_t questionPos = string.find('?');
+    size_t hashPos = string.find('#');
+    unsigned pathEnd;
 
-    if (hashPos >= 0 && (questionPos < 0 || questionPos > hashPos))
+    if (hashPos != notFound && (questionPos == notFound || questionPos > hashPos))
         pathEnd = hashPos;
-    else if (questionPos >= 0)
+    else if (questionPos != notFound)
         pathEnd = questionPos;
     else
         pathEnd = string.length();
@@ -1799,13 +1799,12 @@ bool portAllowed(const KURL& url)
 String mimeTypeFromDataURL(const String& url)
 {
     ASSERT(protocolIs(url, "data"));
-    int index = url.find(';');
-    if (index == -1)
+    size_t index = url.find(';');
+    if (index == notFound)
         index = url.find(',');
-    if (index != -1) {
-        int len = index - 5;
-        if (len > 0)
-            return url.substring(5, len);
+    if (index != notFound) {
+        if (index > 5)
+            return url.substring(5, index - 5);
         return "text/plain"; // Data URLs with no MIME type are considered text/plain.
     }
     return "";
index 00b096b..e2fd9b8 100644 (file)
@@ -103,10 +103,10 @@ Length* newCoordsArray(const String& string, int& len)
     Length* r = new Length[len];
 
     int i = 0;
-    int pos = 0;
-    int pos2;
+    unsigned pos = 0;
+    size_t pos2;
 
-    while ((pos2 = str->find(' ', pos)) != -1) {
+    while ((pos2 = str->find(' ', pos)) != notFound) {
         r[i++] = parseLength(str->characters() + pos, pos2 - pos);
         pos = pos2+1;
     }
@@ -129,10 +129,10 @@ Length* newLengthArray(const String& string, int& len)
     Length* r = new Length[len];
 
     int i = 0;
-    int pos = 0;
-    int pos2;
+    unsigned pos = 0;
+    size_t pos2;
 
-    while ((pos2 = str->find(',', pos)) != -1) {
+    while ((pos2 = str->find(',', pos)) != notFound) {
         r[i++] = parseLength(str->characters() + pos, pos2 - pos);
         pos = pos2+1;
     }
index e239798..86b4c8a 100644 (file)
 
 namespace WebCore {
 
-static inline int findSlashDotDotSlash(const UChar* characters, size_t length)
+static inline size_t findSlashDotDotSlash(const UChar* characters, size_t length)
 {
     if (length < 4)
-        return -1;
+        return notFound;
     unsigned loopLimit = length - 3;
     for (unsigned i = 0; i < loopLimit; ++i) {
         if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '.' && characters[i + 3] == '/')
             return i;
     }
-    return -1;
+    return notFound;
 }
 
-static inline int findSlashSlash(const UChar* characters, size_t length, int position)
+static inline size_t findSlashSlash(const UChar* characters, size_t length, int position)
 {
     if (length < 2)
-        return -1;
+        return notFound;
     unsigned loopLimit = length - 1;
     for (unsigned i = position; i < loopLimit; ++i) {
         if (characters[i] == '/' && characters[i + 1] == '/')
             return i;
     }
-    return -1;
+    return notFound;
 }
 
-static inline int findSlashDotSlash(const UChar* characters, size_t length)
+static inline size_t findSlashDotSlash(const UChar* characters, size_t length)
 {
     if (length < 3)
-        return -1;
+        return notFound;
     unsigned loopLimit = length - 2;
     for (unsigned i = 0; i < loopLimit; ++i) {
         if (characters[i] == '/' && characters[i + 1] == '.' && characters[i + 2] == '/')
             return i;
     }
-    return -1;
+    return notFound;
 }
 
 static inline bool containsColonSlashSlash(const UChar* characters, unsigned length)
@@ -82,36 +82,32 @@ static inline bool containsColonSlashSlash(const UChar* characters, unsigned len
 static inline void cleanPath(Vector<UChar, 512>& path)
 {
     // FIXME: Should not do this in the query or anchor part.
-    int pos;
-    while ((pos = findSlashDotDotSlash(path.data(), path.size())) != -1) {
-        int prev = reverseFind(path.data(), path.size(), '/', pos - 1);
+    size_t pos;
+    while ((pos = findSlashDotDotSlash(path.data(), path.size())) != notFound) {
+        size_t prev = reverseFind(path.data(), path.size(), '/', pos - 1);
         // don't remove the host, i.e. http://foo.org/../foo.html
-        if (prev < 0 || (prev > 3 && path[prev - 2] == ':' && path[prev - 1] == '/'))
+        if (prev == notFound || (prev > 3 && path[prev - 2] == ':' && path[prev - 1] == '/'))
             path.remove(pos, 3);
         else
             path.remove(prev, pos - prev + 3);
     }
 
     // FIXME: Should not do this in the query part.
-    // Set refPos to -2 to mean "I haven't looked for the anchor yet".
-    // We don't want to waste a function call on the search for the the anchor
-    // in the vast majority of cases where there is no "//" in the path.
     pos = 0;
-    int refPos = -2;
-    while ((pos = findSlashSlash(path.data(), path.size(), pos)) != -1) {
-        if (refPos == -2)
-            refPos = find(path.data(), path.size(), '#');
-        if (refPos > 0 && pos >= refPos)
-            break;
-
-        if (pos == 0 || path[pos - 1] != ':')
-            path.remove(pos);
-        else
-            pos += 2;
+    if ((pos = findSlashSlash(path.data(), path.size(), pos)) != notFound) {
+        size_t refPos = find(path.data(), path.size(), '#');
+        while (refPos == 0 || refPos == notFound || pos < refPos) {
+            if (pos == 0 || path[pos - 1] != ':')
+                path.remove(pos);
+            else
+                pos += 2;
+            if ((pos = findSlashSlash(path.data(), path.size(), pos)) == notFound)
+                break;
+        }
     }
 
     // FIXME: Should not do this in the query or anchor part.
-    while ((pos = findSlashDotSlash(path.data(), path.size())) != -1)
+    while ((pos = findSlashDotSlash(path.data(), path.size())) != notFound)
         path.remove(pos, 2);
 }
 
index 606a9bd..1b75fba 100644 (file)
@@ -377,8 +377,8 @@ static void initializeMIMETypeRegistry()
 
 String MIMETypeRegistry::getMIMETypeForPath(const String& path)
 {
-    int pos = path.reverseFind('.');
-    if (pos >= 0) {
+    size_t pos = path.reverseFind('.');
+    if (pos != notFound) {
         String extension = path.substring(pos + 1);
         String result = getMIMETypeForExtension(extension);
         if (result.length())
index 0423236..58df51a 100644 (file)
@@ -113,8 +113,8 @@ bool SchemeRegistry::shouldTreatURLAsLocal(const String& url)
             return true;
     }
 
-    int loc = url.find(':');
-    if (loc == -1)
+    size_t loc = url.find(':');
+    if (loc == notFound)
         return false;
 
     String scheme = url.left(loc);
index 07f7761..fe45c0d 100644 (file)
@@ -252,8 +252,8 @@ void MediaPlayer::load(const String& url, const ContentType& contentType)
 
     // if we don't know the MIME type, see if the extension can help
     if (type.isEmpty() || type == "application/octet-stream" || type == "text/plain") {
-        int pos = url.reverseFind('.');
-        if (pos >= 0) {
+        size_t pos = url.reverseFind('.');
+        if (pos != notFound) {
             String extension = url.substring(pos + 1);
             String mediaType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension);
             if (!mediaType.isEmpty())
index 7b51018..f444b6e 100644 (file)
@@ -87,9 +87,9 @@ RetainPtr<NSImage> createDragImageIconForCachedImage(CachedImage* image)
 {
     const String& filename = image->response().suggestedFilename();
     NSString *extension = nil;
-    int dotIndex = filename.reverseFind('.');
+    size_t dotIndex = filename.reverseFind('.');
     
-    if (dotIndex > 0 && dotIndex < (int)(filename.length() - 1)) // require that a . exists after the first character and before the last
+    if (dotIndex != notFound && dotIndex < (filename.length() - 1)) // require that a . exists after the first character and before the last
         extension = filename.substring(dotIndex + 1);
     else {
         // It might be worth doing a further lookup to pull the extension from the MIME type.
index 4dc2d0c..4fb7799 100644 (file)
@@ -75,9 +75,9 @@ static String protectionSpaceMapKeyFromURL(const KURL& url)
     unsigned directoryURLPathStart = url.pathStart();
     ASSERT(directoryURL[directoryURLPathStart] == '/');
     if (directoryURL.length() > directoryURLPathStart + 1) {
-        int index = directoryURL.reverseFind('/');
-        ASSERT(index > 0);
-        directoryURL = directoryURL.substring(0, (static_cast<unsigned>(index) != directoryURLPathStart) ? static_cast<unsigned>(index) : directoryURLPathStart + 1);
+        size_t index = directoryURL.reverseFind('/');
+        ASSERT(index != notFound);
+        directoryURL = directoryURL.substring(0, (index != directoryURLPathStart) ? index : directoryURLPathStart + 1);
     }
     ASSERT(directoryURL.length() == directoryURLPathStart + 1 || directoryURL[directoryURL.length() - 1] != '/');
 
@@ -132,9 +132,9 @@ static PathToDefaultProtectionSpaceMap::iterator findDefaultProtectionSpaceForUR
         if (directoryURL.length() == directoryURLPathStart + 1)  // path is "/" already, cannot shorten it any more
             return map.end();
 
-        int index = directoryURL.reverseFind('/', -2);
-        ASSERT(index > 0);
-        directoryURL = directoryURL.substring(0, (static_cast<unsigned>(index) == directoryURLPathStart) ? index + 1 : index);
+        size_t index = directoryURL.reverseFind('/', directoryURL.length() - 2);
+        ASSERT(index != notFound);
+        directoryURL = directoryURL.substring(0, (index == directoryURLPathStart) ? index + 1 : index);
         ASSERT(directoryURL.length() > directoryURLPathStart);
         ASSERT(directoryURL.length() == directoryURLPathStart + 1 || directoryURL[directoryURL.length() - 1] != '/');
     }
index 6252bfc..b3f3d45 100644 (file)
@@ -42,9 +42,9 @@ using namespace WTF;
 namespace WebCore {
 
 // true if there is more to parse
-static inline bool skipWhiteSpace(const String& str, int& pos, bool fromHttpEquivMeta)
+static inline bool skipWhiteSpace(const String& str, unsigned& pos, bool fromHttpEquivMeta)
 {
-    int len = str.length();
+    unsigned len = str.length();
 
     if (fromHttpEquivMeta) {
         while (pos != len && str[pos] <= ' ')
@@ -59,9 +59,9 @@ static inline bool skipWhiteSpace(const String& str, int& pos, bool fromHttpEqui
 
 // Returns true if the function can match the whole token (case insensitive).
 // Note: Might return pos == str.length()
-static inline bool skipToken(const String& str, int& pos, const char* token)
+static inline bool skipToken(const String& str, unsigned& pos, const char* token)
 {
-    int len = str.length();
+    unsigned len = str.length();
 
     while (pos != len && *token) {
         if (toASCIILower(str[pos]) != *token++)
@@ -104,8 +104,8 @@ ContentDispositionType contentDispositionType(const String& contentDisposition)
 
 bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& delay, String& url)
 {
-    int len = refresh.length();
-    int pos = 0;
+    unsigned len = refresh.length();
+    unsigned pos = 0;
     
     if (!skipWhiteSpace(refresh, pos, fromHttpEquivMeta))
         return false;
@@ -126,7 +126,7 @@ bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& del
         
         ++pos;
         skipWhiteSpace(refresh, pos, fromHttpEquivMeta);
-        int urlStartPos = pos;
+        unsigned urlStartPos = pos;
         if (refresh.find("url", urlStartPos, false) == urlStartPos) {
             urlStartPos += 3;
             skipWhiteSpace(refresh, urlStartPos, fromHttpEquivMeta);
@@ -137,7 +137,7 @@ bool parseHTTPRefresh(const String& refresh, bool fromHttpEquivMeta, double& del
                 urlStartPos = pos;  // e.g. "Refresh: 0; url.html"
         }
 
-        int urlEndPos = len;
+        unsigned urlEndPos = len;
 
         if (refresh[urlStartPos] == '"' || refresh[urlStartPos] == '\'') {
             UChar quotationMark = refresh[urlStartPos];
@@ -173,8 +173,8 @@ String filenameFromHTTPContentDisposition(const String& value)
 
     unsigned length = keyValuePairs.size();
     for (unsigned i = 0; i < length; i++) {
-        int valueStartPos = keyValuePairs[i].find('=');
-        if (valueStartPos < 0)
+        size_t valueStartPos = keyValuePairs[i].find('=');
+        if (valueStartPos == notFound)
             continue;
 
         String key = keyValuePairs[i].left(valueStartPos).stripWhiteSpace();
@@ -241,12 +241,12 @@ void findCharsetInMediaType(const String& mediaType, unsigned int& charsetPos, u
     charsetPos = start;
     charsetLen = 0;
 
-    int pos = start;
-    int length = (int)mediaType.length();
+    size_t pos = start;
+    unsigned length = mediaType.length();
     
     while (pos < length) {
         pos = mediaType.find("charset", pos, false);
-        if (pos <= 0) {
+        if (pos == notFound || pos == 0) {
             charsetLen = 0;
             return;
         }
@@ -270,7 +270,7 @@ void findCharsetInMediaType(const String& mediaType, unsigned int& charsetPos, u
             ++pos;
 
         // we don't handle spaces within quoted parameter values, because charset names cannot have any
-        int endpos = pos;
+        unsigned endpos = pos;
         while (pos != length && mediaType[endpos] > ' ' && mediaType[endpos] != '"' && mediaType[endpos] != '\'' && mediaType[endpos] != ';')
             ++endpos;
 
@@ -290,8 +290,8 @@ XSSProtectionDisposition parseXSSProtectionHeader(const String& header)
     if (stippedHeader[0] == '0')
         return XSSProtectionDisabled;
 
-    int length = (int)header.length();
-    int pos = 0;
+    unsigned length = header.length();
+    unsigned pos = 0;
     if (stippedHeader[pos++] == '1'
         && skipWhiteSpace(stippedHeader, pos, false)
         && stippedHeader[pos++] == ';'
@@ -309,7 +309,7 @@ XSSProtectionDisposition parseXSSProtectionHeader(const String& header)
 
 String extractReasonPhraseFromHTTPStatusLine(const String& statusLine)
 {
-    int spacePos = statusLine.find(' ');
+    size_t spacePos = statusLine.find(' ');
     // Remove status code from the status line.
     spacePos = statusLine.find(' ', spacePos + 1);
     return statusLine.substring(spacePos + 1);
index f30344e..e231652 100644 (file)
@@ -439,8 +439,8 @@ bool ResourceResponseBase::isAttachment() const
 
     DEFINE_STATIC_LOCAL(const AtomicString, headerName, ("content-disposition"));
     String value = m_httpHeaderFields.get(headerName);
-    int loc = value.find(';');
-    if (loc != -1)
+    size_t loc = value.find(';');
+    if (loc != notFound)
         value = value.left(loc);
     value = value.stripWhiteSpace();
     DEFINE_STATIC_LOCAL(const AtomicString, attachmentString, ("attachment"));
@@ -591,9 +591,9 @@ static void parseCacheHeader(const String& header, Vector<pair<String, String> >
     const String safeHeader = header.removeCharacters(isControlCharacter);
     unsigned max = safeHeader.length();
     for (unsigned pos = 0; pos < max; /* pos incremented in loop */) {
-        int nextCommaPosition = safeHeader.find(',', pos);
-        int nextEqualSignPosition = safeHeader.find('=', pos);
-        if (nextEqualSignPosition >= 0 && (nextEqualSignPosition < nextCommaPosition || nextCommaPosition < 0)) {
+        size_t nextCommaPosition = safeHeader.find(',', pos);
+        size_t nextEqualSignPosition = safeHeader.find('=', pos);
+        if (nextEqualSignPosition != notFound && (nextEqualSignPosition < nextCommaPosition || nextCommaPosition == notFound)) {
             // Get directive name, parse right hand side of equal sign, then add to map
             String directive = trimToNextSeparator(safeHeader.substring(pos, nextEqualSignPosition - pos).stripWhiteSpace());
             pos += nextEqualSignPosition - pos + 1;
@@ -601,14 +601,14 @@ static void parseCacheHeader(const String& header, Vector<pair<String, String> >
             String value = safeHeader.substring(pos, max - pos).stripWhiteSpace();
             if (value[0] == '"') {
                 // The value is a quoted string
-                int nextDoubleQuotePosition = value.find('"', 1);
-                if (nextDoubleQuotePosition >= 0) {
+                size_t nextDoubleQuotePosition = value.find('"', 1);
+                if (nextDoubleQuotePosition != notFound) {
                     // Store the value as a quoted string without quotes
                     result.append(pair<String, String>(directive, value.substring(1, nextDoubleQuotePosition - 1).stripWhiteSpace()));
                     pos += (safeHeader.find('"', pos) - pos) + nextDoubleQuotePosition + 1;
                     // Move past next comma, if there is one
-                    int nextCommaPosition2 = safeHeader.find(',', pos);
-                    if (nextCommaPosition2 >= 0)
+                    size_t nextCommaPosition2 = safeHeader.find(',', pos);
+                    if (nextCommaPosition2 != notFound)
                         pos += nextCommaPosition2 - pos + 1;
                     else
                         return; // Parse error if there is anything left with no comma
@@ -619,8 +619,8 @@ static void parseCacheHeader(const String& header, Vector<pair<String, String> >
                 }
             } else {
                 // The value is a token until the next comma
-                int nextCommaPosition2 = value.find(',', 0);
-                if (nextCommaPosition2 >= 0) {
+                size_t nextCommaPosition2 = value.find(',', 0);
+                if (nextCommaPosition2 != notFound) {
                     // The value is delimited by the next comma
                     result.append(pair<String, String>(directive, trimToNextSeparator(value.substring(0, nextCommaPosition2).stripWhiteSpace())));
                     pos += (safeHeader.find(',', pos) - pos) + 1;
@@ -630,7 +630,7 @@ static void parseCacheHeader(const String& header, Vector<pair<String, String> >
                     return;
                 }
             }
-        } else if (nextCommaPosition >= 0 && (nextCommaPosition < nextEqualSignPosition || nextEqualSignPosition < 0)) {
+        } else if (nextCommaPosition != notFound && (nextCommaPosition < nextEqualSignPosition || nextEqualSignPosition == notFound)) {
             // Add directive to map with empty string as value
             result.append(pair<String, String>(trimToNextSeparator(safeHeader.substring(pos, nextCommaPosition - pos).stripWhiteSpace()), ""));
             pos += nextCommaPosition - pos + 1;
index e72825e..55b230b 100644 (file)
@@ -231,8 +231,8 @@ void RenderEmbeddedObject::updateWidget(bool onlyCreateNonNetscapePlugins)
                     url = p->value();
                 if (serviceType.isEmpty() && equalIgnoringCase(name, "type")) {
                     serviceType = p->value();
-                    int pos = serviceType.find(";");
-                    if (pos != -1)
+                    size_t pos = serviceType.find(";");
+                    if (pos != notFound)
                         serviceType = serviceType.left(pos);
                 }
                 if (!embed && !name.isEmpty()) {
index b882297..c406e09 100644 (file)
@@ -45,8 +45,8 @@ Entry::Entry(PassRefPtr<DOMFileSystem> fileSystem, const String& fullPath, bool
     , m_fullPath(fullPath)
     , m_isDirectory(isDirectory)
 {
-    int index = fullPath.reverseFind("/");
-    if (index != -1)
+    size_t index = fullPath.reverseFind("/");
+    if (index != notFound)
         m_name = fullPath.substring(index);
     else
         m_name = fullPath;
index ee7c192..898c259 100644 (file)
@@ -182,8 +182,8 @@ static inline bool isCompatibleGlyph(const SVGGlyphIdentifier& identifier, bool
         // Split subcode from language, if existant.
         String languagePrefix;
 
-        int subCodeSeparator = language.find('-');
-        if (subCodeSeparator != -1)
+        size_t subCodeSeparator = language.find('-');
+        if (subCodeSeparator != notFound)
             languagePrefix = language.left(subCodeSeparator);
 
         Vector<String>::const_iterator it = identifier.languages.begin();
index e3a7003..97003e5 100644 (file)
@@ -53,12 +53,11 @@ bool SVGURIReference::isKnownAttribute(const QualifiedName& attrName)
 String SVGURIReference::getTarget(const String& url)
 {
     if (url.startsWith("url(")) { // URI References, ie. fill:url(#target)
-        unsigned int start = url.find('#') + 1;
-        unsigned int end = url.reverseFind(')');
-
+        size_t start = url.find('#') + 1;
+        size_t end = url.reverseFind(')');
         return url.substring(start, end - start);
-    } else if (url.find('#') > -1) { // format is #target
-        unsigned int start = url.find('#') + 1;
+    } else if (url.find('#') != notFound) { // format is #target
+        size_t start = url.find('#') + 1;
         return url.substring(start, url.length() - start);
     } else // The url doesn't have any target.
         return String();
index 0352b43..99a5189 100644 (file)
@@ -219,8 +219,8 @@ SMILTime SVGSMILElement::parseClockValue(const String& data)
 
     double result = 0;
     bool ok;
-    int doublePointOne = parse.find(':');
-    int doublePointTwo = parse.find(':', doublePointOne + 1);
+    size_t doublePointOne = parse.find(':');
+    size_t doublePointTwo = parse.find(':', doublePointOne + 1);
     if (doublePointOne == 2 && doublePointTwo == 5 && parse.length() >= 8) { 
         result += parse.substring(0, 2).toUIntStrict(&ok) * 60 * 60;
         if (!ok)
@@ -229,7 +229,7 @@ SMILTime SVGSMILElement::parseClockValue(const String& data)
         if (!ok)
             return SMILTime::unresolved();
         result += parse.substring(6).toDouble(&ok);
-    } else if (doublePointOne == 2 && doublePointTwo == -1 && parse.length() >= 5) { 
+    } else if (doublePointOne == 2 && doublePointTwo == notFound && parse.length() >= 5) { 
         result += parse.substring(0, 2).toUIntStrict(&ok) * 60;
         if (!ok)
             return SMILTime::unresolved();
@@ -253,15 +253,15 @@ bool SVGSMILElement::parseCondition(const String& value, BeginOrEnd beginOrEnd)
     
     double sign = 1.;
     bool ok;
-    int pos = parseString.find('+');
-    if (pos == -1) {
+    size_t pos = parseString.find('+');
+    if (pos == notFound) {
         pos = parseString.find('-');
-        if (pos != -1)
+        if (pos != notFound)
             sign = -1.;
     }
     String conditionString;
     SMILTime offset = 0;
-    if (pos == -1)
+    if (pos == notFound)
         conditionString = parseString;
     else {
         conditionString = parseString.left(pos).stripWhiteSpace();
@@ -277,7 +277,7 @@ bool SVGSMILElement::parseCondition(const String& value, BeginOrEnd beginOrEnd)
     
     String baseID;
     String nameString;
-    if (pos == -1)
+    if (pos == notFound)
         nameString = conditionString;
     else {
         baseID = conditionString.left(pos);
index 41bf795..8b4e720 100644 (file)
@@ -477,9 +477,9 @@ Value FunSubstringBefore::evaluate() const
     if (s2.isEmpty())
         return "";
 
-    int i = s1.find(s2);
+    size_t i = s1.find(s2);
 
-    if (i == -1)
+    if (i == notFound)
         return "";
 
     return s1.left(i);
@@ -490,8 +490,8 @@ Value FunSubstringAfter::evaluate() const
     String s1 = arg(0)->evaluate().toString();
     String s2 = arg(1)->evaluate().toString();
 
-    int i = s1.find(s2);
-    if (i == -1)
+    size_t i = s1.find(s2);
+    if (i == notFound)
         return "";
 
     return s1.substring(i + s2.length());
@@ -556,11 +556,11 @@ Value FunTranslate::evaluate() const
     // FIXME: Building a String a character at a time is quite slow.
     for (unsigned i1 = 0; i1 < s1.length(); ++i1) {
         UChar ch = s1[i1];
-        int i2 = s2.find(ch);
+        size_t i2 = s2.find(ch);
         
-        if (i2 == -1)
+        if (i2 == notFound)
             newString += String(&ch, 1);
-        else if ((unsigned)i2 < s3.length()) {
+        else if (i2 < s3.length()) {
             UChar c2 = s3[i2];
             newString += String(&c2, 1);
         }
@@ -608,8 +608,8 @@ Value FunLang::evaluate() const
             return true;
 
         // Remove suffixes one by one.
-        int index = langValue.reverseFind('-');
-        if (index == -1)
+        size_t index = langValue.reverseFind('-');
+        if (index == notFound)
             break;
         langValue = langValue.left(index);
     }
index aa633dc..20e7590 100644 (file)
@@ -453,8 +453,8 @@ int Parser::lex(void* data)
 
 bool Parser::expandQName(const String& qName, String& localName, String& namespaceURI)
 {
-    int colon = qName.find(':');
-    if (colon >= 0) {
+    size_t colon = qName.find(':');
+    if (colon != notFound) {
         if (!m_resolver)
             return false;
         namespaceURI = m_resolver->lookupNamespaceURI(qName.left(colon));