diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a7e0e9..1aeb49d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,14 +4,14 @@ This project uses [**Break Versioning**](https://www.taoensso.com/break-versioni # `v3.5.0-RC1` (2024-10-28) -- 📦 **Dependency**: available [on Clojars](https://clojars.org/com.taoensso/nippy/versions/3.5.0-RC1) +- **Dependency**: [on Clojars](https://clojars.org/com.taoensso/nippy/versions/3.5.0-RC1) - **Versioning**: [Break Versioning](https://www.taoensso.com/break-versioning) This is a **non-breaking maintenance release** that updates dependencies and includes read support for more native array types to be introduced in a future v3.6 release. It should be safe to update from (at least) all recent versions of Nippy. -| Updating from Nippy | Changes to API? | Changes to [byte output](https://github.com/taoensso/nippy/wiki/2-Operational-considerations#stability-of-byte-output)? | Recommended update sequence [1] +| Updating from Nippy | Changes to API? | Changes to [byte output](https://github.com/taoensso/nippy/wiki/2-Operational-considerations#stability-of-byte-output)? | Rolling update sequence [1] | :-- | :-- | :-- | :-- | `v3.4.2` (2024-05-26) | - | - | - | `v3.4.1` (2024-05-02) | - | - | - @@ -20,7 +20,7 @@ It should be safe to update from (at least) all recent versions of Nippy. | `v3.2.0` (2022-07-18) | - | - | - | `v3.1.3` (2022-06-23) | - | - | - -> [1] Relevant only when introducing support for new types, to help with rolling updates +> [1] Relevant only when introducing support for new types, and for users that do rolling updates If updating from older versions of Nippy, please see the relevant release notes. @@ -36,14 +36,14 @@ As always: # `v3.4.2` (2024-05-26) -> **Dep**: Nippy is [on Clojars](https://clojars.org/com.taoensso/nippy/versions/3.4.2). -> **Versioning**: Nippy uses [Break Versioning](https://www.taoensso.com/break-versioning). +- **Dependency**: [on Clojars](https://clojars.org/com.taoensso/nippy/versions/3.4.2) +- **Versioning**: [Break Versioning](https://www.taoensso.com/break-versioning) ⚠️ This release addresses a [**security vulnerability**](https://github.com/taoensso/nippy/security/advisories/GHSA-vw78-267v-588h) in Nippy's upstream compression library and is **recommended for all existing users**. It should be a **straight-forward and non-breaking update** for almost everyone: -| Updating from Nippy | Changes to API? | Changes to [byte output](https://github.com/taoensso/nippy/wiki/2-Operational-considerations#stability-of-byte-output)? | Recommended update sequence [1] +| Updating from Nippy | Changes to API? | Changes to [byte output](https://github.com/taoensso/nippy/wiki/2-Operational-considerations#stability-of-byte-output)? | Rolling update sequence [1] | :-- | :-- | :-- | :-- | `v3.4.1` (2024-05-02) | - | - | - | `v3.4.0` (2024-04-30) | - | Yes | - @@ -51,7 +51,7 @@ It should be a **straight-forward and non-breaking update** for almost everyone: | `v3.2.0` (2022-07-18) | - | - | - | `v3.1.3` (2022-06-23) | - | - | - -> [1] Relevant only when introducing support for new types, to help with rolling updates +> [1] Relevant only when introducing support for new types, and for users that do rolling updates If updating from older versions of Nippy, please see the relevant release notes. diff --git a/README.md b/README.md index 2c24596..3c955c2 100644 --- a/README.md +++ b/README.md @@ -118,8 +118,8 @@ Licensed under [EPL 1.0](LICENSE.txt) (same as Clojure). -[Codox docs]: https://taoensso.github.io/nippy/ -[cljdoc docs]: https://cljdoc.org/d/com.taoensso/nippy/ +[Codox docs]: https://taoensso.github.io/nippy/ +[cljdoc docs]: https://cljdoc.org/d/com.taoensso/nippy/CURRENT/api/taoensso.nippy [Clojars SVG]: https://img.shields.io/clojars/v/com.taoensso/nippy.svg [Clojars URL]: https://clojars.org/com.taoensso/nippy diff --git a/project.clj b/project.clj index e019b49..95e5026 100644 --- a/project.clj +++ b/project.clj @@ -18,7 +18,7 @@ :profiles {;; :default [:base :system :user :provided :dev] :provided {:dependencies [[org.clojure/clojure "1.11.3"]]} - :c1.12 {:dependencies [[org.clojure/clojure "1.12.0-alpha12"]]} + :c1.12 {:dependencies [[org.clojure/clojure "1.12.0"]]} :c1.11 {:dependencies [[org.clojure/clojure "1.11.3"]]} :c1.10 {:dependencies [[org.clojure/clojure "1.10.1"]]} :c1.9 {:dependencies [[org.clojure/clojure "1.9.0"]]} diff --git a/src/taoensso/nippy.clj b/src/taoensso/nippy.clj index b74ef6c..81b7755 100644 --- a/src/taoensso/nippy.clj +++ b/src/taoensso/nippy.clj @@ -440,13 +440,13 @@ ;; Unfortunately quite a bit of complexity to do this safely (def default-freeze-serializable-allowlist - "Allows *any* class-name to be frozen using Java's `Serializable` interface. + "Allows *any* class name to be frozen using Java's `Serializable` interface. This is generally safe since RCE risk is present only when thawing. See also `*freeze-serializable-allowlist*`." #{"*"}) (def default-thaw-serializable-allowlist - "A set of common safe class-names to allow to be frozen using Java's + "A set of common safe class names to allow to be frozen using Java's `Serializable` interface. PRs welcome for additions. See also `*thaw-serializable-allowlist*`." #{"[I" "[F" "[Z" "[B" "[C" "[D" "[S" "[J" @@ -513,10 +513,10 @@ Example allowlist values: - `(fn allow-class? [class-name] true)` ; Arbitrary predicate fn - - `#{\"java.lang.Throwable\", \"clojure.lang.*\"}` ; Set of class-names + - `#{\"java.lang.Throwable\", \"clojure.lang.*\"}` ; Set of class names - `\"allow-and-record\"` ; Special value, see [2] - Note that class-names in sets may contain \"*\" wildcards. + Note that class names in sets may contain \"*\" wildcards. Default allowlist values are: - default-freeze-serializable-allowlist ; `{\"*\"}` => allow any class @@ -1352,7 +1352,7 @@ id-byte-array-md (read-bytes in (read-md-count in)) id-byte-array-lg (read-bytes in (read-lg-count in))))) -(defmacro ^:private read-array [in thaw-type array array-type] +(defmacro ^:private read-array [in thaw-type array-type array] (let [thawed-sym (with-meta 'thawed-sym {:tag thaw-type}) array-sym (with-meta 'array-sym {:tag array-type})] `(let [~array-sym ~array] @@ -1607,14 +1607,14 @@ id-byte-array-md (read-bytes in (read-md-count in)) id-byte-array-lg (read-bytes in (read-lg-count in)) - id-long-array-lg (read-array in long (long-array (read-lg-count in)) "[J") - id-int-array-lg (read-array in int (int-array (read-lg-count in)) "[I") + id-long-array-lg (read-array in long "[J" (long-array (read-lg-count in))) + id-int-array-lg (read-array in int "[I" (int-array (read-lg-count in))) - id-double-array-lg (read-array in double (double-array (read-lg-count in)) "[D") - id-float-array-lg (read-array in float (float-array (read-lg-count in)) "[F") + id-double-array-lg (read-array in double "[D" (double-array (read-lg-count in))) + id-float-array-lg (read-array in float "[F" (float-array (read-lg-count in))) - id-string-array-lg (read-array in String (make-array String (read-lg-count in)) "[Ljava.lang.String;") - id-object-array-lg (read-array in Object (object-array (read-lg-count in)) "[Ljava.lang.Object;") + id-string-array-lg (read-array in String "[Ljava.lang.String;" (make-array String (read-lg-count in))) + id-object-array-lg (read-array in Object "[Ljava.lang.Object;" (object-array (read-lg-count in))) id-str-0 "" id-str-sm* (read-str in (read-sm-count* in)) diff --git a/src/taoensso/nippy/impl.clj b/src/taoensso/nippy/impl.clj index 1b8b248..014c288 100644 --- a/src/taoensso/nippy/impl.clj +++ b/src/taoensso/nippy/impl.clj @@ -151,6 +151,29 @@ See that function's docstring for more info." [] (trim nmax (state_)))) +(comment + (count (get-recorded-serializable-classes)) + (enc/reduce-n + (fn [_ n] (allow-and-record-any-serializable-class-unsafe (str n))) + nil 0 1e5)) + +(let [compile + (enc/fmemoize + (fn [x] + (if (allow-and-record? x) + allow-and-record-any-serializable-class-unsafe + (enc/name-filter x)))) + + fn? fn? + conform? + (fn [x cn] + (if (fn? x) + (x cn) ; Intentionally uncached, can be handy + ((compile x) cn)))] + + (defn serializable-allowed? [allow-list class-name] + (conform? allow-list class-name))) + ;;;; Release targeting (comment @@ -247,28 +270,3 @@ [min-release] (target>= min-release))) (comment (macroexpand '(target-release>= 340))) - -;;; - -(comment - (count (get-recorded-serializable-classes)) - (enc/reduce-n - (fn [_ n] (allow-and-record-any-serializable-class-unsafe (str n))) - nil 0 1e5)) - -(let [compile - (enc/fmemoize - (fn [x] - (if (allow-and-record? x) - allow-and-record-any-serializable-class-unsafe - (enc/name-filter x)))) - - fn? fn? - conform? - (fn [x cn] - (if (fn? x) - (x cn) ; Intentionally uncached, can be handy - ((compile x) cn)))] - - (defn serializable-allowed? [allow-list class-name] - (conform? allow-list class-name)))