[TikiWiki-commits] [Git][tikiwiki/tiki][master] [FIX][ENH] Url.php: make stricter validation for URL tracker field optional

"Victor Emanouilov \(@kroky\) via TikiWiki-cvs" <[email protected]>
Newsgroups gmane.comp.cms.tiki.cvs
Message-ID <69c26ee795d63_3b13db638915c1@gitlab-sidekiq-low-urgency-cpu-bound-v2-7d7764c54f-vp68w.mail>

Victor Emanouilov pushed to branch master at Tiki Wiki CMS Groupware / Tiki


Commits:
4adf53a4 by Sammy Ndabo at 2026-03-24T10:52:51+00:00
[FIX][ENH] Url.php: make stricter validation for URL tracker field optional
---
* [FIX] trackerfield URL: remove conditional strict validation for wiki syntax feedback display

* [FIX] trackerfield URL: update strict validation option description

* [FIX] trackerfield URL: optimize URL validation error handling

* [FIX][ENH] trackerfield URL: make strict validation optional via trackerfield option, and not global pref

* [FIX] trackerfield URL: move pref trackerfield_url_strict_validation to a proper file for tracker item

* [FIX][ENH] Url.php: make stricter validation for URL tracker field optional

See merge request tikiwiki/tiki!9756

- - - - -


5 changed files:

- lib/core/Tracker/Field/Url.php
- lib/jquery_tiki/tiki-trackers.js
- lib/prefs/trackerfield.php
- lib/test/Core/Tracker/Field/UrlTest.php
- templates/trackerinput/url.tpl


Changes:

=====================================
lib/core/Tracker/Field/Url.php
=====================================
@@ -54,6 +54,17 @@ class Tracker_Field_Url extends \Tracker\Field\AbstractItemField implements \Tra
                             1 => tr('Yes'),
                         ],
                     ],
+                    'strictValidation' => [
+                        'name' => tr('Strict validation'),
+                        'description' => tr('This field expects data that resolves to syntactically valid URLs. Setting this to No disables URL syntax validation at data entry and import.  This will allow you to use currently unsupported data in this field such as raw file paths, but doing so may trigger problems in code that uses this data if it expects valid URLs.  If you set this to No, test the interfaces that use this field in your site thoroughly.'),
+                        'filter' => 'int',
+                        'legacy_index' => 3,
+                        'default' => 1,
+                        'options' => [
+                            0 => tr('No'),
+                            1 => tr('Yes'),
+                        ],
+                    ],
                 ],
             ],
         ];
@@ -125,6 +136,11 @@ class Tracker_Field_Url extends \Tracker\Field\AbstractItemField implements \Tra
             || (str_starts_with($value, '[') && str_ends_with($value, ']'));
     }
 
+    protected function isStrictValidationEnabled(): bool
+    {
+        return (int) $this->getOption('strictValidation') === 1;
+    }
+
     public function isValid($ins_fields_data)
     {
         $fieldId = $this->getFieldId();
@@ -135,6 +151,10 @@ class Tracker_Field_Url extends \Tracker\Field\AbstractItemField implements \Tra
             return true;
         }
 
+        if (! $this->isStrictValidationEnabled()) {
+            return true;
+        }
+
         if (self::isWikiSyntaxLink($trimmed)) {
             $resolvedHref = self::extractParsedWikiLinkData($trimmed)['href'] ?? null;
             if ($resolvedHref === null) {
@@ -161,6 +181,7 @@ class Tracker_Field_Url extends \Tracker\Field\AbstractItemField implements \Tra
     public function renderInput($context = [])
     {
         $templateData = [
+            'strictValidationEnabled' => $this->isStrictValidationEnabled(),
             'wikiSyntaxInfo' => tr('You can also use complete wiki-link syntax: ((PageName)) or [url|text].'),
         ];
 
@@ -257,7 +278,7 @@ class Tracker_Field_Url extends \Tracker\Field\AbstractItemField implements \Tra
             return (bool) preg_match('/^[a-z][a-z0-9+.-]*$/i', $parsed['scheme']) && ! preg_match('/\s/', $url);
         }
 
-        return ! preg_match('/\s/', $url);
+        return false;
     }
 
     protected static function extractWikiLinkTarget(string $value): ?string


=====================================
lib/jquery_tiki/tiki-trackers.js
=====================================
@@ -727,10 +727,18 @@
         let message = '';
 
         if (! isWikiWrapped) {
-            try {
-                new URL(value, window.location.origin);
-            } catch (err) {
-                message = tr('Invalid URL syntax.');
+            const isRelativePath = value.startsWith('/');
+            const hasScheme = /^[a-z][a-z0-9+.-]*:/i.test(value);
+            const hasWhitespace = /\s/.test(value);
+            const INVALID_URL_MESSAGE = tr('Invalid URL syntax');
+            if (hasWhitespace || (! isRelativePath && ! hasScheme)) {
+                message = INVALID_URL_MESSAGE;
+            } else if (hasScheme) {
+                try {
+                    new URL(value);
+                } catch (err) {
+                    message = INVALID_URL_MESSAGE;
+                }
             }
         }
 


=====================================
lib/prefs/trackerfield.php
=====================================
@@ -22,6 +22,5 @@ function prefs_trackerfield_list($partial = false)
             'help' => isset($type['help']) ? urlencode($type['help']) : false,
         ];
     }
