Tech Tip: Utility Method to Decode URLs
PRODUCT: 4D | VERSION: 21 | PLATFORM: Mac & Win
Published On: March 2, 2026
This utility method provides a manual implementation of URL decoding in 4D, as no native command exists. It processes an encoded string by replacing %XX hexadecimal sequences with their corresponding characters, converting + to spaces, and preserving invalid or incomplete sequences as-is. UTF-8 multi-byte characters are supported through byte-level assembly in a BLOB, ensuring accurate reconstruction.
Test examples:
| #DECLARE($encoded :Text) -> $result :Text var $pos :Integer var $len :Integer var $char :Text var $hex :Text var $code :Integer var $blob :Blob SET BLOB SIZE($blob; 0) $len := Length($encoded) $pos := 1 While ($pos <= $len) $char := $encoded[[$pos]] Case of : ($char = "+") SET BLOB SIZE($blob; BLOB size($blob) + 1; 0x0020) : ($char = "%") If ($pos + 2 <= $len) $hex := $encoded[[$pos + 1]] + $encoded[[$pos + 2]] If (Match regex("^[0-9a-fA-F]{2}$"; $hex; 1)) $code := Num($hex; 16) SET BLOB SIZE($blob; BLOB size($blob) + 1; $code) $pos := $pos + 2 Else SET BLOB SIZE($blob; BLOB size($blob) + 1; 0x0025) End if Else SET BLOB SIZE($blob; BLOB size($blob) + 1; 0x0025) End if Else SET BLOB SIZE($blob; BLOB size($blob) + 1; Character code($char)) End case $pos := $pos + 1 End while $result := BLOB to text($blob; UTF8 text without length) return $result |
Test examples:
| //example:1 UTF-8 encoded characters: var $encoded; $decoded; $expected : Text var $ok : Boolean $encoded:="q=Caf%C3%A9+Paris+%F0%9F%8C%B6" $decoded:=URL_DECODE($encoded) $expected:="q=Café Paris 🌶" $ok:=($decoded=$expected) ALERT(Choose($ok; "OK UTF-8"; "FAIL UTF-8")+" => "+$decoded) //example 2: Normal everyday URL parameters $encoded:="name=John+Doe&email=john.doe%40example.com&message=Hello+there%21" $decoded:=URL_DECODE($encoded) $expected:="name=John Doe&email=john.doe@example.com&message=Hello there!" $ok:=($decoded=$expected) ALERT(Choose($ok; "OK"; "FAIL")+" => "+$decoded) //exampe 3: Malformed / malicious input $encoded:="%20SELECT%20*%20FROM%20users--" $decoded:=URL_DECODE($encoded) $expected:=" SELECT * FROM users--" $ok:=($decoded=$expected) ALERT(Choose($ok; "OK SQL-like"; "FAIL SQL")+" => "+$decoded) $encoded:="payload=%3Cscript%3Ealert(1)%3C/script%3E" $decoded:=URL_DECODE($encoded) $expected:="payload=<script>alert(1)</script>" $ok:=($decoded=$expected) ALERT(Choose($ok; "OK XSS"; "FAIL XSS")+" => "+$decoded) |