static CString pathSuitableForTestResult(const char* uriString)
{
    if (!uriString)
        return CString();

    KURL uri = KURL(ParsedURLString, uriString);

    if (!uri.isLocalFile())
        return uri.string().utf8();

    String pathString = uri.path();
    size_t indexBaseName = pathString.reverseFind('/');
    String baseName;
    if (indexBaseName == notFound)
        baseName = pathString;
    else
        baseName = pathString.substring(indexBaseName + 1);

    String dirName;
    if (indexBaseName != notFound) {
        size_t indexDirName = pathString.reverseFind('/', indexBaseName - 1);
        if (indexDirName != notFound)
            dirName = pathString.substring(indexDirName + 1, indexBaseName - indexDirName - 1);
    }

    String ret = dirName + "/" + baseName;
    return ret.utf8();
}
Beispiel #2
0
static bool makeAllDirectories(IFileMgr* fileManager, const String& path)
{
    if (path == canonicalPath(AEEFS_HOME_DIR))
        return true;

    int lastDivPos = path.reverseFind('/');
    int endPos = path.length();
    if (lastDivPos == path.length() - 1) {
        endPos -= 1;
        lastDivPos = path.reverseFind('/', lastDivPos);
    }

    if (lastDivPos > 0) {
        if (!makeAllDirectories(fileManager, path.substring(0, lastDivPos)))
            return false;
    }

    String folder(path.substring(0, endPos));

    // IFILEMGR_MkDir return SUCCESS when the file is successfully created or if file already exists.
    // So we need to check fileinfo.attrib.
    IFILEMGR_MkDir(fileManager, folder.utf8().data());

    FileInfo fileInfo;
    if (IFILEMGR_GetInfo(fileManager, folder.utf8().data(), &fileInfo) != SUCCESS)
        return false;

    return fileInfo.attrib & _FA_DIR;
}
static size_t reverseFindPathSeparator(const String& path, unsigned start = UINT_MAX)
{
    size_t positionSlash = path.reverseFind('/', start);
    size_t positionBackslash = path.reverseFind('\\', start);

    if (positionSlash == notFound)
        return positionBackslash;

    if (positionBackslash == notFound)
        return positionSlash;

    return std::max(positionSlash, positionBackslash);
}
Beispiel #4
0
void ResourceHandle::fileLoadTimer(Timer<ResourceHandle>*)
{
    RefPtr<ResourceHandle> protector(this);
    deref(); // balances ref in start

    if (firstRequest().url().protocolIsData()) {
        handleDataURL(this);
        return;
    }

    String fileName = firstRequest().url().fileSystemPath();
    HANDLE fileHandle = CreateFileW(fileName.charactersWithNullTermination(), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

    if (fileHandle == INVALID_HANDLE_VALUE) {
        client()->didFail(this, ResourceError());
        return;
    }

    ResourceResponse response;

    int dotPos = fileName.reverseFind('.');
    int slashPos = fileName.reverseFind('/');

    if (slashPos < dotPos && dotPos != -1) {
        String ext = fileName.substring(dotPos + 1);
        response.setMimeType(MIMETypeRegistry::getMIMETypeForExtension(ext));
    }

    client()->didReceiveResponse(this, response);

    bool result = false;
    DWORD bytesRead = 0;

    do {
        const int bufferSize = 8192;
        char buffer[bufferSize];
        result = ReadFile(fileHandle, &buffer, bufferSize, &bytesRead, 0);
        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=19793
        // -1 means we do not provide any data about transfer size to inspector so it would use
        // Content-Length headers or content size to show transfer size.
        if (result && bytesRead)
            client()->didReceiveData(this, buffer, bytesRead, -1);
        // Check for end of file.
    } while (result && bytesRead);

    CloseHandle(fileHandle);

    client()->didFinishLoading(this, 0);
}
static String findMagicComment(const String& content, const String& name, MagicCommentType commentType)
{
    ASSERT(name.find("=") == kNotFound);

    unsigned length = content.length();
    unsigned nameLength = name.length();

    size_t pos = length;
    size_t equalSignPos = 0;
    size_t closingCommentPos = 0;
    while (true) {
        pos = content.reverseFind(name, pos);
        if (pos == kNotFound)
            return String();

        // Check for a /\/[\/*][@#][ \t]/ regexp (length of 4) before found name.
        if (pos < 4)
            return String();
        pos -= 4;
        if (content[pos] != '/')
            continue;
        if ((content[pos + 1] != '/' || commentType != JavaScriptMagicComment)
            && (content[pos + 1] != '*' || commentType != CSSMagicComment))
            continue;
        if (content[pos + 2] != '#')
            continue;
        if (content[pos + 3] != ' ' && content[pos + 3] != '\t')
            continue;
        equalSignPos = pos + 4 + nameLength;
        if (equalSignPos < length && content[equalSignPos] != '=')
            continue;
        if (commentType == CSSMagicComment) {
            closingCommentPos = content.find("*/", equalSignPos + 1);
            if (closingCommentPos == kNotFound)
                return String();
        }

        break;
    }

    ASSERT(equalSignPos);
    ASSERT(commentType != CSSMagicComment || closingCommentPos);
    size_t urlPos = equalSignPos + 1;
    String match = commentType == CSSMagicComment
        ? content.substring(urlPos, closingCommentPos - urlPos)
        : content.substring(urlPos);

    size_t newLine = match.find("\n");
    if (newLine != kNotFound)
        match = match.substring(0, newLine);
    match = match.stripWhiteSpace();

    String disallowedChars("\"' \t");
    for (unsigned i = 0; i < match.length(); ++i) {
        if (disallowedChars.find(match[i]) != kNotFound)
            return "";
    }

    return match;
}
static PathToDefaultProtectionSpaceMap::iterator findDefaultProtectionSpaceForURL(const KURL& url)
{
    ASSERT(url.protocolIsInHTTPFamily());
    ASSERT(url.isValid());

    PathToDefaultProtectionSpaceMap& map = pathToDefaultProtectionSpaceMap();

    // Don't spend time iterating the path for origins that don't have any credentials.
    if (!originsWithCredentials().contains(originStringFromURL(url)))
        return map.end();

    String directoryURL = protectionSpaceMapKeyFromURL(url);
    unsigned directoryURLPathStart = url.pathStart();
    while (true) {
        PathToDefaultProtectionSpaceMap::iterator iter = map.find(directoryURL);
        if (iter != map.end())
            return iter;

        if (directoryURL.length() == directoryURLPathStart + 1)  // path is "/" already, cannot shorten it any more
            return map.end();

        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] != '/');
    }
}
Beispiel #7
0
static String notAFunctionSourceAppender(const String& originalMessage, const String& sourceText, RuntimeType type, ErrorInstance::SourceTextWhereErrorOccurred occurrence)
{
    ASSERT(type != TypeFunction);

    if (occurrence == ErrorInstance::FoundApproximateSource)
        return defaultApproximateSourceError(originalMessage, sourceText);

    ASSERT(occurrence == ErrorInstance::FoundExactSource);
    auto notAFunctionIndex = originalMessage.reverseFind("is not a function");
    RELEASE_ASSERT(notAFunctionIndex != notFound);
    StringView displayValue;
    if (originalMessage.is8Bit()) 
        displayValue = StringView(originalMessage.characters8(), notAFunctionIndex - 1);
    else
        displayValue = StringView(originalMessage.characters16(), notAFunctionIndex - 1);

    String base = functionCallBase(sourceText);
    StringBuilder builder;
    builder.append(base);
    builder.appendLiteral(" is not a function. (In '");
    builder.append(sourceText);
    builder.appendLiteral("', '");
    builder.append(base);
    builder.appendLiteral("' is ");
    if (type == TypeObject)
        builder.appendLiteral("an instance of ");
    builder.append(displayValue);
    builder.appendLiteral(")");

    return builder.toString();
}
Beispiel #8
0
static String findPluginMIMETypeFromURL(Page* page, const String& url)
{
    if (!url)
        return String();

    size_t dotIndex = url.reverseFind('.');
    if (dotIndex == notFound)
        return String();

    String extension = url.substring(dotIndex + 1);

    PluginData* pluginData = page->pluginData();
    if (!pluginData)
        return String();

    for (size_t i = 0; i < pluginData->mimes().size(); ++i) {
        const MimeClassInfo& mimeClassInfo = pluginData->mimes()[i];
        for (size_t j = 0; j < mimeClassInfo.extensions.size(); ++j) {
            if (equalIgnoringCase(extension, mimeClassInfo.extensions[j]))
                return mimeClassInfo.type;
        }
    }

    return String();
}
bool MediaPlayer::load(const URL& url, const ContentType& contentType, const String& keySystem)
{
    m_contentMIMEType = contentType.type().lower();
    m_contentTypeCodecs = contentType.parameter(codecs());
    m_url = url;
    m_keySystem = keySystem.lower();
    m_contentMIMETypeWasInferredFromExtension = false;

#if ENABLE(MEDIA_SOURCE)
    m_mediaSource = 0;
#endif

    // If the MIME type is missing or is not meaningful, try to figure it out from the URL.
    if (m_contentMIMEType.isEmpty() || m_contentMIMEType == applicationOctetStream() || m_contentMIMEType == textPlain()) {
        if (m_url.protocolIsData())
            m_contentMIMEType = mimeTypeFromDataURL(m_url.string());
        else {
            String lastPathComponent = url.lastPathComponent();
            size_t pos = lastPathComponent.reverseFind('.');
            if (pos != notFound) {
                String extension = lastPathComponent.substring(pos + 1);
                String mediaType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension);
                if (!mediaType.isEmpty()) {
                    m_contentMIMEType = mediaType;
                    m_contentMIMETypeWasInferredFromExtension = true;
                }
            }
        }
    }

    loadWithNextMediaEngine(0);
    return m_currentMediaEngine;
}
Beispiel #10
0
Value FunLang::evaluate(EvaluationContext& context) const {
  String lang = arg(0)->evaluate(context).toString();

  const Attribute* languageAttribute = nullptr;
  Node* node = context.node.get();
  while (node) {
    if (node->isElementNode()) {
      Element* element = toElement(node);
      languageAttribute = element->attributes().find(XMLNames::langAttr);
    }
    if (languageAttribute)
      break;
    node = node->parentNode();
  }

  if (!languageAttribute)
    return false;

  String langValue = languageAttribute->value();
  while (true) {
    if (equalIgnoringCase(langValue, lang))
      return true;

    // Remove suffixes one by one.
    size_t index = langValue.reverseFind('-');
    if (index == kNotFound)
      break;
    langValue = langValue.left(index);
  }

  return false;
}
void MediaPlayer::load(const String& url, const ContentType& contentType)
{
    String type = contentType.type().lower();
    String typeCodecs = contentType.parameter(codecs());

    // If the MIME type is missing or is not meaningful, try to figure it out from the URL.
    if (type.isEmpty() || type == applicationOctetStream() || type == textPlain()) {
        if (protocolIs(url, "data"))
            type = mimeTypeFromDataURL(url);
        else {
            size_t pos = url.reverseFind('.');
            if (pos != notFound) {
                String extension = url.substring(pos + 1);
                String mediaType = MIMETypeRegistry::getMediaMIMETypeForExtension(extension);
                if (!mediaType.isEmpty())
                    type = mediaType;
            }
        }
    }

    m_url = url;
    m_contentMIMEType = type;
    m_contentTypeCodecs = typeCodecs;
    loadWithNextMediaEngine(0);
}
Beispiel #12
0
static String findPluginMIMETypeFromURL(Page* page, const String& url)
{
    if (!url)
        return String();

    size_t dotIndex = url.reverseFind('.');
    if (dotIndex == notFound)
        return String();

    String extension = url.substring(dotIndex + 1);

    const PluginData& pluginData = page->pluginData();

    Vector<MimeClassInfo> mimes;
    Vector<size_t> mimePluginIndices;
    pluginData.getWebVisibleMimesAndPluginIndices(mimes, mimePluginIndices);
    for (auto& mime : mimes) {
        for (auto& mimeExtension : mime.extensions) {
            if (equalIgnoringASCIICase(extension, mimeExtension))
                return mime.type;
        }
    }

    return String();
}
Beispiel #13
0
static String removeLastComponent(const String& name)
{
    size_t lastSeparator = name.reverseFind('-');
    if (lastSeparator == kNotFound)
        return emptyString();
    return name.left(lastSeparator);
}
Value FunLang::evaluate() const
{
    String lang = argument(0).evaluate().toString();

    const Attribute* languageAttribute = nullptr;
    Node* node = evaluationContext().node.get();
    while (node) {
        if (is<Element>(*node)) {
            Element& element = downcast<Element>(*node);
            if (element.hasAttributes())
                languageAttribute = element.findAttributeByName(XMLNames::langAttr);
        }
        if (languageAttribute)
            break;
        node = node->parentNode();
    }

    if (!languageAttribute)
        return false;

    String langValue = languageAttribute->value();
    while (true) {
        if (equalIgnoringCase(langValue, lang))
            return true;

        // Remove suffixes one by one.
        size_t index = langValue.reverseFind('-');
        if (index == notFound)
            break;
        langValue = langValue.left(index);
    }

    return false;
}
Beispiel #15
0
Value FunLang::evaluate() const
{
    String lang = arg(0)->evaluate().toString();

    RefPtr<Node> langNode = 0;
    Node* node = evaluationContext().node.get();
    while (node) {
        NamedAttrMap* attrs = node->attributes();
        if (attrs)
            langNode = attrs->getNamedItemNS(XMLNames::xmlNamespaceURI, "lang");
        if (langNode)
            break;
        node = node->parentNode();
    }

    if (!langNode)
        return false;

    String langNodeValue = langNode->nodeValue();
    while (true) {
        if (equalIgnoringCase(langNodeValue, lang))
            return true;

        // Remove suffixes one by one.
        int index = langNodeValue.reverseFind('-');
        if (index == -1)
            break;
        langNodeValue = langNodeValue.left(index);
    }

    return false;
}
Beispiel #16
0
static void initializeOverrideInfo(const SourceCode& origCode, const String& newBody, FunctionOverrides::OverrideInfo& info)
{
    String origProviderStr = origCode.provider()->source();
    unsigned origBraceStart = origCode.startOffset();
    unsigned origFunctionStart = origProviderStr.reverseFind("function", origBraceStart);
    unsigned headerLength = origBraceStart - origFunctionStart;
    String origHeader = origProviderStr.substring(origFunctionStart, headerLength);

    String newProviderStr;
    newProviderStr.append(origHeader);
    newProviderStr.append(newBody);

    RefPtr<SourceProvider> newProvider = StringSourceProvider::create(newProviderStr, "<overridden>");

    info.firstLine = 1;
    info.lineCount = 1; // Faking it. This doesn't really matter for now.
    info.startColumn = 1;
    info.endColumn = 1; // Faking it. This doesn't really matter for now.
    info.parametersStartOffset = newProviderStr.find("(");
    info.typeProfilingStartOffset = newProviderStr.find("{");
    info.typeProfilingEndOffset = newProviderStr.length() - 1;

    info.sourceCode =
        SourceCode(newProvider.release(), info.typeProfilingStartOffset, info.typeProfilingEndOffset + 1, 1, 1);
}
Beispiel #17
0
PassRefPtr<SecurityOrigin> SecurityOrigin::createFromDatabaseIdentifier(const String& databaseIdentifier)
{ 
    // Make sure there's a first separator
    size_t separator1 = databaseIdentifier.find(SeparatorCharacter);
    if (separator1 == notFound)
        return create(KURL());
        
    // Make sure there's a second separator
    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
    // underscores in them, so we'll assume that any additional underscores are part of the host.
    if (separator1 == separator2)
        return create(KURL());
        
    // 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 == databaseIdentifier.length() - 1);
    if (!(portOkay || portAbsent))
        return create(KURL());
    
    if (port < 0 || port > MaxAllowedPort)
        return create(KURL());
        
    // Split out the 3 sections of data
    String protocol = databaseIdentifier.substring(0, separator1);
    String host = databaseIdentifier.substring(separator1 + 1, separator2 - separator1 - 1);
    
    host = decodeURLEscapeSequences(host);
    return create(KURL(KURL(), protocol + "://" + host + ":" + String::number(port)));
}
Beispiel #18
0
bool WMLPageState::processAccessControlData(const String& domain, const String& path)
{
    if (m_hasAccessControlData)
        return false;

    m_hasAccessControlData = true;

    KURL previousURL, currentURL;
    if (!tryAccessHistoryURLs(m_page, previousURL, currentURL))
        return true;

    // Spec: The path attribute defaults to the value "/"
    m_accessPath = path.isEmpty() ? "/" : path;

    // Spec: The domain attribute defaults to the current decks domain.
    String previousHost = hostFromURL(previousURL);
    m_accessDomain = domain.isEmpty() ? previousHost : normalizedHostName(domain);

    // Spec: To simplify the development of applications that may not know the absolute path to the 
    // current deck, the path attribute accepts relative URIs. The user agent converts the relative 
    // path to an absolute path and then performs prefix matching against the PATH attribute.
    Document* document = m_page->mainFrame() ? m_page->mainFrame()->document() : 0;
    if (document && previousHost == m_accessDomain && !m_accessPath.startsWith("/")) {
        String currentPath = currentURL.path();

        size_t index = currentPath.reverseFind('/');
        if (index != WTF::notFound)
            m_accessPath = document->completeURL(currentPath.left(index + 1) + m_accessPath).path();
    }

    return true;
}
Beispiel #19
0
Value FunLang::evaluate() const
{
    String lang = arg(0)->evaluate().toString();

    Attribute* languageAttribute = 0;
    Node* node = evaluationContext().node.get();
    while (node) {
        NamedNodeMap* attrs = node->attributes();
        if (attrs)
            languageAttribute = attrs->getAttributeItem(XMLNames::langAttr);
        if (languageAttribute)
            break;
        node = node->parentNode();
    }

    if (!languageAttribute)
        return BOOL_TO_VALUE_CAST false;

    String langValue = languageAttribute->value();
    while (true) {
        if (equalIgnoringCase(langValue, lang))
            return BOOL_TO_VALUE_CAST true;

        // Remove suffixes one by one.
        size_t index = langValue.reverseFind('-');
        if (index == notFound)
            break;
        langValue = langValue.left(index);
    }

    return BOOL_TO_VALUE_CAST false;
}
PassRefPtr<SecurityOrigin> SecurityOrigin::createFromDatabaseIdentifier(const String& databaseIdentifier)
{ 
    // Make sure there's a first separator
    int separator1 = databaseIdentifier.find(SeparatorCharacter);
    if (separator1 == -1)
        return create(KURL());
        
    // Make sure there's a second separator
    int separator2 = databaseIdentifier.find(SeparatorCharacter, separator1 + 1);
    if (separator2 == -1)
        return create(KURL());
        
    // Make sure there's not a third separator
    if (databaseIdentifier.reverseFind(SeparatorCharacter) != separator2)
        return create(KURL());
        
    // 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);
    if (!portOkay && separator2 + 1 == static_cast<int>(databaseIdentifier.length()))
        return create(KURL());
    
    if (port < 0 || port > 65535)
        return create(KURL());
        
    // Split out the 3 sections of data
    String protocol = databaseIdentifier.substring(0, separator1);
    String host = databaseIdentifier.substring(separator1 + 1, separator2 - separator1 - 1);
    return create(KURL(protocol + "://" + host + ":" + String::number(port)));
}
Beispiel #21
0
static String getContentTypeFromFileName(const String& name)
{
    String type;
    int index = name.reverseFind('.');
    if (index != -1)
        type = MIMETypeRegistry::getWellKnownMIMETypeForExtension(name.substring(index + 1));
    return type;
}
Beispiel #22
0
String DOMFilePath::getDirectory(const String& path) {
  int index = path.reverseFind(DOMFilePath::separator);
  if (!index)
    return DOMFilePath::root;
  if (index != -1)
    return path.substring(0, index);
  return ".";
}
Beispiel #23
0
static PassOwnPtr<BlobData> createBlobDataForFileSystemFile(const String& path, const String& fileSystemName)
{
    String type;
    int index = fileSystemName.reverseFind('.');
    if (index != -1)
        type = MIMETypeRegistry::getWellKnownMIMETypeForExtension(fileSystemName.substring(index + 1));
    return createBlobDataForFileWithType(path, type);
}
String mimeTypeFromURL(const KURL& url)
{
    String decodedPath = decodeURLEscapeSequences(url.path());
    String extension = decodedPath.substring(decodedPath.reverseFind('.') + 1);

    // We don't use MIMETypeRegistry::getMIMETypeForPath() because it returns "application/octet-stream" upon failure
    return MIMETypeRegistry::getMIMETypeForExtension(extension);
}
Beispiel #25
0
static PassOwnPtr<BlobData> createBlobDataForFile(const String& path)
{
    String type;
    int index = path.reverseFind('.');
    if (index != -1)
        type = MIMETypeRegistry::getMIMETypeForExtension(path.substring(index + 1));
    return createBlobDataForFileWithType(path, type);
}
String getMIMETypeForUTI(const String & uti)
{
    String mimeType;
    // FIXME: This is an ugly hack: public.type -> image/type mimetype
    if (int dotLocation = uti.reverseFind('.')) {
        mimeType = String("image/")+uti.substring(dotLocation + 1);
    }
    return mimeType;
}
// Find the markup between "<!--StartFragment -->" and "<!--EndFragment -->", accounting for browser quirks.
static String extractMarkupFromCFHTML(const String& cfhtml)
{
    unsigned markupStart = cfhtml.find("<html", 0, false);
    unsigned tagStart = cfhtml.find("startfragment", markupStart, false);
    unsigned fragmentStart = cfhtml.find('>', tagStart) + 1;
    unsigned tagEnd = cfhtml.find("endfragment", fragmentStart, false);
    unsigned fragmentEnd = cfhtml.reverseFind('<', tagEnd);
    return cfhtml.substring(fragmentStart, fragmentEnd - fragmentStart).stripWhiteSpace();
}
String MIMETypeRegistry::getMIMETypeForPath(const String& path)
{
    int pos = path.reverseFind('.');
    if (pos >= 0) {
        String extension = path.substring(pos + 1);
        return getMIMETypeForExtension(extension);
    }
    return "application/octet-stream";
}
Beispiel #29
0
static String findFontFallback(const char* pathOrUrl)
{
    String pathToFontFallback = WebCore::directoryName(pathOrUrl);

    wchar_t fullPath[_MAX_PATH];
    if (!_wfullpath(fullPath, pathToFontFallback.charactersWithNullTermination().data(), _MAX_PATH))
        return emptyString();

    if (!::PathIsDirectoryW(fullPath))
        return emptyString();

    String pathToCheck = fullPath;

    static const String layoutTests = "LayoutTests";

    // Find the layout test root on the current path:
    size_t location = pathToCheck.find(layoutTests);
    if (WTF::notFound == location)
        return emptyString();

    String pathToTest = pathToCheck.substring(location + layoutTests.length() + 1);
    String possiblePathToLogue = WebCore::pathByAppendingComponent(pathToCheck.substring(0, location + layoutTests.length() + 1), "platform\\win");

    Vector<String> possiblePaths;
    possiblePaths.append(WebCore::pathByAppendingComponent(possiblePathToLogue, pathToTest));

    size_t nextCandidateEnd = pathToTest.reverseFind('\\');
    while (nextCandidateEnd && nextCandidateEnd != WTF::notFound) {
        pathToTest = pathToTest.substring(0, nextCandidateEnd);
        possiblePaths.append(WebCore::pathByAppendingComponent(possiblePathToLogue, pathToTest));
        nextCandidateEnd = pathToTest.reverseFind('\\');
    }

    for (Vector<String>::iterator pos = possiblePaths.begin(); pos != possiblePaths.end(); ++pos) {
        pathToFontFallback = WebCore::pathByAppendingComponent(*pos, "resources\\"); 

        if (::PathIsDirectoryW(pathToFontFallback.charactersWithNullTermination().data()))
            return pathToFontFallback;
    }

    return emptyString();
}
bool makeAllDirectories(const String& path)
{
    int lastDivPos = max(path.reverseFind('/'), path.reverseFind('\\'));
    int endPos = path.length();
    if (lastDivPos == path.length() - 1) {
        endPos -= 1;
        lastDivPos = max(path.reverseFind('/', lastDivPos), path.reverseFind('\\', lastDivPos));
    }

    if (lastDivPos > 0) {
        if (!makeAllDirectories(path.substring(0, lastDivPos)))
            return false;
    }

    String folder(path.substring(0, endPos));
    CreateDirectory(folder.charactersWithNullTermination(), 0);

    DWORD fileAttr = GetFileAttributes(folder.charactersWithNullTermination());
    return fileAttr != 0xFFFFFFFF && (fileAttr & FILE_ATTRIBUTE_DIRECTORY);
}