コード例 #1
0
ファイル: ASTMetadataHLSL.cpp プロジェクト: cheekiatng/webkit
MetadataList CreateASTMetadataHLSL(TIntermNode *root, const CallDAG &callDag)
{
    MetadataList metadataList(callDag.size());

    // Compute all the information related to when gradient operations are used.
    // We want to know for each function and control flow operation if they have
    // a gradient operation in their call graph (shortened to "using a gradient"
    // in the rest of the file).
    //
    // This computation is logically split in three steps:
    //  1 - For each function compute if it uses a gradient in its body, ignoring
    // calls to other user-defined functions.
    //  2 - For each function determine if it uses a gradient in its call graph,
    // using the result of step 1 and the CallDAG to know its callees.
    //  3 - For each control flow statement of each function, check if it uses a
    // gradient in the function's body, or if it calls a user-defined function that
    // uses a gradient.
    //
    // We take advantage of the call graph being a DAG and instead compute 1, 2 and 3
    // for leaves first, then going down the tree. This is correct because 1 doesn't
    // depend on other functions, and 2 and 3 depend only on callees.
    for (size_t i = 0; i < callDag.size(); i++)
    {
        PullGradient pull(&metadataList, i, callDag);
        pull.traverse(callDag.getRecordFromIndex(i).node);
    }

    // Compute which loops are discontinuous and which function are called in
    // these loops. The same way computing gradient usage is a "pull" process,
    // computing "bing used in a discont. loop" is a push process. However we also
    // need to know what ifs have a discontinuous loop inside so we do the same type
    // of callgraph analysis as for the gradient.

    // First compute which loops are discontinuous (no specific order) and pull
    // the ifs and functions using a discontinuous loop.
    for (size_t i = 0; i < callDag.size(); i++)
    {
        PullComputeDiscontinuousLoops pull(&metadataList, i, callDag);
        pull.traverse(callDag.getRecordFromIndex(i).node);
    }

    // Then push the information to callees, either from the a local discontinuous
    // loop or from the caller being called in a discontinuous loop already
    for (size_t i = callDag.size(); i-- > 0;)
    {
        PushDiscontinuousLoops push(&metadataList, i, callDag);
        push.traverse(callDag.getRecordFromIndex(i).node);
    }

    // We create "Lod0" version of functions with the gradient operations replaced
    // by non-gradient operations so that the D3D compiler is happier with discont
    // loops.
    for (auto &metadata : metadataList)
    {
        metadata.mNeedsLod0 = metadata.mCalledInDiscontinuousLoop && metadata.mUsesGradient;
    }

    return metadataList;
}
コード例 #2
0
ファイル: SRICheck.cpp プロジェクト: norihirou/gecko-dev
/* static */ nsresult
SRICheck::IntegrityMetadata(const nsAString& aMetadataList,
                            const nsIDocument* aDocument,
                            SRIMetadata* outMetadata)
{
  NS_ENSURE_ARG_POINTER(outMetadata);
  NS_ENSURE_ARG_POINTER(aDocument);
  MOZ_ASSERT(outMetadata->IsEmpty()); // caller must pass empty metadata

  if (!Preferences::GetBool("security.sri.enable", false)) {
    SRILOG(("SRICheck::IntegrityMetadata, sri is disabled (pref)"));
    return NS_ERROR_SRI_DISABLED;
  }

  // put a reasonable bound on the length of the metadata
  NS_ConvertUTF16toUTF8 metadataList(aMetadataList);
  if (metadataList.Length() > SRICheck::MAX_METADATA_LENGTH) {
    metadataList.Truncate(SRICheck::MAX_METADATA_LENGTH);
  }
  MOZ_ASSERT(metadataList.Length() <= aMetadataList.Length());

  // the integrity attribute is a list of whitespace-separated hashes
  // and options so we need to look at them one by one and pick the
  // strongest (valid) one
  nsCWhitespaceTokenizer tokenizer(metadataList);
  nsAutoCString token;
  for (uint32_t i=0; tokenizer.hasMoreTokens() &&
         i < SRICheck::MAX_METADATA_TOKENS; ++i) {
    token = tokenizer.nextToken();

    SRIMetadata metadata(token);
    if (metadata.IsMalformed()) {
      NS_ConvertUTF8toUTF16 tokenUTF16(token);
      const char16_t* params[] = { tokenUTF16.get() };
      nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
                                      NS_LITERAL_CSTRING("Sub-resource Integrity"),
                                      aDocument,
                                      nsContentUtils::eSECURITY_PROPERTIES,
                                      "MalformedIntegrityURI",
                                      params, ArrayLength(params));
    } else if (!metadata.IsAlgorithmSupported()) {
      nsAutoCString alg;
      metadata.GetAlgorithm(&alg);
      NS_ConvertUTF8toUTF16 algUTF16(alg);
      const char16_t* params[] = { algUTF16.get() };
      nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
                                      NS_LITERAL_CSTRING("Sub-resource Integrity"),
                                      aDocument,
                                      nsContentUtils::eSECURITY_PROPERTIES,
                                      "UnsupportedHashAlg",
                                      params, ArrayLength(params));
    }

    nsAutoCString alg1, alg2;
    if (MOZ_LOG_TEST(GetSriLog(), mozilla::LogLevel::Debug)) {
      outMetadata->GetAlgorithm(&alg1);
      metadata.GetAlgorithm(&alg2);
    }
    if (*outMetadata == metadata) {
      SRILOG(("SRICheck::IntegrityMetadata, alg '%s' is the same as '%s'",
              alg1.get(), alg2.get()));
      *outMetadata += metadata; // add new hash to strongest metadata
    } else if (*outMetadata < metadata) {
      SRILOG(("SRICheck::IntegrityMetadata, alg '%s' is weaker than '%s'",
              alg1.get(), alg2.get()));
      *outMetadata = metadata; // replace strongest metadata with current
    }
  }

  if (MOZ_LOG_TEST(GetSriLog(), mozilla::LogLevel::Debug)) {
    if (outMetadata->IsValid()) {
      nsAutoCString alg;
      outMetadata->GetAlgorithm(&alg);
      SRILOG(("SRICheck::IntegrityMetadata, using a '%s' hash", alg.get()));
    } else if (outMetadata->IsEmpty()) {
      SRILOG(("SRICheck::IntegrityMetadata, no metadata"));
    } else {
      SRILOG(("SRICheck::IntegrityMetadata, no valid metadata found"));
    }
  }
  return NS_OK;
}