Merge pull request #123 from gnustep/master

keep up with master
This commit is contained in:
Riccardo 2020-04-30 11:14:10 +02:00 committed by GitHub
commit e23ab3b394
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 1281 additions and 827 deletions

View file

@ -169,7 +169,29 @@ methods.
The gnustep-base-1.27.0.tar.gz distribution file has been placed at
<ftp://ftp.gnustep.org/pub/gnustep/core>.
Please log bug reports on the GNUstep project page
It is accompanied by gnustep-base-1.27.0.tar.gz.sig, a PGP signature
which you can validate by putting both files in the same directory and
using:
gpg --verify gnustep-base-1.27.0.tar.gz.sig
Signature has been created using the key with the following
fingerprint:
83AA E47C E829 A414 6EF8 3420 CA86 8D4C 9914 9679
Read the INSTALL file or the GNUstep-HOWTO for installation
instructions.
1.4 Where do I send bug reports?
================================
Please log bug reports on the GNUstep project page
<http://savannah.gnu.org/bugs/?group=gnustep> or send bug reports to
<bug-gnustep@gnu.org>.
1.5 Obtaining GNUstep Software
==============================
Check out the GNUstep web site. (<http://www.gnustep.org/>) and the GNU
web site. (<http://www.gnu.org/>)

View file

@ -1,3 +1,72 @@
2020-04-26 Fred Kiefer <fredkiefer@gmx.de>
* Source/NSLocale.m: Respect NSLocaleCalendarIdentifier if
NSLocaleCalendar isn't set.
* Headers/Foundation/NSCalendar.h,
* Source/NSCalendar.m: Add newer features for NSDateComponents and
started to clean up NSCalendar implementation.
* Tests/base/NSCalendar/features-10-7.m: Add test for different
time zone.
2020-04-21 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSNotification.m:
Override -hash and -isEqual: so that notifications with the name name,
object, and userInfo are considered equal. This is the OSX behavior.
2020-04-14 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/GNUstepBase/GSConfig.h.in:
* Headers/GNUstepBase/GSVersionMacros.h:
* configure.ac:
* configure:
Remove last vestiges of MIXED ABI support (it didn't really work), and
change code to assume that use of the apple runtime means we have the
nonfragile ABI (true for modern apple systems we may be interested in
using). Regenerate configure script.
2020-04-13 Ivan Vucica <ivan@vucica.net>
* Documentation/announce.texi:
* ANNOUNCE:
Normalize the accompanying text for the release announcement across
core packages: standardize chapter name and GPG information.
2020-04-13 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/Foundation/NSURLProtocol.h:
* Source/NSURLProtocol.m:
Fix [NSURLProtocol -initWithRequest:cachedResponse:client:] to retain
the client (up until the last message is sent to it) as OSX does.
2020-04-12 Richard Frith-Macdonald <rfm@gnu.org>
* CharSets/URLFragmentAllowedCharSet.h:
* CharSets/URLHostAllowedCharSet.h:
* CharSets/URLPasswordAllowedCharSet.h:
* CharSets/URLPathAllowedCharSet.h:
* CharSets/URLQueryAllowedCharSet.h:
* CharSets/URLUserAllowedCharSet.h:
Removed character set data headers from non-standard location.
* NSCharacterSet.m:
Fixed to load URL characterset data from standard file.
Changed bitmap representation to use much less space for charsets
residing wholly in the base plane (in particular the URL charsets
which are purely ASCII characters).
* NSCharacterSetData.h:
Regenerated to contain the URL charactersets and to contain the
latest Unicode data (3rd Oct 2019).
2020-04-10 Richard Frith-Macdonald <rfm@gnu.org>
* Headers/GNUstepBase/GNUstep.h:
Add ASSIGNMUTABLECOPY() macro for consistency with ASSIGNCOPY()
Wolfgang pointed out that the lack of this macro was uninutitive.
2020-04-07 Frederik Seiffert <frederik@algoriddim.com>
* Source/NSOperation.m: Fix completion block memory management.
2020-04-05 Ivan Vucica <ivan@vucica.net>
* ANNOUNCE:

View file

@ -1,3 +1,4 @@
@c -*- texinfo -*-
@chapter Announcement
@c set the vars GNUSTEP-BASE-VERSION and GNUSTEP-BASE-GCC-VERSION
@ -31,9 +32,31 @@ at @samp{http://www.gnustep.org}.
@ifset GNUSTEP-BASE-FTP-MACHINE
The gnustep-base-@value{GNUSTEP-BASE-VERSION}.tar.gz distribution file has
been placed at @url{ftp://@value{GNUSTEP-BASE-FTP-MACHINE}/@value{GNUSTEP-BASE-FTP-DIRECTORY}}.
It is accompanied by gnustep-base-@value{GNUSTEP-BASE-VERSION}.tar.gz.sig, a
PGP signature which you can validate by putting both files in the same
directory and using:
@example
gpg --verify gnustep-base-@value{GNUSTEP-BASE-VERSION}.tar.gz.sig
@end example
Signature has been created using the key with the following fingerprint:
@example
83AA E47C E829 A414 6EF8 3420 CA86 8D4C 9914 9679
@end example
@end ifset
Read the INSTALL file or the GNUstep-HOWTO for installation instructions.
@section Where do I send bug reports?
Please log bug reports on the GNUstep project page
@url{http://savannah.gnu.org/bugs/?group=gnustep} or send bug
reports to @email{bug-gnustep@@gnu.org}.
@section Obtaining GNUstep Software
Check out the GNUstep web site. (@url{http://www.gnustep.org/}) and the
GNU web site. (@url{http://www.gnu.org/})

View file

@ -129,7 +129,7 @@ enum
NSCalendarUnitWeekOfMonth = (1UL << 12),
NSCalendarUnitWeekOfYear = (1UL << 13),
NSCalendarUnitYearForWeekOfYear = (1UL << 14),
NSCalendarUnitNanosecond = (1 << 15), // FIXME: unimplemented
NSCalendarUnitNanosecond = (1 << 15),
NSCalendarUnitCalendar = (1 << 20), // FIXME: unimplemented
NSCalendarUnitTimeZone = (1 << 21) // FIXME: unimplemented
#endif
@ -227,6 +227,7 @@ enum
* yearForWeekOfYear is 2013, since it's already week 1 in 2013.
*/
- (NSInteger) yearForWeekOfYear;
- (NSInteger) nanosecond;
/** Sets the number of the week in this month. */
- (void) setWeekOfMonth: (NSInteger) v;
@ -241,8 +242,22 @@ enum
* See the explanation at <code>-yearForWeekOfYear</code>.
*/
- (void) setYearForWeekOfYear: (NSInteger) v;
- (void) setNanosecond: (NSInteger) v;
#endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_8, GS_API_LATEST)
- (BOOL) leapMonth;
- (void) setLeapMonth: (BOOL) v;
#endif
#if OS_API_VERSION(MAC_OS_X_VERSION_10_9, GS_API_LATEST)
- (BOOL) isValidDate;
- (BOOL) isValidDateInCalendar: (NSCalendar *) calendar;
- (NSInteger) valueForComponent: (NSCalendarUnit) unit;
- (void) setValue: (NSInteger) value
forComponent: (NSCalendarUnit) unit;
#endif
@end

View file

@ -171,7 +171,8 @@ extern "C" {
* The cachedResponse may be the result of a previous load of the
* request (in which case the protocol may validate and use it).<br />
* The client is the object which receives messages about the progress
* of the load.
* of the load. This is retained by the protocl instance and is released
* once the last message has been sent to it.
*/
- (id) initWithRequest: (NSURLRequest *)request
cachedResponse: (NSCachedURLResponse *)cachedResponse

View file

@ -80,6 +80,9 @@
#ifndef ASSIGNCOPY
#define ASSIGNCOPY(object,value) object = [(value) copy]
#endif
#ifndef ASSIGNMUTABLECOPY
#define ASSIGNMUTABLECOPY(object,value) object = [(value) mutableCopy]
#endif
#ifndef DESTROY
#define DESTROY(object) object = nil
#endif
@ -180,6 +183,19 @@ id __object = (object); (__object != nil) ? [__object autorelease] : nil; })
})
#endif
#ifndef ASSIGNMUTABLECOPY
/**
* ASSIGNMUTABLECOPY(object,value) assigns a mutable copy of the value
* to the object with release of the original.<br />
* Use this to avoid retain/release errors.
*/
#define ASSIGNMUTABLECOPY(object,value) ({\
id __object = object; \
object = [(value) mutableCopy];\
[__object release]; \
})
#endif
#ifndef DESTROY
/**
* DESTROY() is a release operation which also sets the variable to be

View file

@ -262,7 +262,6 @@ typedef struct {
#define OBJC2RUNTIME @OBJC2RUNTIME@
#define BASE_NATIVE_OBJC_EXCEPTIONS @BASE_NATIVE_OBJC_EXCEPTIONS@
#define GS_NONFRAGILE @GS_NONFRAGILE@
#define GS_MIXEDABI @GS_MIXEDABI@
#define GS_USE_LIBXML @HAVE_LIBXML@
#define GS_USE_GNUTLS @HAVE_GNUTLS@
#define GS_USE_AVAHI @HAVE_AVAHI@

View file

@ -283,20 +283,15 @@
* in the class source itsself
*/
#if GS_MIXEDABI
# undef GS_NONFRAGILE
# define GS_NONFRAGILE 0 /* Mixed is treated as fragile */
#if (__has_feature(objc_nonfragile_abi))
# if !GS_NONFRAGILE
# if defined(GNUSTEP_BASE_INTERNAL)
# error "You are building gnustep-base using the objc-nonfragile-abi but your gnustep-base was not configured to use it."
# endif
# endif
#else
# if (__has_feature(objc_nonfragile_abi))
# if !GS_NONFRAGILE
# if defined(GNUSTEP_BASE_INTERNAL)
# error "You are building gnustep-base using the objc-nonfragile-abi but your gnustep-base was not configured to use it."
# endif
# endif
# else
# if GS_NONFRAGILE
# error "Your gnustep-base was configured for the objc-nonfragile-abi but you are not using it now."
# endif
# if GS_NONFRAGILE
# error "Your gnustep-base was configured for the objc-nonfragile-abi but you are not using it now."
# endif
#endif

View file

@ -115,7 +115,8 @@ static SEL objSel;
{
NSUInteger count = map.nodeCount;
SEL sel = @selector(encodeObject:);
IMP imp = [aCoder methodForSelector: sel];
id (*imp)(id,SEL,id)
= (id (*)(id,SEL,id))[aCoder methodForSelector: sel];
GSIMapEnumerator_t enumerator = GSIMapEnumeratorForMap(&map);
GSIMapNode node = GSIMapEnumeratorNextNode(&enumerator);
@ -152,7 +153,8 @@ static SEL objSel;
id key;
id value;
SEL sel = @selector(decodeValueOfObjCType:at:);
IMP imp = [aCoder methodForSelector: sel];
void (*imp)(id,SEL,const char*,void*)
= (void (*)(id,SEL,const char*,void*))[aCoder methodForSelector: sel];
const char *type = @encode(id);
[aCoder decodeValueOfObjCType: @encode(NSUInteger)
@ -220,8 +222,9 @@ static SEL objSel;
if (c > 0)
{
NSEnumerator *e = [other keyEnumerator];
IMP nxtObj = [e methodForSelector: nxtSel];
IMP otherObj = [other methodForSelector: objSel];
id (*nxtObj)(id, SEL) = (id (*)(id,SEL))[e methodForSelector: nxtSel];
id (*otherObj)(id, SEL, id)
= (id (*)(id,SEL,id))[other methodForSelector: objSel];
BOOL isProxy = [other isProxy];
NSUInteger i;
@ -293,7 +296,8 @@ static SEL objSel;
{
GSIMapEnumerator_t enumerator;
GSIMapNode node;
IMP otherObj = [other methodForSelector: objSel];
id (*otherObj)(id, SEL, id)
= (id (*)(id,SEL,id))[other methodForSelector: objSel];
enumerator = GSIMapEnumeratorForMap(&map);
while ((node = GSIMapEnumeratorNextNode(&enumerator)) != 0)

View file

@ -132,6 +132,7 @@ static NSString *CteContentType = @"content-type";
static NSString *CteQuotedPrintable = @"quoted-printable";
static NSString *CteXuuencode = @"x-uuencode";
typedef id (*oaiIMP)(id, SEL, NSUInteger);
typedef BOOL (*boolIMP)(id, SEL, id);
static char *hex = "0123456789ABCDEF";
@ -6184,12 +6185,12 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
if (count > 0)
{
IMP imp1;
oaiIMP imp1;
boolIMP imp2;
name = [name lowercaseString];
imp1 = [headers methodForSelector: @selector(objectAtIndex:)];
imp1 = (oaiIMP)[headers methodForSelector: @selector(objectAtIndex:)];
imp2 = (boolIMP)[name methodForSelector: @selector(isEqualToString:)];
while (count-- > 0)
{
@ -6330,11 +6331,11 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
if (count > 0)
{
NSUInteger index;
IMP imp1;
oaiIMP imp1;
boolIMP imp2;
name = [headerClass makeToken: name preservingCase: NO];
imp1 = [headers methodForSelector: @selector(objectAtIndex:)];
imp1 = (oaiIMP)[headers methodForSelector: @selector(objectAtIndex:)];
imp2 = (boolIMP)[name methodForSelector: @selector(isEqualToString:)];
for (index = 0; index < count; index++)
{
@ -6364,10 +6365,10 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
{
NSUInteger index;
NSMutableArray *array;
IMP imp1;
oaiIMP imp1;
boolIMP imp2;
imp1 = [headers methodForSelector: @selector(objectAtIndex:)];
imp1 = (oaiIMP)[headers methodForSelector: @selector(objectAtIndex:)];
imp2 = (boolIMP)[name methodForSelector: @selector(isEqualToString:)];
array = [NSMutableArray array];
@ -7285,10 +7286,10 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
if (count > 0)
{
NSUInteger index;
IMP imp1;
oaiIMP imp1;
boolIMP imp2;
imp1 = [headers methodForSelector: @selector(objectAtIndex:)];
imp1 = (oaiIMP)[headers methodForSelector: @selector(objectAtIndex:)];
imp2 = (boolIMP)[name methodForSelector: @selector(isEqualToString:)];
for (index = 0; index < count; index++)
{
@ -7310,10 +7311,10 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
if (count > 0)
{
IMP imp1;
oaiIMP imp1;
boolIMP imp2;
imp1 = [headers methodForSelector: @selector(objectAtIndex:)];
imp1 = (oaiIMP)[headers methodForSelector: @selector(objectAtIndex:)];
imp2 = (boolIMP)[name methodForSelector: @selector(isEqualToString:)];
while (count-- > 0)
{

View file

@ -1983,7 +1983,7 @@ GSAutoreleasedBuffer(unsigned size)
static Class buffer_class = 0;
static Class autorelease_class;
static SEL autorelease_sel;
static IMP autorelease_imp;
static id (*autorelease_imp)(Class, SEL, id);
static int instance_size;
static int offset;
NSObject *o;
@ -1995,7 +1995,8 @@ GSAutoreleasedBuffer(unsigned size)
offset = instance_size % ALIGN;
autorelease_class = [NSAutoreleasePool class];
autorelease_sel = @selector(addObject:);
autorelease_imp = [autorelease_class methodForSelector: autorelease_sel];
autorelease_imp = (id (*)(Class, SEL, id))
[autorelease_class methodForSelector: autorelease_sel];
}
o = (NSObject*)NSAllocateObject(buffer_class,
size + offset, NSDefaultMallocZone());
@ -2065,7 +2066,9 @@ GSPrintf (FILE *fptr, NSString* format, ...)
# define AADD(c, o)
# define AREM(c, o)
# endif
#else
# define AADD(c, o)
# define AREM(c, o)
#endif /* defined(GNUSTEP_BASE_LIBRARY) */
void

View file

@ -104,7 +104,7 @@
*/
static Class NSString_class;
static Class treeClass;
static IMP usImp;
static id (*usImp)(id, SEL, const unsigned char*);
static SEL usSel;
static xmlExternalEntityLoader originalLoader = NULL;
@ -166,7 +166,8 @@ setupCache()
xmlDefaultSAXHandlerInit();
NSString_class = [NSString class];
usSel = @selector(stringWithUTF8String:);
usImp = [NSString_class methodForSelector: usSel];
usImp = (id (*)(id, SEL, const unsigned char*))
[NSString_class methodForSelector: usSel];
treeClass = [GSTreeSAXHandler class];
}
}

View file

@ -38,7 +38,7 @@
NSUInteger lower = 0;
NSUInteger index;
SEL oaiSel;
IMP oai;
id (*oai)(id,SEL,NSUInteger);
if (item == nil)
{
@ -52,7 +52,7 @@
}
oaiSel = @selector(objectAtIndex:);
oai = [self methodForSelector: oaiSel];
oai = (id(*)(id,SEL,NSUInteger))[self methodForSelector: oaiSel];
/*
* Binary search for an item equal to the one to be inserted.
*/
@ -95,7 +95,7 @@
NSUInteger index;
NSComparisonResult (*imp)(id, SEL, id);
SEL oaiSel;
IMP oai;
id (*oai)(id,SEL,NSUInteger);
if (item == nil)
{
@ -115,7 +115,7 @@
}
oaiSel = @selector(objectAtIndex:);
oai = [self methodForSelector: oaiSel];
oai = (id(*)(id,SEL,NSUInteger))[self methodForSelector: oaiSel];
/*
* Binary search for an item equal to the one to be inserted.
*/

View file

@ -27,6 +27,7 @@
#import "Foundation/NSException.h"
#import "Foundation/NSHashTable.h"
#import "Foundation/NSLock.h"
#import "GNUstepBase/GSObjCRuntime.h"
#import "GNUstepBase/NSObject+GNUstepBase.h"
#import "GNUstepBase/NSDebug+GNUstepBase.h"
#import "GNUstepBase/NSThread+GNUstepBase.h"
@ -412,7 +413,9 @@ handleExit()
NSUInteger size;
#if GS_SIZEOF_VOIDP > 4
if ((((NSUInteger)void*)self) & 0x07)
NSUInteger xxx = (NSUInteger)(void*)self;
if (xxx & 0x07)
{
return 0; // Small object has no size
}

View file

@ -39,7 +39,7 @@ static BOOL debugTemporarilyDisabled = NO;
BOOL GSDebugSet(NSString *level)
{
static IMP debugImp = 0;
static id (*debugImp)(id,SEL,id) = 0;
static SEL debugSel;
if (debugTemporarilyDisabled == YES)
@ -53,7 +53,7 @@ BOOL GSDebugSet(NSString *level)
{
[[NSProcessInfo processInfo] debugSet];
}
debugImp = [_debug_set methodForSelector: debugSel];
debugImp = (id (*)(id,SEL,id))[_debug_set methodForSelector: debugSel];
if (debugImp == 0)
{
fprintf(stderr, "Unable to set up with [NSProcessInfo-debugSet]\n");

View file

@ -415,7 +415,8 @@ OAppend(id obj, NSDictionary *loc, unsigned lev, unsigned step,
const char *iBaseString;
const char *iSizeString;
SEL objSel = @selector(objectForKey:);
IMP myObj = [obj methodForSelector: objSel];
id (*myObj)(id,SEL,id)
= (id(*)(id,SEL,id))[obj methodForSelector: objSel];
unsigned i;
NSArray *keyArray = [obj allKeys];
unsigned numKeys = [keyArray count];
@ -642,7 +643,8 @@ OAppend(id obj, NSDictionary *loc, unsigned lev, unsigned step,
OAppend(aPropertyList, loc, 0, step > 3 ? 3 : step, dest);
return dest;
}
return (*originalImp)(self, _cmd, aPropertyList, aFormat, anErrorString);
return (*(id(*)(id,SEL,id,id,id))originalImp)
(self, _cmd, aPropertyList, aFormat, anErrorString);
}
+ (void) load

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

File diff suppressed because it is too large Load diff

View file

@ -49,12 +49,6 @@
#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
@ -122,6 +116,20 @@
i--;
}
i *= GSBITMAP_SIZE;
if (GSBITMAP_SIZE == i)
{
/* In the base plane, find the number of used bytes, so we don't
* produce a bitmap that is longer than necessary.
*/
if (_length < i)
{
i = _length;
}
while (i > 0 && 0 == _data[i - 1])
{
i--;
}
}
if (i < _length)
{
return [NSData dataWithBytes: _data length: i];
@ -206,7 +214,7 @@
{
unsigned length = [bitmap length];
if ((length % GSBITMAP_SIZE) != 0 || length > GSBITMAP_MAX)
if (length > GSBITMAP_MAX)
{
NSLog(@"attempt to initialize character set with invalid bitmap");
[self dealloc];
@ -280,13 +288,22 @@
}
/* Make space if needed.
* Use exact size if we have nothing beyond the base plane,
* otherwise round up to a plane boundary.
*/
b = (m - 1) / 8;
if (b >= _length)
{
while (b >= _length)
if (b < GSBITMAP_SIZE)
{
_length += GSBITMAP_SIZE;
_length = b + 1;
}
else
{
while (b >= _length)
{
_length += GSBITMAP_SIZE;
}
}
[_obj setLength: _length];
_data = [_obj mutableBytes];
@ -337,10 +354,14 @@
if (length > 0)
{
NSUInteger i;
unsigned max = _length;
unichar (*get)(id, SEL, NSUInteger);
get = (unichar (*)(id, SEL, NSUInteger))
[aString methodForSelector: @selector(characterAtIndex:)];
/* Determine size of bitmap needed.
*/
for (i = 0; i < length; i++)
{
unichar letter;
@ -358,15 +379,49 @@
+ (second - 0xdc00) + 0x0010000;
}
byte = letter/8;
if (byte >= _length)
if (byte >= max)
{
while (byte >= _length)
max = byte;
}
}
/* Make space if needed.
* Use exact size if we have nothing beyond the base plane,
* otherwise round up to a plane boundary.
*/
if (max >= _length)
{
if (max < GSBITMAP_SIZE)
{
_length = max + 1;
}
else
{
while (max >= _length)
{
_length += GSBITMAP_SIZE;
}
[_obj setLength: _length];
_data = [_obj mutableBytes];
}
[_obj setLength: _length];
_data = [_obj mutableBytes];
}
for (i = 0; i < length; i++)
{
unichar letter;
unichar second;
unsigned byte;
letter = (*get)(aString, @selector(characterAtIndex:), i);
// Convert a surrogate pair if necessary
if (letter >= 0xd800 && letter <= 0xdbff && i < length-1
&& (second = (*get)(aString, @selector(characterAtIndex:), i+1))
>= 0xdc00 && second <= 0xdfff)
{
i++;
letter = ((letter - 0xd800) << 10)
+ (second - 0xdc00) + 0x0010000;
}
byte = letter/8;
GSSETBIT(_data[byte], letter % 8);
}
}
@ -382,6 +437,20 @@
i--;
}
i *= GSBITMAP_SIZE;
if (GSBITMAP_SIZE == i)
{
/* In the base plane, find the number of used bytes, so we don't
* produce a bitmap that is longer than necessary.
*/
if (_length < i)
{
i = _length;
}
while (i > 0 && 0 == _data[i - 1])
{
i--;
}
}
return [NSData dataWithBytes: _data length: i];
}
@ -430,7 +499,7 @@
unsigned length = [bitmap length];
id tmp;
if ((length % GSBITMAP_SIZE) != 0 || length > GSBITMAP_MAX)
if (length > GSBITMAP_MAX)
{
NSLog(@"attempt to initialize character set with invalid bitmap");
[self dealloc];
@ -623,7 +692,8 @@ static Class concreteMutableClass = nil;
- (id) initWithBitmap: (NSData*)bitmap number: (int)number
{
if ((self = (_GSStaticCharSet*)[(NSBitmapCharSet*)self initWithBitmap: bitmap]) != nil)
if ((self = (_GSStaticCharSet*)[(NSBitmapCharSet*)self
initWithBitmap: bitmap]) != nil)
{
_index = number;
}
@ -841,56 +911,66 @@ static Class concreteMutableClass = nil;
+ (id) URLFragmentAllowedCharacterSet
{
return [self _staticSet: urlFragmentAllowedCharSet
length: sizeof(urlFragmentAllowedCharSet)
return [self _staticSet: URLFragmentAllowedCharSet
length: sizeof(URLFragmentAllowedCharSet)
number: 15];
}
+ (id) URLPasswordAllowedCharacterSet
{
return [self _staticSet: urlPasswordAllowedCharSet
length: sizeof(urlPasswordAllowedCharSet)
return [self _staticSet: URLPasswordAllowedCharSet
length: sizeof(URLPasswordAllowedCharSet)
number: 16];
}
+ (id) URLPathAllowedCharacterSet
{
return [self _staticSet: urlPathAllowedCharSet
length: sizeof(urlPathAllowedCharSet)
return [self _staticSet: URLPathAllowedCharSet
length: sizeof(URLPathAllowedCharSet)
number: 17];
}
+ (id) URLQueryAllowedCharacterSet
{
return [self _staticSet: urlQueryAllowedCharSet
length: sizeof(urlQueryAllowedCharSet)
return [self _staticSet: URLQueryAllowedCharSet
length: sizeof(URLQueryAllowedCharSet)
number: 18];
}
+ (id) URLUserAllowedCharacterSet
{
return [self _staticSet: urlUserAllowedCharSet
length: sizeof(urlUserAllowedCharSet)
return [self _staticSet: URLUserAllowedCharSet
length: sizeof(URLUserAllowedCharSet)
number: 19];
}
+ (id) URLHostAllowedCharacterSet
{
return [self _staticSet: urlHostAllowedCharSet
length: sizeof(urlHostAllowedCharSet)
return [self _staticSet: URLHostAllowedCharSet
length: sizeof(URLHostAllowedCharSet)
number: 20];
}
- (NSData*) bitmapRepresentation
{
BOOL (*imp)(id, SEL, unichar);
NSMutableData *m = [NSMutableData dataWithLength: 8192];
unsigned char *p = (unsigned char*)[m mutableBytes];
NSMutableData *m;
unsigned char *p;
unsigned end;
unsigned i;
imp = (BOOL (*)(id,SEL,unichar))
[self methodForSelector: @selector(characterIsMember:)];
for (i = 0; i <= 0xffff; i++)
for (end = 0xffff; end > 0; end--)
{
if (imp(self, @selector(characterIsMember:), end) == YES)
{
break;
}
}
m = [NSMutableData dataWithLength: end / 8 + 1];
p = (unsigned char*)[m mutableBytes];
for (i = 0; i <= end; i++)
{
if (imp(self, @selector(characterIsMember:), i) == YES)
{

File diff suppressed because one or more lines are too long

View file

@ -34,7 +34,7 @@
also contain commas, most notably in the Expires field (which is not quoted
and can contain spaces as well). The last key/value does not have to have a
semi-colon, so this can be tricky to parse if another cookie occurs
after this (See GSRangeOfCookie).
after this (See GSCookieStrings).
*/
#import "common.h"
@ -114,7 +114,7 @@ static const unsigned char whitespace[32] = {
#define GS_IS_WHITESPACE(X) IS_BIT_SET(whitespace[(X)/8], (X) % 8)
static id GSPropertyListFromCookieFormat(NSString *string, int version);
static NSRange GSRangeOfCookie(NSString *string);
static NSMutableArray *GSCookieStrings(NSString *string);
@implementation NSHTTPCookie
@ -141,36 +141,42 @@ static NSRange GSRangeOfCookie(NSString *string);
forHeader: (NSString *)header
andURL: (NSURL *)url
{
int version;
NSString *defaultPath, *defaultDomain;
NSMutableArray *a;
int version;
NSString *defaultPath;
NSString *defaultDomain;
NSMutableArray *cookies;
NSUInteger count;
if ([header isEqual: @"Set-Cookie"])
version = 0;
{
version = 0;
}
else if ([header isEqual: @"Set-Cookie2"])
version = 1;
{
version = 1;
}
else
return nil;
a = [NSMutableArray array];
{
return nil;
}
defaultDomain = [url host];
defaultPath = [url path];
if ([[url absoluteString] hasSuffix: @"/"] == NO)
defaultPath = [defaultPath stringByDeletingLastPathComponent];
{
defaultPath = [defaultPath stringByDeletingLastPathComponent];
}
cookies = GSCookieStrings(field);
count = [cookies count];
/* We could use an NSScanner here, but this string could contain all
sorts of odd stuff. It's not quite a property list either - it has
dates and also could have tokens without values. */
while (1)
while (count-- > 0)
{
NSHTTPCookie *cookie;
NSMutableDictionary *dict;
NSString *onecookie;
NSRange range = GSRangeOfCookie(field);
NSHTTPCookie *cookie;
NSMutableDictionary *dict;
NSString *onecookie = [cookies objectAtIndex: count];
if (range.location == NSNotFound)
break;
onecookie = [field substringWithRange: range];
NS_DURING
dict = GSPropertyListFromCookieFormat(onecookie, version);
NS_HANDLER
@ -179,18 +185,25 @@ static NSRange GSRangeOfCookie(NSString *string);
if ([dict count])
{
if ([dict objectForKey: NSHTTPCookiePath] == nil)
[dict setObject: defaultPath forKey: NSHTTPCookiePath];
{
[dict setObject: defaultPath forKey: NSHTTPCookiePath];
}
if ([dict objectForKey: NSHTTPCookieDomain] == nil)
[dict setObject: defaultDomain forKey: NSHTTPCookieDomain];
{
[dict setObject: defaultDomain forKey: NSHTTPCookieDomain];
}
cookie = [NSHTTPCookie cookieWithProperties: dict];
if (cookie)
[a addObject: cookie];
{
[cookies replaceObjectAtIndex: count withObject: cookie];
}
else
{
[cookies removeObjectAtIndex: count];
}
}
if ([field length] <= NSMaxRange(range))
break;
field = [field substringFromIndex: NSMaxRange(range)+1];
}
return a;
return cookies;
}
+ (NSArray *) cookiesWithResponseHeaderFields: (NSDictionary *)headerFields
@ -833,72 +846,139 @@ GSPropertyListFromCookieFormat(NSString *string, int version)
return AUTORELEASE(dict);
}
/* Look for the comma that separates cookies. Commas can also occur in
date strings, like "expires", but perhaps it can occur other places.
For instance, the key/value pair key=value1,value2 is not really
valid, but should we handle it anyway? Definitely we should handle the
perfectly normal case of:
Set-Cookie: domain=test.com; expires=Thu, 12-Sep-2109 14:58:04 GMT;
session=foo
Set-Cookie: bar=baz
which gets concatenated into something like:
Set-Cookie: domain=test.com; expires=Thu, 12-Sep-2109 14:58:04 GMT;
session=foo,bar=baz
*/
static NSRange
GSRangeOfCookie(NSString *string)
/* Split a string containing comma seprated cookeie settings into an array
* of individual cookie specifications.
* Look for the comma that separates cookies. Commas can also occur in
* date strings, like "expires", but perhaps it can occur other places.
* For instance, the key/value pair key=value1,value2 is not really
* valid, but should we handle it anyway? Definitely we should handle the
* perfectly normal case of:
*
* Set-Cookie: domain=test.com; expires=Thu, 12-Sep-2109 14:58:04 GMT;
* session=foo
* Set-Cookie: bar=baz
*
* which gets concatenated into something like:
*
* Set-Cookie: domain=test.com; expires=Thu, 12-Sep-2109 14:58:04 GMT;
* session=foo,bar=baz
*/
static NSMutableArray*
GSCookieStrings(NSString *string)
{
pldata _pld;
pldata *pld = &_pld;
unsigned char *ptr;
unsigned pos;
unsigned end;
NSData *d;
NSRange range;
NSMutableArray *cookies;
unsigned start = 0;
unsigned saved = 0;
/*
* An empty string is a nil property list.
*/
range = NSMakeRange(NSNotFound, NSNotFound);
if ([string length] == 0)
{
return range;
return nil;
}
d = [string dataUsingEncoding: NSUTF8StringEncoding];
NSCAssert(d, @"Couldn't get utf8 data from string.");
_pld.ptr = (unsigned char*)[d bytes];
_pld.pos = 0;
_pld.end = [d length];
_pld.err = nil;
_pld.lin = 0;
_pld.opt = 0;
_pld.key = NO;
_pld.old = YES; // OpenStep style
ptr = (unsigned char*)[d bytes];
pos = 0;
end = [d length];
while (skipSpace(pld) == YES)
cookies = [NSMutableArray arrayWithCapacity: 4];
while (pos < end)
{
if (pld->ptr[pld->pos] == ',')
while (pos < end && isspace(ptr[pos]))
{
/* Look ahead for something that will tell us if this is a
separate cookie or not */
unsigned saved_pos = pld->pos;
while (pld->ptr[pld->pos] != '=' && pld->ptr[pld->pos] != ';'
&& pld->ptr[pld->pos] != ',' && pld->pos < pld->end )
pld->pos++;
if (pld->ptr[pld->pos] == '=')
{
/* Separate comment */
range = NSMakeRange(0, saved_pos-1);
break;
}
pld->pos = saved_pos;
pos++;
}
pld->pos++;
}
if (range.location == NSNotFound)
range = NSMakeRange(0, [string length]);
start = pos;
return range;
while (pos < end)
{
if (ptr[pos] == ',')
{
/* Look ahead for something that will tell us if this is a
* separate cookie or not. We look for something of the form
* ' token =' where a space represents any optional whitespace.
*/
saved = pos++;
while (pos < end && isspace(ptr[pos]))
{
pos++;
}
if (pos < end)
{
const char *bad = "()<>@,;:\\\"/[]?={}";
int c = ptr[pos];
/* skip past token characters.
*/
while (c > 32 && c < 128 && strchr(bad, c) == 0)
{
pos++;
if (pos < end)
{
c = ptr[pos];
}
}
while (pos < end && isspace(ptr[pos]))
{
pos++;
}
if (pos < end && '=' == ptr[pos])
{
pos = saved + 1;
/* We found a comma separator: so make the text before
* the comma a cooke string as long as it is not empty.
*/
while (saved > start
&& isspace(ptr[saved - 1]))
{
saved--;
}
if (saved > start)
{
NSString *str = [NSString alloc];
str = [str initWithBytes: ptr + start
length: saved - start
encoding: NSUTF8StringEncoding];
[cookies addObject: str];
RELEASE(str);
}
start = saved = pos;
}
}
pos = saved;
}
pos++;
}
}
if (pos > start)
{
/* There was data after the last comma; make it into a cookie string
* as long as it's not empty after removing spaces
*/
saved = pos;
while (saved > start
&& isspace(ptr[saved - 1]))
{
saved--;
}
if (saved > start)
{
NSString *str = [NSString alloc];
/* There may not be room to add a nul terminator, so we use an
* initialiser which doesn't need one.
*/
str = [str initWithBytes: ptr + start
length: saved - start
encoding: NSUTF8StringEncoding];
[cookies addObject: str];
RELEASE(str);
}
}
return cookies; // The individual cookies
}

View file

@ -627,6 +627,11 @@ static NSRecursiveLock *classLock = nil;
[[dict objectForKey: NSLocaleCollationIdentifier] UTF8String];
const char *currency = [[dict objectForKey: NSLocaleCurrencyCode] UTF8String];
if (!calendar)
{
calendar = [[dict objectForKey: NSLocaleCalendarIdentifier] UTF8String];
}
// A locale cannot be constructed without a language.
if (language == NULL)
return nil;

View file

@ -110,6 +110,11 @@ static Class concreteClass = 0;
[self name], [self object], [self userInfo]];
}
- (NSUInteger) hash
{
return [[self name] hash] ^ [[self object] hash];
}
- (id) init
{
if ([self class] == abstractClass)
@ -122,6 +127,22 @@ static Class concreteClass = 0;
return self;
}
- (BOOL) isEqual: (id)other
{
NSNotification *o;
NSObject *v1;
NSObject *v2;
if (NO == [(o = other) isKindOfClass: [NSNotification class]]
|| ((v1 = [self name]) != (v2 = [o name]) && ![v1 isEqual: v2])
|| ((v1 = [self object]) != (v2 = [o object]) && ![v1 isEqual: v2])
|| ((v1 = [self userInfo]) != (v2 = [o userInfo]) && ![v1 isEqual: v2]))
{
return NO;
}
return YES;
}
/**
* Returns the notification name.
*/

View file

@ -217,6 +217,7 @@ static NSArray *empty = nil;
RELEASE(internal->dependencies);
RELEASE(internal->cond);
RELEASE(internal->lock);
RELEASE(internal->completionBlock);
GS_DESTROY_INTERNAL(NSOperation);
}
[super dealloc];
@ -381,7 +382,7 @@ static NSArray *empty = nil;
- (void) setCompletionBlock: (GSOperationCompletionBlock)aBlock
{
internal->completionBlock = aBlock;
ASSIGNCOPY(internal->completionBlock, aBlock);
}
- (void) setQueuePriority: (NSOperationQueuePriority)pri
@ -1099,9 +1100,18 @@ static NSOperationQueue *mainQueue = nil;
|| (pending > 0 && internal->threadCount < POOL))
{
internal->threadCount++;
[NSThread detachNewThreadSelector: @selector(_thread)
toTarget: self
withObject: nil];
NS_DURING
{
[NSThread detachNewThreadSelector: @selector(_thread)
toTarget: self
withObject: nil];
}
NS_HANDLER
{
NSLog(@"Failed to create thread for %@: %@",
self, localException);
}
NS_ENDHANDLER
}
/* Tell the thread pool that there is an operation to start.
*/

View file

@ -1901,7 +1901,8 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
}
}
- (NSString *) stringByAddingPercentEncodingWithAllowedCharacters: (NSCharacterSet *)aSet
- (NSString *) stringByAddingPercentEncodingWithAllowedCharacters:
(NSCharacterSet *)aSet
{
NSData *data = [self dataUsingEncoding: NSUTF8StringEncoding];
NSString *s = nil;
@ -1921,7 +1922,10 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
unsigned int hi;
unsigned int lo;
if([aSet characterIsMember: c]) // if the character is in the allowed set, put it in
/* If the character is in the allowed set *and* is in the
* 7-bit ASCII range, it can be added unchanged.
*/
if (c < 128 && [aSet characterIsMember: c])
{
dst[dpos++] = c;
}
@ -1936,7 +1940,7 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
}
s = [[NSString alloc] initWithBytes: dst
length: dpos
encoding: NSUTF8StringEncoding];
encoding: NSASCIIStringEncoding];
NSZoneFree(NSDefaultMallocZone(), dst);
IF_NO_GC([s autorelease];)
}
@ -1963,7 +1967,7 @@ GSICUCollatorOpen(NSStringCompareOptions mask, NSLocale *locale)
uint8_t hi = s[index+1];
uint8_t lo = s[index+2];
if (isdigit(hi) && isxdigit(lo))
if (isxdigit(hi) && isxdigit(lo))
{
index += 2;
if (hi <= '9')

View file

@ -68,6 +68,7 @@ function may be incorrect
#import "common.h"
#define EXPOSE_NSURL_IVARS 1
#import "Foundation/NSArray.h"
#import "Foundation/NSAutoreleasePool.h"
#import "Foundation/NSCoder.h"
#import "Foundation/NSData.h"
#import "Foundation/NSDictionary.h"
@ -89,138 +90,6 @@ function may be incorrect
NSString * const NSURLErrorDomain = @"NSURLErrorDomain";
NSString * const NSErrorFailingURLStringKey = @"NSErrorFailingURLStringKey";
@interface NSString (NSURLPrivate)
- (NSString*) _stringByAddingPercentEscapes;
- (NSString*) _stringByAddingPercentEscapesForQuery;
@end
@implementation NSString (NSURLPrivate)
/* Like the normal percent escape method, but with additional characters
* escaped (for use by file scheme URLs).
*/
- (NSString*) _stringByAddingPercentEscapes
{
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)
{
unsigned char c = src[spos++];
unsigned int hi;
unsigned int lo;
if (c <= 32
|| c > 126
|| c == 34
|| c == 35
|| c == 37
|| c == 59
|| c == 60
|| c == 62
|| c == 63
|| c == 91
|| c == 92
|| c == 93
|| c == 94
|| c == 96
|| c == 123
|| c == 124
|| c == 125)
{
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;
}
else
{
dst[dpos++] = c;
}
}
s = [[NSString alloc] initWithBytes: dst
length: dpos
encoding: NSASCIIStringEncoding];
NSZoneFree(NSDefaultMallocZone(), dst);
IF_NO_GC([s autorelease];)
}
return s;
}
/*
* Encode query
*/
- (NSString*) _stringByAddingPercentEscapesForQuery
{
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)
{
unsigned char c = src[spos++];
unsigned int hi;
unsigned int lo;
if (c <= 32
|| c > 126
|| c == 34
|| c == 35
|| c == 37
|| c == 38
|| c == 59
|| c == 60
|| c == 61
|| c == 62
|| c == 91
|| c == 92
|| c == 93
|| c == 94
|| c == 96
|| c == 123
|| c == 124
|| c == 125)
{
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;
}
else
{
dst[dpos++] = c;
}
}
s = [[NSString alloc] initWithBytes: dst
length: dpos
encoding: NSASCIIStringEncoding];
NSZoneFree(NSDefaultMallocZone(), dst);
IF_NO_GC([s autorelease];)
}
return s;
}
@end
@interface NSURL (GSPrivate)
- (NSURL*) _URLBySettingPath: (NSString*)newPath;
@end
@ -707,6 +576,7 @@ static char *unescape(const char *from, char * to)
@implementation NSURL
static NSCharacterSet *fileCharSet = nil;
static NSUInteger urlAlign;
+ (id) fileURLWithPath: (NSString*)aPath
@ -732,6 +602,8 @@ static NSUInteger urlAlign;
NSGetSizeAndAlignment(@encode(parsedURL), &urlAlign, 0);
clientsLock = [NSLock new];
[[NSObject leakAt: &clientsLock] release];
ASSIGN(fileCharSet, [NSCharacterSet characterSetWithCharactersInString:
@"!$&'()*+,-./0123456789:=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~"]);
}
}
@ -832,7 +704,8 @@ static NSUInteger urlAlign;
if ([aScheme isEqualToString: @"file"])
{
aPath = [aPath _stringByAddingPercentEscapes];
aPath = [aPath stringByAddingPercentEncodingWithAllowedCharacters:
fileCharSet];
}
else
{
@ -2325,6 +2198,30 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
@implementation NSURLComponents
static NSCharacterSet *queryItemCharSet = nil;
+ (void) initialize
{
if (nil == queryItemCharSet)
{
ENTER_POOL
NSMutableCharacterSet *m;
m = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
/* Rationale: if a query item contained an ampersand we would not be
* able to tell where one name/value pair ends and the next starts,
* so we cannot permit that character in an item. Similarly, if a
* query item contained an equals sign we would not be able to tell
* where the name ends and the value starts, so we cannot permit that
* character either.
*/
[m removeCharactersInString: @"&="];
queryItemCharSet = [m copy];
LEAVE_POOL
}
}
// Creating URL components...
+ (instancetype) componentsWithString: (NSString *)urlString
{
@ -2765,8 +2662,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
// Accessing Components in PercentEncoded Format
- (NSString *) percentEncodedFragment
{
return [internal->_fragment stringByAddingPercentEncodingWithAllowedCharacters:
[NSCharacterSet URLFragmentAllowedCharacterSet]];
return [internal->_fragment
stringByAddingPercentEncodingWithAllowedCharacters:
[NSCharacterSet URLFragmentAllowedCharacterSet]];
}
- (void) setPercentEncodedFragment: (NSString *)fragment
@ -2776,8 +2674,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
- (NSString *) percentEncodedHost
{
return [internal->_host stringByAddingPercentEncodingWithAllowedCharacters:
[NSCharacterSet URLHostAllowedCharacterSet]];
return [internal->_host
stringByAddingPercentEncodingWithAllowedCharacters:
[NSCharacterSet URLHostAllowedCharacterSet]];
}
- (void) setPercentEncodedHost: (NSString *)host
@ -2787,8 +2686,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
- (NSString *) percentEncodedPassword
{
return [internal->_password stringByAddingPercentEncodingWithAllowedCharacters:
[NSCharacterSet URLPasswordAllowedCharacterSet]];
return [internal->_password
stringByAddingPercentEncodingWithAllowedCharacters:
[NSCharacterSet URLPasswordAllowedCharacterSet]];
}
- (void) setPercentEncodedPassword: (NSString *)password
@ -2798,8 +2698,9 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
- (NSString *) percentEncodedPath
{
return [internal->_path stringByAddingPercentEncodingWithAllowedCharacters:
[NSCharacterSet URLPathAllowedCharacterSet]];
return [internal->_path
stringByAddingPercentEncodingWithAllowedCharacters:
[NSCharacterSet URLPathAllowedCharacterSet]];
}
- (void) setPercentEncodedPath: (NSString *)path
@ -2874,8 +2775,10 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
NSString *name = [i name];
NSString *value = [i value];
name = [name _stringByAddingPercentEscapesForQuery];
value = [value _stringByAddingPercentEscapesForQuery];
name = [name stringByAddingPercentEncodingWithAllowedCharacters:
queryItemCharSet];
value = [value stringByAddingPercentEncodingWithAllowedCharacters:
queryItemCharSet];
ni = [NSURLQueryItem queryItemWithName: name
value: value];
[items addObject: ni];
@ -2915,7 +2818,7 @@ GS_PRIVATE_INTERNAL(NSURLComponents)
- (NSString *) percentEncodedUser
{
return [internal->_user stringByAddingPercentEncodingWithAllowedCharacters:
[NSCharacterSet URLUserAllowedCharacterSet]];
[NSCharacterSet URLUserAllowedCharacterSet]];
}
- (void) setPercentEncodedUser: (NSString *)user

View file

@ -373,7 +373,7 @@ typedef struct {
NSInputStream *input;
NSOutputStream *output;
NSCachedURLResponse *cachedResponse;
id <NSURLProtocolClient> client; // Not retained
id <NSURLProtocolClient> client;
NSURLRequest *request;
NSString *in;
NSString *out;
@ -526,6 +526,7 @@ static NSURLProtocol *placeholder = nil;
}
DESTROY(this->cachedResponse);
DESTROY(this->request);
DESTROY(this->client);
#if USE_ZLIB
if (this->compressing == YES)
{
@ -596,7 +597,7 @@ static NSURLProtocol *placeholder = nil;
{
this->request = [request copy];
this->cachedResponse = RETAIN(cachedResponse);
this->client = client; // Not retained
this->client = RETAIN(client);
}
return self;
}

View file

@ -114,12 +114,29 @@ typedef struct {
{
GSMimeHeader *h;
/* Remove existing headers matching the ones we are setting.
*/
e = [(NSArray*)headers objectEnumerator];
while ((h = [e nextObject]) != nil)
{
NSString *n = [h namePreservingCase: YES];
[this->headers removeObjectForKey: n];
}
/* Set new headers, joining values where we have multiple headers
* with the same name.
*/
e = [(NSArray*)headers objectEnumerator];
while ((h = [e nextObject]) != nil)
{
NSString *n = [h namePreservingCase: YES];
NSString *o = [this->headers objectForKey: n];
NSString *v = [h fullValue];
if (nil != o)
{
n = [NSString stringWithFormat: @"%@, %@", o, n];
}
[self _setValue: v forHTTPHeaderField: n];
}
}

View file

@ -17,6 +17,8 @@ int main()
NSCalendar *cal;
NSDate *date;
NSDate *date2;
NSDate *date3;
NSDate *date4;
START_SET("NSCalendar 10.7 features")
if (!NSCALENDAR_SUPPORTED)
@ -48,7 +50,13 @@ int main()
date2 = [comps date];
PASS_EQUAL(date, date2, "-[NSDateComponents date] returns the correct date");
date3 = [NSDate dateWithString: @"2012-12-31 13:57:00 +0200"];
[comps setTimeZone: [NSTimeZone timeZoneForSecondsFromGMT: 7200]];
date4 = [cal dateFromComponents: comps];
PASS_EQUAL(date3, date4, "-[NSCalendar dateFromComponents:] respects the time zone");
RELEASE(comps);
RELEASE(cal);

View file

@ -39,14 +39,15 @@ int main()
PASS(cookie == nil, "cookie without path returns nil");
dict = [NSDictionary dictionaryWithObject:
@"S=calendar=R7tjDKqNB5L8YTZSvf29Bg;Expires=Wed, 09-Mar-2011 23:00:35 GMT"
@"S=calendar=R7tjDKqNB5L8YTZSvf29Bg;Expires=Wed, 09-Mar-2011 23:00:35 GMT, "
@"S=xxxxxxxx=R7tjDKqNB5L8YTZSvf29Bg;Expires=Thu, 10-Mar-2011 23:00:35 GMT"
forKey: @"Set-Cookie"];
url = [NSURL URLWithString: @"http://www.google.com/calendar/feeds/default/"];
cookies= [NSHTTPCookie cookiesWithResponseHeaderFields: dict forURL: url];
TEST_FOR_CLASS(@"NSArray", cookies,
"NSHTTPCookie +cookiesWithResponseHeaderFields: returns an NSArray");
PASS([cookies count ] == 1, "cookies array contains a cookie");
PASS([cookies count ] == 2, "cookies array contains two cookies");
cookie = [cookies objectAtIndex: 0];
PASS([[cookie name] isEqual: @"S"], "NSHTTPCookie returns proper name");
PASS([[cookie value] isEqual: @"calendar=R7tjDKqNB5L8YTZSvf29Bg"],
@ -56,6 +57,7 @@ int main()
PASS(![cookie isSecure], "Cookie is not secure");
PASS(![cookie isHTTPOnly], "Cookie is not http only");
cookies = [cookies subarrayWithRange: NSMakeRange(0, 1)];
dict = [NSHTTPCookie requestHeaderFieldsWithCookies: cookies];
PASS_EQUAL([dict objectForKey: @"Cookie"],
@"S=calendar=R7tjDKqNB5L8YTZSvf29Bg",

View file

@ -26,7 +26,19 @@ int main()
NSMutableArray *testObjs = [[NSMutableArray alloc] init];
NSAutoreleasePool *arp = [NSAutoreleasePool new];
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:
@"obj", @"key", nil];
NSNotification *o1 = [NSNotification notificationWithName: @"hello"
object: @"there"
userInfo: info];
NSNotification *o2 = [NSNotification notificationWithName: @"hello"
object: @"there"
userInfo: info];
PASS([o1 hash] == [o2 hash], "equal notification hashes")
PASS_EQUAL(o1, o2, "equal notifications")
test_alloc(@"NSNotification");
obj = [NSNotification new];
[testObjs addObject: obj];
test_NSObject(@"NSNotification", testObjs);

View file

@ -3,55 +3,93 @@
#import <Foundation/NSString.h>
#import <Foundation/NSCharacterSet.h>
BOOL testUrlCharacterSetEncoding(
NSString* decodedString,
NSString* encodedString,
NSCharacterSet* allowedCharacterSet)
{
NSString *testString
= [decodedString stringByAddingPercentEncodingWithAllowedCharacters:
allowedCharacterSet];
// NSLog(@"String by adding percent, done. test=%@ decoded=%@", testString, decodedString);
return [encodedString isEqualToString: testString];
void testEncodeDecode(NSString* encoded, NSString* decoded, NSCharacterSet* charset, NSString* description){
NSString* encodeTest = [decoded stringByAddingPercentEncodingWithAllowedCharacters:charset];
NSString* decodeTest = [encoded stringByRemovingPercentEncoding];
const char* encodeMsg = [[NSString stringWithFormat:@"Percent-Encode: %@", description] UTF8String];
const char* decodeMsg = [[NSString stringWithFormat:@"Percent-Decode: %@", description] UTF8String];
PASS_EQUAL(encodeTest, encoded, "%s", encodeMsg);
PASS_EQUAL(decodeTest, decoded, "%s", decodeMsg);
}
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
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");
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";
testEncodeDecode(urlEncodedString, urlDecodedString, [NSCharacterSet alphanumericCharacterSet],
@"Skip alphanumericCharacterSet 01");
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");
testEncodeDecode(urlEncodedString, urlDecodedString, [NSCharacterSet URLFragmentAllowedCharacterSet],
@"Skip URLFragmentAllowedCharacterSet 02");
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");
testEncodeDecode(urlEncodedString, urlDecodedString, [[NSCharacterSet alphanumericCharacterSet] invertedSet],
@"Skip not alphanumericCharacterSet 03");
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");
testEncodeDecode(urlEncodedString, urlDecodedString, [NSCharacterSet URLFragmentAllowedCharacterSet],
@"Skip URLFragmentAllowedCharacterSet 04");
urlDecodedString = @"\1";
urlEncodedString = @"%01";
allowedCharacterSet = [NSCharacterSet alphanumericCharacterSet];
PASS(testUrlCharacterSetEncoding(urlDecodedString, urlEncodedString, allowedCharacterSet), "alphanumericCharacterSet");
testEncodeDecode(urlEncodedString, urlDecodedString, [NSCharacterSet alphanumericCharacterSet],
@"Skip URLFragmentAllowedCharacterSet 05");
urlDecodedString = @"£";
urlEncodedString = @"%C2%A3";
testEncodeDecode(urlEncodedString, urlDecodedString, [NSCharacterSet alphanumericCharacterSet],
@"Two-byte character 06");
urlDecodedString = @"€";
urlEncodedString = @"%E2%82%AC";
testEncodeDecode(urlEncodedString, urlDecodedString, [NSCharacterSet alphanumericCharacterSet],
@"Three-byte character 07");
urlDecodedString = @"𐍈";
urlEncodedString = @"%F0%90%8D%88";
testEncodeDecode(urlEncodedString, urlDecodedString, [NSCharacterSet alphanumericCharacterSet],
@"Four-byte character 08");
//check full string encoding and decoding
urlDecodedString = @"0123456789 AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz _-~`!#$%&'()*+,/:;=?@[]™…©®£ƒ‰¥§";
urlEncodedString = @"%30%31%32%33%34%35%36%37%38%39%20%41%61%42%62%43%63%44%64%45%65%46%66%47%67%48%68%49%69%4A%6A%4B%6B%4C%6C%4D%6D%4E%6E%4F%6F%50%70%51%71%52%72%53%73%54%74%55%75%56%76%57%77%58%78%59%79%5A%7A%20%5F%2D%7E%60%21%23%24%25%26%27%28%29%2A%2B%2C%2F%3A%3B%3D%3F%40%5B%5D%E2%84%A2%E2%80%A6%C2%A9%C2%AE%C2%A3%C6%92%E2%80%B0%C2%A5%C2%A7";
testEncodeDecode(urlEncodedString, urlDecodedString, [[NSCharacterSet characterSetWithCharactersInString:urlDecodedString] invertedSet],
@"All characters in string 09");
//check decoding of string with an unencoded part at the beginning
NSString* asIsString = @"0123456789 AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz _-~`!#$&'()*+,/:;=?@[]™…©®£ƒ‰¥§";
urlDecodedString = [asIsString stringByAppendingString:urlDecodedString];
urlEncodedString = [asIsString stringByAppendingString:urlEncodedString];
PASS_EQUAL([urlEncodedString stringByRemovingPercentEncoding], urlDecodedString, "Percent-encoded string decoding 10");
//check decoding of string with the encoded part in the middle
urlDecodedString = [urlDecodedString stringByAppendingString:asIsString];
urlEncodedString = [urlEncodedString stringByAppendingString:asIsString];
PASS_EQUAL([urlEncodedString stringByRemovingPercentEncoding], urlDecodedString, "Percent-encoded string decoding 11");
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;
}

View file

@ -29,9 +29,12 @@ int main()
TEST_FOR_CLASS(@"NSURL", [NSURL URLWithString: @"http://www.w3.org/"],
"NSURL +URLWithString: returns an NSURL");
url = [NSURL URLWithString: nil];
PASS(nil == url, "A nil string result in nil URL");
str = [NSString stringWithCharacters: bad length: sizeof(bad)/sizeof(*bad)];
url = [NSURL URLWithString: str];
PASS(nil == url, "Bad characters result in nil");
PASS(nil == url, "Bad characters result in nil URL");
str = [NSString stringWithCharacters: &u length: 1];
url = [NSURL fileURLWithPath: str];
@ -292,17 +295,20 @@ GSPathHandling("right");
PASS(nil == [url host], "host");
PASS(nil == [url user], "user");
PASS(nil == [url password], "password");
PASS([@"/pathtofile;parameters?query#anchor"
isEqual: [url resourceSpecifier]], "resourceSpecifier");
PASS([@"/pathtofile" isEqual: [url path]], "path");
PASS([@"query" isEqual: [url query]], "query");
PASS([@"parameters" isEqual: [url parameterString]], "parameterString");
PASS([@"anchor" isEqual: [url fragment]], "fragment");
PASS([@"file:///pathtofile;parameters?query#anchor"
isEqual: [url absoluteString]], "absoluteString");
PASS([@"/pathtofile" isEqual: [url relativePath]], "relativePath");
PASS([@"file:///pathtofile;parameters?query#anchor"
isEqual: [url description]], "description");
PASS_EQUAL([url resourceSpecifier],
@"/pathtofile;parameters?query#anchor",
"resourceSpecifier");
PASS_EQUAL([url path], @"/pathtofile", "path");
PASS_EQUAL([url query], @"query", "query");
PASS_EQUAL([url parameterString], @"parameters", "parameterString");
PASS_EQUAL([url fragment], @"anchor", "fragment");
PASS_EQUAL([url absoluteString],
@"file:///pathtofile;parameters?query#anchor",
"absoluteString");
PASS_EQUAL([url relativePath], @"/pathtofile", "relativePath");
PASS_EQUAL([url description],
@"file:///pathtofile;parameters?query#anchor",
"description");
url = [NSURL URLWithString: @"file:///pathtofile; parameters? query #anchor"]; // can't initialize with spaces (must be %20)
PASS(nil == url, "url with spaces");

View file

@ -0,0 +1,55 @@
#import <Foundation/Foundation.h>
#import "Testing.h"
#import "ObjectTesting.h"
int main()
{
START_SET("URL character sets")
NSMutableString *m = [NSMutableString string];
NSDictionary *sets;
NSEnumerator *enumerator;
NSString *key;
sets = [NSDictionary dictionaryWithObjectsAndKeys:
@"!$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~",
@"URLFragmentAllowedCharacterSet",
@"!$&'()*+,-.0123456789:;=ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~",
@"URLHostAllowedCharacterSet",
@"!$&'()*+,-.0123456789;=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~",
@"URLPasswordAllowedCharacterSet",
@"!$&'()*+,-./0123456789:=@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~",
@"URLPathAllowedCharacterSet",
@"!$&'()*+,-./0123456789:;=?@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~",
@"URLQueryAllowedCharacterSet",
@"!$&'()*+,-.0123456789;=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~",
@"URLUserAllowedCharacterSet",
nil];
enumerator = [sets keyEnumerator];
while (nil != (key = [enumerator nextObject]))
{
NSString *expect = [sets objectForKey: key];
const char *name = [key UTF8String];
NSCharacterSet *set;
unichar c;
set = (NSCharacterSet*)[[NSCharacterSet class] performSelector:
NSSelectorFromString(key)];
[m setString: @""];
for (c = 0; c < 128; c++)
{
if ([set characterIsMember: c])
{
NSString *s;
s = [[NSString alloc] initWithCharacters: &c length: 1];
[m appendString: s];
RELEASE(s);
}
}
PASS_EQUAL(m, expect, "%s as string", name)
}
END_SET("URL character sets")
return 0;
}

23
configure vendored
View file

@ -670,7 +670,6 @@ HAVE_PTS_STREAM_MODULES
OBJCFLAGS
HAVE_OBJC_SYNC_ENTER
BASE_NATIVE_OBJC_EXCEPTIONS
GS_MIXEDABI
GS_NONFRAGILE
HAVE_BLOCKS
OBJC2RUNTIME
@ -794,7 +793,6 @@ with_default_config
with_installation_domain
enable_largefile
enable_nxconstantstring
enable_mixedabi
enable_bfd
enable_procfs
enable_procfs_psinfo
@ -1477,9 +1475,6 @@ Optional Features:
--disable-largefile omit support for large files
--enable-nxconstantstring
Enables the use of the NXConstantString class for old compilers.
--disable-mixedabi
Disables the combined use of fragile and nonfragile ABI so that base
can be built taking full advantage of the nonfragile ABI.
--enable-bfd
Enables the use of libbfd to provide symbolic stack traces.
Enabling this option provides support for symbolic stack traces
@ -2732,8 +2727,9 @@ fi
if test -z "$LIBRARY_COMBO"; then
LIBRARY_COMBO=`gnustep-config --variable=LIBRARY_COMBO 2>&5`
fi
OBJC_RUNTIME_LIB=`echo $LIBRARY_COMBO | tr '-' ' ' | awk '{print $1}'`
if test "$OBJC_RUNTIME_LIB" = "ng"; then
if test "$OBJC_RUNTIME_LIB" = "ng" -o "$OBJC_RUNTIME_LIB" = "apple"; then
nonfragile=yes
BASE_NONFRAGILE_ABI=1
else
@ -6008,7 +6004,6 @@ esac
#--------------------------------------------------------------------
# Set Apple/Darwin/OSX/NeXT information for other tests
#--------------------------------------------------------------------
OBJC_RUNTIME_LIB=`echo $LIBRARY_COMBO | tr '-' ' ' | awk '{print $1}'`
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the Objective-C runtime" >&5
$as_echo_n "checking the Objective-C runtime... " >&6; }
if test "$OBJC_RUNTIME_LIB" = "nx" -o "$OBJC_RUNTIME_LIB" = "apple"; then
@ -8101,7 +8096,6 @@ fi
# Don't revert any Objective-C flags as they are used in the next test
GS_NONFRAGILE=0
GS_MIXEDABI=0
if test "$nonfragile" = "yes"; then
saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $OBJCFLAGS -x objective-c"
@ -8126,18 +8120,6 @@ fi
CPPFLAGS="$saved_CPPFLAGS"
if test $non_fragile = yes; then
GS_NONFRAGILE=1
if test "$OBJC_RUNTIME_LIB" != "ng"; then
# Check whether --enable-mixedabi was given.
if test "${enable_mixedabi+set}" = set; then :
enableval=$enable_mixedabi;
else
enable_mixedabi=yes
fi
if test $enable_mixedabi = yes; then
GS_MIXEDABI=1
fi
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $non_fragile" >&5
$as_echo "$non_fragile" >&6; }
@ -8145,7 +8127,6 @@ fi
# Don't revert any Objective-C flags as they are used in the next test
#--------------------------------------------------------------------

View file

@ -89,8 +89,9 @@ fi
if test -z "$LIBRARY_COMBO"; then
LIBRARY_COMBO=`gnustep-config --variable=LIBRARY_COMBO 2>&5`
fi
OBJC_RUNTIME_LIB=`echo $LIBRARY_COMBO | tr '-' ' ' | awk '{print $1}'`
if test "$OBJC_RUNTIME_LIB" = "ng"; then
if test "$OBJC_RUNTIME_LIB" = "ng" -o "$OBJC_RUNTIME_LIB" = "apple"; then
nonfragile=yes
BASE_NONFRAGILE_ABI=1
else
@ -1254,7 +1255,6 @@ esac
#--------------------------------------------------------------------
# Set Apple/Darwin/OSX/NeXT information for other tests
#--------------------------------------------------------------------
OBJC_RUNTIME_LIB=`echo $LIBRARY_COMBO | tr '-' ' ' | awk '{print $1}'`
AC_MSG_CHECKING(the Objective-C runtime)
if test "$OBJC_RUNTIME_LIB" = "nx" -o "$OBJC_RUNTIME_LIB" = "apple"; then
AC_MSG_RESULT(NeXT)
@ -2017,7 +2017,6 @@ AC_SUBST(HAVE_BLOCKS)
# Don't revert any Objective-C flags as they are used in the next test
GS_NONFRAGILE=0
GS_MIXEDABI=0
if test "$nonfragile" = "yes"; then
saved_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $OBJCFLAGS -x objective-c"
@ -2029,21 +2028,10 @@ if test "$nonfragile" = "yes"; then
CPPFLAGS="$saved_CPPFLAGS"
if test $non_fragile = yes; then
GS_NONFRAGILE=1
if test "$OBJC_RUNTIME_LIB" != "ng"; then
AC_ARG_ENABLE(mixedabi,
[ --disable-mixedabi
Disables the combined use of fragile and nonfragile ABI so that base
can be built taking full advantage of the nonfragile ABI.],,
enable_mixedabi=yes)
if test $enable_mixedabi = yes; then
GS_MIXEDABI=1
fi
fi
fi
AC_MSG_RESULT($non_fragile)
fi
AC_SUBST(GS_NONFRAGILE)
AC_SUBST(GS_MIXEDABI)
# Don't revert any Objective-C flags as they are used in the next test