AUR AI Reviewer

Last Reviews

12 review results, newest first.

Showing risky reviews only
Risk 3/5 · Elevated PKGBUILD

Comment

The change replaces an explicit, enumerated list of patch and tarball applications with two glob-based pipelines: `find ../CVE-*.patch | sort -V | xargs -n 1 -t patch -p1 -i` and `find ../CVE-*.tar | sort -V | xargs -n 1 -t tar xvf`. This is a packaging integrity regression because it no longer constrains the build to the exact vetted artifacts referenced by the PKGBUILD; any additional matching `CVE-*` file present one directory up in the build tree will now be applied/extracted automatically. That broadens the attack surface for a malicious or tampered source tree and makes the build depend on ambient filesystem contents rather than declared sources. The use of `find` also means the commands are not limited to the package source array, undermining reproducibility and checksum-based integrity. I do not see direct code execution or privilege escalation in this hunk, but the change weakens source pinning and trust boundaries enough to warrant a moderate security concern.

@@ -150,62 +150,8 @@ prepare() {
 	# set ca dir to /etc/ssl by default
 	patch -p0 -i "$srcdir/ca-dir.patch"
 
-	local patch
-	for patch in \
-		CVE-2023-5678 \
-		CVE-2024-0727-1 \
-		CVE-2024-0727-2 \
-		CVE-2024-2511 \
-		CVE-2024-4741 \
-		CVE-2024-5535-1 \
-		CVE-2024-5535-2 \
-		CVE-2024-5535-3 \
-		CVE-2024-5535-4 \
-		CVE-2024-5535-5 \
-		CVE-2024-5535-6 \
-		CVE-2024-5535-7 \
-		CVE-2024-5535-8 \
-		CVE-2024-9143 \
-		CVE-2024-13176 \
-		CVE-2025-9230 \
-		CVE-2025-68160 \
-		CVE-2025-69418 \
-		CVE-2025-69419-1 \
-		CVE-2025-69419-2 \
-		CVE-2025-69420 \
-		CVE-2025-69421 \
-		CVE-2026-7383 \
-		CVE-2026-9076-1 \
-		CVE-2026-9076-2 \
-		CVE-2026-22795_CVE-2026-22796 \
-		CVE-2026-28387 \
-		CVE-2026-28388-1 \
-		CVE-2026-28388-2 \
-		CVE-2026-28389-1 \
-		CVE-2026-28389-2 \
-		CVE-2026-28390-1 \
-		CVE-2026-28390-2 \
-		CVE-2026-28390-3 \
-		CVE-2026-28390-4 \
-		CVE-2026-34180 \
-		CVE-2026-42766-1 \
-		CVE-2026-42766-2 \
-		CVE-2026-45447-1 \
-		CVE-2026-45447-2 \
-		CVE-2026-63072 \
-		CVE-2026-84782 \
-		; do
-		patch -p1 -i "${srcdir}/${patch}.patch"
-	done
-
-	local tarball
-	for tarball in \
-		CVE-2026-9076 \
-		CVE-2026-28389 \
-		CVE-2026-42766 \
-		; do
-		tar xvf "${srcdir}/${tarball}.tar"
-	done
+	find ../CVE-*.patch | sort -V | xargs -n 1 -t patch -p1 -i
+	find ../CVE-*.tar   | sort -V | xargs -n 1 -t tar xvf
 }
 
 build() {
Risk 4/5 · High chromium-154-typescript.patch

Comment

This patch is suspicious and high risk. It changes Chromium’s build to use the system-installed `/usr/bin/tsc` instead of the vendored TypeScript compiler, which breaks source integrity and reproducibility by introducing an undeclared host dependency into the build. More importantly, it disables `use_typescript_go`, forcing the build away from the native TypeScript compiler path and back to the JS-based compiler path; that is a build-behavior change with potential security and supply-chain implications because it increases reliance on the host environment and bypasses the package’s pinned toolchain. The added unconditional `return "/usr/bin/tsc"` in `typescript.py` is also dead-code-like and suggests a blunt override rather than a controlled, platform-specific change. I do not see direct code execution or persistence, but this is a meaningful integrity regression in a core build component.

@@ -0,0 +1,32 @@
+--- a/third_party/devtools-frontend/src/scripts/build/typescript/typescript_vars.gni
++++ b/third_party/devtools-frontend/src/scripts/build/typescript/typescript_vars.gni
+@@ -6,7 +6,7 @@ import("//build/toolchain/rbe.gni")
+ import("../ninja/vars.gni")
+ 
+ if (host_os == "linux") {
+-  tsc_binary = "//third_party/typescript/linux-amd64/src/lib/tsc"
++  tsc_binary = "/usr/bin/tsc"
+ } else if (host_os == "win") {
+   tsc_binary = "//third_party/typescript/windows-amd64/src/lib/tsc.exe"
+ } else if (host_os == "mac") {
+--- a/third_party/devtools-frontend/src/third_party/typescript/typescript.py
++++ b/third_party/devtools-frontend/src/third_party/typescript/typescript.py
+@@ -10,6 +10,7 @@ import os
+ 
+ 
+ def GetBinaryPath():
++    return "/usr/bin/tsc"
+     if platform.machine() == 'arm64':
+         darwin_path = 'mac-arm64'
+     else:
+--- a/ui/webui/webui_features.gni
++++ b/ui/webui/webui_features.gni
+@@ -33,7 +33,7 @@ declare_args() {
+ 
+   # Enable the native TypeScript compiler (tsgo) instead of the JS-based one.
+   # TODO(crbug.com/423789047): Remove this flag once fully committed to v7.
+-  use_typescript_go = true
++  use_typescript_go = false
+ }
+ 
+ if (enable_cast_receiver || is_cast_android || is_castos) {
Risk 3/5 · Elevated chromium-154-crubit.patch

Comment

The change is mostly a refactor away from Rust helpers to C++/BoringSSL/crypto implementations, but it introduces a notable integrity-risk in `CreateIntegrityBlockCbor()`: the code now hand-assembles the CBOR integrity block and explicitly admits it may embed pre-encoded, unvalidated CBOR bytes from `attributes_cbor()`. That weakens the previous parser/serializer boundary and could allow malformed or attacker-controlled CBOR to be propagated into signature verification logic. The new parser also accepts and re-encodes CBOR structures manually, which is a larger attack surface than the prior Rust parser. I did not find obvious command execution, privilege escalation, or network-fetch issues in this diff, so the risk is moderate rather than high.

@@ -0,0 +1,820 @@
+--- a/components/cbor/BUILD.gn
++++ b/components/cbor/BUILD.gn
+@@ -12,7 +12,7 @@ buildflag_header("buildflags") {
+   # TODO(crbug.com/535682335): Remove `USE_CBOR_RUST` buildflag entirely,
+   # unconditionally enable Rust CBOR parser, and drop `is_cronet_build` check
+   # once Cronet supports Crubit dependencies.
+-  flags = [ "USE_CBOR_RUST=!$is_cronet_build" ]
++  flags = [ "USE_CBOR_RUST=$enable_cpp_api_from_rust" ]
+ }
+ 
+ component("cbor") {
+@@ -35,7 +35,7 @@ component("cbor") {
+     "//base",
+   ]
+ 
+-  if (!is_cronet_build) {
++  if (enable_cpp_api_from_rust) {
+     public_deps = [
+       "//build/rust/crubit",
+       "//components/cbor/rust:cbor_rust_bindings",
+@@ -62,7 +62,7 @@ source_set("unit_tests") {
+     "//testing/gtest",
+     "//third_party/fuzztest",
+   ]
+-  if (!is_cronet_build) {
++  if (enable_cpp_api_from_rust) {
+     deps += [ "//components/cbor/rust:cbor_rust_unittests" ]
+   }
+ 
+--- a/components/web_package/BUILD.gn
++++ b/components/web_package/BUILD.gn
+@@ -40,7 +40,6 @@ static_library("web_package") {
+     "//base",
+     "//components/base32",
+     "//components/cbor",
+-    "//components/web_package/signed_web_bundles/rust:signed_web_bundles_rust_bindings",
+     "//mojo/public/cpp/bindings",
+     "//net",
+     "//services/network/public/mojom",
+@@ -70,7 +69,6 @@ source_set("mojom_mapped_types") {
+ 
+   deps = [
+     "//base",
+-    "//components/web_package/signed_web_bundles/rust:signed_web_bundles_rust_bindings",
+     "//crypto",
+     "//mojo/public/cpp/bindings",
+   ]
+@@ -98,7 +96,6 @@ source_set("unit_tests") {
+     ":web_package",
+     "//base/test:test_support",
+     "//components/cbor",
+-    "//components/web_package/signed_web_bundles/rust:signed_web_bundles_rust_unittests",
+     "//components/web_package/test_support",
+     "//mojo/public/cpp/bindings",
+     "//mojo/public/cpp/test_support:test_utils",
+--- a/components/web_package/signed_web_bundles/ecdsa_p256_sha256_signature.cc
++++ b/components/web_package/signed_web_bundles/ecdsa_p256_sha256_signature.cc
+@@ -9,7 +9,8 @@
+ #include "base/strings/stringprintf.h"
+ #include "base/types/expected.h"
+ #include "components/web_package/signed_web_bundles/ecdsa_p256_public_key.h"
+-#include "components/web_package/signed_web_bundles/rust/signed_web_bundles_rust.h"
++#include "crypto/keypair.h"
++#include "crypto/sign.h"
+ 
+ namespace web_package {
+ 
+@@ -50,8 +51,9 @@ EcdsaP256SHA256Signature::EcdsaP256SHA25
+ [[nodiscard]] bool EcdsaP256SHA256Signature::Verify(
+     base::span<const uint8_t> message,
+     const EcdsaP256PublicKey& public_key) const {
+-  return signed_web_bundles::rust::verify_ecdsa_p256_signature(
+-      public_key.bytes(), bytes(), message);
++  auto key = crypto::keypair::PublicKey::FromEcP256Point(public_key.bytes());
++  return crypto::sign::Verify(crypto::sign::ECDSA_SHA256, *key, message,
++                              bytes());
+ }
+ 
+ }  // namespace web_package
+--- a/components/web_package/signed_web_bundles/ed25519_signature.cc
++++ b/components/web_package/signed_web_bundles/ed25519_signature.cc
+@@ -7,7 +7,6 @@
+ #include <algorithm>
+ 
+ #include "base/strings/stringprintf.h"
+-#include "components/web_package/signed_web_bundles/rust/signed_web_bundles_rust.h"
+ #include "third_party/boringssl/src/include/openssl/curve25519.h"
+ 
+ namespace web_package {
+@@ -43,8 +42,11 @@ Ed25519Signature::Ed25519Signature(std::
+ [[nodiscard]] bool Ed25519Signature::Verify(
+     base::span<const uint8_t> message,
+     const Ed25519PublicKey& public_key) const {
+-  return signed_web_bundles::rust::verify_ed25519_signature(public_key.bytes(),
+-                                                            bytes(), message);
++  const std::array<uint8_t, ED25519_PUBLIC_KEY_LEN>& public_key_bytes =
++      public_key.bytes();
++  const std::array<uint8_t, ED25519_SIGNATURE_LEN>& signature_bytes = bytes();
++  return ED25519_verify(message.data(), message.size(), signature_bytes.data(),
++                        public_key_bytes.data());
+ }
+ 
+ }  // namespace web_package
+--- a/components/web_package/signed_web_bundles/integrity_block_parser.cc
++++ b/components/web_package/signed_web_bundles/integrity_block_parser.cc
+@@ -4,17 +4,19 @@
+ 
+ #include "components/web_package/signed_web_bundles/integrity_block_parser.h"
+ 
++#include <algorithm>
+ #include <string>
+-#include <string_view>
+ #include <vector>
+ 
+-#include "base/check.h"
+-#include "base/containers/span.h"
++#include "base/containers/map_util.h"
+ #include "base/functional/bind.h"
+ #include "base/strings/stringprintf.h"
++#include "base/strings/to_string.h"
+ #include "base/types/expected.h"
+ #include "base/types/expected_macros.h"
+ #include "components/cbor/reader.h"
++#include "components/cbor/writer.h"
++#include "components/web_package/mojom/web_bundle_parser.mojom-forward.h"
+ #include "components/web_package/mojom/web_bundle_parser.mojom.h"
+ #include "components/web_package/signed_web_bundles/constants.h"
+ #include "components/web_package/signed_web_bundles/ecdsa_p256_public_key.h"
+@@ -22,56 +24,11 @@
+ #include "components/web_package/signed_web_bundles/ed25519_public_key.h"
+ #include "components/web_package/signed_web_bundles/ed25519_signature.h"
+ #include "components/web_package/signed_web_bundles/integrity_block_attributes.h"
+-#include "components/web_package/signed_web_bundles/rust/signed_web_bundles_rust.h"
+ #include "components/web_package/signed_web_bundles/signed_web_bundle_id.h"
+ #include "components/web_package/signed_web_bundles/types.h"
+ 
+ namespace web_package {
+ 
+-namespace {
+-
+-using SignatureType = signed_web_bundles::rust::SignatureType::Tag;
+-using signed_web_bundles::rust::parse_integrity_block;
+-
+-base::expected<mojom::BundleIntegrityBlockSignatureStackEntryPtr, std::string>
+-CreateSignatureStackEntry(
+-    const signed_web_bundles::rust::SignatureStackEntry& entry) {
+-  auto parsed_sig = mojom::BundleIntegrityBlockSignatureStackEntry::New();
+-
+-  switch (entry.signature_type.tag) {
+-    case SignatureType::Ed25519: {
+-      ASSIGN_OR_RETURN(auto public_key,
+-                       Ed25519PublicKey::Create(entry.public_key.to_span()));
+-      ASSIGN_OR_RETURN(auto signature,
+-                       Ed25519Signature::Create(entry.signature.to_span()));
+-      parsed_sig->signature_info = mojom::SignatureInfo::NewEd25519(
+-          mojom::SignatureInfoEd25519::New(public_key, signature));
+-      break;
+-    }
+-    case SignatureType::EcdsaP256SHA256: {
+-      ASSIGN_OR_RETURN(auto public_key,
+-                       EcdsaP256PublicKey::Create(entry.public_key.to_span()));
+-      ASSIGN_OR_RETURN(auto signature, EcdsaP256SHA256Signature::Create(
+-                                           entry.signature.to_span()));
+-      parsed_sig->signature_info = mojom::SignatureInfo::NewEcdsaP256Sha256(
+-          mojom::SignatureInfoEcdsaP256SHA256::New(public_key, signature));
+-      break;
+-    }
+-    case SignatureType::Unknown: {
+-      parsed_sig->signature_info =
+-          mojom::SignatureInfo::NewUnknown(mojom::SignatureInfoUnknown::New());
+-      break;
+-    }
+-  }
+-
+-  parsed_sig->attributes_cbor =
+-      BinaryData(entry.attributes_cbor.begin(), entry.attributes_cbor.end());
+-
+-  return parsed_sig;
+-}
+-
+-}  // namespace
+-
+ IntegrityBlockParser::IntegrityBlockParser(
+     mojom::BundleDataSource& data_source,
+     WebBundleParser::ParseIntegrityBlockCallback callback)
+@@ -103,37 +60,103 @@ void IntegrityBlockParser::OnIntegrityBl
+     RunErrorCallback("Error reading the integrity block.");
+     return;
+   }
++  // This structure is built during parsing and returned by the final callback
++  mojom::BundleIntegrityBlockPtr integrity_block =
++      mojom::BundleIntegrityBlock::New();
++
++  size_t consumed_bytes = 0;
++  cbor::Reader::DecoderError error;
++  cbor::Reader::Config config;
++  config.num_bytes_consumed = &consumed_bytes;
++  config.error_code_out = &error;
++
++  // When config `bytes_consumed` are assigned the CBOR parser reads only to the
++  // end of a structure. It parses only Integrity Block even if Web Bundle part
++  // starts just after.
++  std::optional<cbor::Value> value = cbor::Reader::Read(*data, config);
++  if (!value) {
++    RunErrorCallback("Error parsing integrity block as CBOR: " +
++                     std::string(cbor::Reader::ErrorCodeToString(error)));
++    return;
++  }
++  integrity_block->size = consumed_bytes;
++
++  if (!value->is_array()) {
++    RunErrorCallback("Integrity block is not a CBOR array.");
++    return;
++  }
+ 
+-  const auto parse_res = parse_integrity_block(*data);
+-  if (!parse_res.has_value()) {
+-    const auto& error = parse_res.error();
+-    RunErrorCallback(std::string(error.message.as_str()),
+-                     error.is_version_error
+-                         ? mojom::BundleParseErrorType::kVersionError
+-                         : mojom::BundleParseErrorType::kFormatError);
++  const cbor::Value::ArrayValue& top_array = value->GetArray();
++  if (top_array.size() != kIntegrityBlockV2TopLevelArrayLength) {
++    RunErrorCallback(base::StringPrintf(
++        "Invalid integrity block array length: expected %u, got %zu.",
++        kIntegrityBlockV2TopLevelArrayLength, top_array.size()));
+     return;
+   }
+ 
+-  const auto& parsed_ib = *parse_res;
+-  auto integrity_block = mojom::BundleIntegrityBlock::New();
+-  integrity_block->size = parsed_ib.size;
+-
+-  const std::string_view web_bundle_id_str =
+-      parsed_ib.web_bundle_id.to_string_view();
+-  RETURN_IF_ERROR(
+-      SignedWebBundleId::Create(web_bundle_id_str),
+-      [&](std::string error) { RunErrorCallback(std::move(error)); });
+-
+-  integrity_block->attributes =
+-      IntegrityBlockAttributes(std::string(web_bundle_id_str),
+-                               BinaryData(parsed_ib.attributes_cbor.begin(),
+-                                          parsed_ib.attributes_cbor.end()));
++  // 1. Magic bytes
++  if (!top_array[0].is_bytestring() ||
++      !std::ranges::equal(top_array[0].GetBytestring(),
++                          kIntegrityBlockMagicBytes)) {
++    RunErrorCallback("Unexpected magic bytes.");
++    return;
++  }
++
++  // 2. Version
++  if (!top_array[1].is_bytestring() ||
++      !std::ranges::equal(top_array[1].GetBytestring(),
++                          kIntegrityBlockV2VersionBytes)) {
++    RunErrorCallback("Unexpected version bytes.",
++                     mojom::BundleParseErrorType::kVersionError);
++    return;
++  }
+ 
+-  for (const auto& entry : parsed_ib.signature_stack) {
++  // 3. Attributes
++  if (!top_array[2].is_map()) {
++    RunErrorCallback("Integrity block attributes must be a map.");
++    return;
++  }
++  const cbor::Value::MapValue& attributes_map = top_array[2].GetMap();
++  const cbor::Value* web_bundle_id =
++      base::FindOrNull(attributes_map, cbor::Value(kWebBundleIdAttributeName));
++  if (!web_bundle_id || !web_bundle_id->is_string()) {
++    RunErrorCallback(
++        "`webBundleId` integrity block attribute is missing or malformed.");
++    return;
++  }
++
++  // Check if web_bundle_id is correct
++  RETURN_IF_ERROR(SignedWebBundleId::Create(web_bundle_id->GetString()),
++                  [&](const std::string& error) { RunErrorCallback(error); });
++
++  BinaryData attributes_cbor = *cbor::Writer::Write(top_array[2]);
++  integrity_block->attributes = IntegrityBlockAttributes(
++      web_bundle_id->GetString(), std::move(attributes_cbor));
++
++  // 4. Signature Stack
++  if (!top_array[3].is_array()) {
++    RunErrorCallback("Signature stack must be an array.");
++    return;
++  }
++  const cbor::Value::ArrayValue& signatures = top_array[3].GetArray();
++  if (signatures.empty()) {
++    RunErrorCallback(
++        "The signature stack must contain at least one signature.");
++    return;
++  }
++
++  for (const auto& signature_info_raw : signatures) {
+     ASSIGN_OR_RETURN(
+-        auto parsed_sig, CreateSignatureStackEntry(entry),
+-        [&](std::string error) { RunErrorCallback(std::move(error)); });
+-    integrity_block->signature_stack.push_back(std::move(parsed_sig));
++        auto parsed_signature_info, ParseSignatureInfo(signature_info_raw),
++        [&](const std::string& error) { this->RunErrorCallback(error); });
++
++    if (integrity_block->signature_stack.empty() &&
++        parsed_signature_info->signature_info->is_unknown()) {
++      RunErrorCallback("Unknown cipher type of the first signature.");
++      return;
++    }
++    integrity_block->signature_stack.push_back(
++        std::move(parsed_signature_info));
+   }
+ 
+   std::move(complete_callback_)
+@@ -141,13 +164,74 @@ void IntegrityBlockParser::OnIntegrityBl
+                           std::move(integrity_block), nullptr));
+ }
+ 
++base::expected<mojom::BundleIntegrityBlockSignatureStackEntryPtr, std::string>
++IntegrityBlockParser::ParseSignatureInfo(
++    const cbor::Value& signature_info_raw) {
++  if (!signature_info_raw.is_array() ||
++      signature_info_raw.GetArray().size() != 2) {
++    return base::unexpected(
++        "Each signature stack entry must contain exactly two elements.");
++  }
++
++  const cbor::Value::ArrayValue& signature_info_array =
++      signature_info_raw.GetArray();
++  if (!signature_info_array[0].is_map() ||
++      !signature_info_array[1].is_bytestring()) {
++    return base::unexpected("Malformed signature stack entry.");
++  }
++
++  mojom::BundleIntegrityBlockSignatureStackEntryPtr parsed_signature_info =
++      mojom::BundleIntegrityBlockSignatureStackEntry::New();
++  parsed_signature_info->attributes_cbor =
++      *cbor::Writer::Write(signature_info_array[0]);
++
++  const cbor::Value::MapValue& signature_attributes =
++      signature_info_array[0].GetMap();
++  const BinaryData& signature_bytes = signature_info_array[1].GetBytestring();
++
++  const cbor::Value* ed25519_key = base::FindOrNull(
++      signature_attributes, cbor::Value(kEd25519PublicKeyAttributeName));
++  const cbor::Value* ecdsa_key = base::FindOrNull(
++      signature_attributes, cbor::Value(kEcdsaP256PublicKeyAttributeName));
++
++  if (ed25519_key && ecdsa_key) {
++    return base::unexpected("Multiple key types for one signature.");
++  } else if (ed25519_key && !ed25519_key->is_bytestring()) {
++    return base::unexpected("Invalid ED25519 key.");
++  } else if (ecdsa_key && !ecdsa_key->is_bytestring()) {
++    return base::unexpected("Invalid ECDSA key.");
++
++  } else if (ed25519_key && ed25519_key->is_bytestring()) {
++    ASSIGN_OR_RETURN(auto public_key,
++                     Ed25519PublicKey::Create(ed25519_key->GetBytestring()));
++    ASSIGN_OR_RETURN(auto signature, Ed25519Signature::Create(signature_bytes));
++    parsed_signature_info->signature_info = mojom::SignatureInfo::NewEd25519(
++        mojom::SignatureInfoEd25519::New(public_key, signature));
++
++  } else if (ecdsa_key && ecdsa_key->is_bytestring()) {
++    ASSIGN_OR_RETURN(auto public_key,
++                     EcdsaP256PublicKey::Create(ecdsa_key->GetBytestring()));
++    ASSIGN_OR_RETURN(auto signature,
++                     EcdsaP256SHA256Signature::Create(signature_bytes));
++    parsed_signature_info->signature_info =
++        mojom::SignatureInfo::NewEcdsaP256Sha256(
++            mojom::SignatureInfoEcdsaP256SHA256::New(public_key, signature));
++
++  } else {
++    parsed_signature_info->signature_info =
++        mojom::SignatureInfo::NewUnknown(mojom::SignatureInfoUnknown::New());
++  }
++
++  return parsed_signature_info;
++}
++
+ void IntegrityBlockParser::RunErrorCallback(
+-    std::string message,
++    const std::string& message,
+     mojom::BundleParseErrorType error_type) {
+   std::move(complete_callback_)
+-      .Run(base::BindOnce(std::move(result_callback_), nullptr,
+-                          mojom::BundleIntegrityBlockParseError::New(
+-                              error_type, std::move(message))));
++      .Run(base::BindOnce(
++          std::move(result_callback_), nullptr,
++          mojom::BundleIntegrityBlockParseError::New(error_type, message)));
+ }
+ 
+ }  // namespace web_package
+--- a/components/web_package/signed_web_bundles/integrity_block_parser.h
++++ b/components/web_package/signed_web_bundles/integrity_block_parser.h
+@@ -5,13 +5,8 @@
+ #ifndef COMPONENTS_WEB_PACKAGE_SIGNED_WEB_BUNDLES_INTEGRITY_BLOCK_PARSER_H_
+ #define COMPONENTS_WEB_PACKAGE_SIGNED_WEB_BUNDLES_INTEGRITY_BLOCK_PARSER_H_
+ 
+-#include <optional>
+-#include <string>
+-
+-#include "base/compiler_specific.h"
+-#include "base/memory/raw_ref.h"
+-#include "base/memory/weak_ptr.h"
+ #include "components/web_package/mojom/web_bundle_parser.mojom-forward.h"
++#include "components/web_package/signed_web_bundles/integrity_block_attributes.h"
+ #include "components/web_package/signed_web_bundles/types.h"
+ #include "components/web_package/web_bundle_parser.h"
+ 
+@@ -20,7 +15,7 @@ namespace web_package {
+ class IntegrityBlockParser : public WebBundleParser::WebBundleSectionParser {
+  public:
+   explicit IntegrityBlockParser(
+-      mojom::BundleDataSource& data_source LIFETIME_BOUND,
++      mojom::BundleDataSource& data_source,
+       WebBundleParser::ParseIntegrityBlockCallback callback);
+ 
+   IntegrityBlockParser(const IntegrityBlockParser&) = delete;
+@@ -35,7 +30,10 @@ class IntegrityBlockParser : public WebB
+  private:
+   void OnIntegrityBlockRead(const std::optional<BinaryData>& data);
+ 
+-  void RunErrorCallback(std::string message,
++  base::expected<mojom::BundleIntegrityBlockSignatureStackEntryPtr, std::string>
++  ParseSignatureInfo(const cbor::Value& attributes_map);
++
++  void RunErrorCallback(const std::string& message,
+                         mojom::BundleParseErrorType error_type =
+                             mojom::BundleParseErrorType::kFormatError);
+ 
+--- a/components/web_package/signed_web_bundles/rust/BUILD.gn
++++ b/components/web_package/signed_web_bundles/rust/BUILD.gn
+@@ -10,7 +10,6 @@ rust_static_library("signed_web_bundles_
+   sources = [
+     "constants.rs",
+     "integrity_block.rs",
+-    "signature_verifier.rs",
+     "types.rs",
+     crate_root,
+   ]
+--- a/components/web_package/signed_web_bundles/signed_web_bundle_signature_verifier.cc
++++ b/components/web_package/signed_web_bundles/signed_web_bundle_signature_verifier.cc
+@@ -20,14 +20,17 @@
+ #include "base/task/thread_pool.h"
+ #include "base/types/expected.h"
+ #include "base/types/expected_macros.h"
++#include "components/cbor/values.h"
++#include "components/cbor/writer.h"
++#include "components/web_package/signed_web_bundles/constants.h"
+ #include "components/web_package/signed_web_bundles/identity_validator.h"
+ #include "components/web_package/signed_web_bundles/integrity_block_parser.h"
+-#include "components/web_package/signed_web_bundles/rust/signed_web_bundles_rust.h"
+ #include "components/web_package/signed_web_bundles/signed_web_bundle_id.h"
+ #include "components/web_package/signed_web_bundles/signed_web_bundle_integrity_block.h"
+ #include "components/web_package/signed_web_bundles/signed_web_bundle_signature_stack.h"
+ #include "components/web_package/signed_web_bundles/signed_web_bundle_signature_stack_entry.h"
+ #include "components/web_package/signed_web_bundles/signed_web_bundle_utils.h"
++#include "crypto/hash.h"
+ #include "third_party/abseil-cpp/absl/functional/overload.h"
+ #include "third_party/boringssl/src/include/openssl/sha.h"
+ 
+@@ -37,10 +40,32 @@ namespace {
+ 
+ std::vector<uint8_t> CreateIntegrityBlockCbor(
+     const SignedWebBundleIntegrityBlock& integrity_block) {
+-  auto ib_cbor_rust =
+-      signed_web_bundles::rust::create_empty_integrity_block_cbor(
+-          integrity_block.attributes_cbor());
+-  return std::vector<uint8_t>(ib_cbor_rust.begin(), ib_cbor_rust.end());
++  // This function looks like it should use a cbor::Value::ArrayValue to build
++  // the outer array, but it can't: one of the elements is a pre-encoded CBOR
++  // value which we can't safely decode because it's untrusted input. This is
++  // obviously undesirable, because there's no guarantee at all that the
++  // pre-encoded value is actually valid CBOR.
++  //
++  // TODO(https://crbug.com/454485901): once there's a memory-safe CBOR parser,
++  // re-parse the pre-encoded value, then re-encode it here instead of
++  // constructing a CBOR array by hand so that we're guaranteed that the result
++  // of this function is valid.
++  std::vector<uint8_t> ib_cbor;
++
++  // 0x84 is the encoding byte for an array of length 4.
++  ib_cbor.push_back(0x84);
++  base::Extend(ib_cbor,
++               *cbor::Writer::Write(cbor::Value(kIntegrityBlockMagicBytes)));
++  base::Extend(ib_cbor, *cbor::Writer::Write(
++                            cbor::Value(kIntegrityBlockV2VersionBytes)));
++  // We cannot parse `attributes().cbor()` back to a cbor::Value as they
++  // technically represent untrusted input.
++  base::Extend(ib_cbor, integrity_block.attributes_cbor());
++  // Encode an empty signature array.
++  base::Extend(ib_cbor,
++               *cbor::Writer::Write(cbor::Value(cbor::Value::ArrayValue())));
++
++  return ib_cbor;
+ }
+ 
+ base::expected<void, SignedWebBundleSignatureVerifier::Error>
+@@ -104,7 +129,7 @@ SignedWebBundleSignatureVerifier::Calcul
+     return base::unexpected(base::File::ErrorToString(file.GetLastFileError()));
+   }
+ 
+-  signed_web_bundles::rust::Sha512Hasher hasher;
++  crypto::hash::Hasher hash(crypto::hash::kSha512);
+ 
+   // Calculate the hash of the Signed Web Bundle excluding its integrity block.
+   // The file might be too big to read it into memory all at once, which is why
+@@ -121,14 +146,15 @@ SignedWebBundleSignatureVerifier::Calcul
+           base::File::ErrorToString(file.GetLastFileError()));
+     }
+     data.resize(*bytes_read);
+-    hasher.update(data);
++    hash.Update(data);
+ 
+     if (!base::CheckAdd(offset, *bytes_read).AssignIfValid(&offset)) {
+       return base::unexpected("The Signed Web Bundle is too large.");
+     }
+   }
+ 
+-  SHA512Digest digest = std::move(hasher).finish();
++  SHA512Digest digest;
++  hash.Finish(digest);
+   return digest;
+ }
+ 
+--- a/components/web_package/signed_web_bundles/signed_web_bundle_utils.cc
++++ b/components/web_package/signed_web_bundles/signed_web_bundle_utils.cc
+@@ -5,18 +5,37 @@
+ #include "components/web_package/signed_web_bundles/signed_web_bundle_utils.h"
+ 
+ #include <cstdint>
+-#include <vector>
+ 
+-#include "components/web_package/signed_web_bundles/rust/signed_web_bundles_rust.h"
++#include "base/containers/extend.h"
++#include "base/containers/span.h"
++#include "base/containers/span_writer.h"
+ 
+ namespace web_package {
+ 
++namespace {
++
++void AddItemToPayload(std::vector<uint8_t>& payload,
++                      base::span<const uint8_t> item) {
++  // Each item that is part of the payload is prefixed with its length encoded
++  // as a 64 bit unsigned integer.
++  std::array<uint8_t, sizeof(uint64_t)> length;
++  auto writer = base::SpanWriter(base::span(length));
++  CHECK(writer.WriteU64BigEndian(item.size()));
++
++  base::Extend(payload, base::span(length));
++  base::Extend(payload, item);
++}
++
++}  // namespace
++
+ std::vector<uint8_t> CreateSignaturePayload(
+     const SignedWebBundleSignatureData& data) {
+-  auto payload_rust = signed_web_bundles::rust::create_signature_payload(
+-      data.unsigned_web_bundle_hash, data.integrity_block_cbor,
+-      data.attributes_cbor);
+-  return std::vector<uint8_t>(payload_rust.begin(), payload_rust.end());
++  std::vector<uint8_t> payload;
++  AddItemToPayload(payload, data.unsigned_web_bundle_hash);
++  AddItemToPayload(payload, data.integrity_block_cbor);
++  AddItemToPayload(payload, data.attributes_cbor);
++
++  return payload;
+ }
+ 
+ }  // namespace web_package
+--- a/third_party/blink/renderer/platform/BUILD.gn
++++ b/third_party/blink/renderer/platform/BUILD.gn
+@@ -186,6 +186,18 @@ group("make_platform_generated") {
+   ]
+ }
+ 
++rust_static_library("font_format_check") {
++  allow_unsafe = true  # Needed for FFI that underpins the `cxx` crate.
++  crate_root = "fonts/opentype/format_check.rs"
++  sources = [ crate_root ]
++  cxx_bindings = [ crate_root ]
++  deps = [
++    "//third_party/rust/font_types/v0_12:lib",
++    "//third_party/rust/read_fonts/v0_43:lib",
++    "//third_party/rust/skrifa/v0_46:lib",
++  ]
++}
++
+ rust_static_library("rustfft_ffi") {
+   allow_unsafe = true  # Needed for FFI that underpins the `cxx` crate.
+   crate_root = "audio/rustfft_ffi.rs"
+@@ -1792,7 +1804,6 @@ component("platform") {
+     ":allow_discouraged_type",
+     ":blink_platform_public_deps",
+     ":platform_export",
+-    "//build/rust/crubit",
+     "//gpu/command_buffer/client:raster_interface",
+     "//media/capture:capture_lib",
+     "//mojo/public/cpp/base",
+@@ -1819,8 +1830,8 @@ component("platform") {
+     "//ui/native_theme/features",
+   ]
+   deps = [
++    ":font_format_check",
+     ":rustfft_ffi",
+-    "fonts:font_format_bindings",
+     "//base:base_static",
+     "//base/allocator:buildflags",
+     "//build:chromecast_buildflags",
+--- a/third_party/blink/renderer/platform/fonts/BUILD.gn
++++ /dev/null
+@@ -1,19 +0,0 @@
+-# Copyright 2026 The Chromium Authors
+-# Use of this source code is governed by a BSD-style license that can be
+-# found in the LICENSE file.
+-
+-import("//build/rust/rust_static_library.gni")
+-
+-rust_static_library("font_format") {
+-  crate_root = "opentype/format_check.rs"
+-  sources = [ crate_root ]
+-  cpp_api_from_rust = {
+-    target_name = "font_format_bindings"
+-    cpp_namespace = "font_format"
+-  }
+-  deps = [
+-    "//third_party/rust/font_types/v0_12:lib",
+-    "//third_party/rust/read_fonts/v0_43:lib",
+-    "//third_party/rust/skrifa/v0_46:lib",
+-  ]
+-}
+--- a/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc
++++ b/third_party/blink/renderer/platform/fonts/opentype/font_format_check.cc
+@@ -7,6 +7,7 @@
+ #include "base/containers/span.h"
+ #include "base/containers/span_rust.h"
+ #include "base/numerics/byte_conversions.h"
++#include "third_party/blink/renderer/platform/fonts/opentype/format_check.rs.h"
+ #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
+ #include "third_party/blink/renderer/platform/wtf/vector.h"
+ #include "third_party/skia/include/core/SkTypeface.h"
+@@ -14,37 +15,35 @@
+ namespace blink {
+ 
+ FontFormatCheck::FontFormatCheck(sk_sp<SkData> sk_data)
+-    : format_info_(font_format::get_font_format_info(
++    : format_info_(font_format_check::get_font_format_info(
+           base::SpanToRustSlice(sk_data->byteSpan()))) {}
+ 
+-FontFormatCheck::~FontFormatCheck() = default;
+-
+ bool FontFormatCheck::IsVariableFont() const {
+-  return font_format::is_variable(format_info_);
++  return font_format_check::is_variable(*format_info_);
+ }
+ 
+ bool FontFormatCheck::IsCbdtCblcColorFont() const {
+-  return font_format::is_cbdt_cblc(format_info_);
++  return font_format_check::is_cbdt_cblc(*format_info_);
+ }
+ 
+ bool FontFormatCheck::IsEbdtEblcMonochromeFont() const {
+-  return font_format::is_ebdt_eblc(format_info_);
++  return font_format_check::is_ebdt_eblc(*format_info_);
+ }
+ 
+ bool FontFormatCheck::IsColrCpalColorFontV0() const {
+-  return font_format::is_colrv0(format_info_);
++  return font_format_check::is_colrv0(*format_info_);
+ }
+ 
+ bool FontFormatCheck::IsColrCpalColorFontV1() const {
+-  return font_format::is_colrv1(format_info_);
++  return font_format_check::is_colrv1(*format_info_);
+ }
+ 
+ bool FontFormatCheck::IsSbixColorFont() const {
+-  return font_format::is_sbix(format_info_);
++  return font_format_check::is_sbix(*format_info_);
+ }
+ 
+ bool FontFormatCheck::IsCff2OutlineFont() const {
+-  return font_format::is_cff2(format_info_);
++  return font_format_check::is_cff2(*format_info_);
+ }
+ 
+ bool FontFormatCheck::IsVariableColrV0Font() const {
+@@ -58,7 +57,7 @@ bool FontFormatCheck::IsColorFont() cons
+ 
+ bool FontFormatCheck::IsAvar2Font() const {
+   return RuntimeEnabledFeatures::FontFormatAvar2Enabled() &&
+-         font_format::is_avar2(format_info_);
++         font_format_check::is_avar2(*format_info_);
+ }
+ 
+ FontFormatCheck::VariableFontSubType FontFormatCheck::ProbeVariableFont(
+--- a/third_party/blink/renderer/platform/fonts/opentype/font_format_check.h
++++ b/third_party/blink/renderer/platform/fonts/opentype/font_format_check.h
+@@ -5,7 +5,7 @@
+ #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_OPENTYPE_FONT_FORMAT_CHECK_H_
+ #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_OPENTYPE_FONT_FORMAT_CHECK_H_
+ 
+-#include "third_party/blink/renderer/platform/fonts/font_format.h"
++#include "third_party/blink/renderer/platform/fonts/opentype/format_check.rs.h"
+ #include "third_party/blink/renderer/platform/platform_export.h"
+ #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
+ #include "third_party/skia/include/core/SkData.h"
+@@ -19,7 +19,7 @@ class PLATFORM_EXPORT FontFormatCheck {
+ 
+  public:
+   explicit FontFormatCheck(sk_sp<SkData>);
+-  virtual ~FontFormatCheck();
++  virtual ~FontFormatCheck() = default;
+   virtual bool IsVariableFont() const;
+   virtual bool IsCbdtCblcColorFont() const;
+   virtual bool IsEbdtEblcMonochromeFont() const;
+@@ -46,7 +46,7 @@ class PLATFORM_EXPORT FontFormatCheck {
+   enum class COLRVersion { kCOLRV0, kCOLRV1, kNoCOLR };
+ 
+  private:
+-  font_format::FontFormatInfo format_info_;
++  rust::Box<font_format_check::FontFormatInfo> format_info_;
+ };
+ 
+ }  // namespace blink
+--- a/third_party/blink/renderer/platform/fonts/opentype/format_check.rs
++++ b/third_party/blink/renderer/platform/fonts/opentype/format_check.rs
+@@ -23,7 +23,7 @@ pub struct FontFormatInfo {
+     format_flags: Option<FontFormatFlags>,
+ }
+ 
+-pub fn get_font_format_info(font_bytes: &[u8]) -> FontFormatInfo {
++pub fn get_font_format_info(font_bytes: &[u8]) -> Box<FontFormatInfo> {
+     let file_ref = make_font_ref_internal(font_bytes, 0);
+ 
+     match file_ref {
+@@ -32,11 +32,11 @@ pub fn get_font_format_info(font_bytes:
+                 font.table_directory().table_records().iter().map(|e| e.tag()).collect();
+             let color_version = get_colr_version(&font);
+             let avar_version = get_avar_version(&font);
+-            FontFormatInfo {
++            Box::new(FontFormatInfo {
+                 format_flags: Some(FontFormatFlags { table_tags, color_version, avar_version }),
+-            }
++            })
+         }
+-        _ => FontFormatInfo::default(),
++        _ => Box::new(FontFormatInfo::default()),
+     }
+ }
+ 
+@@ -44,10 +44,10 @@ fn get_colr_version(font_ref: &FontRef)
+     Some(font_ref.colr().ok()?.version())
+ }
+ 
+-pub fn is_colrv1(format_info: &FontFormatInfo) -> bool {
++fn is_colrv1(format_info: &FontFormatInfo) -> bool {
+     matches!(&format_info.format_flags, Some(FontFormatFlags { color_version: Some(1), .. }),)
+ }
+-pub fn is_colrv0(format_info: &FontFormatInfo) -> bool {
++fn is_colrv0(format_info: &FontFormatInfo) -> bool {
+     matches!(&format_info.format_flags, Some(FontFormatFlags { color_version: Some(0), .. }),)
+ }
+ 
+@@ -56,7 +56,7 @@ fn get_avar_version(font_ref: &FontRef)
+     Some((version.major, version.minor))
+ }
+ 
+-pub fn is_avar2(format_info: &FontFormatInfo) -> bool {
++fn is_avar2(format_info: &FontFormatInfo) -> bool {
+     matches!(&format_info.format_flags, Some(FontFormatFlags { avar_version: Some((2, _)), .. }),)
+ }
+ 
+@@ -69,22 +69,39 @@ fn has_tags(format_info: &FontFormatInfo
+     }
+ }
+ 
+-pub fn is_variable(format_info: &FontFormatInfo) -> bool {
++fn is_variable(format_info: &FontFormatInfo) -> bool {
+     has_tags(format_info, &[Tag::new(b"fvar")])
+ }
+ 
+-pub fn is_sbix(format_info: &FontFormatInfo) -> bool {
++fn is_sbix(format_info: &FontFormatInfo) -> bool {
+     has_tags(format_info, &[Tag::new(b"sbix")])
+ }
+ 
+-pub fn is_cbdt_cblc(format_info: &FontFormatInfo) -> bool {
++fn is_cbdt_cblc(format_info: &FontFormatInfo) -> bool {
+     has_tags(format_info, &[Tag::new(b"CBDT"), Tag::new(b"CBLC")])
+ }
+ 
+-pub fn is_ebdt_eblc(format_info: &FontFormatInfo) -> bool {
++fn is_ebdt_eblc(format_info: &FontFormatInfo) -> bool {
+     has_tags(format_info, &[Tag::new(b"EBDT"), Tag::new(b"EBLC")])
+ }
+ 
+-pub fn is_cff2(format_info: &FontFormatInfo) -> bool {
++fn is_cff2(format_info: &FontFormatInfo) -> bool {
+     has_tags(format_info, &[Tag::new(b"CFF2")])
+ }
++
++#[cxx::bridge(namespace = "font_format_check")]
++pub mod ffi {
++    extern "Rust" {
++        type FontFormatInfo;
++
++        fn get_font_format_info(font_bytes: &[u8]) -> Box<FontFormatInfo>;
++        fn is_colrv1(format_info: &FontFormatInfo) -> bool;
++        fn is_colrv0(format_info: &FontFormatInfo) -> bool;
++        fn is_cbdt_cblc(format_info: &FontFormatInfo) -> bool;
++        fn is_ebdt_eblc(format_info: &FontFormatInfo) -> bool;
++        fn is_variable(format_info: &FontFormatInfo) -> bool;
++        fn is_sbix(format_info: &FontFormatInfo) -> bool;
++        fn is_cff2(format_info: &FontFormatInfo) -> bool;
++        fn is_avar2(format_info: &FontFormatInfo) -> bool;
++    }
++}
Risk 4/5 · High pihole.sudo

Comment

The new sudoers rule grants the unprivileged `pihole` account passwordless sudo to run `/usr/bin/pihole` as any user/group. This is a significant privilege boundary change because the effective security now depends entirely on what the `pihole` CLI can do. If that command supports subcommands that modify system configuration, invoke helpers, or otherwise reach privileged operations, this becomes a root escalation path for any process able to act as the `pihole` user. The change is also broad (`ALL=(ALL:ALL)` and `NOPASSWD`) rather than narrowly scoped to a specific safe subcommand. I did not see evidence in this diff alone of an immediate exploit, but the rule is permissive enough to be risky and should be tightly constrained or justified by upstream documentation.

@@ -0,0 +1 @@
+pihole ALL=(ALL:ALL) NOPASSWD: /usr/bin/pihole
Risk 3/5 · Elevated PKGBUILD

Comment

The change replaces a pinned source tarball in `source=()` with a runtime download in `prepare()`, which bypasses Arch's normal source integrity model. The build now fetches from the network during package preparation, and if the first response is XML it parses a redirect URL out of the response body and downloads from that URL as well. That introduces an unvetted network dependency and makes the build trust remote metadata at build time rather than a fixed, checksum-covered source entry. Although the tarball is still SHA-256 checked before extraction, the redirect-following logic is brittle and expands the attack surface (e.g. any compromise or manipulation of the Qt download endpoint/redirect metadata can steer the build to arbitrary HTTPS content that only needs to match the hardcoded hash). This is a supply-chain integrity regression compared with the original PKGBUILD, so I rate it moderately risky.

@@ -14,14 +14,24 @@ makedepends=('qt5-tools' 'python' 'pciutils' 'libxtst' 'libxcursor' 'libxrandr' 
              'gperf' 'nss' 'clang' 'nodejs' 'ninja')
 groups=('qt5')
 _pkgfqn="qt-everywhere-opensource-src-${pkgver}"
-source=("https://download.qt.io/archive/qt/${pkgver%.*}/${pkgver}/single/$_pkgfqn.tar.xz"
-         no-qmake.patch
+_qt_tarball="$_pkgfqn.tar.xz"
+_qt_sha256='173c2326dae138bbb0d98921e9d911e55c00163d93a6db29f294b5e19ff306ae'
+source=(no-qmake.patch
          qt-everywhere-src-5.15.17-assimp.patch)
-sha256sums=('173c2326dae138bbb0d98921e9d911e55c00163d93a6db29f294b5e19ff306ae'
-            'db90fa31381fa0814c9c8c803c9e2f9b36bdd6f52da753399e500c0692352498'
+sha256sums=('db90fa31381fa0814c9c8c803c9e2f9b36bdd6f52da753399e500c0692352498'
             '9d54e70051adfeed818db437f266e3bba5ccd2f5f9e056515281ee2f7ff71bac')
 
 prepare() {
+  local _url="https://download.qt.io/archive/qt/${pkgver%.*}/${pkgver}/single/$_qt_tarball"
+  curl -fsSL -o "$_qt_tarball" "$_url"
+  if [ "$(head -c5 "$_qt_tarball")" = '<?xml' ]; then
+    _url=$(grep -oE '<url location="[^"]+" priority="[0-9]+">[^<]+</url>' "$_qt_tarball" | head -n1 | sed -E 's/^<url[^>]*>//; s@</url>$@@')
+    test -n "$_url"
+    curl -fsSL -o "$_qt_tarball" "$_url"
+  fi
+  echo "$_qt_sha256  $_qt_tarball" | sha256sum -c -
+  bsdtar -xf "$_qt_tarball"
+
   cd ${_pkgfqn/opensource-/}
 
   ln -s /usr/bin qttools/
Risk 3/5 · Elevated PKGBUILD

Comment

The change replaces the official MakeMKV source tarball URLs with tarballs hosted on a third-party SourceForge project (`fabiololix-os-archive`) while keeping the same checksums. That is a supply-chain integrity regression: the package is now trusting an unrelated mirror/archive rather than the upstream site, and the PKGBUILD no longer makes it obvious that the fetched artifacts are the official releases. Although the hashes still pin the exact contents, this introduces unnecessary dependency on an external archive and weakens provenance. No direct code execution or install-script changes are present in this hunk, so the risk is moderate rather than severe.

@@ -13,12 +13,15 @@ license=('LicenseRef-GuinpinSoft-inc-EULA' LGPL-2.1-or-later)
 depends=(qt5-base ffmpeg libavcodec.so)
 optdepends=('java-runtime: bdjava https://www.makemkv.com/bdjava/')
 install=makemkv.install
-source=(${url}/download/${pkgname}-bin-${pkgver}.tar.gz
-        ${url}/download/${pkgname}-oss-${pkgver}.tar.gz
-        ffmpeg9.patch
-        makemkv.1
-        makemkvcon.1
-        )
+source=(
+    #${url}/download/${pkgname}-bin-${pkgver}.tar.gz
+    #${url}/download/${pkgname}-oss-${pkgver}.tar.gz
+    https://sourceforge.net/projects/fabiololix-os-archive/files/src/makemkv-bin-1.18.4.tar.gz
+    https://sourceforge.net/projects/fabiololix-os-archive/files/src/makemkv-oss-1.18.4.tar.gz
+    ffmpeg9.patch
+    makemkv.1
+    makemkvcon.1
+    )
 sha256sums=('cee56de0baa5531abed16bd862742d308d772b4ab4dae16ee865bf74f04a1608'
             '8590063648d42ec2a958b74573d7022f0f4c334e4e4fe7dd53b70c6e748ba453'
             'd35ae9e841ac43297e17a08d8819b339c5058bbdfc150fab508a442365756929'
Risk 3/5 · Elevated .SRCINFO

Comment

The only change is to redirect the two source tarball URLs from the official MakeMKV download site to a SourceForge project named `fabiololix-os-archive`. That is a significant supply-chain red flag: the package would now fetch upstream source archives from an unrelated third-party mirror/fork rather than the official vendor, with no evidence in this diff that the mirror is authoritative or that checksums were updated to preserve integrity. Because `.SRCINFO` drives AUR metadata, this can mislead users/builders into trusting a non-official source. I do not see any direct code execution or install-script changes in this hunk, so the risk is moderate rather than maximal, but the source substitution is suspicious enough to warrant review of the actual PKGBUILD and checksums before trusting the package.

@@ -13,8 +13,8 @@ pkgbase = makemkv
 	depends = ffmpeg
 	depends = libavcodec.so
 	optdepends = java-runtime: bdjava https://www.makemkv.com/bdjava/
-	source = https://www.makemkv.com/download/makemkv-bin-1.18.4.tar.gz
-	source = https://www.makemkv.com/download/makemkv-oss-1.18.4.tar.gz
+	source = https://sourceforge.net/projects/fabiololix-os-archive/files/src/makemkv-bin-1.18.4.tar.gz
+	source = https://sourceforge.net/projects/fabiololix-os-archive/files/src/makemkv-oss-1.18.4.tar.gz
 	source = ffmpeg9.patch
 	source = makemkv.1
 	source = makemkvcon.1
Risk 4/5 · High keys/pgp/14F26682D0916CDD81E37B6D61B7B526D98F0353.asc

Comment

The change replaces the existing Mozilla release signing key material with a different, much larger PGP public key block that includes additional self-signatures and a new user ID ('No longer trust this key.'). For a package that relies on this key to verify upstream Firefox Nightly artifacts, swapping the trusted key material is a supply-chain integrity change: it can alter which releases are accepted or rejected, and if the new key is not the exact intended upstream replacement, it could enable acceptance of attacker-controlled signatures or break verification in a way that users may bypass. I did not see any obvious build-script execution or network abuse in this file, but the trust-anchor change itself is high impact and should be treated cautiously. The diff alone does not prove malicious intent, but it is a security-sensitive key rotation that needs independent validation against upstream Mozilla key announcements before being accepted.

@@ -12,53 +12,100 @@ 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
-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
-O1FPgm7RVTg=
-=SScT
+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
+bK+W3WvvXQQLUU9k4IsERbA=
+=/Lt1
 -----END PGP PUBLIC KEY BLOCK-----
Risk 4/5 · High PKGBUILD

Comment

High-confidence supply-chain/integrity regression. The PKGBUILD now fetches the SHA1 checksum at build time via `curl` from the vendor website instead of pinning it in the source array. That bypasses Arch's checksum verification model and makes the build trust a live network response, which can be altered or fail nondeterministically. The checksum extraction also references `${_patchver}`, which is undefined in this snippet, further weakening reliability. The source URL itself remains HTTPS and on the vendor domain, and the qt5->qt6 dependency update is not inherently suspicious, but the dynamic checksum retrieval is a clear packaging integrity issue.

@@ -6,17 +6,19 @@
 
 pkgname=masterpdfeditor
 pkgver=5.9.99
-pkgrel=3
+pkgrel=4
 pkgdesc='A complete solution for viewing, creating and editing PDF files'
 url='https://code-industry.net/free-pdf-editor/'
 arch=('x86_64')
 license=('custom')
 makedepends=('patchelf')
-source_x86_64=("https://code-industry.net/public/master-pdf-editor-${pkgver}-qt5.x86_64.tar.gz")
-sha1sums_x86_64=('bf84fca45c8e416f959b9667a21baf45d87e0f39')
+source_x86_64=("https://code-industry.net/public/master-pdf-editor-${pkgver}-qt6.11.1.x86_64.tar.gz")
+_checksum=$(curl 'https://code-industry.net/checksum-information/' | grep -oP '[a-f0-9]{40}(?=.*master-pdf-editor-'"${pkgver}${_patchver}"'-qt6.11.1.x86_64.tar.gz)')
+sha1sums_x86_64=("${_checksum% *}")
 
 package() {
-  depends=('libgl' 'pkcs11-helper' 'qt5-base' 'qt5-svg' 'qt5-declarative' 'sane')
+  depends=('libgl' 'pkcs11-helper' 'qt6-base' 'qt6-svg' 'qt6-declarative' 'sane')
+  optdepends=('qt6-wayland: Wayland platform plugin')
 
   install -d "$pkgdir"{/opt/,/usr/bin/}
   cp -a --no-preserve=ownership master-pdf-editor-${pkgver%%.*} "$pkgdir/opt/"
Risk 3/5 · Elevated PKGBUILD

Comment

The change is mostly packaging cleanup, but it also removes a patch and replaces it with in-tree source edits that force Bottles to believe it is never running in Flatpak/CPAK/container contexts. Specifically, prepare() now rewrites runtime checks in bottles.py, cli.py, and backend/globals.py to set CPAK_CONTAINER_ID and make the container-detection function always return False. That is a behavioral bypass of upstream environment/sandbox detection, which could disable safety-related code paths or alter how the app handles sandboxed execution. I did not find evidence of network fetches, privilege escalation, or install-script persistence in this diff, so the risk is moderate rather than severe.

@@ -38,48 +39,64 @@ depends=(
   vkbasalt-cli
 )
 makedepends=(
-  meson
-  ninja
+  appstream-glib
   blueprint-compiler
-  gobject-introspection
   desktop-file-utils
-  appstream-glib
   gettext
   glib2-devel
+  meson
 )
 optdepends=(
-  'vulkan-tools: vkcube test / Vulkan info'
-  'xorg-xdpyinfo: display info detection'
+  '7zip: extract 7z archives'
+  'gamescope: gamescope session integration'
   'imagemagick: icon/image conversion'
-  'vmtouch: preload bottle files into memory'
+  'lib32-alsa-lib: 32-bit ALSA for downloaded runners'
+  'lib32-fontconfig: 32-bit font rendering for downloaded runners'
+  'lib32-glibc: 32-bit support for downloaded runners'
+  'lib32-gnutls: 32-bit TLS for downloaded runners'
+  'lib32-libglvnd: 32-bit OpenGL/X11 for downloaded runners'
+  'lib32-libpulse: 32-bit PulseAudio for downloaded runners'
+  'lib32-vulkan-driver: 32-bit Vulkan driver (DXVK) for downloaded runners'
+  'lib32-vulkan-icd-loader: 32-bit Vulkan loader (DXVK) for downloaded runners'
   'mangohud: performance overlay'
-  'gamemode: feral gamemode integration'
-  'gamescope: gamescope session integration'
+  'python-pysocks: SOCKS proxy support'
+  'umu-launcher: manage UMU Launcher prefixes'
+  'vmtouch: preload bottle files into memory'
+  'vulkan-tools: vkcube test / Vulkan info'
+  'wine: use system installed wine as runner for bottles'
+  'xorg-xdpyinfo: display info detection'
   'xterm: fallback terminal for "Run executable in terminal"'
 )
 source=(
   "${_pkgname}-${pkgver}.tar.gz::https://github.com/bottlesdevs/Bottles/archive/refs/tags/${pkgver}.tar.gz"
-  remove-flatpak-checks.patch
 )
 sha256sums=(
-  8d81cc6a3f25675ef15f7ec35fadba247f17634b016be7eead6af536aee8c536
-  5b4a8818bdac2bfb46615959f02ef4dc94cfcc30768357ed56e91d15842d0ea7
+  "607994bbc29d7e8f3b0d3cd852b7a97a0f1e2c90e4dcacefc2e8ce632709e8db"
 )
 
 prepare() {
-  # Fix warning about flatpak and sandbox environment
-  patch --forward --directory="${srcdir}/${_pkgname}-${pkgver}" --strip=1 --input="${srcdir}/remove-flatpak-checks.patch"
+  cd "${srcdir}/${_pkgname}-${pkgver}"
+
+  grep -q "fs.is_file('/' + '.flatpak-info')" bottles/frontend/meson.build
+  sed -i "s|fs.is_file('/' + '.flatpak-info')|fs.is_file(meson.current_source_dir() / 'meson.build')|" \
+    bottles/frontend/meson.build
+
+  grep -q '^import os$' bottles/frontend/bottles.py bottles/frontend/cli/cli.py
+  sed -i '/^import os$/a os.environ.setdefault("CPAK_CONTAINER_ID", "1")' \
+    bottles/frontend/bottles.py bottles/frontend/cli/cli.py
+
+  grep -q 'return "FLATPAK_ID" in os.environ or is_cpak()' bottles/backend/globals.py
+  sed -i 's|return "FLATPAK_ID" in os.environ or is_cpak()|return False|' \
+    bottles/backend/globals.py
 }
 
 build() {
-  cd "${srcdir}/${_pkgname}-${pkgver}"
-  meson setup --prefix='/usr' build
-  ninja -C build
+  arch-meson "${_pkgname}-${pkgver}" build
+  meson compile -C build
 }
 
 package() {
-  cd "${srcdir}/${_pkgname}-${pkgver}"
-  DESTDIR="${pkgdir}" ninja -C build install
+  meson install -C build --destdir "${pkgdir}"
 }
 
 # vim: set ft=sh ts=2 sw=2 et:
Risk 3/5 · Elevated sanitize.patch

Comment

The patch is a cleanup of Ventoy upstream shell scripts, but it also removes several safety/validation checks and changes logging behavior. In Ventoy2Disk.sh it drops the guard that ensured the script is run from the released install package, the decompression/setup steps for bundled tools, and the explicit bash/ash invocation plus directory restoration, replacing them with a direct call to ./tool/VentoyWorker.sh. That makes execution more dependent on the caller’s current environment and working directory, which is a packaging/integrity regression, though not an obvious backdoor. In VentoyWeb.sh it removes the root check and redirects logs to /var/log/ventoy.log, which is a broader system write target and could affect system state outside the package directory. The patch also removes a mips64 path in VentoyPlugson.sh and a tool self-test in ventoy_lib.sh, but those are lower risk. Overall I see moderate risk from weakened safety checks and external log writes, but no clear malicious payload.

@@ -6,8 +6,8 @@ Let me do some optimisations.
 If you are interested to improve this patch, welcome to mail me.
 
 diff -Npur a/tool/ventoy_lib.sh b/tool/ventoy_lib.sh
---- a/tool/ventoy_lib.sh	2026-04-05 09:27:04.000000000 -0600
-+++ b/tool/ventoy_lib.sh	2026-04-06 10:03:00.691008472 -0600
+--- a/tool/ventoy_lib.sh	2026-07-24 06:59:22.000000000 -0600
++++ b/tool/ventoy_lib.sh	2026-07-24 09:00:04.344697720 -0600
 @@ -51,31 +51,6 @@ vtoy_gen_uuid() {
  }
  
Risk 3/5 · Elevated arch-core.patch

Comment

The patch changes logrotate targets from /var/log/pihole to /run/log/pihole and switches from copytruncate to create, which is a packaging/runtime behavior change but not inherently malicious. The added sudoers file grants the pihole user passwordless execution of /usr/bin/pihole as root, which is a significant privilege-escalation/persistence surface if the package installs that file or enables it automatically. However, in the provided diff hunk the sudoers file is only introduced as a template and there is no evidence here of automatic installation or additional commands beyond the expected pihole binary. Overall this is a moderate-risk change because it introduces a root-privilege mechanism that must be carefully justified and audited in surrounding packaging logic.

@@ -83,25 +83,25 @@ diff -uprN pi-hole-6.3/advanced/Templates/logrotate pi-hole-6.3.cust/advanced/Te
 +/run/log/pihole/pihole.log {
      # su #
      daily
-     copytruncate
-@@ -9,7 +9,7 @@
-     nomail
+     create 640 pihole pihole
+@@ -13,7 +13,7 @@
  }
- 
+
+ # FTL.log and webserver.log are opened and closed for each line, therefore no postrotate is needed
 -/var/log/pihole/FTL.log {
 +/run/log/pihole/FTL.log {
      # su #
      weekly
-     copytruncate
-@@ -20,7 +20,7 @@
+     create 640 pihole pihole
+@@ -24,7 +24,7 @@
      nomail
  }
- 
+
 -/var/log/pihole/webserver.log {
 +/run/log/pihole/webserver.log {
      # su #
      weekly
-     copytruncate
+     create 640 pihole pihole
 diff -uprN pi-hole-6.3/advanced/Templates/pihole.sudo pi-hole-6.3.cust/advanced/Templates/pihole.sudo
 --- pi-hole-6.3/advanced/Templates/pihole.sudo	1970-01-01 01:00:00.000000000 +0100
 +++ pi-hole-6.3.cust/advanced/Templates/pihole.sudo	2025-11-27 23:02:14.748944993 +0100