api: O(n) folder listing pagination + defensive page cap

ober

35819acef9de8cc998396942b71a4f47ca85e9f1

diff --git a/protonstorage/drive/api.ss b/protonstorage/drive/api.ss
index e113f6f..93d9a93 100644
--- a/protonstorage/drive/api.ss
+++ b/protonstorage/drive/api.ss
@@ -48,6 +48,9 @@
 
   (define default-proton-drive-api-base-url "https://drive-api.proton.me")
   (define proton-drive-max-folder-page-size 150)
+  ;; Defensive bound so a server that never returns an empty page cannot
+  ;; drive an unbounded pagination loop.
+  (define proton-drive-max-folder-pages 100000)
 
   (def (json-object . fields)
     (let ([ht (make-hash-table)])
@@ -331,17 +334,19 @@
 
   (def (proton-drive-list-children session share-id link-id)
     (let loop ([page 0] [acc '()])
-      (let ([links
-             (proton-drive-list-children-page
-               session
-               share-id
-               link-id
-               page
-               proton-drive-max-folder-page-size
-               #t)])
-        (if (null? links)
-            acc
-            (loop (+ page 1) (append acc links))))))
+      (if (>= page proton-drive-max-folder-pages)
+          (reverse acc)
+          (let ([links
+                 (proton-drive-list-children-page
+                   session
+                   share-id
+                   link-id
+                   page
+                   proton-drive-max-folder-page-size
+                   #t)])
+            (if (null? links)
+                (reverse acc)
+                (loop (+ page 1) (append (reverse links) acc)))))))
 
   (def (proton-drive-check-available-hashes session share-id link-id hashes)
     (drive-session-post