From cce183e7ce2c14b221e59f15bdf0c9cfea73ecd1 Mon Sep 17 00:00:00 2001 From: John Swanson <john.swanson@metabase.com> Date: Wed, 3 Apr 2024 13:30:10 -0500 Subject: [PATCH] Don't throw when sent non-int `limit`/`offset` (#40821) This middleware shouldn't throw exceptions when `limit` or `offset` query parametesr aren't integers. --- .../server/middleware/offset_paging.clj | 41 +++++-------------- .../server/middleware/offset_paging_test.clj | 17 ++++---- 2 files changed, 18 insertions(+), 40 deletions(-) diff --git a/src/metabase/server/middleware/offset_paging.clj b/src/metabase/server/middleware/offset_paging.clj index d08fb532105..441196ce7e2 100644 --- a/src/metabase/server/middleware/offset_paging.clj +++ b/src/metabase/server/middleware/offset_paging.clj @@ -1,8 +1,6 @@ (ns metabase.server.middleware.offset-paging (:require - [medley.core :as m] - [metabase.server.middleware.security :as mw.security] - [metabase.util.i18n :refer [tru]])) + [medley.core :as m])) (set! *warn-on-reflection* true) @@ -17,15 +15,11 @@ Automatically generated by a handler in offset-paging middleware." false) -(defn- offset-paged? [{{:strs [page limit offset]} :query-params}] - (or page limit offset)) - (defn- parse-paging-params [{{:strs [limit offset]} :query-params}] - (let [limit (or (some-> limit Integer/parseUnsignedInt) - default-limit) - offset (or (some-> offset Integer/parseUnsignedInt) - default-offset)] - {:limit limit, :offset offset})) + (let [limit (some-> limit parse-long) + offset (some-> offset parse-long)] + (when (or limit offset) + {:limit (or limit default-limit), :offset (or offset default-offset)}))) (defn- with-paging-params [request {:keys [limit offset]}] (-> request @@ -41,22 +35,9 @@ (it isn't stable with respect to underlying data changing, though)" [handler] (fn [request respond raise] - (if-not (offset-paged? request) - (handler request respond raise) - (let [paging-params (try - (parse-paging-params request) - (catch Throwable e - e))] - (if (instance? Throwable paging-params) - (let [^Throwable e paging-params] - (respond {:status 400 - :headers (mw.security/security-headers) - :body (merge - (Throwable->map e) - {:message (tru "Error parsing paging parameters: {0}" (ex-message e))})})) - (let [{:keys [limit offset]} paging-params - request (with-paging-params request paging-params)] - (binding [*limit* limit - *offset* offset - *paged?* true] - (handler request respond raise)))))))) + (if-let [{:keys [limit offset] :as paging-params} (parse-paging-params request)] + (binding [*limit* limit + *offset* offset + *paged?* true] + (handler (with-paging-params request paging-params) respond raise)) + (handler request respond raise)))) diff --git a/test/metabase/server/middleware/offset_paging_test.clj b/test/metabase/server/middleware/offset_paging_test.clj index a2506835342..11690076e1a 100644 --- a/test/metabase/server/middleware/offset_paging_test.clj +++ b/test/metabase/server/middleware/offset_paging_test.clj @@ -5,8 +5,6 @@ [clojure.test :refer :all] [metabase.server.handler :as handler] [metabase.server.middleware.offset-paging :as mw.offset-paging] - [metabase.server.middleware.security :as mw.security] - [metabase.test :as mt] [ring.mock.request :as ring.mock] [ring.util.response :as response]) (:import @@ -48,11 +46,10 @@ "paged?" true "params" {"whatever" "true"}}} (read-response (handler (ring.mock/request :get "/" {:offset "200", :limit "100", :whatever "true"})))))) - ;; set the system clock here so this doesn't flake if we cross the second boundary between evaluating the expected - ;; form and the actual form - (mt/with-clock #t "2023-02-20T15:01:00-08:00[US/Pacific]" - (testing "invalid params" - (is (=? {:status 400 - :headers (mw.security/security-headers) - :body {"message" #"Error parsing paging parameters.*"}} - (read-response (handler (ring.mock/request :get "/" {:offset "abc", :limit "100"})))))))) + (testing "w/ non-numeric paging params, paging is disabled" + (is (=? {:status 200 + :body {"limit" nil + "offset" nil + "paged?" false + "params" {}}} + (read-response (handler (ring.mock/request :get "/" {:offset "foo" :limit "bar"}))))))) -- GitLab