No Code Attached Yet
avatar bhuvan-somisetty
bhuvan-somisetty
25 Sep 2026

What happened?

When configuring a url form field (UrlField) or validating a field with validate="url" (UrlRule) or filtering with filter="url" (UrlFilter), the relative XML attribute is improperly evaluated as a raw SimpleXMLElement object in boolean expressions instead of being cast to a string or boolean:

  1. In UrlField::getLayoutData() (libraries/src/Form/Field/UrlField.php line 71):
$inputType = $this->element['relative'] ? 'type="text"' : 'type="url"';
  1. In UrlRule::test() (libraries/src/Form/Rule/UrlRule.php line 85):
if ($urlParts === false || !$element['relative']) {
  1. In UrlFilter::filter() (libraries/src/Form/Filter/UrlFilter.php lines 64 & 77):
if (
    ((string) $element['type'] === 'url' && !$protocol && !$element['relative'])
    || ((string) $element['type'] !== 'url' && !$protocol)
) {
    ...
} elseif (!$protocol && $element['relative']) {
    ...
}

In PHP, a non-empty SimpleXMLElement object (such as one representing relative="false") evaluates to true when evaluated directly in a boolean context.

As a result, when relative="false" is explicitly set on a field XML definition:

  • UrlField renders with <input type="text"> instead of <input type="url">.
  • UrlRule allows scheme-less relative paths (e.g. /my-path) to pass validation when they should fail.
  • UrlFilter skips prepending the default external protocol (http://) and instead treats the value as an internal relative URL, prepending Uri::root(true).

Steps to reproduce:

  1. Create a form XML definition with a url field where relative="false":
<field
    name="external_website"
    type="url"
    label="External Website"
    relative="false"
    validate="url"
    filter="url"
/>
  1. Render the field via $form->getInput('external_website') and inspect the generated <input> tag.
  2. Validate a relative URL value (e.g. '/contact-us') via $form->validate(['external_website' => '/contact-us']) or (new \Joomla\CMS\Form\Rule\UrlRule())->test($element, '/contact-us').
  3. Filter a scheme-less value (e.g. 'example.com') via (new \Joomla\CMS\Form\Filter\UrlFilter())->filter($element, 'example.com').

Version

5.4

Expected result

  1. UrlField renders <input type="url" ...> when relative="false" (or when relative is not specified).
  2. UrlRule::test() returns false (validation failure) for relative paths without a scheme (e.g. '/contact-us') when relative="false".
  3. UrlFilter::filter() treats scheme-less inputs as external URLs and prepends http:// when relative="false".

Actual result

  1. UrlField evaluates $this->element['relative'] as truthy and renders <input type="text" ...>.
  2. UrlRule::test() evaluates !$element['relative'] as false, bypassing the missing scheme check and accepting relative URLs as valid.
  3. UrlFilter::filter() enters the elseif (!$protocol && $element['relative']) block and incorrectly prepends the site root path instead of the external protocol.

System Information

  • Joomla 5.4-dev / 6.0-dev
  • PHP 8.1 / 8.2 / 8.3 / 8.4

Additional Comments

In UrlRule.php, other attributes are properly cast before evaluation (e.g. (string) $element['required'] === 'true' and (string) $element['disableXssCheck'] !== 'true').

$relative should be checked consistently, for example:

$relative = isset($element['relative']) && !in_array((string) $element['relative'], ['false', '0', 'off'], true);

or (string) $element['relative'] === 'true' || (string) $element['relative'] === 'relative' || (string) $element['relative'] === '1'.
Additionally, UrlField could benefit from property getter/setter support for $relative in line with other form field classes.

avatar bhuvan-somisetty bhuvan-somisetty - open - 25 Sep 2026
avatar joomla-cms-bot joomla-cms-bot - change - 25 Sep 2026
Labels Added: No Code Attached Yet
avatar joomla-cms-bot joomla-cms-bot - labeled - 25 Sep 2026

Add a Comment

Login with GitHub to post a comment