Skip to content

Commit 918536d

Browse files
committed
Fix UrlEncode edge cases
1 parent 4685fa9 commit 918536d

File tree

3 files changed

+36
-13
lines changed

3 files changed

+36
-13
lines changed

specs/Specs_WebHelpers.bas

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,10 @@ Public Function Specs() As SpecSuite
194194
' UrlEncode
195195
' --------------------------------------------- '
196196
With Specs.It("should url-encode string (with space as plus and encode unsafe options)")
197-
.Expect(WebHelpers.UrlEncode("$&+,/:;=?@", EncodeUnsafe:=False)).ToEqual "%24%26%2B%2C%2F%3A%3B%3D%3F%40"
197+
.Expect(WebHelpers.UrlEncode("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890$-_.+!*'(),")).ToEqual "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890$-_.+!*'(),"
198+
.Expect(WebHelpers.UrlEncode("&/:;=?@")).ToEqual "%26%2F%3A%3B%3D%3F%40"
198199
.Expect(WebHelpers.UrlEncode(" ""<>#%{}|\^~[]`")).ToEqual "%20%22%3C%3E%23%25%7B%7D%7C%5C%5E%7E%5B%5D%60"
199-
.Expect(WebHelpers.UrlEncode("A + B")).ToEqual "A%20%2B%20B"
200+
.Expect(WebHelpers.UrlEncode("A + B")).ToEqual "A%20+%20B"
200201
.Expect(WebHelpers.UrlEncode("A + B", SpaceAsPlus:=True)).ToEqual "A+%2B+B"
201202
End With
202203

specs/Specs_WebRequest.bas

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,9 @@ Public Function Specs() As SpecSuite
228228
Set Request = New WebRequest
229229

230230
Request.Resource = "{segment}"
231-
Request.AddUrlSegment "segment", "$&+,/:;=?@"
231+
Request.AddUrlSegment "segment", "&/:;=?@"
232232

233-
.Expect(Request.FormattedResource).ToEqual "%24%26%2B%2C%2F%3A%3B%3D%3F%40"
233+
.Expect(Request.FormattedResource).ToEqual "%26%2F%3A%3B%3D%3F%40"
234234
End With
235235

236236
With Specs.It("FormattedResource should include querystring parameters")
@@ -266,9 +266,9 @@ Public Function Specs() As SpecSuite
266266
With Specs.It("FormattedResource should URL encode querystring")
267267
Set Request = New WebRequest
268268

269-
Request.AddQuerystringParam "A B", "$&+,/:;=?@"
269+
Request.AddQuerystringParam "A B", "&/:;=?@"
270270

271-
.Expect(Request.FormattedResource).ToEqual "?A+B=%24%26%2B%2C%2F%3A%3B%3D%3F%40"
271+
.Expect(Request.FormattedResource).ToEqual "?A+B=%26%2F%3A%3B%3D%3F%40"
272272
End With
273273

274274
' UserAgent

src/WebHelpers.bas

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -812,7 +812,14 @@ End Function
812812

813813
''
814814
' Encode string for URLs
815-
' Reference: http://www.blooberry.com/indexdot/html/topics/urlencoding.htm
815+
' Reference:
816+
' - http://www.blooberry.com/indexdot/html/topics/urlencoding.htm
817+
' - https://www.ietf.org/rfc/rfc1738.txt
818+
'
819+
' From RFC 1738:
820+
' > Thus, only alphanumerics, the special characters "$-_.+!*'(),", and
821+
' reserved characters used for their reserved purposes may be used
822+
' unencoded within a URL.
816823
'
817824
' @method UrlEncode
818825
' @param {Variant} Text Text to encode
@@ -850,19 +857,34 @@ Public Function UrlEncode(Text As Variant, Optional SpaceAsPlus As Boolean = Fal
850857
web_CharCode = VBA.Asc(web_Char)
851858

852859
Select Case web_CharCode
853-
Case 97 To 122, 65 To 90, 48 To 57, 45, 46, 95, 126
860+
Case 33, 36, 39, 40, 41, 42, 44, 45, 46, 48 To 57, 65 To 90, 95, 97 To 122
861+
' Unencoded:
862+
' alphanumeric - 48-57, 65-90, 97-122
863+
' $-_.!*'(), - 33, 36, 39, 40, 41, 42, 43, 44, 45, 46, 95
854864
web_Result(web_i) = web_Char
855-
Case 32
856-
web_Result(web_i) = web_Space
857-
Case 0 To 15
858-
web_Result(web_i) = "%0" & VBA.Hex(web_CharCode)
859865
Case 34, 35, 37, 60, 62, 91 To 94, 96, 123 To 126
860-
' Unsafe characters
866+
' Unsafe characters: <>"#%{}|\^~[]`
867+
If EncodeUnsafe Then
868+
web_Result(web_i) = "%" & VBA.Hex(web_CharCode)
869+
Else
870+
web_Result(web_i) = web_Char
871+
End If
872+
Case 32
861873
If EncodeUnsafe Then
874+
web_Result(web_i) = web_Space
875+
Else
876+
web_Result(web_i) = web_Char
877+
End If
878+
Case 43
879+
' + is considered safe special character
880+
' but in space-as-plus cases, it's encoded to differentiate with space
881+
If EncodeUnsafe And SpaceAsPlus Then
862882
web_Result(web_i) = "%" & VBA.Hex(web_CharCode)
863883
Else
864884
web_Result(web_i) = web_Char
865885
End If
886+
Case 0 To 15
887+
web_Result(web_i) = "%0" & VBA.Hex(web_CharCode)
866888
Case Else
867889
web_Result(web_i) = "%" & VBA.Hex(web_CharCode)
868890
End Select

0 commit comments

Comments
 (0)