static PRBool GConfIgnoreHost(const nsACString& aIgnore,
                              const nsACString& aHost)
{
  if (aIgnore.Equals(aHost, nsCaseInsensitiveCStringComparator()))
    return PR_TRUE;

  if (aIgnore.First() == '*' &&
      StringEndsWith(aHost, nsDependentCSubstring(aIgnore, 1),
                     nsCaseInsensitiveCStringComparator()))
    return PR_TRUE;

  PRInt32 mask = 128;
  nsReadingIterator<char> start;
  nsReadingIterator<char> slash;
  nsReadingIterator<char> end;
  aIgnore.BeginReading(start);
  aIgnore.BeginReading(slash);
  aIgnore.EndReading(end);
  if (FindCharInReadable('/', slash, end)) {
    ++slash;
    nsDependentCSubstring maskStr(slash, end);
    nsCAutoString maskStr2(maskStr);
    PRInt32 err;
    mask = maskStr2.ToInteger(&err);
    if (err != 0) {
      mask = 128;
    }
    --slash;
  } else {
    slash = end;
  }

  PRIPv6Addr ignoreAddr, hostAddr;
  if (!ConvertToIPV6Addr(aIgnore, &ignoreAddr) ||
      !ConvertToIPV6Addr(aHost, &hostAddr))
    return PR_FALSE;

  proxy_MaskIPv6Addr(ignoreAddr, mask);
  proxy_MaskIPv6Addr(hostAddr, mask);
  
  return memcmp(&ignoreAddr, &hostAddr, sizeof(PRIPv6Addr)) == 0;
}
void
GeckoChildProcessHost::SetChildLogName(const char* varName, const char* origLogName,
                                       nsACString &buffer)
{
  // We currently have no portable way to launch child with environment
  // different than parent.  So temporarily change NSPR_LOG_FILE so child
  // inherits value we want it to have. (NSPR only looks at NSPR_LOG_FILE at
  // startup, so it's 'safe' to play with the parent's environment this way.)
  buffer.Assign(varName);
  buffer.Append(origLogName);

  // Append child-specific postfix to name
  buffer.AppendLiteral(".child-");
  buffer.AppendInt(mChildCounter);

  // Passing temporary to PR_SetEnv is ok here if we keep the temporary
  // for the time we launch the sub-process.  It's copied to the new
  // environment.
  PR_SetEnv(buffer.BeginReading());
}
Exemplo n.º 3
0
bool
net_IsAbsoluteURL(const nsACString& uri)
{
    nsACString::const_iterator start, end;
    uri.BeginReading(start);
    uri.EndReading(end);

    // Strip C0 and space from begining
    while (start != end) {
        if ((uint8_t) *start > 0x20) {
            break;
        }
        start++;
    }

    Tokenizer p(Substring(start, end), "\r\n\t");

    // First char must be alpha
    if (!p.CheckChar(isAsciiAlpha)) {
        return false;
    }

    while (p.CheckChar(net_IsValidSchemeChar) || p.CheckWhite()) {
        // Skip valid scheme characters or \r\n\t
    }
    if (!p.CheckChar(':')) {
        return false;
    }
    p.SkipWhites();

    if (!p.CheckChar('/')) {
        return false;
    }
    p.SkipWhites();

    if (p.CheckChar('/')) {
        // aSpec is really absolute. Ignore aBaseURI in this case
        return true;
    }
    return false;
}
/* static */
nsresult
sbURIChecker::CheckPath( nsACString &aPath, nsIURI *aSiteURI )
{
  // aPath may be empty
  NS_ENSURE_ARG_POINTER(aSiteURI);
  LOG(( "sbURIChecker::CheckPath(%s)", aPath.BeginReading() ));

  nsresult rv;

  nsCString fixedSitePath;
  rv = sbURIChecker::FixupPath( aSiteURI, fixedSitePath );
  NS_ENSURE_SUCCESS( rv, rv );

  if ( aPath.IsEmpty() ) {
    // If the path was empty we use aSiteURI that was retrieved from the system.
    aPath.Assign(fixedSitePath);

    // The rest of this function will ensure that the path is actually a subpath
    // of aURI. If nothing was passed in aPath then we already know that this
    // is true because we constructed aPath from aURI. Therefore we're done and
    // can go ahead and return.
    return NS_OK;
  }

  // Compare fixedPath to fixedSitePath to make sure that fixedPath is within
  // fixedSitePath.
  nsCString fixedPath;
  rv = sbURIChecker::FixupPath( aPath, fixedPath );
  NS_ENSURE_SUCCESS( rv, rv );

  // Verify that this path is indeed part of the site URI.
  if ( !StringBeginsWith( fixedSitePath, fixedPath ) ) {
    LOG(("sbURIChecker::CheckPath() -- FAILED Path Prefix Check"));
    return NS_ERROR_FAILURE;
  }

  LOG(("sbURIChecker::CheckPath() -- PASSED Path Prefix Check"));

  aPath.Assign(fixedPath);
  return NS_OK;
}
Exemplo n.º 5
0
NS_IMETHODIMP _OldStorage::AsyncOpenURI(nsIURI *aURI,
                                        const nsACString & aIdExtension,
                                        uint32_t aFlags,
                                        nsICacheEntryOpenCallback *aCallback)
{
  NS_ENSURE_ARG(aURI);
  NS_ENSURE_ARG(aCallback);

#ifdef MOZ_LOGGING
  nsAutoCString uriSpec;
  aURI->GetAsciiSpec(uriSpec);
  LOG(("_OldStorage::AsyncOpenURI [this=%p, uri=%s, ide=%s, flags=%x]",
    this, uriSpec.get(), aIdExtension.BeginReading(), aFlags));
#endif

  nsresult rv;

  nsAutoCString cacheKey, scheme;
  rv = AssembleCacheKey(aURI, aIdExtension, cacheKey, scheme);
  NS_ENSURE_SUCCESS(rv, rv);

  if (!mAppCache && (mLookupAppCache || mOfflineStorage)) {
    rv = ChooseApplicationCache(cacheKey, getter_AddRefs(mAppCache));
    NS_ENSURE_SUCCESS(rv, rv);

    if (mAppCache) {
      // From a chosen appcache open only as readonly
      aFlags &= ~nsICacheStorage::OPEN_TRUNCATE;
    }
  }

  RefPtr<_OldCacheLoad> cacheLoad =
    new _OldCacheLoad(scheme, cacheKey, aCallback, mAppCache,
                      mLoadInfo, mWriteToDisk, aFlags);

  rv = cacheLoad->Start();
  NS_ENSURE_SUCCESS(rv, rv);

  return NS_OK;
}
Exemplo n.º 6
0
PRBool
nsNodeInfo::QualifiedNameEqualsInternal(const nsACString& aQualifiedName) const
{
  NS_PRECONDITION(mInner.mPrefix, "Must have prefix");
  
  nsACString::const_iterator start;
  aQualifiedName.BeginReading(start);

  nsACString::const_iterator colon(start);

  const char* prefix;
  mInner.mPrefix->GetUTF8String(&prefix);

  PRUint32 len = strlen(prefix);

  if (len >= aQualifiedName.Length()) {
    return PR_FALSE;
  }

  colon.advance(len);

  // If the character at the prefix length index is not a colon,
  // aQualifiedName is not equal to this string.
  if (*colon != ':') {
    return PR_FALSE;
  }

  // Compare the prefix to the string from the start to the colon
  if (!mInner.mPrefix->EqualsUTF8(Substring(start, colon)))
    return PR_FALSE;

  ++colon; // Skip the ':'

  nsACString::const_iterator end;
  aQualifiedName.EndReading(end);

  // Compare the local name to the string between the colon and the
  // end of aQualifiedName
  return mInner.mName->EqualsUTF8(Substring(colon, end));
}
Exemplo n.º 7
0
nsresult
SecretDecoderRing::Encrypt(const nsACString& data, /*out*/ nsACString& result)
{
  nsNSSShutDownPreventionLock locker;
  if (isAlreadyShutDown()) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  UniquePK11SlotInfo slot(PK11_GetInternalKeySlot());
  if (!slot) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  /* Make sure token is initialized. */
  nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
  nsresult rv = setPassword(slot.get(), ctx, locker);
  if (NS_FAILED(rv)) {
    return rv;
  }

  /* Force authentication */
  if (PK11_Authenticate(slot.get(), true, ctx) != SECSuccess) {
    return NS_ERROR_FAILURE;
  }

  /* Use default key id */
  SECItem keyid;
  keyid.data = nullptr;
  keyid.len = 0;
  SECItem request;
  request.data = BitwiseCast<unsigned char*, const char*>(data.BeginReading());
  request.len = data.Length();
  ScopedAutoSECItem reply;
  if (PK11SDR_Encrypt(&keyid, &request, &reply, ctx) != SECSuccess) {
    return NS_ERROR_FAILURE;
  }

  result.Assign(BitwiseCast<char*, unsigned char*>(reply.data), reply.len);
  return NS_OK;
}
Exemplo n.º 8
0
NS_IMETHODIMP
nsGZFileWriter::Write(const nsACString& aStr)
{
  NS_ENSURE_TRUE(mInitialized, NS_ERROR_NOT_INITIALIZED);
  NS_ENSURE_FALSE(mFinished, NS_ERROR_FAILURE);

  // gzwrite uses a return value of 0 to indicate failure.  Otherwise, it
  // returns the number of uncompressed bytes written.  To ensure we can
  // distinguish between success and failure, don't call gzwrite when we have 0
  // bytes to write.
  if (aStr.IsEmpty()) {
    return NS_OK;
  }

  // gzwrite never does a short write -- that is, the return value should
  // always be either 0 or aStr.Length(), and we shouldn't have to call it
  // multiple times in order to get it to read the whole buffer.
  int rv = gzwrite(mGZFile, aStr.BeginReading(), aStr.Length());
  NS_ENSURE_TRUE(rv == static_cast<int>(aStr.Length()), NS_ERROR_FAILURE);

  return NS_OK;
}
Exemplo n.º 9
0
NS_IMETHODIMP nsMailboxService::NewURI(const nsACString &aSpec,
                                       const char *aOriginCharset,
                                       nsIURI *aBaseURI,
                                       nsIURI **_retval)
{
    nsresult rv = NS_OK;
    nsACString::const_iterator b, e;
    if (FindInReadable(NS_LITERAL_CSTRING("?uidl="), aSpec.BeginReading(b), aSpec.EndReading(e)) ||
        FindInReadable(NS_LITERAL_CSTRING("&uidl="), aSpec.BeginReading(b), aSpec.EndReading(e)))
  {
    nsCOMPtr<nsIProtocolHandler> handler = 
             do_GetService(kCPop3ServiceCID, &rv);
    if (NS_SUCCEEDED(rv))
        rv = handler->NewURI(aSpec, aOriginCharset, aBaseURI, _retval);
  }
  else
  {
    nsCOMPtr<nsIURI> aMsgUri = do_CreateInstance(kCMailboxUrl, &rv);
        
    if (NS_SUCCEEDED(rv))
    {
      if (aBaseURI) 
      {
        nsCAutoString newSpec;
        rv = aBaseURI->Resolve(aSpec, newSpec);
        if (NS_FAILED(rv))
          return rv;
        aMsgUri->SetSpec(newSpec);
      } 
      else 
      {
        aMsgUri->SetSpec(aSpec);
      }
      NS_ADDREF(*_retval = aMsgUri);
    }
  }

  return rv;
}
Exemplo n.º 10
0
nsresult
NS_CopyNativeToUnicode(const nsACString &input, nsAString  &output)
{
    uint32_t inputLen = input.Length();

    nsACString::const_iterator iter;
    input.BeginReading(iter);
    const char *inputStr = iter.get();

    // determine length of result
    uint32_t resultLen = inputLen;
    if (!output.SetLength(resultLen, fallible_t()))
        return NS_ERROR_OUT_OF_MEMORY;

    nsAString::iterator out_iter;
    output.BeginWriting(out_iter);
    UniChar *result = (UniChar*)out_iter.get();

    size_t cSubs = 0;
    size_t resultLeft = resultLen;

    if (!UnicodeConverter)
      NS_StartupNativeCharsetUtils();

    int unirc = ::UniUconvToUcs(UnicodeConverter, (void**)&inputStr, &inputLen,
                                &result, &resultLeft, &cSubs);

    NS_ASSERTION(unirc != UCONV_E2BIG, "Path too big");

    if (unirc != ULS_SUCCESS) {
        output.Truncate();
        return NS_ERROR_FAILURE;
    }

    // Need to update string length to reflect how many bytes were actually
    // written.
    output.Truncate(resultLen - resultLeft);
    return NS_OK;
}
Exemplo n.º 11
0
void
URLSearchParams::ConvertString(const nsACString& aInput, nsAString& aOutput)
{
  aOutput.Truncate();

  if (!mDecoder) {
    mDecoder = EncodingUtils::DecoderForEncoding("UTF-8");
    if (!mDecoder) {
      MOZ_ASSERT(mDecoder, "Failed to create a decoder.");
      return;
    }
  }

  nsACString::const_iterator iter;
  aInput.BeginReading(iter);

  int32_t inputLength = aInput.Length();
  int32_t outputLength = 0;

  nsresult rv = mDecoder->GetMaxLength(iter.get(), inputLength,
                                       &outputLength);
  if (NS_WARN_IF(NS_FAILED(rv))) {
    return;
  }

  const mozilla::fallible_t fallible = mozilla::fallible_t();
  nsAutoArrayPtr<char16_t> buf(new (fallible) char16_t[outputLength + 1]);
  if (!buf) {
    return;
  }

  rv = mDecoder->Convert(iter.get(), &inputLength, buf, &outputLength);
  if (NS_SUCCEEDED(rv)) {
    buf[outputLength] = 0;
    if (!aOutput.Assign(buf, outputLength, mozilla::fallible_t())) {
      aOutput.Truncate();
    }
  }
}
Exemplo n.º 12
0
bool
IsASCII( const nsACString& aString )
  {
    static const char NOT_ASCII = char(~0x7F);


    // Don't want to use |copy_string| for this task, since we can stop at the first non-ASCII character

    nsACString::const_iterator iter, done_reading;
    aString.BeginReading(iter);
    aString.EndReading(done_reading);

    const char* c = iter.get();
    const char* end = done_reading.get();
    
    while ( c < end )
      {
        if ( *c++ & NOT_ASCII )
          return false;
      }

    return true;
  }
