Merge pull request #38 from gnustep/nsstring_and_nscharacterset_changes

NSString and NSCharacterSet changes
This commit is contained in:
Gregory Casamento 2019-04-13 07:48:43 -04:00 committed by GitHub
commit 6377b93726
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 439 additions and 2 deletions

View file

@ -1,4 +1,16 @@
2019-04-12 Gregory John Casamento <greg.casamento@gmail.com>
* Source/NSCharacterSet.m: Added declarations/implementations for
URL*AllowedCharacterSet.
* Headers/NSCharacterSet.h: Added declarations here for
URL*AllowedCharacterSet
* Source/CharSets/*: Added headers to define new charactersets.
* Source/NSString.m: Added methods stringByRemovingPercentEncoding/
stringByAddingPercentEncodingWithAllowedCharacterSet:
* Header/NSString.h: Added declrations for methods mentioned above.
2019-03-29 Igor Zhukov <fsb4000@yandex.ru>
* Source/NSDateFormatter.m:
* configure:
* configure.ac:

View file

@ -98,6 +98,36 @@ extern "C" {
* 0x000A and 0x000D and nextline 0x0085 character.
*/
+ (id) newlineCharacterSet;
/**
* Returns allowed characers for URL fragment component.
*/
+ (id) URLFragmentAllowedCharacterSet;
/**
* Returns allowed characers for URL host component.
*/
+ (id) URLHostAllowedCharacterSet;
/**
* Returns allowed characers for URL password component.
*/
+ (id) URLPasswordAllowedCharacterSet;
/**
* Returns allowed characers for URL path component.
*/
+ (id) URLPathAllowedCharacterSet;
/**
* Returns allowed characers for URL query component.
*/
+ (id) URLQueryAllowedCharacterSet;
/**
* Returns allowed characers for URL USER component.
*/
+ (id) URLUserAllowedCharacterSet;
#endif
/**

View file

@ -802,6 +802,11 @@ typedef NSUInteger NSStringEncodingConversionOptions;
- (const char *)UTF8String;
#endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_9,GS_API_LATEST)
- (NSString *) stringByAddingPercentEncodingWithAllowedCharacters: (NSCharacterSet *)aSet;
- (NSString *) stringByRemovingPercentEncoding;
#endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_3,GS_API_LATEST)
/** Not implemented */
- (void) getParagraphStart: (NSUInteger *)startIndex

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -49,6 +49,12 @@
#undef GNUSTEP_INDEX_CHARSET
#import "NSCharacterSetData.h"
#import "CharSets/URLFragmentAllowedCharSet.h"
#import "CharSets/URLHostAllowedCharSet.h"
#import "CharSets/URLPasswordAllowedCharSet.h"
#import "CharSets/URLPathAllowedCharSet.h"
#import "CharSets/URLQueryAllowedCharSet.h"
#import "CharSets/URLUserAllowedCharSet.h"
#define GSUNICODE_MAX 1114112
#define GSBITMAP_SIZE 8192
@ -537,7 +543,7 @@
/* A simple array for caching standard bitmap sets */
#define MAX_STANDARD_SETS 15
#define MAX_STANDARD_SETS 21
static NSCharacterSet *cache_set[MAX_STANDARD_SETS];
static Class abstractClass = nil;
static Class abstractMutableClass = nil;
@ -833,6 +839,48 @@ static Class concreteMutableClass = nil;
return nil;
}
+ (id) URLFragmentAllowedCharacterSet
{
return [self _staticSet: urlFragmentAllowedCharSet
length: sizeof(urlFragmentAllowedCharSet)
number: 15];
}
+ (id) URLPasswordAllowedCharacterSet
{
return [self _staticSet: urlPasswordAllowedCharSet
length: sizeof(urlPasswordAllowedCharSet)
number: 16];
}
+ (id) URLPathAllowedCharacterSet
{
return [self _staticSet: urlPathAllowedCharSet
length: sizeof(urlPathAllowedCharSet)
number: 17];
}
+ (id) URLQueryAllowedCharacterSet
{
return [self _staticSet: urlQueryAllowedCharSet
length: sizeof(urlQueryAllowedCharSet)
number: 18];
}
+ (id) URLUserAllowedCharacterSet
{
return [self _staticSet: urlUserAllowedCharSet
length: sizeof(urlUserAllowedCharSet)
number: 19];
}
+ (id) URLHostAllowedCharacterSet
{
return [self _staticSet: urlHostAllowedCharSet
length: sizeof(urlHostAllowedCharSet)
number: 20];
}
- (NSData*) bitmapRepresentation
{
BOOL (*imp)(id, SEL, unichar);
@ -1118,6 +1166,36 @@ static Class concreteMutableClass = nil;
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (id) URLFragmentAllowedCharacterSet;
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (id) URLHostAllowedCharacterSet;
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (id) URLPasswordAllowedCharacterSet;
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (id) URLPathAllowedCharacterSet;
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (id) URLQueryAllowedCharacterSet;
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (id) URLUserAllowedCharacterSet
{
return AUTORELEASE([[abstractClass performSelector: _cmd] mutableCopy]);
}
+ (id) characterSetWithCharactersInString: (NSString*)aString
{
NSMutableCharacterSet *ms;

View file

@ -276,6 +276,42 @@ 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() \
@ -1886,6 +1922,70 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
}
}
- (NSString *) stringByAddingPercentEncodingWithAllowedCharacters: (NSCharacterSet *)aSet
{
NSData *data = [self dataUsingEncoding: NSUTF8StringEncoding];
NSString *s = nil;
if (data != nil)
{
unsigned char *src = (unsigned char*)[data bytes];
unsigned int slen = [data length];
unsigned char *dst;
unsigned int spos = 0;
unsigned int dpos = 0;
dst = (unsigned char*)NSZoneMalloc(NSDefaultMallocZone(), slen * 3);
while (spos < slen)
{
unichar c = src[spos++];
unsigned int hi;
unsigned int lo;
if([aSet characterIsMember: c]) // if the character is in the allowed set, put it in
{
dst[dpos++] = c;
}
else // if not, then encode it...
{
dst[dpos++] = '%';
hi = (c & 0xf0) >> 4;
dst[dpos++] = (hi > 9) ? 'A' + hi - 10 : '0' + hi;
lo = (c & 0x0f);
dst[dpos++] = (lo > 9) ? 'A' + lo - 10 : '0' + lo;
}
}
s = [[NSString alloc] initWithBytes: dst
length: dpos
encoding: NSUTF8StringEncoding];
NSZoneFree(NSDefaultMallocZone(), dst);
IF_NO_GC([s autorelease];)
}
return s;
}
- (NSString *) stringByRemovingPercentEncoding
{
NSData *data = [self dataUsingEncoding: NSUTF8StringEncoding];
NSString *result = nil;
char *s = (char *)[data bytes];
NSUInteger slen = 0;
char *o = NULL;
// Allocate memory...
slen = strlen(s);
o = (char *)NSZoneMalloc(NSDefaultMallocZone(), slen);
// Decode...
urldecode(s,o);
// Free up temporary space...
result = [NSString stringWithCString: o encoding: NSUTF8StringEncoding];
NSZoneFree(NSDefaultMallocZone(), o);
return result;
}
/**
* Constructs a new ASCII string which is a representation of the receiver
* in which characters are escaped where necessary in order to produce a

View file

@ -88,8 +88,53 @@ int main()
![theSet characterIsMember: '#'],
"Check custom set");
theSet = [NSCharacterSet URLFragmentAllowedCharacterSet];
NSString *setString = @"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ?/:@-._~!$&'()*+,=";
NSUInteger i = 0;
BOOL p = YES;
for(i = 0; i < [setString length]; i++)
{
char c = [setString characterAtIndex: i];
if([theSet characterIsMember: c] == NO) // , [msg cStringUsingEncoding: NSUTF8Encoding]);
{
NSLog(@"%c is not in set", c);
PASS(NO,"URLFragmentAllowedCharacterSet char not found");
p = NO;
}
}
if(!p)
{
PASS(YES, "URLFragmentAllowedCharacterSet passwed");
}
/*
PASS(//[theSet characterIsMember: 'A'] &&
//[theSet characterIsMember: 'Z'] &&
//[theSet characterIsMember: 'a'] &&
//[theSet characterIsMember: 'z'] &&
//[theSet characterIsMember: '9'] &&
// [theSet characterIsMember: '0'] &&
[theSet characterIsMember: '?'] &&
[theSet characterIsMember: '/ '] &&
[theSet characterIsMember: ':'] &&
[theSet characterIsMember: '@ '] &&
[theSet characterIsMember: '-'] &&
[theSet characterIsMember: '.'] &&
[theSet characterIsMember: '_'] &&
[theSet characterIsMember: '~'] &&
[theSet characterIsMember: '!'] &&
[theSet characterIsMember: '$ '] &&
[theSet characterIsMember: '&'] &&
// [theSet characterIsMember: '\''] &&
[theSet characterIsMember: '('] &&
[theSet characterIsMember: ')'] &&
[theSet characterIsMember: '*'] &&
[theSet characterIsMember: '+'] &&
[theSet characterIsMember: ','] &&
[theSet characterIsMember: ';'] &&
[theSet characterIsMember: '='],
"Check some characters from URLFramgmentAllowedCharacterSet"); */
[arp release]; arp = nil;
return 0;
}

View file

@ -0,0 +1,59 @@
#import "ObjectTesting.h"
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSString.h>
#import <Foundation/NSCharacterSet.h>
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);
return [encodedString isEqualToString: testString];
}
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);
[pool drain];
return 0;
}