Skip to content

Commit

Permalink
Ensure all keywords are stringified by java-util-hashmappify-vals (#68)
Browse files Browse the repository at this point in the history
* Ensure all keywords are stringified by java-util-hashmappify-vals

Change java-util-hashmappify-vals to also change keywords to strings
for lone values nested under a map's direct values.

When postwalk would encounter a non-map value, the value would be
returned as-is.  This means a keyword which would be nested inside
another non-map structure would not be converted to a string.  For
maps, if the keys or values are keywords themselves, it would always
directly convert them into strings, which masked the problem.

This results in weird-looking serialization which exposes the
underlying Java Keyword object, as per #67.

* Simplify java-util-hashmappify-vals function

Instead of doing the map? test twice, do it once, using postwalk.
Postwalk already traverses all objects depth-first, so there's no need
to test for map? again in the inner "f" function.

To preserve existing functionality, use walk on the outer map (or
whatever object) to prevent it from being converted to a HashMap.

Add a test for the class of the resulting value and nested values to
ensure the functionality is still as before.
  • Loading branch information
sjamaan authored Nov 28, 2024
1 parent 4e975ac commit 5dca07d
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 9 deletions.
15 changes: 10 additions & 5 deletions src/sentry_clj/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,16 @@
values recursively translated into java.util.HashMap objects. Based
on walk/stringify-keys."
[m]
(let [f (fn [[k v]]
(let [k (if (keyword? k) (str (symbol k)) k)
v (if (keyword? v) (str (symbol v)) v)]
(if (map? v) [k (HashMap. ^Map v)] [k v])))]
(walk/postwalk (fn [x] (if (map? x) (into {} (map f x)) x)) m)))
;; Only inner maps are converted; use plain "walk" on outer map
(walk/walk
(fn [m]
(walk/postwalk (fn [x] (cond
(map? x) (HashMap. ^Map x)
(keyword? x) (str (symbol x))
:else x))
m))
identity
m))

(defn ^:private map->breadcrumb
"Converts a map into a Breadcrumb."
Expand Down
16 changes: 12 additions & 4 deletions test/sentry_clj/core_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
[io.sentry Breadcrumb EventProcessor Instrumenter JsonSerializer SentryLevel SentryOptions]
[io.sentry.protocol Request User]
[java.io StringWriter]
[java.util Date UUID]))
[java.util Date HashMap UUID]))

(defexpect keyword->level-test
(expecting
Expand All @@ -22,11 +22,19 @@
(expecting
"everything is a string"
(expect {"a" "b"} (#'sut/java-util-hashmappify-vals {:a :b}))
(expect {"a" "b" {"c" "d"} (#'sut/java-util-hashmappify-vals {:a {:b {:c :d}}})})
(expect {"var1" "val1" "var2" {"a" {"b" {"c" {"d" {"e" "f"} "g" "h"}}}}} (#'sut/java-util-hashmappify-vals {:var1 "val1" :var2 {:a {:b {:c {:d {:e :f} :g :h}}}}})))
(expecting "nested maps are visited and turned into hashmaps"
(let [result (#'sut/java-util-hashmappify-vals {:a {:b {:c :d}}})]
(expect {"a" {"b" {"c" "d"}}} result)
(expect clojure.lang.PersistentArrayMap (.getClass result)) ; Outer map is _not_ converted
(expect HashMap (.getClass (get result "a")))
(expect HashMap (.getClass (get-in result ["a" "b"])))))
(expect {"var1" "val1" "var2" {"a" {"b" {"c" {["d" 1] {"e" ["f"]} "g" "h"}}}}} (#'sut/java-util-hashmappify-vals {:var1 "val1" :var2 {:a {:b {:c {[:d 1] {:e [:f]} :g :h}}}}})))
(expecting
"keyword namespaces are preserved"
(expect {"foo/qux" "some/value" "bar/qux" "another/value"} (#'sut/java-util-hashmappify-vals {:foo/qux :some/value :bar/qux :another/value}))))
(expect {"foo/qux" "some/value" "bar/qux" "another/value"} (#'sut/java-util-hashmappify-vals {:foo/qux :some/value :bar/qux :another/value})))
(expecting
"nested arrays containing keywords are stringified"
(expect ["foo/qux" ["some/value" "bar/qux"] [["another/value"]]] (#'sut/java-util-hashmappify-vals [:foo/qux [:some/value :bar/qux] [[:another/value]]]))))

(def event
{:event-id (UUID/fromString "4c4fbea9-57a7-4c99-808d-2284306e6c98")
Expand Down

0 comments on commit 5dca07d

Please sign in to comment.