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

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

Victor Emanouilov pushed to branch 27.x at Tiki Wiki CMS Groupware / Tiki


Commits:
4f7100d1 by Sammy Ndabo at 2026-03-25T09:41:15+00:00
[BP][FIX][ENH] Url.php: make stricter validation for URL tracker field optional and disabled by default
---
* [BP][FIX] Url.php: update strict validation option to be disabled by default

* [BP][FIX][ENH] Url.php: make stricter validation for URL tracker field optional
---
* [BP][FIX][ENH] Url.php: make stricter validation for URL tracker field optional
---
* [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

(cherry picked from commit 4adf53a4eb790dd4f6a79a9c44415486ac6fe197)

See merge request tikiwiki/tiki!9832

(cherry picked from commit 39e52d892f020d946319b3555b233161112ad33f)

See merge request tikiwiki/tiki!9833

(cherry picked from commit cdc0c1504463ad60418247abf4d2f0d98d0c700c)

See merge request tikiwiki/tiki!9835

- - - - -


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('Validate this URL field with stricter syntax checks. Disable this to preserve legacy values such as relative or Windows/UNC-style paths.'),
+                        'filter' => 'int',
+                        'legacy_index' => 3,
+                        'default' => 0,
+                        'options' => [
+                            0 => tr('No'),
+                            1 => tr('Yes'),
+                        ],
+                    ],
                 ],
             ],
         ];
@@ -123,6 +134,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();
@@ -133,6 +149,10 @@ class Tracker_Field_Url extends \Tracker\Field\AbstractItemField implements \Tra
             return true;
         }
 
+        if (! $this->isStrictValidationEnabled()) {
+            return true;
+        }
+
         if (self::isWikiSyntaxLink($trimmed)) {
             $resolvedHref = self::extractFirstHrefFromParsedWikiLink($trimmed);
             if ($resolvedHref === null) {
@@ -159,6 +179,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].'),
         ];
 
@@ -248,7 +269,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
=====================================
@@ -625,10 +625,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 testStrictValidationDefaultsToDisabled(): void
+    {
+        $this->assertTrue($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 ?? 0;
+            }
+
+            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/4f7100d1113bf11d83dfa6b70538778ad28a2b60

-- 
View it on GitLab: https://gitlab.com/tikiwiki/tiki/-/commit/4f7100d1113bf11d83dfa6b70538778ad28a2b60
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.