void
DOMStorageManager::ClearCaches(uint32_t aUnloadFlags,
                               const OriginAttributesPattern& aPattern,
                               const nsACString& aOriginScope)
{
  for (auto iter1 = mCaches.Iter(); !iter1.Done(); iter1.Next()) {
    PrincipalOriginAttributes oa;
    DebugOnly<bool> rv = oa.PopulateFromSuffix(iter1.Key());
    MOZ_ASSERT(rv);
    if (!aPattern.Matches(oa)) {
      // This table doesn't match the given origin attributes pattern
      continue;
    }

    CacheOriginHashtable* table = iter1.Data();

    for (auto iter2 = table->Iter(); !iter2.Done(); iter2.Next()) {
      DOMStorageCache* cache = iter2.Get()->cache();

      if (aOriginScope.IsEmpty() ||
          StringBeginsWith(cache->OriginNoSuffix(), aOriginScope)) {
        cache->UnloadItems(aUnloadFlags);
      }
    }
  }
}
예제 #2
0
NS_IMETHODIMP
LoadInfo::ResetPrincipalsToNullPrincipal()
{
  // take the originAttributes from the LoadInfo and create
  // a new NullPrincipal using those origin attributes.
  PrincipalOriginAttributes pAttrs;
  pAttrs.InheritFromNecko(mOriginAttributes);
  nsCOMPtr<nsIPrincipal> newNullPrincipal = nsNullPrincipal::Create(pAttrs);

  MOZ_ASSERT(mInternalContentPolicyType != nsIContentPolicy::TYPE_DOCUMENT ||
             !mLoadingPrincipal,
             "LoadingPrincipal should be null for toplevel loads");

  // the loadingPrincipal for toplevel loads is always a nullptr;
  if (mInternalContentPolicyType != nsIContentPolicy::TYPE_DOCUMENT) {
    mLoadingPrincipal = newNullPrincipal;
  }
  mTriggeringPrincipal = newNullPrincipal;
  mPrincipalToInherit = newNullPrincipal;

  // setting SEC_FORCE_INHERIT_PRINCIPAL_OVERRULE_OWNER will overrule
  // any non null owner set on the channel and will return the principal
  // form the loadinfo instead.
  mSecurityFlags |= SEC_FORCE_INHERIT_PRINCIPAL_OVERRULE_OWNER;

  return NS_OK;
}
예제 #3
0
/* static */ already_AddRefed<nsNullPrincipal>
nsNullPrincipal::CreateWithInheritedAttributes(nsIDocShell* aDocShell)
{
  PrincipalOriginAttributes attrs;
  attrs.InheritFromDocShellToDoc(nsDocShell::Cast(aDocShell)->GetOriginAttributes(), nullptr);

  RefPtr<nsNullPrincipal> nullPrin = new nsNullPrincipal();
  nsresult rv = nullPrin->Init(attrs);
  MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
  return nullPrin.forget();
}
예제 #4
0
NS_IMETHODIMP
nsPrincipal::Read(nsIObjectInputStream* aStream)
{
    nsCOMPtr<nsISupports> supports;
    nsCOMPtr<nsIURI> codebase;
    nsresult rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
    if (NS_FAILED(rv)) {
        return rv;
    }

    codebase = do_QueryInterface(supports);

    nsCOMPtr<nsIURI> domain;
    rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
    if (NS_FAILED(rv)) {
        return rv;
    }

    domain = do_QueryInterface(supports);

    nsAutoCString suffix;
    rv = aStream->ReadCString(suffix);
    NS_ENSURE_SUCCESS(rv, rv);

    PrincipalOriginAttributes attrs;
    bool ok = attrs.PopulateFromSuffix(suffix);
    NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);

    rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
    NS_ENSURE_SUCCESS(rv, rv);

    // This may be null.
    nsCOMPtr<nsIContentSecurityPolicy> csp = do_QueryInterface(supports, &rv);

    rv = Init(codebase, attrs);
    NS_ENSURE_SUCCESS(rv, rv);

    rv = SetCsp(csp);
    NS_ENSURE_SUCCESS(rv, rv);

    // need to link in the CSP context here (link in the URI of the protected
    // resource).
    if (csp) {
        csp->SetRequestContext(nullptr, this);
    }

    SetDomain(domain);

    return NS_OK;
}
예제 #5
0
static bool
ReadSuffixAndSpec(JSStructuredCloneReader* aReader,
                  PrincipalOriginAttributes& aAttrs,
                  nsACString& aSpec)
{
    uint32_t suffixLength, specLength;
    if (!JS_ReadUint32Pair(aReader, &suffixLength, &specLength)) {
        return false;
    }

    nsAutoCString suffix;
    suffix.SetLength(suffixLength);
    if (!JS_ReadBytes(aReader, suffix.BeginWriting(), suffixLength)) {
        return false;
    }

    if (!aAttrs.PopulateFromSuffix(suffix)) {
        return false;
    }

    aSpec.SetLength(specLength);
    if (!JS_ReadBytes(aReader, aSpec.BeginWriting(), specLength)) {
        return false;
    }

    return true;
}
예제 #6
0
/* static */ uint32_t
ImageCacheKey::ComputeHash(ImageURL* aURI,
                           const Maybe<uint64_t>& aBlobSerial,
                           const PrincipalOriginAttributes& aAttrs,
                           void* aControlledDocument)
{
  // Since we frequently call Hash() several times in a row on the same
  // ImageCacheKey, as an optimization we compute our hash once and store it.

  nsPrintfCString ptr("%p", aControlledDocument);
  nsAutoCString suffix;
  aAttrs.CreateSuffix(suffix);

  if (aBlobSerial) {
    // For blob URIs, we hash the serial number of the underlying blob, so that
    // different blob URIs which point to the same blob share a cache entry. We
    // also include the ref portion of the URI to support media fragments which
    // requires us to create different Image objects even if the source data is
    // the same.
    nsAutoCString ref;
    aURI->GetRef(ref);
    return HashGeneric(*aBlobSerial, HashString(ref + suffix + ptr));
  }

  // For non-blob URIs, we hash the URI spec.
  nsAutoCString spec;
  aURI->GetSpec(spec);
  return HashString(spec + suffix + ptr);
}
예제 #7
0
NS_IMETHODIMP
nsPrincipal::Read(nsIObjectInputStream* aStream)
{
  nsCOMPtr<nsISupports> supports;
  nsCOMPtr<nsIURI> codebase;
  nsresult rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
  if (NS_FAILED(rv)) {
    return rv;
  }

  codebase = do_QueryInterface(supports);

  nsCOMPtr<nsIURI> domain;
  rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
  if (NS_FAILED(rv)) {
    return rv;
  }

  domain = do_QueryInterface(supports);

  nsAutoCString suffix;
  rv = aStream->ReadCString(suffix);
  NS_ENSURE_SUCCESS(rv, rv);

  PrincipalOriginAttributes attrs;
  bool ok = attrs.PopulateFromSuffix(suffix);
  NS_ENSURE_TRUE(ok, NS_ERROR_FAILURE);

  rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(supports));
  NS_ENSURE_SUCCESS(rv, rv);

  rv = Init(codebase, attrs);
  NS_ENSURE_SUCCESS(rv, rv);

  mCSP = do_QueryInterface(supports, &rv);
  // make sure setRequestContext is called after Init(),
  // to make sure  the principals URI been initalized.
  if (mCSP) {
    mCSP->SetRequestContext(nullptr, this);
  }

  SetDomain(domain);

  return NS_OK;
}
예제 #8
0
static bool
WriteSuffixAndSpec(JSStructuredCloneWriter* aWriter,
                   const PrincipalOriginAttributes& aAttrs,
                   const nsCString& aSpec)
{
  nsAutoCString suffix;
  aAttrs.CreateSuffix(suffix);

  return JS_WriteUint32Pair(aWriter, suffix.Length(), aSpec.Length()) &&
         JS_WriteBytes(aWriter, suffix.get(), suffix.Length()) &&
         JS_WriteBytes(aWriter, aSpec.get(), aSpec.Length());
}
nsresult
ServiceWorkerRegistrar::ReadData()
{
    // We cannot assert about the correct thread because normally this method
    // runs on a IO thread, but in gTests we call it from the main-thread.

    MOZ_ASSERT(mProfileDir);

    nsCOMPtr<nsIFile> file;
    nsresult rv = mProfileDir->Clone(getter_AddRefs(file));
    if (NS_WARN_IF(NS_FAILED(rv))) {
        return rv;
    }

    rv = file->Append(NS_LITERAL_STRING(SERVICEWORKERREGISTRAR_FILE));
    if (NS_WARN_IF(NS_FAILED(rv))) {
        return rv;
    }

    bool exists;
    rv = file->Exists(&exists);
    if (NS_WARN_IF(NS_FAILED(rv))) {
        return rv;
    }

    if (!exists) {
        return NS_OK;
    }

    nsCOMPtr<nsIInputStream> stream;
    rv = NS_NewLocalFileInputStream(getter_AddRefs(stream), file);
    if (NS_WARN_IF(NS_FAILED(rv))) {
        return rv;
    }

    nsCOMPtr<nsILineInputStream> lineInputStream = do_QueryInterface(stream);
    MOZ_ASSERT(lineInputStream);

    nsAutoCString version;
    bool hasMoreLines;
    rv = lineInputStream->ReadLine(version, &hasMoreLines);
    if (NS_WARN_IF(NS_FAILED(rv))) {
        return rv;
    }

    if (!IsSupportedVersion(version)) {
        nsContentUtils::LogMessageToConsole(nsPrintfCString(
                                                "Unsupported service worker registrar version: %s", version.get()).get());
        return NS_ERROR_FAILURE;
    }

    nsTArray<ServiceWorkerRegistrationData> tmpData;

    bool overwrite = false;
    bool dedupe = false;
    while (hasMoreLines) {
        ServiceWorkerRegistrationData* entry = tmpData.AppendElement();

#define GET_LINE(x)                                   \
    rv = lineInputStream->ReadLine(x, &hasMoreLines); \
    if (NS_WARN_IF(NS_FAILED(rv))) {                  \
      return rv;                                      \
    }                                                 \
    if (NS_WARN_IF(!hasMoreLines)) {                  \
      return NS_ERROR_FAILURE;                        \
    }

        nsAutoCString line;
        nsAutoCString unused;
        if (version.EqualsLiteral(SERVICEWORKERREGISTRAR_VERSION)) {
            nsAutoCString suffix;
            GET_LINE(suffix);

            PrincipalOriginAttributes attrs;
            if (!attrs.PopulateFromSuffix(suffix)) {
                return NS_ERROR_INVALID_ARG;
            }

            GET_LINE(entry->scope());

            entry->principal() =
                mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());

            GET_LINE(entry->currentWorkerURL());

            nsAutoCString cacheName;
            GET_LINE(cacheName);
            CopyUTF8toUTF16(cacheName, entry->cacheName());
        } else if (version.EqualsLiteral("3")) {
            overwrite = true;
            dedupe = true;

            nsAutoCString suffix;
            GET_LINE(suffix);

            PrincipalOriginAttributes attrs;
            if (!attrs.PopulateFromSuffix(suffix)) {
                return NS_ERROR_INVALID_ARG;
            }

            // principal spec is no longer used; we use scope directly instead
            GET_LINE(unused);

            GET_LINE(entry->scope());

            entry->principal() =
                mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());

            GET_LINE(entry->currentWorkerURL());

            nsAutoCString cacheName;
            GET_LINE(cacheName);
            CopyUTF8toUTF16(cacheName, entry->cacheName());
        } else if (version.EqualsLiteral("2")) {
            overwrite = true;
            dedupe = true;

            nsAutoCString suffix;
            GET_LINE(suffix);

            PrincipalOriginAttributes attrs;
            if (!attrs.PopulateFromSuffix(suffix)) {
                return NS_ERROR_INVALID_ARG;
            }

            // principal spec is no longer used; we use scope directly instead
            GET_LINE(unused);

            GET_LINE(entry->scope());

            entry->principal() =
                mozilla::ipc::ContentPrincipalInfo(attrs, entry->scope());

            // scriptSpec is no more used in latest version.
            GET_LINE(unused);

            GET_LINE(entry->currentWorkerURL());

            nsAutoCString cacheName;
            GET_LINE(cacheName);
            CopyUTF8toUTF16(cacheName, entry->cacheName());

            // waitingCacheName is no more used in latest version.
            GET_LINE(unused);
        } else {
            MOZ_ASSERT_UNREACHABLE("Should never get here!");
        }