Exemplo n.º 13
0
// callback while receiving UDP packet
NS_IMETHODIMP NrSocketIpc::CallListenerReceivedData(const nsACString &type,
                                                    const nsACString &host,
                                                    uint16_t port, uint8_t *data,
                                                    uint32_t data_length) {
  ASSERT_ON_THREAD(main_thread_);
  MOZ_ASSERT(type.EqualsLiteral("ondata"));

  PRNetAddr addr;
  memset(&addr, 0, sizeof(addr));

  {
    ReentrantMonitorAutoEnter mon(monitor_);

    if (PR_SUCCESS != PR_StringToNetAddr(host.BeginReading(), &addr)) {
      err_ = true;
      MOZ_ASSERT(false, "Failed to convert remote host to PRNetAddr");
      return NS_OK;
    }

    // Use PR_IpAddrNull to avoid address being reset to 0.
    if (PR_SUCCESS != PR_SetNetAddr(PR_IpAddrNull, addr.raw.family, port, &addr)) {
      err_ = true;
      MOZ_ASSERT(false, "Failed to set port in PRNetAddr");
      return NS_OK;
    }
  }

  nsAutoPtr<DataBuffer> buf(new DataBuffer(data, data_length));
  RefPtr<nr_udp_message> msg(new nr_udp_message(addr, buf));

  RUN_ON_THREAD(sts_thread_,
                mozilla::WrapRunnable(nsRefPtr<NrSocketIpc>(this),
                                      &NrSocketIpc::recv_callback_s,
                                      msg),
                NS_DISPATCH_NORMAL);
  return NS_OK;
}
Exemplo n.º 14
0
nsresult
NS_CopyNativeToUnicode(const nsACString& aInput, nsAString& aOutput)
{
  aOutput.Truncate();

  uint32_t inputLen = aInput.Length();

  nsACString::const_iterator iter;
  aInput.BeginReading(iter);

  //
  // OPTIMIZATION: preallocate space for largest possible result; convert
  // directly into the result buffer to avoid intermediate buffer copy.
  //
  // this will generally result in a larger allocation, but that seems
  // better than an extra buffer copy.
  //
  if (!aOutput.SetLength(inputLen, fallible)) {
    return NS_ERROR_OUT_OF_MEMORY;
  }
  nsAString::iterator out_iter;
  aOutput.BeginWriting(out_iter);

  char16_t* result = out_iter.get();
  uint32_t resultLeft = inputLen;

  const char* buf = iter.get();
  uint32_t bufLeft = inputLen;

  nsNativeCharsetConverter conv;
  nsresult rv = conv.NativeToUnicode(&buf, &bufLeft, &result, &resultLeft);
  if (NS_SUCCEEDED(rv)) {
    NS_ASSERTION(bufLeft == 0, "did not consume entire input buffer");
    aOutput.SetLength(inputLen - resultLeft);
  }
  return rv;
}
Exemplo n.º 15
0
bool
AppendASCIItoUTF16(const nsACString& aSource, nsAString& aDest,
                   const mozilla::fallible_t&)
{
  uint32_t old_dest_length = aDest.Length();
  if (!aDest.SetLength(old_dest_length + aSource.Length(),
                       mozilla::fallible_t())) {
    return false;
  }

  nsACString::const_iterator fromBegin, fromEnd;

  nsAString::iterator dest;
  aDest.BeginWriting(dest);

  dest.advance(old_dest_length);

  // right now, this won't work on multi-fragment destinations
  LossyConvertEncoding8to16 converter(dest.get());

  copy_string(aSource.BeginReading(fromBegin), aSource.EndReading(fromEnd),
              converter);
  return true;
}
Exemplo n.º 16
0
  /* static */
  bool
  MatchAutoCompleteFunction::findBeginning(const nsDependentCSubstring &aToken,
                                           const nsACString &aSourceString)
  {
    NS_PRECONDITION(!aToken.IsEmpty(), "Don't search for an empty token!");

    // We can't use StringBeginsWith here, unfortunately.  Although it will
    // happily take a case-insensitive UTF8 comparator, it eventually calls
    // nsACString::Equals, which checks that the two strings contain the same
    // number of bytes before calling the comparator.  Two characters may be
    // case-insensitively equal while taking up different numbers of bytes, so
    // this is not what we want.

    const_char_iterator tokenStart(aToken.BeginReading()),
                        tokenEnd(aToken.EndReading()),
                        sourceStart(aSourceString.BeginReading()),
                        sourceEnd(aSourceString.EndReading());

    bool dummy;
    while (sourceStart < sourceEnd &&
           CaseInsensitiveUTF8CharsEqual(sourceStart, tokenStart,
                                         sourceEnd, tokenEnd,
                                         &sourceStart, &tokenStart, &dummy)) {

      // We found the token!
      if (tokenStart >= tokenEnd) {
        return true;
      }
    }

    // We don't need to check CaseInsensitiveUTF8CharsEqual's error condition
    // (stored in |dummy|), since the function will return false if it
    // encounters an error.

    return false;
  }
