Example #1
0
/* static */
nsresult
DataStorage::ValidateKeyAndValue(const nsCString& aKey, const nsCString& aValue)
{
  if (aKey.IsEmpty()) {
    return NS_ERROR_INVALID_ARG;
  }
  if (aKey.Length() > 256) {
    return NS_ERROR_INVALID_ARG;
  }
  int32_t delimiterIndex = aKey.FindChar('\t', 0);
  if (delimiterIndex >= 0) {
    return NS_ERROR_INVALID_ARG;
  }
  delimiterIndex = aKey.FindChar('\n', 0);
  if (delimiterIndex >= 0) {
    return NS_ERROR_INVALID_ARG;
  }
  delimiterIndex = aValue.FindChar('\n', 0);
  if (delimiterIndex >= 0) {
    return NS_ERROR_INVALID_ARG;
  }
  if (aValue.Length() > 1024) {
    return NS_ERROR_INVALID_ARG;
  }

  return NS_OK;
}
void nsEudoraWin32::ConvertPath( nsCString& str)
{
  nsCString  temp;
  nsCString  path;
  PRInt32    idx = 0;
  PRInt32    start = 0;
  nsCString  search;

  idx = str.FindChar( '\\', idx);
  if ((idx == 2) && (str.CharAt( 1) == ':'))
  {
    str.Left( path, 3);
    idx++;
    idx = str.FindChar( '\\', idx);
    start = 3;
    if ((idx == -1) && (str.Length() > 3))
    {
      str.Right( temp, str.Length() - start);
      path.Append( temp);
    }
  }

  WIN32_FIND_DATA findFileData;
  while (idx != -1)
  {
    str.Mid( temp, start, idx - start);
    search = path;
    search.Append( temp);
    HANDLE h = FindFirstFile( search.get(), &findFileData);
    if (h == INVALID_HANDLE_VALUE)
      return;
    path.Append( findFileData.cFileName);
    idx++;
    start = idx;
    idx = str.FindChar( '\\', idx);
    FindClose( h);
    if (idx != -1)
      path.Append( '\\');
    else
    {
      str.Right( temp, str.Length() - start);
      path.Append( '\\');
      path.Append( temp);
    }
  }

  str = path;
}
Example #3
0
/* static */ nsresult
nsHttpHandler::GenerateHostPort(const nsCString& host, PRInt32 port,
                                nsCString& hostLine)
{
    if (strchr(host.get(), ':')) {
        // host is an IPv6 address literal and must be encapsulated in []'s
        hostLine.Assign('[');
        // scope id is not needed for Host header.
        int scopeIdPos = host.FindChar('%');
        if (scopeIdPos == kNotFound)
            hostLine.Append(host);
        else if (scopeIdPos > 0)
            hostLine.Append(Substring(host, 0, scopeIdPos));
        else
          return NS_ERROR_MALFORMED_URI;
        hostLine.Append(']');
    }
    else
        hostLine.Assign(host);
    if (port != -1) {
        hostLine.Append(':');
        hostLine.AppendInt(port);
    }
    return NS_OK;
}
void nsEudoraAddress::ExtractNoteField( nsCString& note, nsCString& value, const char *pFieldName)
{
  value.Truncate();
  nsCString field("<");
  field.Append( pFieldName);
  field.Append( ':');

/*
    this is a bit of a cheat, but there's no reason it won't work
    fine for us, even better than Eudora in some cases!
*/

  PRInt32 idx = note.Find( field);
  if (idx != -1) {
    idx += field.Length();
    PRInt32 endIdx = note.FindChar( '>', idx);
    if (endIdx == -1)
      endIdx = note.Length() - 1;
    note.Mid( value, idx, endIdx - idx);
    idx -= field.Length();
    nsCString tempL;
    if (idx)
      note.Left( tempL, idx);
    nsCString tempR;
    note.Right( tempR, note.Length() - endIdx - 1);
    note = tempL;
    note.Append( tempR);
  }
}
static inline bool
CheckHeaderKey(const nsCString &aHeader, const char *aKeyString)
{
  nsAutoCString key(StringHead(aHeader, aHeader.FindChar(':')));
  key.Trim(" \t");
  return key.Equals(aKeyString);
}
Example #6
0
void DoErrTest(nsCString& aString) {
  PRInt32 pos=aString.FindChar(0);
  if(kNotFound<pos) {
    if(aString.Length()-1!=pos) {
    }
  }
}
Example #7
0
void
XRemoteService::FindRestInList(nsCString &aString, nsCString &retString,
                               PRUint32 *aIndexRet)
{
  // init our return
  *aIndexRet = 0;
  nsCString tempString;
  PRInt32   strIndex;
  // find out if there's a comma from the start of the string
  strIndex = aString.FindChar(',');

  // give up now if you can
  if (strIndex == kNotFound)
    return;

  // cut the string down to the first ,
  tempString = Substring(aString, strIndex+1, aString.Length());

  // strip off leading + trailing whitespace
  tempString.Trim(" ", PR_TRUE, PR_TRUE);

  // see if we've reduced it to nothing
  if (tempString.IsEmpty())
    return;

  *aIndexRet = strIndex;

  // otherwise, return it as a new C string
  retString = tempString;

}
nsresult
nsGopherContentStream::ParseTypeAndSelector(char &type, nsCString &selector)
{
    nsCAutoString buffer;
    nsresult rv = mChannel->URI()->GetPath(buffer); // unescaped down below
    if (NS_FAILED(rv))
        return rv;

    // No path given
    if (buffer[0] == '\0' || (buffer[0] == '/' && buffer[1] == '\0')) {
        type = '1';
        selector.Truncate();
    } else {
        NS_ENSURE_STATE(buffer[1] != '\0');

        type = buffer[1]; // Ignore leading '/'

        // Do it this way in case selector contains embedded nulls after
        // unescaping.
        char *sel = buffer.BeginWriting() + 2;
        PRInt32 count = nsUnescapeCount(sel);
        selector.Assign(sel, count);

        // NOTE: FindCharInSet cannot be used to search for a null byte.
        if (selector.FindCharInSet("\t\n\r") != kNotFound ||
            selector.FindChar('\0') != kNotFound) {
            // gopher selectors cannot containt tab, cr, lf, or \0
            return NS_ERROR_MALFORMED_URI;
        }
    }

    return NS_OK;
}
/**
 * Decodes the given base64 string.
 *
 * It returns its decoded string in its input.
 *
 * @param pBufInOut   (inout) a buffer of the string
 */
