From 3e59754a25381fc17608ca9e822cd2284fb0c1bc Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 4 Aug 2026 15:38:22 +0000 Subject: [PATCH] :sparkles: Add optional max-size param to blob decode functions Accept an optional :max-size keyword argument in blob/decode and blob/decode-str. When provided, the uncompressed size declared in the blob header is validated before allocating memory, raising an error if it exceeds the limit. Callers that do not pass :max-size are unaffected. AI-assisted-by: deepseek-v4-pro --- backend/src/app/util/blob.clj | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/backend/src/app/util/blob.clj b/backend/src/app/util/blob.clj index afc71653bc..09df353da1 100644 --- a/backend/src/app/util/blob.clj +++ b/backend/src/app/util/blob.clj @@ -8,6 +8,7 @@ "A generic blob storage encoding. Mainly used for page data, page options and txlog payload storage." (:require + [app.common.exceptions :as ex] [app.common.fressian :as fres] [app.common.transit :as t] [app.config :as cf]) @@ -58,12 +59,18 @@ (.encodeToString (.withoutPadding (Base64/getUrlEncoder)) ^bytes (encode data opts)))) (defn decode - "A function used for decode persisted blobs in the database." - [^bytes data] + "A function used for decode persisted blobs in the database. + Accepts optional keyword arguments: + :max-size — maximum allowed uncompressed size in bytes" + [^bytes data & {:keys [max-size]}] (with-open [bais (ByteArrayInputStream. data) dis (DataInputStream. bais)] (let [version (.readShort dis) ulen (.readInt dis)] + (when (and max-size (> ulen max-size)) + (ex/raise :type :validation + :code :blob-too-large + :hint "blob uncompressed size exceeds limit")) (case version 1 (decode-v1 data ulen) 3 (decode-v3 data ulen) @@ -72,9 +79,10 @@ (throw (ex-info "unsupported version" {:version version})))))) (defn decode-str - "Decode a URL-safe base64 string produced by `encode-str` back to data." - [^String s] - (decode (.decode (Base64/getUrlDecoder) s))) + "Decode a URL-safe base64 string produced by `encode-str` back to data. + Accepts the same optional keyword arguments as `decode`." + [^String s & {:as opts}] + (decode (.decode (Base64/getUrlDecoder) s) opts)) ;; --- IMPL