Exemplo n.º 17
0
static bool
HasStringPrefix(const nsCString& str, const nsACString& prefix) {
  return str.Compare(prefix.BeginReading(), false, prefix.Length()) == 0;
}
Exemplo n.º 18
0
void
nsUrlClassifierUtils::ParseIPAddress(const nsACString & host,
                                     nsACString & _retval)
{
  _retval.Truncate();
  nsACString::const_iterator iter, end;
  host.BeginReading(iter);
  host.EndReading(end);

  if (host.Length() <= 15) {
    // The Windows resolver allows a 4-part dotted decimal IP address to
    // have a space followed by any old rubbish, so long as the total length
    // of the string doesn't get above 15 characters. So, "10.192.95.89 xy"
    // is resolved to 10.192.95.89.
    // If the string length is greater than 15 characters, e.g.
    // "10.192.95.89 xy.wildcard.example.com", it will be resolved through
    // DNS.

    if (FindCharInReadable(' ', iter, end)) {
      end = iter;
    }
  }

  for (host.BeginReading(iter); iter != end; iter++) {
    if (!(isxdigit(*iter) || *iter == 'x' || *iter == 'X' || *iter == '.')) {
      // not an IP
      return;
    }
  }

  host.BeginReading(iter);
  nsTArray<nsCString> parts;
  ParseString(PromiseFlatCString(Substring(iter, end)), '.', parts);
  if (parts.Length() > 4) {
    return;
  }

  // If any potentially-octal numbers (start with 0 but not hex) have
  // non-octal digits, no part of the ip can be in octal
  // XXX: this came from the old javascript implementation, is it really
  // supposed to be like this?
  bool allowOctal = true;
  uint32_t i;

  for (i = 0; i < parts.Length(); i++) {
    const nsCString& part = parts[i];
    if (part[0] == '0') {
      for (uint32_t j = 1; j < part.Length(); j++) {
        if (part[j] == 'x') {
          break;
        }
        if (part[j] == '8' || part[j] == '9') {
          allowOctal = false;
          break;
        }
      }
    }
  }

  for (i = 0; i < parts.Length(); i++) {
    nsAutoCString canonical;

    if (i == parts.Length() - 1) {
      CanonicalNum(parts[i], 5 - parts.Length(), allowOctal, canonical);
    } else {
      CanonicalNum(parts[i], 1, allowOctal, canonical);
    }

    if (canonical.IsEmpty()) {
      _retval.Truncate();
      return;
    }

    if (_retval.IsEmpty()) {
      _retval.Assign(canonical);
    } else {
      _retval.Append('.');
      _retval.Append(canonical);
    }
  }
  return;
}
Exemplo n.º 19
0
/* static */ nsresult
LookupCache::GetLookupFragments(const nsACString& aSpec,
                                nsTArray<nsCString>* aFragments)

