Skip to content

Fixed pagination bug#2231

Merged
Eric-Wasson merged 1 commit into
devfrom
2208-hashlist-pagination-bug
Jun 18, 2026
Merged

Fixed pagination bug#2231
Eric-Wasson merged 1 commit into
devfrom
2208-hashlist-pagination-bug

Conversation

@Eric-Wasson

@Eric-Wasson Eric-Wasson commented Jun 16, 2026

Copy link
Copy Markdown

Fixes issue #2208

Details:

When the hashlists get ordered on another column than the id (e.g. cracked or name) and the second page gets called, a CORS error happens. This is due to the response including a previously silenced warning:

Warning: Array to string conversion in /var/www/html/src/dba/AbstractModelFactory.php on line 708
{"jsonapi":{"version":"1.1","ext":["https://jsonapi.org/profiles/ethanresnick/cursor-pagination"]},"links":{"self":"http://localhost:8080/api/v2/ui/hashlists?page[size]=5&page[after]=eyJwcmltYXJ5Ijp7ImNyYWNrZWQiOjB9LCJzZWNvbmRhcnkiOnsiaGFzaGxpc3RJZCI6NX19&include=hashType,accessGroup&filter[isArchived__eq]=false&filter[format__nin]=3&sort=cracked","first":"http://localhost:8080/api/v2/ui/hashlists?page[size]=5&include=hashType,accessGroup&filter[isArchived__eq]=false&filter[format__nin]=3&sort=cracked","last":"http://localhost:8080/api/v2/ui/hashlists?page[size]=5&page[before]=eyJwcmltYXJ5Ijp7ImNyYWNrZWQiOjB9LCJzZWNvbmRhcnkiOnsiaGFzaGxpc3RJZCI6N319&include=hashType,accessGroup&filter[isArchived__eq]=false&filter[format__nin]=3&sort=cracked","next":null,"prev":null},"meta":{"page":{"total_elements":6},"Include errors":[]},"data":[]} 

The malformed/incorrectly made SQL query is (see the last part with "Hashlist.format NOT IN ('Array'))"):

SELECT Hashlist.hashlistId AS Hashlist_hashlistId, Hashlist.hashlistName AS Hashlist_hashlistName, Hashlist.format AS Hashlist_format, Hashlist.hashTypeId AS Hashlist_hashTypeId, Hashlist.hashCount AS Hashlist_hashCount, Hashlist.saltSeparator AS Hashlist_saltSeparator, Hashlist.cracked AS Hashlist_cracked, Hashlist.isSecret AS Hashlist_isSecret, Hashlist.hexSalt AS Hashlist_hexSalt, Hashlist.isSalted AS Hashlist_isSalted, Hashlist.accessGroupId AS Hashlist_accessGroupId, Hashlist.notes AS Hashlist_notes, Hashlist.brainId AS Hashlist_brainId, Hashlist.brainFeatures AS Hashlist_brainFeatures, Hashlist.isArchived AS Hashlist_isArchived FROM Hashlist WHERE Hashlist.accessGroupId IN ('1') AND Hashlist.isArchived='0' AND Hashlist.format NOT IN ('3') AND (Hashlist.cracked>'0') OR (Hashlist.cracked='0' AND Hashlist.hashlistId>'5' AND Hashlist.isArchived='0' AND Hashlist.format NOT IN ('Array')) ORDER BY Hashlist.cracked ASC, Hashlist.hashlistId ASC LIMIT 5

This happens because the hashlist.format ContainFilter in the PaginationFilter used to create this query doesn't contain a single int but an int in an array:

["filter"]=>
  array(4) {
    [... omitted ...]
    [3]=>
    object(Hashtopolis\dba\PaginationFilter)#1813 (7) {
      ["key":"Hashtopolis\dba\PaginationFilter":private]=>
      string(7) "cracked"
      ["value":"Hashtopolis\dba\PaginationFilter":private]=>
      int(0)
      ["operator":"Hashtopolis\dba\PaginationFilter":private]=>
      string(1) ">"
      ["tieBreakerKey":"Hashtopolis\dba\PaginationFilter":private]=>
      string(10) "hashlistId"
      ["tieBreakerValue":"Hashtopolis\dba\PaginationFilter":private]=>
      int(5)
      ["filters":"Hashtopolis\dba\PaginationFilter":private]=>
      array(2) {
        [0]=>
        object(Hashtopolis\dba\QueryFilter)#1834 (4) {
          ["key":"Hashtopolis\dba\QueryFilter":private]=>
          string(10) "isArchived"
          ["value":"Hashtopolis\dba\QueryFilter":private]=>
          int(0)
          ["operator":"Hashtopolis\dba\QueryFilter":private]=>
          string(1) "="
          ["overrideFactory":"Hashtopolis\dba\QueryFilter":private]=>
          object(Hashtopolis\dba\models\HashlistFactory)#1841 (0) {
          }
        }
        [1]=>
        object(Hashtopolis\dba\ContainFilter)#1827 (4) {
          ["key":"Hashtopolis\dba\ContainFilter":private]=>
          string(6) "format"
          ["values":"Hashtopolis\dba\ContainFilter":private]=>
          array(1) {
            [0]=>
            int(3)
          }
          ["overrideFactory":"Hashtopolis\dba\ContainFilter":private]=>
          object(Hashtopolis\dba\models\HashlistFactory)#1841 (0) {
          }
          ["inverse":"Hashtopolis\dba\ContainFilter":private]=>
          bool(true)
        }
      }
      ["overrideFactory":"Hashtopolis\dba\PaginationFilter":private]=>
      NULL
    }
  }

This is due to the applyFilters function in the AbstractModelFactory not being able to handle array that are more nested than two levels. I used a recursive function to handle it so it also doesn't happen in other cases with deeper nested arrays.

@s3inlc

s3inlc commented Jun 17, 2026

Copy link
Copy Markdown
Member

As this is a change to the DBA core, can you please write at least one phpunit test which tests such a case?

@Eric-Wasson Eric-Wasson merged commit 105d883 into dev Jun 18, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working server Hashtopolis API/Server related

Development

Successfully merging this pull request may close these issues.

3 participants