Project

General

Profile

Actions

Bug #87641

closed

Increase StaticRangeMapper max range or make it configurable

Added by Christian Stern almost 6 years ago. Updated 5 months ago.

Status:
Rejected
Priority:
Must have
Assignee:
-
Category:
Site Handling, Site Sets & Routing
Start date:
2019-02-04
Due date:
% Done:

0%

Estimated time:
TYPO3 Version:
9
PHP Version:
7.2
Tags:
Complexity:
easy
Is Regression:
Sprint Focus:

Description

I guess there are more projects than ours that deals with more than 100k news or records that needs to get paginated. When using f:widget.paginate and nice routes we do not want to use 100 elements per page because the amount of maximum pages is limited.

This part limits the amount of max pages inside pagination. Is there a special reason for the amount of 1000?

 protected function buildRange(): array
    {
        $range = array_map('strval', range($this->start, $this->end));
        if (count($range) > 1000) {
            throw new \LengthException(
                'Range is larger than 1000 items',
                1537696771
            );
        }

For exmaple routeconfig used for pagination of EXT:news

routeEnhancers:
  NewsPlugin:
    type: Extbase
    limitToPages: 
      - 1337
      - 13370
    extension: News
    plugin: Pi1
    routes:
      - { routePath: '/{page}', _controller: 'News::list', _arguments: {'page': '@widget_0/currentPage'} }
      - { routePath: '/{news_title}', _controller: 'News::detail', _arguments: {'news_title': 'news'} }
    defaultController: 'News::list'
    requirements:
      page: '\d+'
    defaults:
      page: '0'
    aspects:
      page:
        type: StaticRangeMapper
        start: '1'
        end: '1000'
      news_title:
        type: PersistedPatternMapper
        tableName: tx_news_domain_model_news
        routeFieldPattern: '^(?P<path_segment>.+)-(?P<uid>\d+)$'
        routeFieldResult: '{path_segment}-{uid}'
Actions #1

Updated by Stefan Froemken over 5 years ago

They convert the range into an array and yes...there is a limitation of max array elements. I have tried it with a timestamp in range:

Start: 1000000000
End: 99999999999

Which results in:

Warning: range(): The supplied range exceeds the maximum array size: start=1000000000 end=99999999999 in /Users/froemken/htdocs/test.test/temp.php on line 2

I would prefer to remove this array range strval thing.

Stefan

Actions #2

Updated by Guido Schmechel over 5 years ago

The reason is described in the functions doc:
"The amount of items is limited to 1000 in order to avoid brute-force scenarios and the risk of cache-flooding."

+1 for removing the complete range construct. If you have, e.g. given a range from 4000 to 6000 for postals you haven't got a chance to define this.

Maybe we can change the exception to a log entry (warning)?

Actions #3

Updated by Oliver Hader over 5 years ago

Exactly, the range limitation has been added in order to avoid brute force attacks which lead to many cache entries - the StaticRangeMapper is just mitigating that to 1000, PageRouter has a similar maximum on StaticMappableAspectInterface implementations set to 10000 (for all affected mappers/aspects).

This has to been seen as alternative to know cHash which creates a signature over all arbitrary parameters in order to make the request unique and valid - thus, verification if the requested resource really exists (and triggers a new cache entry) is the primary goal here.

This could be achieved by using an additional mapper/aspect which could guarantee that, e.g.

  • database lookup wether a record with a given uid exists - SELECT COUNT(uid) FROM <table> WHERE uid=<parameter> (must exist) - having 123
  • database lookup wether some date representation exists - SELECT COUNT(uid) FROM <table> WHERE DATE_FORMAT(tstamp, '%Y-%m')=<parameter> (must exist) - having 2019-03

An alternative would be a mapper/aspect that is storing valid URLs in the database, like RealURL did - however that also had some side-effects on cHash and would not have worked having empty "caches" (URL not generated yet).

In general new implementations depend on their actual use case (e.g. "date and month filter", "color filter", "combination of categories", "alphabetical prefix - titles starting with 'A'", ...).

Actions #4

Updated by Oliver Hader over 5 years ago

Stefan Froemken wrote:

They convert the range into an array and yes...there is a limitation of max array elements. I have tried it with a timestamp in range:

Start: 1000000000
End: 99999999999

Which results in:

Warning: range(): The supplied range exceeds the maximum array size: start=1000000000 end=99999999999 in /Users/froemken/htdocs/test.test/temp.php on line 2

I would prefer to remove this array range strval thing.

Why and what is your use case? How is the timestamp used in your scenario?

Actions #5

Updated by Oliver Hader over 5 years ago

I guess there are more projects than ours that deals with more than 100k news or records that needs to get paginated. When using f:widget.paginate and nice routes we do not want to use 100 elements per page because the amount of maximum pages is limited.

For this scenario the "valid values" would be in the range of [0; count(news) % page-size] where the news amount is dynamic (adding new records) and page-size is configured in TypoScript (but could be duplicated to route configuration in case it would be the same for all news plugins on that installation).

Actions #6

Updated by Benni Mack over 5 years ago

  • Target version changed from next-patchlevel to Candidate for patchlevel
Actions #7

Updated by Markus Pircher over 4 years ago

For this case i created my own StaticNumberRangeMapper for only numeric range and do not need an array

Actions #8

Updated by Bernhard Berger over 3 years ago

This hardcoded limit is very annoying and makes it impossible to generate URLs for more than 25 pages in my news archive module..

Actions #9

Updated by Jan Kornblum almost 2 years ago

+ 1 for making the range constraint optional.

Actions #10

Updated by Stefanos Karasavvidis about 1 year ago

Markus Pircher wrote in #note-7:

For this case i created my own StaticNumberRangeMapper for only numeric range and do not need an array

Just hit this issue. I have ~20000 posts, with 15 items per post. Results in over 1000 pages. Really annoying...

@Markus Pircher is your StaticNumberRangeMapper public?

Actions #11

Updated by Georg Ringer 5 months ago

just being curious:

20000 posts, with 15 items per post

how do you solve this from UX side? no user will click through 1000 pages

Actions #12

Updated by Stefanos Karasavvidis 5 months ago

Georg Ringer wrote in #note-11:

just being curious:

20000 posts, with 15 items per post

how do you solve this from UX side? no user will click through 1000 pages

indeed, noone will click through 1000 pages.

I do have a detailed search form.
Some people change the url and set a page number (I do this regularly).
And if I ever find the time, I plan to change the paging ui to have a "+10 pages" button instead of just the "next page".

I can not delete the posts. There has to be some kind of "browse through all posts" functionality. For now, I just changed to more posts per page, but I expect to hit the same problem sometimes in the next 2 years.

Actions #13

Updated by Georg Ringer 5 months ago

  • Status changed from New to Rejected

hey! I am closing this issue because core really tries to provide a secure featureset. as mentioned already, no user will click through hundreds of pages and of course it is also still possible to either have no mapping for the pagination or use a custom mapper.

if you don't agree, feel free to contact me via slack!

Actions #14

Updated by Jan Kornblum 5 months ago

Please reopen. I‘ve sent you my arguments via Slack…

Actions

Also available in: Atom PDF