{
  aFragments->Clear();

  nsACString::const_iterator begin, end, iter;
  aSpec.BeginReading(begin);
  aSpec.EndReading(end);

  iter = begin;
  if (!FindCharInReadable('/', iter, end)) {
    return NS_OK;
  }

  const nsCSubstring& host = Substring(begin, iter++);
  nsAutoCString path;
  path.Assign(Substring(iter, end));

  /**
   * From the protocol doc:
   * For the hostname, the client will try at most 5 different strings.  They
   * are:
   * a) The exact hostname of the url
   * b) The 4 hostnames formed by starting with the last 5 components and
   *    successivly removing the leading component.  The top-level component
   *    can be skipped. This is not done if the hostname is a numerical IP.
   */
  nsTArray<nsCString> hosts;
  hosts.AppendElement(host);

  if (!IsCanonicalizedIP(host)) {
    host.BeginReading(begin);
    host.EndReading(end);
    int numHostComponents = 0;
    while (RFindInReadable(NS_LITERAL_CSTRING("."), begin, end) &&
           numHostComponents < MAX_HOST_COMPONENTS) {
      // don't bother checking toplevel domains
      if (++numHostComponents >= 2) {
        host.EndReading(iter);
        hosts.AppendElement(Substring(end, iter));
      }
      end = begin;
      host.BeginReading(begin);
    }
  }

  /**
   * From the protocol doc:
   * For the path, the client will also try at most 6 different strings.
   * They are:
   * a) the exact path of the url, including query parameters
   * b) the exact path of the url, without query parameters
   * c) the 4 paths formed by starting at the root (/) and
   *    successively appending path components, including a trailing
   *    slash.  This behavior should only extend up to the next-to-last
   *    path component, that is, a trailing slash should never be
   *    appended that was not present in the original url.
   */
  nsTArray<nsCString> paths;
  nsAutoCString pathToAdd;

  path.BeginReading(begin);
  path.EndReading(end);
  iter = begin;
  if (FindCharInReadable('?', iter, end)) {
    pathToAdd = Substring(begin, iter);
    paths.AppendElement(pathToAdd);
    end = iter;
  }

  int numPathComponents = 1;
  iter = begin;
  while (FindCharInReadable('/', iter, end) &&
         numPathComponents < MAX_PATH_COMPONENTS) {
    iter++;
    pathToAdd.Assign(Substring(begin, iter));
    paths.AppendElement(pathToAdd);
    numPathComponents++;
  }

  // If we haven't already done so, add the full path
  if (!pathToAdd.Equals(path)) {
    paths.AppendElement(path);
  }
  // Check an empty path (for whole-domain blacklist entries)
  paths.AppendElement(EmptyCString());

  for (uint32_t hostIndex = 0; hostIndex < hosts.Length(); hostIndex++) {
    for (uint32_t pathIndex = 0; pathIndex < paths.Length(); pathIndex++) {
      nsCString key;
      key.Assign(hosts[hostIndex]);
      key.Append('/');
      key.Append(paths[pathIndex]);
      LOG(("Checking fragment %s", key.get()));

      aFragments->AppendElement(key);
    }
  }

  return NS_OK;
}
Exemplo n.º 20
0
NS_IMETHODIMP
Preferences::PrefHasUserValue(const nsACString& aPrefName, bool* aHasValue)
{
  *aHasValue = PREF_HasUserPref(aPrefName.BeginReading());
  return NS_OK;
}
Exemplo n.º 21
0
NS_IMETHODIMP
Preferences::ClearContentPref(const nsACString& aPrefName)
{
  return PREF_ClearUserPref(aPrefName.BeginReading());
}
Exemplo n.º 22
0
nsresult
net_ResolveRelativePath(const nsACString &relativePath,
                        const nsACString &basePath,
                        nsACString &result)
{
    nsCAutoString name;
    nsCAutoString path(basePath);
    bool needsDelim = false;

    if ( !path.IsEmpty() ) {
        PRUnichar last = path.Last();
        needsDelim = !(last == '/');
    }

    nsACString::const_iterator beg, end;
    relativePath.BeginReading(beg);
    relativePath.EndReading(end);

    bool stop = false;
    char c;
    for (; !stop; ++beg) {
        c = (beg == end) ? '\0' : *beg;
        //printf("%c [name=%s] [path=%s]\n", c, name.get(), path.get());
        switch (c) {
          case '\0':
          case '#':
          case '?':
            stop = true;
            // fall through...
          case '/':
            // delimiter found
            if (name.EqualsLiteral("..")) {
                // pop path
                // If we already have the delim at end, then
                //  skip over that when searching for next one to the left
                PRInt32 offset = path.Length() - (needsDelim ? 1 : 2);
                // First check for errors
                if (offset < 0 ) 
                    return NS_ERROR_MALFORMED_URI;
                PRInt32 pos = path.RFind("/", false, offset);
                if (pos >= 0)
                    path.Truncate(pos + 1);
                else
                    path.Truncate();
            }
            else if (name.IsEmpty() || name.EqualsLiteral(".")) {
                // do nothing
            }
            else {
                // append name to path
                if (needsDelim)
                    path += '/';
                path += name;
                needsDelim = true;
            }
            name.Truncate();
            break;

          default:
            // append char to name
            name += c;
        }
    }
    // append anything left on relativePath (e.g. #..., ;..., ?...)
    if (c != '\0')
        path += Substring(--beg, end);

    result = path;
    return NS_OK;
}
Exemplo n.º 23
0
 PrefixString(const nsACString& aStr, uint32_t aSize)
  : pos(0)
  , size(aSize)
 {
   data.Rebind(aStr.BeginReading(), aStr.Length());
 }