void nsMsgBodyHandler::Base64Decode (nsCString &pBufInOut)
{
  char *decodedBody = PL_Base64Decode(pBufInOut.get(), pBufInOut.Length(), nullptr);
  if (decodedBody)
    pBufInOut.Adopt(decodedBody);

  int32_t offset = pBufInOut.FindChar('\n');
  while (offset != -1) {
    pBufInOut.Replace(offset, 1, ' ');
    offset = pBufInOut.FindChar('\n', offset);
  }
  offset = pBufInOut.FindChar('\r');
  while (offset != -1) {
    pBufInOut.Replace(offset, 1, ' ');
    offset = pBufInOut.FindChar('\r', offset);
  } 
}
Example #10
0
/* parses ImapMessageURI */
nsresult nsParseImapMessageURI(const char* uri, nsCString& folderURI, PRUint32 *key, char **part)
{
    if(!key)
        return NS_ERROR_NULL_POINTER;

    nsCAutoString uriStr(uri);
    PRInt32 folderEnd = -1;
    // imap-message uri's can have imap:// url strings tacked on the end,
    // e.g., when opening/saving attachments. We don't want to look for '#'
    // in that part of the uri, if the attachment name contains '#',
    // so check for that here.
    if (StringBeginsWith(uriStr, NS_LITERAL_CSTRING("imap-message")))
        folderEnd = uriStr.Find("imap://");

    PRInt32 keySeparator = MsgRFindChar(uriStr, '#', folderEnd);
    if(keySeparator != -1)
    {
        PRInt32 keyEndSeparator = MsgFindCharInSet(uriStr, "/?&", keySeparator);
        nsAutoString folderPath;
        folderURI = StringHead(uriStr, keySeparator);
        folderURI.Cut(4, 8); // cut out the _message part of imap-message:
        // folder uri's don't have fully escaped usernames.
        PRInt32 atPos = folderURI.FindChar('@');
        if (atPos != -1)
        {
            nsCString unescapedName, escapedName;
            PRInt32 userNamePos = folderURI.Find("//") + 2;
            PRUint32 origUserNameLen = atPos - userNamePos;
            if (NS_SUCCEEDED(MsgUnescapeString(Substring(folderURI, userNamePos,
                                               origUserNameLen),
                                               0, unescapedName)))
            {
                // Re-escape the username, matching the way we do it in uris, not the
                // way necko escapes urls. See nsMsgIncomingServer::GetServerURI.
                MsgEscapeString(unescapedName, nsINetUtil::ESCAPE_XALPHAS, escapedName);
                folderURI.Replace(userNamePos, origUserNameLen, escapedName);
            }
        }
        nsCAutoString keyStr;
        if (keyEndSeparator != -1)
            keyStr = Substring(uriStr, keySeparator + 1, keyEndSeparator - (keySeparator + 1));
        else
            keyStr = Substring(uriStr, keySeparator + 1);

        *key = strtoul(keyStr.get(), nsnull, 10);

        if (part && keyEndSeparator != -1)
        {
            PRInt32 partPos = MsgFind(uriStr, "part=", PR_FALSE, keyEndSeparator);
            if (partPos != -1)
            {
                *part = ToNewCString(Substring(uriStr, keyEndSeparator));
            }
        }
    }
    return NS_OK;
}
Example #11
0
// convert '"' to "&quot;"
static void
rdf_EscapeQuotes(nsCString& s)
{
    int32_t i = 0;
    while ((i = s.FindChar('"', i)) != -1) {
        s.Replace(i, 1, quot, sizeof(quot) - 1);
        i += sizeof(quot) - 2;
    }
}
void nsEudoraWin32::GetServerAndUserName( const char *pSection, const char *pIni, nsCString& serverName, nsCString& userName, char *pBuff)
{
  DWORD    valSize;
  int      idx;
  nsCString  tStr;

  serverName.Truncate();
  userName.Truncate();

  valSize = ::GetPrivateProfileString( pSection, "PopServer", "", pBuff, kIniValueSize, pIni);
  if (valSize)
    serverName = pBuff;
  else
  {
    valSize = ::GetPrivateProfileString( pSection, "POPAccount", "", pBuff, kIniValueSize, pIni);
    if (valSize)
    {
      serverName = pBuff;
      idx = serverName.FindChar( '@');
      if (idx != -1)
      {
        serverName.Right( tStr, serverName.Length() - idx - 1);
        serverName = tStr;
      }
    }
  }
  valSize = ::GetPrivateProfileString( pSection, "LoginName", "", pBuff, kIniValueSize, pIni);
  if (valSize)
    userName = pBuff;
  else
  {
    valSize = ::GetPrivateProfileString( pSection, "POPAccount", "", pBuff, kIniValueSize, pIni);
    if (valSize)
    {
      userName = pBuff;
      idx = userName.FindChar( '@');
      if (idx != -1)
      {
        userName.Left( tStr, idx);
        userName = tStr;
      }
    }
  }
}
Example #13
0
void ImportAddressImpl::SanitizeSampleData(nsCString& val)
{
  // remove any line-feeds...
  PRInt32 offset = val.Find(NS_LITERAL_CSTRING("\x0D\x0A"));
  while (offset != -1) {
    val.Replace(offset, 2, ", ");
    offset = val.Find(NS_LITERAL_CSTRING("\x0D\x0A"), offset + 2);
  }
  offset = val.FindChar(13);
  while (offset != -1) {
    val.Replace(offset, 1, ',');
    offset = val.FindChar(13, offset + 2);
  }
  offset = val.FindChar(10);
  while (offset != -1) {
    val.Replace(offset, 1, ',');
    offset = val.FindChar(10, offset + 2);
  }
}
nsresult
nsBeckyFilters::ParseRuleLine(const nsCString &aLine,
                              nsMsgSearchAttribValue *aSearchAttribute,
                              nsMsgSearchOpValue *aSearchOperator,
                              nsString &aSearchKeyword)
{
  int32_t firstColonPosition = aLine.FindChar(':');
  if (firstColonPosition == -1 ||
      (int32_t)aLine.Length() == firstColonPosition - 1) {
    return NS_ERROR_FAILURE;
  }

  int32_t secondColonPosition = aLine.FindChar(':', firstColonPosition + 1);
  if (secondColonPosition == -1 ||
      (int32_t)aLine.Length() == secondColonPosition - 1) {
    return NS_ERROR_FAILURE;
  }

  int32_t length = secondColonPosition - firstColonPosition - 1;
  nsMsgSearchAttribValue searchAttribute;
  searchAttribute = ConvertSearchKeyToAttrib(Substring(aLine, firstColonPosition + 1, length));
  if (searchAttribute < 0)
    return NS_ERROR_FAILURE;

  int32_t tabPosition = aLine.FindChar('\t');
  if (tabPosition == -1 ||
      (int32_t)aLine.Length() == tabPosition - 1) {
    return NS_ERROR_FAILURE;
  }

  nsMsgSearchOpValue searchOperator;
  searchOperator = ConvertSearchFlagsToOperator(Substring(aLine, tabPosition + 1));
  if (searchOperator < 0)
    return NS_ERROR_FAILURE;

  *aSearchOperator = searchOperator;
  *aSearchAttribute = searchAttribute;
  length = tabPosition - secondColonPosition - 1;
  CopyUTF8toUTF16(Substring(aLine, secondColonPosition + 1, length), aSearchKeyword);
  return NS_OK;
}
Example #15
0
nsresult WebCL_parseOpenCLVersion (nsCString const& aVersionStr,
                                   int& aVersionMajorOut,
                                   int& aVersionMinorOut,
                                   nsCString& aVendorSpecificInfoOut)
{
  D_METHOD_START;

  // Sanity check: make sure the OpenCL version string is something valid.
  // It must begin with "OpenCL "
  PRInt32 m1 = aVersionStr.FindChar (' ');
  if (!nsCString(aVersionStr.get(), m1).EqualsLiteral("OpenCL"))
  {
    D_LOG (LOG_LEVEL_WARNING, "Version string does not begin with \"OpenCL\".");
    return NS_ERROR_FAILURE;
  }

  // Major version
  PRInt32 m2 = aVersionStr.FindChar('.', m1 + 1);
  nsresult rv;
  nsCOMPtr<nsIWritableVariant> variant = do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
  rv = variant->SetAsACString (nsCString(aVersionStr.get() + m1, m2-m1));
  NS_ENSURE_SUCCESS (rv, rv);
  rv = variant->GetAsInt32 (&aVersionMajorOut);
  NS_ENSURE_SUCCESS (rv, rv);

  // Minor version
  m1 = m2+1;
  m2 = aVersionStr.FindChar(' ', m1);
  rv = variant->SetAsACString (nsCString(aVersionStr.get() + m1, m2-m1));
  NS_ENSURE_SUCCESS (rv, rv);
  rv = variant->GetAsInt32 (&aVersionMinorOut);
  NS_ENSURE_SUCCESS (rv, rv);

  // Vendor specific information

  aVendorSpecificInfoOut = nsCString (aVersionStr.get() + m2 + 1);

  return NS_OK;
}
nsresult
nsBeckyFilters::GetActionTarget(const nsCString &aLine,
                                nsCString &aTarget)
{
  int32_t firstColonPosition = aLine.FindChar(':');
  if (firstColonPosition < -1 ||
      aLine.Length() == static_cast<uint32_t>(firstColonPosition)) {
    return NS_ERROR_FAILURE;
  }

  aTarget.Assign(Substring(aLine, firstColonPosition + 1));

  return NS_OK;
}
Example #17
0
nsNullPrincipalURI::nsNullPrincipalURI(const nsCString &aSpec)
{
    int32_t dividerPosition = aSpec.FindChar(':');
    NS_ASSERTION(dividerPosition != -1, "Malformed URI!");

    int32_t n = aSpec.Left(mScheme, dividerPosition);
    NS_ASSERTION(n == dividerPosition, "Storing the scheme failed!");

    int32_t count = aSpec.Length() - dividerPosition - 1;
    n = aSpec.Mid(mPath, dividerPosition + 1, count);
    NS_ASSERTION(n == count, "Storing the path failed!");

    ToLowerCase(mScheme);
}
static nsresult
GetBeckyStatusValue(const nsCString &aHeader, nsACString &aValue)
{
  int32_t valueStartPosition;

  valueStartPosition = aHeader.FindChar(':');
  if (valueStartPosition < 0)
    return NS_ERROR_UNEXPECTED;

  valueStartPosition++;

  int32_t commaPosition = aHeader.FindChar(',', valueStartPosition);
  if (commaPosition < 0)
    return NS_ERROR_UNEXPECTED;

  nsAutoCString value(Substring(aHeader,
                                valueStartPosition,
                                commaPosition - valueStartPosition));
  value.Trim(" \t");

  aValue.Assign(value);

  return NS_OK;
}
static nsresult
GetBeckyIncludeValue(const nsCString &aHeader, nsACString &aValue)
{
  int32_t valueStartPosition;

  valueStartPosition = aHeader.FindChar(':');
  if (valueStartPosition < 0)
    return NS_ERROR_FAILURE;

  valueStartPosition++;
  nsAutoCString value(Substring(aHeader, valueStartPosition));
  value.Trim(" \t");

  aValue.Assign(value);

  return NS_OK;
}
void nsEudoraAddress::ExtractNoteField(nsCString& note, nsCString& value, const char *pFieldName)
{
  value.Truncate();
  nsCString field("<");
  field.Append(pFieldName);
  field.Append(':');

/*
    this is a bit of a cheat, but there's no reason it won't work
    fine for us, even better than Eudora in some cases!
*/

  int32_t idx = note.Find(field);
  if (idx != -1) {
    idx += field.Length();
    int32_t endIdx = note.FindChar('>', idx);
    if (endIdx == -1)
      endIdx = note.Length() - 1;
    value = Substring(note, idx, endIdx - idx);
    idx -= field.Length();
    note.Cut(idx, endIdx + 1);
  }
}
// short cut function for creating a mailto url...
nsresult NS_MsgBuildSmtpUrl(nsIFile * aFilePath,
                            const nsCString &aSmtpHostName,
                            PRInt32 aSmtpPort,
                            const nsCString &aSmtpUserName,
                            const char * aRecipients, 
                            nsIMsgIdentity * aSenderIdentity,
                            nsIUrlListener * aUrlListener, 
                            nsIMsgStatusFeedback *aStatusFeedback,
                            nsIInterfaceRequestor* aNotificationCallbacks,
                            nsIURI ** aUrl,
                            PRBool aRequestDSN)
{
  // mscott: this function is a convience hack until netlib actually dispatches
  // smtp urls. in addition until we have a session to get a password, host and
  // other stuff from, we need to use default values....
  // ..for testing purposes....

  nsresult rv;
  nsCOMPtr<nsISmtpUrl> smtpUrl(do_CreateInstance(kCSmtpUrlCID, &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  nsCAutoString urlSpec("smtp://");

  if (!aSmtpUserName.IsEmpty())
  {
    nsCString escapedUsername;
    MsgEscapeString(aSmtpUserName, nsINetUtil::ESCAPE_XALPHAS,
                    escapedUsername);
    urlSpec.Append(escapedUsername);
    urlSpec.Append('@');
  }

  urlSpec.Append(aSmtpHostName);
  if (aSmtpHostName.FindChar(':') == -1)
  {
    urlSpec.Append(':');
    urlSpec.AppendInt(aSmtpPort);
  }

  nsCOMPtr<nsIMsgMailNewsUrl> url(do_QueryInterface(smtpUrl, &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  url->SetSpec(urlSpec);
  smtpUrl->SetRecipients(aRecipients);
  smtpUrl->SetRequestDSN(aRequestDSN);
  smtpUrl->SetPostMessageFile(aFilePath);
  smtpUrl->SetSenderIdentity(aSenderIdentity);
  smtpUrl->SetNotificationCallbacks(aNotificationCallbacks);

  nsCOMPtr<nsIPrompt> smtpPrompt(do_GetInterface(aNotificationCallbacks));
  nsCOMPtr<nsIAuthPrompt> smtpAuthPrompt(do_GetInterface(aNotificationCallbacks));
  if (!smtpPrompt || !smtpAuthPrompt)
  {
    nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv));
    NS_ENSURE_SUCCESS(rv, rv);

    if (!smtpPrompt)
      wwatch->GetNewPrompter(0, getter_AddRefs(smtpPrompt));
    if (!smtpAuthPrompt)
      wwatch->GetNewAuthPrompter(0, getter_AddRefs(smtpAuthPrompt));
  }

  smtpUrl->SetPrompt(smtpPrompt);            
  smtpUrl->SetAuthPrompt(smtpAuthPrompt);

  url->RegisterListener(aUrlListener);
  if (aStatusFeedback)
    url->SetStatusFeedback(aStatusFeedback);

  return CallQueryInterface(smtpUrl, aUrl);
}
Example #22
0
static void
HandleMailtoSubject(nsCString& aPath) {

  // Walk through the string and see if we have a subject already.
  bool hasSubject = false;
  bool hasParams = false;
  int32_t paramSep = aPath.FindChar('?');
  while (paramSep != kNotFound && paramSep < (int32_t)aPath.Length()) {
    hasParams = true;

    // Get the end of the name at the = op.  If it is *after* the next &,
    // assume that someone made a parameter without an = in it
    int32_t nameEnd = aPath.FindChar('=', paramSep+1);
    int32_t nextParamSep = aPath.FindChar('&', paramSep+1);
    if (nextParamSep == kNotFound) {
      nextParamSep = aPath.Length();
    }

    // If the = op is after the &, this parameter is a name without value.
    // If there is no = op, same thing.
    if (nameEnd == kNotFound || nextParamSep < nameEnd) {
      nameEnd = nextParamSep;
    }

    if (nameEnd != kNotFound) {
      if (Substring(aPath, paramSep+1, nameEnd-(paramSep+1)).
          LowerCaseEqualsLiteral("subject")) {
        hasSubject = true;
        break;
      }
    }

    paramSep = nextParamSep;
  }

  // If there is no subject, append a preformed subject to the mailto line
  if (!hasSubject) {
    if (hasParams) {
      aPath.Append('&');
    } else {
      aPath.Append('?');
    }

    // Get the default subject
    nsXPIDLString brandName;
    nsresult rv =
      nsContentUtils::GetLocalizedString(nsContentUtils::eBRAND_PROPERTIES,
                                         "brandShortName", brandName);
    if (NS_FAILED(rv))
      return;
    const char16_t *formatStrings[] = { brandName.get() };
    nsXPIDLString subjectStr;
    rv = nsContentUtils::FormatLocalizedString(
                                           nsContentUtils::eFORMS_PROPERTIES,
                                           "DefaultFormSubject",
                                           formatStrings,
                                           subjectStr);
    if (NS_FAILED(rv))
      return;
    aPath.AppendLiteral("subject=");
    nsCString subjectStrEscaped;
    aPath.Append(NS_EscapeURL(NS_ConvertUTF16toUTF8(subjectStr), esc_Query,
                              subjectStrEscaped));
  }
}
static nsresult
SplitURL(nsIURI *aChromeURI, nsCString& aPackage, nsCString& aProvider, nsCString& aFile,
         PRBool *aModified = nsnull)
{
  // Splits a "chrome:" URL into its package, provider, and file parts.
  // Here are the current portions of a
  // chrome: url that make up the chrome-
  //
  //     chrome://global/skin/foo?bar
  //     \------/ \----/\---/ \-----/
  //         |       |     |     |
  //         |       |     |     `-- RemainingPortion
  //         |       |     |
  //         |       |     `-- Provider
  //         |       |
  //         |       `-- Package
  //         |
  //         `-- Always "chrome://"
  //
  //

  nsresult rv;

  nsCAutoString str;
  rv = aChromeURI->GetSpec(str);
  if (NS_FAILED(rv)) return rv;

  // We only want to deal with "chrome:" URLs here. We could return
  // an error code if the URL isn't properly prefixed here...
  if (PL_strncmp(str.get(), kChromePrefix, sizeof(kChromePrefix) - 1) != 0)
    return NS_ERROR_INVALID_ARG;

  // Cull out the "package" string; e.g., "navigator"
  aPackage = str.get() + sizeof(kChromePrefix) - 1;

  PRInt32 idx;
  idx = aPackage.FindChar('/');
  if (idx < 0)
    return NS_OK;

  // Cull out the "provider" string; e.g., "content"
  aPackage.Right(aProvider, aPackage.Length() - (idx + 1));
  aPackage.Truncate(idx);

  idx = aProvider.FindChar('/');
  if (idx < 0) {
    // Force the provider to end with a '/'
    idx = aProvider.Length();
    aProvider.Append('/');
  }

  // Cull out the "file"; e.g., "navigator.xul"
  aProvider.Right(aFile, aProvider.Length() - (idx + 1));
  aProvider.Truncate(idx);

  PRBool nofile = aFile.IsEmpty();
  if (nofile) {
    // If there is no file, then construct the default file
    aFile = aPackage;

    if (aProvider.Equals("content")) {
      aFile += ".xul";
    }
    else if (aProvider.Equals("skin")) {
      aFile += ".css";
    }
    else if (aProvider.Equals("locale")) {
      aFile += ".dtd";
    }
    else {
      NS_ERROR("unknown provider");
      return NS_ERROR_FAILURE;
    }
  } else {
    // Protect against URIs containing .. that reach up out of the
    // chrome directory to grant chrome privileges to non-chrome files.
    int depth = 0;
    PRBool sawSlash = PR_TRUE;  // .. at the beginning is suspect as well as /..
    for (const char* p=aFile.get(); *p; p++) {
      if (sawSlash) {
        if (p[0] == '.' && p[1] == '.'){
          depth--;    // we have /.., decrement depth.
        } else {
          static const char escape[] = "%2E%2E";
          if (PL_strncasecmp(p, escape, sizeof(escape)-1) == 0)
            depth--;   // we have the HTML-escaped form of /.., decrement depth.
        }
      } else if (p[0] != '/') {
        depth++;        // we have /x for some x that is not /
      }
      sawSlash = (p[0] == '/');

      if (depth < 0) {
        return NS_ERROR_FAILURE;
      }
    }
  }
  if (aModified)
    *aModified = nofile;
  return NS_OK;
}