auto-quote unusual entities by default

This commit is contained in:
Sean Corfield 2022-08-23 15:41:38 -07:00
parent 7a23ab649e
commit a879a2d8a1
3 changed files with 29 additions and 4 deletions

View file

@ -1,6 +1,7 @@
# Changes
* 2.3.next in progress
* **WIP** Address [#422](https://github.com/seancorfield/honeysql/issues/422) by auto-quoting unusual entity names when `:quoted` (and `:dialect`) are not specified, making HoneySQL more secure by default.
* Address [#419](https://github.com/seancorfield/honeysql/issues/419) by adding `honey.sql.protocols` and `InlineValue` with a `sqlize` function.
* Address [#413](https://github.com/seancorfield/honeysql/issues/413) by flagging a lack of `WHERE` clause for `DELETE`, `DELETE FROM`, and `UPDATE` when `:checking :basic` (or `:checking :strict`).
* Fix [#392](https://github.com/seancorfield/honeysql/issues/392) by adding support for `WITH` / (`NOT`) `MATERIALIZED` -- via PR [#420](https://github.com/seancorfield/honeysql/issues/420) [@robhanlon22](https://github.com/robhanlon22).

View file

@ -210,13 +210,25 @@
(let [col-fn (if (or *quoted* (string? e))
(if *quoted-snake* name-_ name)
name-_)
quote-fn (if (or *quoted* (string? e)) (:quote *dialect*) identity)
col-e (col-fn e)
dialect-q (:quote *dialect* identity)
quote-fn (cond (or *quoted* (string? e))
dialect-q
;; #422: if default quoting and "unusual"
;; characters in entity, then quote it:
(nil? *quoted*)
(fn opt-quote [part]
(if (re-find #"^[A-Za-z0-9_]+$" part)
part
(dialect-q part)))
:else
identity)
parts (if-let [n (when-not (or drop-ns (string? e))
(namespace-_ e))]
[n (col-fn e)]
[n col-e]
(if aliased
[(col-fn e)]
(str/split (col-fn e) #"\.")))
[col-e]
(str/split col-e #"\.")))
entity (str/join "." (map #(cond-> % (not= "*" %) (quote-fn)) parts))
suspicious #";"]
(when-not *allow-suspicious-entities*

View file

@ -936,3 +936,15 @@ ORDER BY id = ? DESC
(is (= ["SELECT `A\"B`"] (sut/format {:select (keyword "A\"B")} {:dialect :mysql})))
(is (= ["SELECT `A``B`"] (sut/format {:select (keyword "A`B")} {:dialect :mysql})))
(is (= ["SELECT \"A\"\"B\""] (sut/format {:select (keyword "A\"B")} {:dialect :oracle}))))
(deftest issue-422-quoting
;; default quote if strange entity:
(is (= ["SELECT A, \"B C\""] (sut/format {:select [:A (keyword "B C")]})))
;; default don't quote normal entity:
(is (= ["SELECT A, B_C"] (sut/format {:select [:A (keyword "B_C")]})))
;; quote all entities when quoting enabled:
(is (= ["SELECT \"A\", \"B C\""] (sut/format {:select [:A (keyword "B C")]}
{:quoted true})))
;; don't quote if quoting disabled (illegal SQL):
(is (= ["SELECT A, B C"] (sut/format {:select [:A (keyword "B C")]}
{:quoted false}))))