Exemplo n.º 24
0
NS_IMETHODIMP
nsDNSService::AsyncResolve(const nsACString  &hostname,
                           uint32_t           flags,
                           nsIDNSListener    *listener,
                           nsIEventTarget    *target_,
                           nsICancelable    **result)
{
    // grab reference to global host resolver and IDN service.  beware
    // simultaneous shutdown!!
    nsRefPtr<nsHostResolver> res;
    nsCOMPtr<nsIIDNService> idn;
    nsCOMPtr<nsIEventTarget> target = target_;
    bool localDomain = false;
    {
        MutexAutoLock lock(mLock);

        if (mDisablePrefetch && (flags & RESOLVE_SPECULATE))
            return NS_ERROR_DNS_LOOKUP_QUEUE_FULL;

        res = mResolver;
        idn = mIDN;
        localDomain = mLocalDomains.GetEntry(hostname);
    }

    if (mNotifyResolution) {
        NS_DispatchToMainThread(new NotifyDNSResolution(mObserverService,
                                                        hostname));
    }

    if (!res)
        return NS_ERROR_OFFLINE;

    if (mOffline)
        flags |= RESOLVE_OFFLINE;

    const nsACString *hostPtr = &hostname;

    if (localDomain) {
        hostPtr = &(NS_LITERAL_CSTRING("localhost"));
    }

    nsresult rv;
    nsAutoCString hostACE;
    if (idn && !IsASCII(*hostPtr)) {
        if (NS_SUCCEEDED(idn->ConvertUTF8toACE(*hostPtr, hostACE)))
            hostPtr = &hostACE;
    }

    // make sure JS callers get notification on the main thread
    nsCOMPtr<nsIXPConnectWrappedJS> wrappedListener = do_QueryInterface(listener);
    if (wrappedListener && !target) {
        nsCOMPtr<nsIThread> mainThread;
        NS_GetMainThread(getter_AddRefs(mainThread));
        target = do_QueryInterface(mainThread);
    }

    if (target) {
      listener = new DNSListenerProxy(listener, target);
    }

    uint16_t af = GetAFForLookup(*hostPtr, flags);

    nsDNSAsyncRequest *req =
            new nsDNSAsyncRequest(res, *hostPtr, listener, flags, af);
    if (!req)
        return NS_ERROR_OUT_OF_MEMORY;
    NS_ADDREF(*result = req);

    MOZ_EVENT_TRACER_NAME_OBJECT(req, hostname.BeginReading());
    MOZ_EVENT_TRACER_WAIT(req, "net::dns::lookup");

    // addref for resolver; will be released when OnLookupComplete is called.
    NS_ADDREF(req);
    rv = res->ResolveHost(req->mHost.get(), flags, af, req);
    if (NS_FAILED(rv)) {
        NS_RELEASE(req);
        NS_RELEASE(*result);
    }
    return rv;
}
Exemplo n.º 25
0
nsresult
Http2Decompressor::OutputHeader(const nsACString &name, const nsACString &value)
{
    // exclusions
  if (name.Equals(NS_LITERAL_CSTRING("connection")) ||
      name.Equals(NS_LITERAL_CSTRING("host")) ||
      name.Equals(NS_LITERAL_CSTRING("keep-alive")) ||
      name.Equals(NS_LITERAL_CSTRING("proxy-connection")) ||
      name.Equals(NS_LITERAL_CSTRING("te")) ||
      name.Equals(NS_LITERAL_CSTRING("transfer-encoding")) ||
      name.Equals(NS_LITERAL_CSTRING("upgrade")) ||
      name.Equals(("accept-encoding"))) {
    nsCString toLog(name);
    LOG3(("HTTP Decompressor illegal response header found : %s",
          toLog.get()));
    return NS_ERROR_ILLEGAL_VALUE;
  }

  // Look for upper case characters in the name.
  for (const char *cPtr = name.BeginReading();
       cPtr && cPtr < name.EndReading();
       ++cPtr) {
    if (*cPtr <= 'Z' && *cPtr >= 'A') {
      nsCString toLog(name);
      LOG3(("HTTP Decompressor upper case response header found. [%s]\n",
            toLog.get()));
      return NS_ERROR_ILLEGAL_VALUE;
    }
  }

  // Look for CR OR LF in value - could be smuggling Sec 10.3
  // can map to space safely
  for (const char *cPtr = value.BeginReading();
       cPtr && cPtr < value.EndReading();
       ++cPtr) {
    if (*cPtr == '\r' || *cPtr== '\n') {
      char *wPtr = const_cast<char *>(cPtr);
      *wPtr = ' ';
    }
  }

  // Status comes first
  if (name.Equals(NS_LITERAL_CSTRING(":status"))) {
    nsAutoCString status(NS_LITERAL_CSTRING("HTTP/2.0 "));
    status.Append(value);
    status.Append(NS_LITERAL_CSTRING("\r\n"));
    mOutput->Insert(status, 0);
    mHeaderStatus = value;
  } else if (name.Equals(NS_LITERAL_CSTRING(":authority"))) {
    mHeaderHost = value;
  } else if (name.Equals(NS_LITERAL_CSTRING(":scheme"))) {
    mHeaderScheme = value;
  } else if (name.Equals(NS_LITERAL_CSTRING(":path"))) {
    mHeaderPath = value;
  } else if (name.Equals(NS_LITERAL_CSTRING(":method"))) {
    mHeaderMethod = value;
  }

  // http/2 transport level headers shouldn't be gatewayed into http/1
  if(*(name.BeginReading()) == ':') {
    LOG3(("HTTP Decompressor not gatewaying %s into http/1",
          name.BeginReading()));
    return NS_OK;
  }

  mOutput->Append(name);
  mOutput->Append(NS_LITERAL_CSTRING(": "));
  // Special handling for set-cookie according to the spec
  bool isSetCookie = name.Equals(NS_LITERAL_CSTRING("set-cookie"));
  int32_t valueLen = value.Length();
  for (int32_t i = 0; i < valueLen; ++i) {
    if (value[i] == '\0') {
      if (isSetCookie) {
        mOutput->Append(NS_LITERAL_CSTRING("\r\n"));
        mOutput->Append(name);
        mOutput->Append(NS_LITERAL_CSTRING(": "));
      } else {
        mOutput->Append(NS_LITERAL_CSTRING(", "));
      }
    } else {
      mOutput->Append(value[i]);
    }
  }
  mOutput->Append(NS_LITERAL_CSTRING("\r\n"));
  return NS_OK;
}
Exemplo n.º 26
0
bool
FakeInputStream::CheckTest(nsACString& aResult)
{
  return !strcmp(aResult.BeginReading(), mTest->mResult) ? true : false;
}
/* static */ nsresult
nsPluginPlayPreviewInfo::CheckWhitelist(const nsACString& aPageURI,
                                        const nsACString& aObjectURI,
                                        const nsACString& aWhitelist,
                                        bool *_retval)
{
  if (aWhitelist.Length() == 0) {
    // Considering empty whitelist as '*' entry.
    *_retval = true;
    return NS_OK;
  }

  // Parses whitelist as comma separated entries of
  //   [@page_url object_url|@page_url|object_url]
  // where page_url and object_url pattern matches for aPageURI
  // and aObjectURI, and performs matching as the same time.
  nsACString::const_iterator start, end;
  aWhitelist.BeginReading(start);
  aWhitelist.EndReading(end);

  nsAutoCString pageURI(aPageURI);
  nsAutoCString objectURI(aObjectURI);
  nsACString::const_iterator pos = start, entryStart, entryEnd;
  nsACString::const_iterator pagePatternStart, pagePatternEnd;
  nsACString::const_iterator objectPatternStart, objectPatternEnd;
  int matchResult;
  bool matched, didMatching;
  while (pos != end) {
    matched = true;
    didMatching = false;
    entryStart = pos;
    // Looking for end of the entry.
    while (pos != end && *pos != ',') {
      pos++;
    }
    entryEnd = pos;
    if (entryStart != entryEnd && *entryStart == '@') {
      // Pattern for aPageURL is found, finding a space or end of the entry.
      pagePatternStart = entryStart;
      pagePatternStart++;
      pagePatternEnd = pagePatternStart;
      while (pagePatternEnd != entryEnd && *pagePatternEnd != ' ') {
        pagePatternEnd++;
      }
      nsAutoCString pagePattern(Substring(pagePatternStart, pagePatternEnd));
      matchResult = NS_WildCardMatch(pageURI.get(), pagePattern.get(), true);
      matched &= matchResult == MATCH;
      didMatching = true;
      objectPatternStart = pagePatternEnd;
    } else {
      objectPatternStart = entryStart;
    }
    while (objectPatternStart != entryEnd && *objectPatternStart == ' ') {
      objectPatternStart++;
    }
    if (objectPatternStart != entryEnd) {
      // Pattern for aObjectURL is found, removing trailing spaces.
      objectPatternEnd = entryEnd;
      --objectPatternEnd;
      while (objectPatternStart != objectPatternEnd &&
             *objectPatternEnd == ' ') {
        objectPatternEnd--;
      };
      objectPatternEnd++;
      nsAutoCString objectPattern(Substring(objectPatternStart,
                                            objectPatternEnd));
      matchResult = NS_WildCardMatch(objectURI.get(), objectPattern.get(), true);
      matched &= matchResult == MATCH;
      didMatching = true;
    }
    // Ignoring match result for empty entries.
    if (didMatching && matched) {
      *_retval = true;
      return NS_OK;
    }
    if (pos == end) {
      break;
    }
    pos++;
  }

  *_retval = false;
  return NS_OK;
}
Exemplo n.º 28
0
bool nsDefaultURIFixup::PossiblyHostPortUrl(const nsACString &aUrl)
{
    // Oh dear, the protocol is invalid. Test if the protocol might
    // actually be a url without a protocol:
    //
    //   http://www.faqs.org/rfcs/rfc1738.html
    //   http://www.faqs.org/rfcs/rfc2396.html
    //
    // e.g. Anything of the form:
    //
    //   <hostname>:<port> or
    //   <hostname>:<port>/
    //
    // Where <hostname> is a string of alphanumeric characters and dashes
    // separated by dots.
    // and <port> is a 5 or less digits. This actually breaks the rfc2396
    // definition of a scheme which allows dots in schemes.
    //
    // Note:
    //   People expecting this to work with
    //   <user>:<password>@<host>:<port>/<url-path> will be disappointed!
    //
    // Note: Parser could be a lot tighter, tossing out silly hostnames
    //       such as those containing consecutive dots and so on.

    // Read the hostname which should of the form
    // [a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]+)*:

    nsACString::const_iterator iterBegin;
    nsACString::const_iterator iterEnd;
    aUrl.BeginReading(iterBegin);
    aUrl.EndReading(iterEnd);
    nsACString::const_iterator iter = iterBegin;

    while (iter != iterEnd)
    {
        uint32_t chunkSize = 0;
        // Parse a chunk of the address
        while (iter != iterEnd &&
               (*iter == '-' ||
                nsCRT::IsAsciiAlpha(*iter) ||
                nsCRT::IsAsciiDigit(*iter)))
        {
            ++chunkSize;
            ++iter;
        }
        if (chunkSize == 0 || iter == iterEnd)
        {
            return false;
        }
        if (*iter == ':')
        {
            // Go onto checking the for the digits
            break;
        }
        if (*iter != '.')
        {
            // Whatever it is, it ain't a hostname!
            return false;
        }
        ++iter;
    }
    if (iter == iterEnd)
    {
        // No point continuing since there is no colon
        return false;
    }
    ++iter;

    // Count the number of digits after the colon and before the
    // next forward slash (or end of string)

    uint32_t digitCount = 0;
    while (iter != iterEnd && digitCount <= 5)
    {
        if (nsCRT::IsAsciiDigit(*iter))
        {
            digitCount++;
        }
        else if (*iter == '/')
        {
            break;
        }
        else
        {
            // Whatever it is, it ain't a port!
            return false;
        }
        ++iter;
    }
    if (digitCount == 0 || digitCount > 5)
    {
        // No digits or more digits than a port would have.
        return false;
    }

    // Yes, it's possibly a host:port url
    return true;
}
Exemplo n.º 29
0
nsresult
nsDefaultURIFixup::KeywordURIFixup(const nsACString & aURIString,
                                   nsDefaultURIFixupInfo* aFixupInfo,
                                   nsIInputStream **aPostData)
{
    // These are keyword formatted strings
    // "what is mozilla"
    // "what is mozilla?"
    // "docshell site:mozilla.org" - has no dot/colon in the first space-separated substring
    // "?mozilla" - anything that begins with a question mark
    // "?site:mozilla.org docshell"
    // Things that have a quote before the first dot/colon
    // "mozilla" - checked against a whitelist to see if it's a host or not
    // ".mozilla", "mozilla." - ditto

    // These are not keyword formatted strings
    // "www.blah.com" - first space-separated substring contains a dot, doesn't start with "?"
    // "www.blah.com stuff"
    // "nonQualifiedHost:80" - first space-separated substring contains a colon, doesn't start with "?"
    // "nonQualifiedHost:80 args"
    // "nonQualifiedHost?"
    // "nonQualifiedHost?args"
    // "nonQualifiedHost?some args"
    // "blah.com."

    // Note: uint32_t(kNotFound) is greater than any actual location
    // in practice.  So if we cast all locations to uint32_t, then a <
    // b guarantees that either b is kNotFound and a is found, or both
    // are found and a found before b.

    uint32_t firstDotLoc = uint32_t(kNotFound);
    uint32_t lastDotLoc = uint32_t(kNotFound);
    uint32_t firstColonLoc = uint32_t(kNotFound);
    uint32_t firstQuoteLoc = uint32_t(kNotFound);
    uint32_t firstSpaceLoc = uint32_t(kNotFound);
    uint32_t firstQMarkLoc = uint32_t(kNotFound);
    uint32_t lastLSBracketLoc = uint32_t(kNotFound);
    uint32_t lastSlashLoc = uint32_t(kNotFound);
    uint32_t pos = 0;
    uint32_t foundDots = 0;
    uint32_t foundColons = 0;
    uint32_t foundDigits = 0;
    uint32_t foundRSBrackets = 0;
    bool looksLikeIpv6 = true;
    bool hasAsciiAlpha = false;

    nsACString::const_iterator iterBegin;
    nsACString::const_iterator iterEnd;
    aURIString.BeginReading(iterBegin);
    aURIString.EndReading(iterEnd);
    nsACString::const_iterator iter = iterBegin;

    while (iter != iterEnd) {
        if (pos >= 1 && foundRSBrackets == 0) {
            if (!(lastLSBracketLoc == 0 &&
                  (*iter == ':' ||
                   *iter == '.' ||
                   *iter == ']' ||
                   (*iter >= 'a' && *iter <= 'f') ||
                   (*iter >= 'A' && *iter <= 'F') ||
                   nsCRT::IsAsciiDigit(*iter)))) {
                looksLikeIpv6 = false;
            }
        }
        if (*iter == '.') {
            ++foundDots;
            lastDotLoc = pos;
            if (firstDotLoc == uint32_t(kNotFound)) {
                firstDotLoc = pos;
            }
        } else if (*iter == ':') {
            ++foundColons;
            if (firstColonLoc == uint32_t(kNotFound)) {
                firstColonLoc = pos;
            }
        } else if (*iter == ' ' && firstSpaceLoc == uint32_t(kNotFound)) {
            firstSpaceLoc = pos;
        } else if (*iter == '?' && firstQMarkLoc == uint32_t(kNotFound)) {
            firstQMarkLoc = pos;
        } else if ((*iter == '\'' || *iter == '"') && firstQuoteLoc == uint32_t(kNotFound)) {
            firstQuoteLoc = pos;
        } else if (*iter == '[') {
            lastLSBracketLoc = pos;
        } else if (*iter == ']') {
            foundRSBrackets++;
        } else if (*iter == '/') {
            lastSlashLoc = pos;
        } else if (nsCRT::IsAsciiAlpha(*iter)) {
            hasAsciiAlpha = true;
        } else if (nsCRT::IsAsciiDigit(*iter)) {
            ++foundDigits;
        }

        pos++;
        iter++;
    }

    if (lastLSBracketLoc > 0 || foundRSBrackets != 1) {
        looksLikeIpv6 = false;
    }

    nsAutoCString asciiHost;
    nsAutoCString host;

    bool isValidAsciiHost = aFixupInfo->mFixedURI &&
        NS_SUCCEEDED(aFixupInfo->mFixedURI->GetAsciiHost(asciiHost)) &&
        !asciiHost.IsEmpty();

    bool isValidHost = aFixupInfo->mFixedURI &&
        NS_SUCCEEDED(aFixupInfo->mFixedURI->GetHost(host)) &&
        !host.IsEmpty();

    // If there are 2 dots and only numbers between them, an optional port number
    // and a trailing slash, then don't do a keyword lookup
    if (foundDots == 2 && lastSlashLoc == pos - 1 &&
        ((foundDots + foundDigits == pos - 1) ||
         (foundColons == 1 && firstColonLoc > lastDotLoc &&
          foundDots + foundDigits + foundColons == pos - 1))) {
        return NS_OK;
    }

    uint32_t posWithNoTrailingSlash = pos;
    if (lastSlashLoc == pos - 1) {
        posWithNoTrailingSlash -= 1;
    }
    // If there are 3 dots and only numbers between them, an optional port number
    // and an optional trailling slash, then don't do a keyword lookup (ipv4)
    if (foundDots == 3 &&
        ((foundDots + foundDigits == posWithNoTrailingSlash) ||
         (foundColons == 1 && firstColonLoc > lastDotLoc &&
          foundDots + foundDigits + foundColons == posWithNoTrailingSlash))) {
        return NS_OK;
    }

    // If there are only colons and only hexadecimal characters ([a-z][0-9])
    // enclosed in [], then don't do a keyword lookup
    if (looksLikeIpv6) {
        return NS_OK;
    }

    nsresult rv = NS_OK;
    // We do keyword lookups if a space or quote preceded the dot, colon
    // or question mark (or if the latter is not found, or if the input starts with a question mark)
    if (((firstSpaceLoc < firstDotLoc || firstQuoteLoc < firstDotLoc) &&
         (firstSpaceLoc < firstColonLoc || firstQuoteLoc < firstColonLoc) &&
         (firstSpaceLoc < firstQMarkLoc || firstQuoteLoc < firstQMarkLoc)) || firstQMarkLoc == 0) {
        rv = TryKeywordFixupForURIInfo(aFixupInfo->mOriginalInput, aFixupInfo, aPostData);
    // ... or when the host is the same as asciiHost and there are no
    // characters from [a-z][A-Z]
    } else if (isValidAsciiHost && isValidHost && !hasAsciiAlpha &&
               host.EqualsIgnoreCase(asciiHost.get())) {
        if (!sDNSFirstForSingleWords) {
            rv = TryKeywordFixupForURIInfo(aFixupInfo->mOriginalInput, aFixupInfo, aPostData);
        }
    }
    // ... or if there is no question mark or colon, and there is either no
    // dot, or exactly 1 and it is the first or last character of the input:
    else if ((firstDotLoc == uint32_t(kNotFound) ||
              (foundDots == 1 && (firstDotLoc == 0 || firstDotLoc == aURIString.Length() - 1))) &&
              firstColonLoc == uint32_t(kNotFound) && firstQMarkLoc == uint32_t(kNotFound)) {

        if (isValidAsciiHost && IsDomainWhitelisted(asciiHost, firstDotLoc)) {
            return NS_OK;
        }

        // ... unless there are no dots, and a slash, and alpha characters, and this is a valid host:
        if (firstDotLoc == uint32_t(kNotFound) && lastSlashLoc != uint32_t(kNotFound) &&
            hasAsciiAlpha && isValidAsciiHost) {
            return NS_OK;
        }


        // If we get here, we don't have a valid URI, or we did but the
        // host is not whitelisted, so we do a keyword search *anyway*:
        rv = TryKeywordFixupForURIInfo(aFixupInfo->mOriginalInput, aFixupInfo, aPostData);
    }
    return rv;
}
NS_IMETHODIMP
nsAboutCache::OnCacheEntryInfo(nsIURI *aURI, const nsACString & aIdEnhance,
                               int64_t aDataSize, int32_t aFetchCount,
                               uint32_t aLastModified, uint32_t aExpirationTime,
                               bool aPinned)
{
    // We need mStream for this
    if (!mStream) {
        return NS_ERROR_FAILURE;
    }

    if (!mEntriesHeaderAdded) {
        mBuffer.AppendLiteral("<hr/>\n"
                              "<table id=\"entries\">\n"
                              "  <colgroup>\n"
                              "   <col id=\"col-key\">\n"
                              "   <col id=\"col-dataSize\">\n"
                              "   <col id=\"col-fetchCount\">\n"
                              "   <col id=\"col-lastModified\">\n"
                              "   <col id=\"col-expires\">\n"
                              "   <col id=\"col-pinned\">\n"
                              "  </colgroup>\n"
                              "  <thead>\n"
                              "    <tr>\n"
                              "      <th>Key</th>\n"
                              "      <th>Data size</th>\n"
                              "      <th>Fetch count</th>\n"
                              "      <th>Last Modifed</th>\n"
                              "      <th>Expires</th>\n"
                              "      <th>Pinning</th>\n"
                              "    </tr>\n"
                              "  </thead>\n");
        mEntriesHeaderAdded = true;
    }

    // Generate a about:cache-entry URL for this entry...

    nsAutoCString url;
    url.AssignLiteral("about:cache-entry?storage=");
    url.Append(mStorageName);

    url.AppendLiteral("&amp;context=");
    char* escapedContext = nsEscapeHTML(mContextString.get());
    url += escapedContext;
    free(escapedContext);

    url.AppendLiteral("&amp;eid=");
    char* escapedEID = nsEscapeHTML(aIdEnhance.BeginReading());
    url += escapedEID;
    free(escapedEID);

    nsAutoCString cacheUriSpec;
    aURI->GetAsciiSpec(cacheUriSpec);
    char* escapedCacheURI = nsEscapeHTML(cacheUriSpec.get());
    url.AppendLiteral("&amp;uri=");
    url += escapedCacheURI;

    // Entry start...
    mBuffer.AppendLiteral("  <tr>\n");

    // URI
    mBuffer.AppendLiteral("    <td><a href=\"");
    mBuffer.Append(url);
    mBuffer.AppendLiteral("\">");
    if (!aIdEnhance.IsEmpty()) {
        mBuffer.Append(aIdEnhance);
        mBuffer.Append(':');
    }
    mBuffer.Append(escapedCacheURI);
    mBuffer.AppendLiteral("</a></td>\n");

    free(escapedCacheURI);

    // Content length
    mBuffer.AppendLiteral("    <td>");
    mBuffer.AppendInt(aDataSize);
    mBuffer.AppendLiteral(" bytes</td>\n");

    // Number of accesses
    mBuffer.AppendLiteral("    <td>");
    mBuffer.AppendInt(aFetchCount);
    mBuffer.AppendLiteral("</td>\n");

    // vars for reporting time
    char buf[255];

    // Last modified time
    mBuffer.AppendLiteral("    <td>");
    if (aLastModified) {
        PrintTimeString(buf, sizeof(buf), aLastModified);
        mBuffer.Append(buf);
    } else {
        mBuffer.AppendLiteral("No last modified time (bug 1000338)");
    }
    mBuffer.AppendLiteral("</td>\n");

    // Expires time
    mBuffer.AppendLiteral("    <td>");
    if (aExpirationTime < 0xFFFFFFFF) {
        PrintTimeString(buf, sizeof(buf), aExpirationTime);
        mBuffer.Append(buf);
    } else {
        mBuffer.AppendLiteral("No expiration time");
    }
    mBuffer.AppendLiteral("</td>\n");

    // Pinning
    mBuffer.AppendLiteral("    <td>");
    if (aPinned) {
      mBuffer.Append(NS_LITERAL_CSTRING("Pinned"));
    } else {
      mBuffer.Append(NS_LITERAL_CSTRING("&nbsp;"));
    }
    mBuffer.AppendLiteral("</td>\n");

    // Entry is done...
    mBuffer.AppendLiteral("  </tr>\n");

    FlushBuffer();
    return NS_OK;
}