Cleanups to avoid code conflicts and buffer overrun fixes.

This commit is contained in:
Richard Frith-Macdonald 2019-04-16 08:07:16 +01:00
parent 6377b93726
commit 8ed7ccea9e
3 changed files with 67 additions and 59 deletions

View file

@ -1,3 +1,11 @@
2019-02-16 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSString.m: Removed public functions which could conflict
with application code. Rewrote percent unescaping to avoid possible
buffer overruns.
* Tests/base/NSString/test09.m: avoid excess logging (for readability
of test output).
2019-04-12 Gregory John Casamento <greg.casamento@gmail.com>
* Source/NSCharacterSet.m: Added declarations/implementations for

View file

@ -276,42 +276,6 @@ GSPathHandling(const char *mode)
}
}
// Test if the digit is hex..
inline int ishex(int x)
{
return
(x >= '0' && x <= '9') ||
(x >= 'a' && x <= 'f') ||
(x >= 'A' && x <= 'F');
}
// URL decoding...
int urldecode(const char *s, char *dec)
{
char *o;
const char *end = s + strlen(s);
int c;
int cx;
for (o = dec; s <= end; o++)
{
c = *s++;
cx = c; // preserve original value if we are not to decode
if (c == '%' && (!ishex(*s++) ||
!ishex(*s++) ||
!sscanf(s - 2, "%2x", &c)))
{
c = cx; // reset c to original value.
s--;
}
if (dec)
{
*o = c;
}
}
return o - dec;
}
#define GSPathHandlingRight() \
((pathHandling == PH_DO_THE_RIGHT_THING) ? YES : NO)
#define GSPathHandlingUnix() \
@ -1966,21 +1930,59 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
- (NSString *) stringByRemovingPercentEncoding
{
NSData *data = [self dataUsingEncoding: NSUTF8StringEncoding];
NSString *result = nil;
char *s = (char *)[data bytes];
NSUInteger slen = 0;
char *o = NULL;
NSData *data = [self dataUsingEncoding: NSUTF8StringEncoding];
const uint8_t *s = [data bytes];
NSUInteger length = [data length];
NSUInteger lastPercent = length - 3;
char *o = (char *)NSZoneMalloc(NSDefaultMallocZone(), length + 1);
char *next = o;
NSUInteger index;
NSString *result;
// Allocate memory...
slen = strlen(s);
o = (char *)NSZoneMalloc(NSDefaultMallocZone(), slen);
for (index = 0; index < length; index++)
{
char c = s[index];
// Decode...
urldecode(s,o);
if ('%' == c && index < lastPercent)
{
uint8_t hi = s[index+1];
uint8_t lo = s[index+2];
// Free up temporary space...
result = [NSString stringWithCString: o encoding: NSUTF8StringEncoding];
if (isdigit(hi) && isxdigit(lo))
{
index += 2;
if (hi <= '9')
{
c = hi - '0';
}
else if (hi <= 'F')
{
c = hi - 'A' + 10;
}
else
{
c = hi - 'a' + 10;
}
c <<= 4;
if (lo <= '9')
{
c += lo - '0';
}
else if (lo <= 'F')
{
c += lo - 'A' + 10;
}
else
{
c += lo - 'a' + 10;
}
}
}
*next++ = c;
}
*next = '\0';
result = [NSString stringWithUTF8String: o];
NSZoneFree(NSDefaultMallocZone(), o);
return result;

View file

@ -3,11 +3,15 @@
#import <Foundation/NSString.h>
#import <Foundation/NSCharacterSet.h>
BOOL testUrlCharacterSetEncoding(NSString* decodedString, NSString* encodedString, NSCharacterSet* allowedCharacterSet)
BOOL testUrlCharacterSetEncoding(
NSString* decodedString,
NSString* encodedString,
NSCharacterSet* allowedCharacterSet)
{
NSLog(@"String by adding percent");
NSString* testString = [decodedString stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
NSLog(@"String by adding percent, done. test=%@ decoded=%@", testString, decodedString);
NSString *testString
= [decodedString stringByAddingPercentEncodingWithAllowedCharacters:
allowedCharacterSet];
// NSLog(@"String by adding percent, done. test=%@ decoded=%@", testString, decodedString);
return [encodedString isEqualToString: testString];
}
@ -15,45 +19,39 @@ int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSLog(@"Test1");
NSString *urlDecodedString = @"Only alphabetic characters should be allowed and not encoded. !@#$%^&*()_+-=";
NSString *urlEncodedString =
@"Only%20alphabetic%20characters%20should%20be%20allowed%20and%20not%20encoded%2E%20%21%40%23%24%25%5E%26%2A%28%29%5F%2B%2D%3D";
NSCharacterSet *allowedCharacterSet = [NSCharacterSet alphanumericCharacterSet];
PASS(testUrlCharacterSetEncoding(urlDecodedString, urlEncodedString, allowedCharacterSet), "alphanumericCharacterSet");
NSLog(@"Test2");
urlDecodedString = @"https://www.microsoft.com/en-us/!@#$%^&*()_";
urlEncodedString = @"https://www.microsoft.com/en-us/!@%23$%25%5E&*()_";
allowedCharacterSet = [NSCharacterSet URLFragmentAllowedCharacterSet];
PASS(testUrlCharacterSetEncoding(urlDecodedString, urlEncodedString, allowedCharacterSet), "fragmentCharacterSet");
NSLog(@"Test3");
urlDecodedString = @"All alphabetic characters should be encoded. Symbols should not be: !@#$%^&*()_+-=";
urlEncodedString = @"%41%6C%6C %61%6C%70%68%61%62%65%74%69%63 %63%68%61%72%61%63%74%65%72%73 %73%68%6F%75%6C%64 %62%65 "
@"%65%6E%63%6F%64%65%64. %53%79%6D%62%6F%6C%73 %73%68%6F%75%6C%64 %6E%6F%74 %62%65: !@#$%^&*()_+-=";
allowedCharacterSet = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
PASS(testUrlCharacterSetEncoding(urlDecodedString, urlEncodedString, allowedCharacterSet), "inverted");
NSLog(@"Test4");
urlDecodedString = @"Here are some Emojis: \U0001F601 \U0001F602 \U0001F638 Emojis done."; // Multibyte encoded characters
urlEncodedString = @"Here%20are%20some%20Emojis:%20%F0%9F%98%81%20%F0%9F%98%82%20%F0%9F%98%B8%20Emojis%20done.";
allowedCharacterSet = [NSCharacterSet URLFragmentAllowedCharacterSet];
PASS(testUrlCharacterSetEncoding(urlDecodedString, urlEncodedString, allowedCharacterSet), "fragmentCharacterSet emojis");
NSLog(@"Test5");
urlDecodedString = @"\1";
urlEncodedString = @"%01";
allowedCharacterSet = [NSCharacterSet alphanumericCharacterSet];
PASS(testUrlCharacterSetEncoding(urlDecodedString, urlEncodedString, allowedCharacterSet), "alphanumericCharacterSet");
NSLog(@"Test5");
urlDecodedString = @"All alphabetic characters should be encoded. Symbols should not be: !@#$%^&*()_+-=";
urlEncodedString = @"%41%6C%6C %61%6C%70%68%61%62%65%74%69%63 %63%68%61%72%61%63%74%65%72%73 %73%68%6F%75%6C%64 %62%65 "
@"%65%6E%63%6F%64%65%64. %53%79%6D%62%6F%6C%73 %73%68%6F%75%6C%64 %6E%6F%74 %62%65: !@#$%^&*()_+-=";
NSString *result = [urlEncodedString stringByRemovingPercentEncoding];
PASS([urlDecodedString isEqualToString: result], "stringByRemovingPercentEncoding");
NSLog(@"Result = \"%@\",\ndecodedString = \"%@\",\nencodedString = \"%@\"", result, urlDecodedString, urlEncodedString);
// NSLog(@"Result = \"%@\",\ndecodedString = \"%@\",\nencodedString = \"%@\"", result, urlDecodedString, urlEncodedString);
[pool drain];
return 0;
}