#undef GET_LINE

        rv = lineInputStream->ReadLine(line, &hasMoreLines);
        if (NS_WARN_IF(NS_FAILED(rv))) {
            return rv;
        }

        if (!line.EqualsLiteral(SERVICEWORKERREGISTRAR_TERMINATOR)) {
            return NS_ERROR_FAILURE;
        }
    }

    stream->Close();

    // Copy data over to mData.
    for (uint32_t i = 0; i < tmpData.Length(); ++i) {
        bool match = false;
        if (dedupe) {
            MOZ_ASSERT(overwrite);
            // If this is an old profile, then we might need to deduplicate.  In
            // theory this can be removed in the future (Bug 1248449)
            for (uint32_t j = 0; j < mData.Length(); ++j) {
                // Use same comparison as RegisterServiceWorker. Scope contains
                // basic origin information.  Combine with any principal attributes.
                if (Equivalent(tmpData[i], mData[j])) {
                    // Last match wins, just like legacy loading used to do in
                    // the ServiceWorkerManager.
                    mData[j] = tmpData[i];
                    // Dupe found, so overwrite file with reduced list.
                    match = true;
                    break;
                }
            }
        } else {
#ifdef DEBUG
            // Otherwise assert no duplications in debug builds.
            for (uint32_t j = 0; j < mData.Length(); ++j) {
                MOZ_ASSERT(!Equivalent(tmpData[i], mData[j]));
            }
#endif
        }
        if (!match) {
            mData.AppendElement(tmpData[i]);
        }
    }

    // Overwrite previous version.
    // Cannot call SaveData directly because gtest uses main-thread.
    if (overwrite && NS_FAILED(WriteData())) {
        NS_WARNING("Failed to write data for the ServiceWorker Registations.");
        DeleteData();
    }

    return NS_OK;
}