Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-24790] iOS: HTTPClient - URL with invalid characters causes a crash

GitHub Issuen/a
TypeBug
PriorityMedium
StatusClosed
ResolutionCannot Reproduce
Resolution Date2019-07-02T17:59:54.000+0000
Affected Version/sRelease 6.1.0
Fix Version/sn/a
ComponentsiOS
Labelshttpclient, ios
ReporterJoshua Quick
AssigneeUnknown
Created2017-06-07T01:53:08.000+0000
Updated2019-07-02T17:59:54.000+0000

Description

*Summary:* The HTTPClient will cause a crash on iOS when given a URL containing invalid characters such as: * Space ' ' character. * Percent '%' sign not followed by a hex digit. * Unicode character. *Steps to reproduce:*

Set up a Titanium project to use the attached JavaScript file.

Build and run for iOS.

Tap the "Send HTTP Request" button.

*Result:* Crashes due to invalid characters in the URL. *Expected Result:* Should not crash. Should log a warning and/or invoke the onerror callback. Even better, we should add "autoEncodeUrl" support to iOS for feature parity with Android and Windows Phone. By default, this property is set true. This way, invalid URLs will be automatically %-encoded. http://docs.appcelerator.com/platform/latest/#!/api/Titanium.Network.HTTPClient-property-autoEncodeUrl *Notes:* * The attached project does not crash on Android. Invalid URLs are automatically encoded. * Percent signs are the only characters that should not be automatically encoded. This is in case the given URL already contains %-encoded characters. If there is a lone percent sign without a hex value, then it should produce an invalid URL.

Attachments

FileDateSize
app.js2017-06-07T01:52:26.000+00001043

Comments

  1. Hans Knöchel 2017-06-07

    Good catch! It returns a nil values from [here](https://github.com/appcelerator/titanium_mobile/blob/master/iphone/Classes/TiUtils.m#L926), causing the APSHTTPClient URL to be nil as well, the assertion then fails and the crash is produced. What's interesting is that the fix (like in [this line](https://github.com/appcelerator/titanium_mobile/blob/master/iphone/Classes/TiUtils.m#L933)) is already there, but not honored for URL's beginning with http/https. Not sure why that was done and what the best approach would be. *EDIT*: The way it was implemented was because of TIMOB-18765 - probably because the remote-URL case was not recognized. So we could: a) Add the encoding for both local and remote URL's (now: only local) b) Support the autoEncodeUrl property on iOS and check that one. Problem: We auto-encode it by default for local URL's already, how to handle that?
  2. Joshua Quick 2017-06-07

    Hmm... I just noticed that iOS already auto-encodes http/https URL parameters. So, as long as the URL part to the left of the '?' are valid, it works fine. I tested it with the following URL... http://localhost:40404/path?test=Hello World&percent=50% ...and the above gave me the following encoded URL path and parameter in my test code... /path?test=hello%20world&percent=50%25 So, it seems like our Objective-C "toURL" method was already intended to auto-encode by default. I can see that we call CFURLCreateStringByAddingPercentEscapes() [here](https://github.com/appcelerator/titanium_mobile/blob/master/iphone/Classes/TiUtils.m#L917) for an http/https URL's path part, which would include the parameters. The toURL method just has the above mentioned bug and doesn't support disabling auto-encoding. So, I suppose if we were to add the ability to disable auto-encoding in the future, we could create another "toURL" method with an extra argument to enable/disable auto-encoding. Also, I noticed an issue with my URL parameter test above. We're not supposed to encode a space to %20 in URL parameters. We're supposed to encode them to '+' characters instead. That is, URL query parameters are supposed to use the "application/x-www-form-urlencoded" MIME format and the rest of the URL is supposed to follow the "RFC 2373" specification. https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Syntax I'm currently fixing URL auto-encoding issues on Android now and I'm finding the tricky things to handle are: * The username part of the URL (the part to the left of the @hostname) can be an e-mail account name. Which means it'll have an additional @ character in the URL that'll have to be %-escaped. For example, http://john@domain.com@host.com would have to be escaped to http://john%40domain.com@host.com. (This currently work on iOS now.) * The : and @ characters don't have to be encoded in the URL's path, query parameters, or #fragment/anchor-tag. They only get special treatment in the authority part of the URL. * The ? and / characters don't have to be encoded in the URL's query parameters or #fragment/anchor-tag. * Spaces should be encoded as + in the query parameters and as %20 in all other places. Note that the URL #fragment/anchor-tag comes after the query parameters. For example, http://host.com/my path?test=hello world#my anchor should be encoded to http://host.com/my%20path?test=hello+world#my%20anchor. * The existing %-encoded characters in the URL string should be preserved. A simple solution to this is to %-encode the given URL string, then replace all %25 substrings with %. For example, a string such as 100%25 (intended to be decoded as 100%) would be encoded as 100%2525 and then the substring substitution would turn it back to 100%25. The only limitation is that standalone % characters without hex values would not get encoded, making the URL invalid... but I think this is the 1 ambiguous case we can't handle and it's fine. Is there a simple Objective-C function/method to auto-encode URLs? I hope so. I ask because the CFURLCreateStringByAddingPercentEscapes() function can create invalid URLs if applied to the entire URL string, which is probably why we don't do it. (On Android, there is no single magic Java function either and I have to do this myself.) Starting off, we may just want to fix the crash and let the URL be invalid. We can punt on the auto-encoding for now if we feel like it's a riskier change.

JSON Source