Unexpected url validation behaviour

Hello,

I have an url field,

columns: 
  - width: 3/4
    fields:
      link:
        label: External Link
        type: url
        required: true

On localhost, the following url gives no problem when entering it into the field, saving the page, or making it public:

https://flash---art.com/2021/05/kw-digital-with-the-last-museum-a-website-specific-exhibition/#

…but on the staging sever, the same url gives an error only when trying to make the page public which I am not sure is the expected behaviour , I would expect the error to hit me when saving the page, not when making it public:

image

Sooo… what’s going on ?

Thank you

Kirby does not validate page while in draft state, therefore you will only get the error when you publish a page.

As to why it works locally but not on the remote server, I can’t tell.

1 Like

Thank you.

I tested directly the regex in the url function of the V class, and it seems that the triple hyphen in the url makes it invalid (actually anything more than one hyphen in ‘flash—art’)

See here.

So it is working as it should in staging, so I guess the question is why isn’t the validation working localhost ?

Thanks

In my local environment (Mac with Laravel Valet):

$url = 'https://flash---art.com/2021/05/kw-digital-with-the-last-museum-a-website-specific-exhibition/#';

var_dump(V::url($url));

returns false.

But in any case, this this URL exists and only the validator fails, you wouldn’t win much.

Wild, we’ve just run into this exact issue trying to add press coverage from some https://flash---art.com articles. Fails on local and production servers.

require 'kirby/src/Toolkit/V.php';

$url = 'https://flash---art.com/';
$isValid = Kirby\Toolkit\V::url($url);

var_dump($isValid);

As @plagasul mentioned, anything from flash---art URL fails that validation. Changing the link field options from url to custom is an okay band-aid for now, but is there any other workaround for this?

php 8.4, kirby 4.6.1
Thanks

1 Like

Kirby uses a regex pattern to validate URLs, it’s probably not perfect:

	'url' => function ($value): bool {
		// In search for the perfect regular expression: https://mathiasbynens.be/demo/url-regex
		// Added localhost support and removed 127.*.*.* ip restriction
		$regex = '_^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:localhost)|(?:(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)*(?:\.(?:[a-z\x{00a1}-\x{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$_iu';
		return preg_match($regex, $value ?? '') !== 0;
	},

It is in this part

(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-?)*[a-z\x{00a1}-\x{ffff}0-9]+)

where it would have to be changed to

(?:\.(?:[a-z\x{00a1}-\x{ffff}0-9]+-+)*[a-z\x{00a1}-\x{ffff}0-9]+)

to allow multiple hyphens in the domain name

1 Like