Skip to content

Maximum execution time exceeded in Parser/Cursor.php when processing large base64 string. #1026

Open
@Duberry

Description

Version(s) affected

2.4.2

Description

When I have a large base64 image in markdown directly adjacent to other text, Cursor.php exceeds execution time at line 180

      if ($this->isMultibyte) {
            return $this->charCache[$this->currentPosition] ??= \mb_substr($this->line, $this->currentPosition, 1, 'UTF-8');
        }

When there is a carriage return separating the base64 image from text the error does not occur.

How to reproduce

Place a large base64 image into markup adjacent to plain markup, try to generate html. Timeout.

This is my markup.![image.png](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABrEAAAJUCAYAAACyig2eAAAgAElEQVR4XuydB2AUZdrH/9uSQCD03kFUioIgUoRTBAEVBXvXs9x3nufZ61nA3vvZe0exgIqAHUUEqdJ7E6SEDiF98z3POzOb2c1udhOWGOA/3xeT7M68885v3nAwv/......................

I have not been able to determine the exact length of base64 string required to cause the issue. It's large, but less than 1Mb.

Possible solution

Cache the string if it's multibyte.....

  public function __construct(string $line)
    {
        if (! \mb_check_encoding($line, 'UTF-8')) {
            throw new UnexpectedEncodingException('Unexpected encoding - UTF-8 or ASCII was expected');
        }
    
        $this->line            = $line;
        $this->length          = \mb_strlen($line, 'UTF-8') ?: 0;
        $this->isMultibyte     = $this->length !== \strlen($line);
        $this->lastTabPosition = $this->isMultibyte ? \mb_strrpos($line, "\t", 0, 'UTF-8') : \strrpos($line, "\t");
    
        // Cache the entire string if it's multibyte for faster access
        if ($this->isMultibyte) {
            $this->charCache = \preg_split('//u', $line, -1, PREG_SPLIT_NO_EMPTY);
        }
    }
public function getCurrentCharacter(): ?string
    {
        if ($this->currentPosition >= $this->length) {
            return null;
        }
    
        if ($this->isMultibyte) {
            return $this->charCache[$this->currentPosition] ?? null;
        }
    
        return $this->line[$this->currentPosition];
    }

Additional context

No response

Did this project help you today? Did it make you happy in any way?

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions