Skip to content

TypeError thrown in DefaultFormRendered::renderBegin() #348

@tvape

Description

@tvape

Version: 3.2.8
PHP: 8.4.15

Bug Description

When you set a formally valid URL e.g. https://www.example.com/?foo as a form action and 'get' as the form method, the null value passed to urldecode() function throws TypeError in DefaultFormRenderer::renderBegin() method because $parts[1] is not set and the script has declare(strict_types=1); set:

TypeError: urldecode(): Argument #1 ($string) must be of type string, null given

public function renderBegin(): string
{
	$this->counter = 0;

	foreach ($this->form->getControls() as $control) {
		$control->setOption('rendered', false);
	}

	if ($this->form->isMethod('get')) {
		$el = clone $this->form->getElementPrototype();
		$el->action = (string) $el->action;
		$query = parse_url($el->action, PHP_URL_QUERY) ?: '';
		$el->action = str_replace("?$query", '', $el->action);
		$s = '';
		foreach (preg_split('#[;&]#', $query, -1, PREG_SPLIT_NO_EMPTY) as $param) {
			$parts = explode('=', $param, 2);
			$name = urldecode($parts[0]);
			$prefix = explode('[', $name, 2)[0];
			if (!isset($this->form[$prefix])) {
				$s .= Html::el('input', ['type' => 'hidden', 'name' => $name, 'value' => urldecode($parts[1])]);
			}
		}

		return $el->startTag() . ($s ? "\n\t" . $this->getWrapper('hidden container')->setHtml($s) : '');

	} else {
		return $this->form->getElementPrototype()->startTag();
	}
}

Steps To Reproduce

$form = new \Nette\Forms\Form();
$form->setAction('https://www.example.com/?foo');
$form->setMethod('get');
echo $form;

Expected Behavior

No exception thrown and parameter 'foo' set as a hidden input with an empty value.

Possible Solution

Solution is simply using null coalescing operator for urldecode($parts[1] ?? '')

$s .= Html::el('input', ['type' => 'hidden', 'name' => $name, 'value' => urldecode($parts[1] ?? '')]);

Metadata

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