-
     return $prefs;
 }


=====================================
lib/test/Core/Tracker/Field/UrlTest.php
=====================================
@@ -47,6 +47,31 @@ class TrackerFieldUrlTest extends \PHPUnit\Framework\TestCase
         ];
     }
 
+    public function testStrictValidationOptionDisabledAllowsInvalidUrlValues(): void
+    {
+        $this->assertTrue($this->invokeIsValid('not a valid url', 0));
+    }
+
+    public function testStrictValidationOptionEnabledRejectsInvalidUrlValues(): void
+    {
+        $this->assertSame(tr('Invalid URL syntax.'), $this->invokeIsValid('not a valid url', 1));
+    }
+
+    public function testStrictValidationDefaultsToEnabled(): void
+    {
+        $this->assertSame(tr('Invalid URL syntax.'), $this->invokeIsValid('not a valid url'));
+    }
+
+    public function testStrictValidationEnabledRejectsWindowsUncPath(): void
+    {
+        $this->assertSame(tr('Invalid URL syntax.'), $this->invokeIsValid('\\\\192.168.1.10\\public\\docs\\file.txt', 1));
+    }
+
+    public function testStrictValidationEnabledRejectsBrokenWikiSyntaxPrefix(): void
+    {
+        $this->assertSame(tr('Invalid URL syntax.'), $this->invokeIsValid('((Test-Link-Parsing', 1));
+    }
+
     private function invokeIsWikiSyntaxLink(string $value): bool
     {
         $method = new \ReflectionMethod(\Tracker_Field_Url::class, 'isWikiSyntaxLink');
@@ -54,4 +79,26 @@ class TrackerFieldUrlTest extends \PHPUnit\Framework\TestCase
 
         return (bool) $method->invoke(null, $value);
     }
+
+    private function invokeIsValid(string $value, ?int $strictValidation = null)
+    {
+        $field = $this->getMockBuilder(\Tracker_Field_Url::class)
+            ->disableOriginalConstructor()
+            ->onlyMethods(['getFieldId', 'getValue', 'getOption'])
+            ->getMock();
+
+        $field->method('getFieldId')->willReturn(1);
+        $field->method('getValue')->willReturn('');
+        $field->method('getOption')->willReturnCallback(function (string $name, $default = null) use ($strictValidation) {
+            if ($name === 'strictValidation') {
+                return $strictValidation ?? 1;
+            }
+
+            return $default;
+        });
+
+        return $field->isValid([
+            1 => ['value' => $value],
+        ]);
+    }
 }


=====================================
templates/trackerinput/url.tpl
=====================================
@@ -1,8 +1,8 @@
 <div{if !empty($field.options_map.labelasplaceholder)} class="input-group"{/if}>
     <input type="text" class="form-control{if !empty($field.options_map.labelasplaceholder)} labelasplaceholder{/if}"
            name="{$field.ins_id}" id="{$field.ins_id}" value="{$field.value|escape}" size="60"
-           data-url-wiki-wrapper-validation-input=""
-           data-url-wiki-wrapper-feedback-id="{$field.ins_id}_wikiSyntaxLive"
+           {if $data.strictValidationEnabled}data-url-wiki-wrapper-validation-input=""
+           data-url-wiki-wrapper-feedback-id="{$field.ins_id}_wikiSyntaxLive"{/if}
            {if !empty($field.options_map.labelasplaceholder)}placeholder="{$field.name}"{/if}
     >
     {if $field.options_map.labelasplaceholder and $field.isMandatory eq 'y'}



View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/4adf53a4eb790dd4f6a79a9c44415486ac6fe197

-- 
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/4adf53a4eb790dd4f6a79a9c44415486ac6fe197
You're receiving this email because of your account on gitlab.com. Manage all notifications: https://gitlab.com/-/profile/notifications | Help: https://gitlab.com/help

_______________________________________________
TikiWiki-cvs mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tikiwiki-cvs
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.