ObjFW  Check-in [36669d22b4]

Overview
Comment:Merge trunk into 1.0 branch
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | 1.0
Files: files | file ages | folders
SHA3-256: 36669d22b4045a853e24faa89f21ab9069a7d8bb42e690f3ca3eab9f5fe59bfe
User & Date: js on 2021-04-07 21:18:26
Other Links: branch diff | manifest | tags
Context
2021-04-07
22:38
Merge trunk into 1.0 branch check-in: 5234b350ac user: js tags: 1.0
21:18
Merge trunk into 1.0 branch check-in: 36669d22b4 user: js tags: 1.0
21:14
Rename OFCryptoHash -> OFCryptographicHash check-in: 2969086342 user: js tags: trunk
2021-03-30
21:23
Merge trunk into 1.0 branch check-in: 564d6d6b6f user: js tags: 1.0
Changes

Modified src/Makefile from [c505c2d004] to [581f6c2e48].

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
       OFArray.m			\
       OFBlock.m			\
       OFCharacterSet.m			\
       OFColor.m			\
       OFConstantString.m		\
       OFCountedSet.m			\
       OFData.m				\
       OFData+CryptoHashing.m		\
       OFData+MessagePackParsing.m	\
       OFDate.m				\
       OFDictionary.m			\
       OFEnumerator.m			\
       OFFileManager.m			\
       OFGZIPStream.m			\
       OFHMAC.m				\







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
       OFArray.m			\
       OFBlock.m			\
       OFCharacterSet.m			\
       OFColor.m			\
       OFConstantString.m		\
       OFCountedSet.m			\
       OFData.m				\
       OFData+CryptographicHashing.m	\
       OFData+MessagePackParsing.m	\
       OFDate.m				\
       OFDictionary.m			\
       OFEnumerator.m			\
       OFFileManager.m			\
       OFGZIPStream.m			\
       OFHMAC.m				\
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
       OFSHA384Hash.m			\
       OFSHA384Or512Hash.m		\
       OFSHA512Hash.m			\
       OFSortedList.m			\
       OFStdIOStream.m			\
       OFStream.m			\
       OFString.m			\
       OFString+CryptoHashing.m		\
       OFString+JSONParsing.m		\
       OFString+PropertyListParsing.m	\
       OFString+Serialization.m		\
       OFString+URLEncoding.m		\
       OFString+XMLEscaping.m		\
       OFString+XMLUnescaping.m		\
       ${OF_SUBUPROCESS_M}		\







|







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
       OFSHA384Hash.m			\
       OFSHA384Or512Hash.m		\
       OFSHA512Hash.m			\
       OFSortedList.m			\
       OFStdIOStream.m			\
       OFStream.m			\
       OFString.m			\
       OFString+CryptographicHashing.m	\
       OFString+JSONParsing.m		\
       OFString+PropertyListParsing.m	\
       OFString+Serialization.m		\
       OFString+URLEncoding.m		\
       OFString+XMLEscaping.m		\
       OFString+XMLUnescaping.m		\
       ${OF_SUBUPROCESS_M}		\
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
		  atomic_no_threads.h		\
		  atomic_osatomic.h		\
		  atomic_powerpc.h		\
		  atomic_sync_builtins.h	\
		  atomic_x86.h
INCLUDES := ${SRCS:.m=.h}			\
	    OFCollection.h			\
	    OFCryptoHash.h			\
	    OFJSONRepresentation.h		\
	    OFKernelEventObserver.h		\
	    OFKeyValueCoding.h			\
	    OFLocking.h				\
	    OFMessagePackRepresentation.h	\
	    OFSerialization.h			\
	    OFTLSSocket.h			\







|







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
		  atomic_no_threads.h		\
		  atomic_osatomic.h		\
		  atomic_powerpc.h		\
		  atomic_sync_builtins.h	\
		  atomic_x86.h
INCLUDES := ${SRCS:.m=.h}			\
	    OFCollection.h			\
	    OFCryptographicHash.h		\
	    OFJSONRepresentation.h		\
	    OFKernelEventObserver.h		\
	    OFKeyValueCoding.h			\
	    OFLocking.h				\
	    OFMessagePackRepresentation.h	\
	    OFSerialization.h			\
	    OFTLSSocket.h			\

Modified src/OFArray.h from [134eddeab8] to [702817f9c0].

213
214
215
216
217
218
219







220
221
222
223
224
225
226
 * @param objects A C array of objects
 * @param count The length of the C array
 * @return An initialized OFArray
 */
- (instancetype)initWithObjects: (ObjectType const _Nonnull *_Nonnull)objects
			  count: (size_t)count;








/**
 * @brief Returns the object at the specified index in the array.
 *
 * @warning The returned object is *not* retained and autoreleased for
 *	    performance reasons!
 *
 * @param index The index of the object to return







>
>
>
>
>
>
>







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
 * @param objects A C array of objects
 * @param count The length of the C array
 * @return An initialized OFArray
 */
- (instancetype)initWithObjects: (ObjectType const _Nonnull *_Nonnull)objects
			  count: (size_t)count;

/**
 * @brief Returns an OFEnumerator to enumerate through all objects of the array.
 *
 * @return An OFEnumerator to enumerate through all objects of the array
 */
- (OFEnumerator OF_GENERIC(ObjectType) *)objectEnumerator;

/**
 * @brief Returns the object at the specified index in the array.
 *
 * @warning The returned object is *not* retained and autoreleased for
 *	    performance reasons!
 *
 * @param index The index of the object to return

Modified src/OFCollection.h from [9e18f6ef6d] to [af0d421edb].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
OF_ASSUME_NONNULL_BEGIN

/**
 * @protocol OFCollection OFCollection.h ObjFW/OFCollection.h
 *
 * @brief A protocol with methods common for all collections.
 */
@protocol OFCollection <OFEnumerating, OFFastEnumeration>
/**
 * @brief The number of objects in the collection
 */
@property (readonly, nonatomic) size_t count;

/**
 * @brief Checks whether the collection contains an object equal to the







|







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
OF_ASSUME_NONNULL_BEGIN

/**
 * @protocol OFCollection OFCollection.h ObjFW/OFCollection.h
 *
 * @brief A protocol with methods common for all collections.
 */
@protocol OFCollection <OFEnumeration, OFFastEnumeration>
/**
 * @brief The number of objects in the collection
 */
@property (readonly, nonatomic) size_t count;

/**
 * @brief Checks whether the collection contains an object equal to the

Modified src/OFConstantString.m from [3252c9a3ca] to [415348861e].

174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/* From protocol OFMutableCopying */
- (id)mutableCopy
{
	[self finishInitialization];
	return [self mutableCopy];
}

/* From protocol OFComparing */
- (of_comparison_result_t)compare: (id <OFComparing>)object
{
	[self finishInitialization];
	return [self compare: object];
}

/* From OFObject, but reimplemented in OFString */
- (bool)isEqual: (id)object







|
|







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/* From protocol OFMutableCopying */
- (id)mutableCopy
{
	[self finishInitialization];
	return [self mutableCopy];
}

/* From protocol OFComparing,  but overridden in OFString */
- (of_comparison_result_t)compare: (OFString *)object
{
	[self finishInitialization];
	return [self compare: object];
}

/* From OFObject, but reimplemented in OFString */
- (bool)isEqual: (id)object

Renamed and modified src/OFCryptoHash.h [eb798114fa] to src/OFCryptographicHash.h [3e39e62dc1].

14
15
16
17
18
19
20
21

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 */

#import "OFObject.h"

OF_ASSUME_NONNULL_BEGIN

/**
 * @protocol OFCryptoHash OFCryptoHash.h ObjFW/OFCryptoHash.h

 *
 * @brief A protocol for classes providing cryptographic hash functions.
 *
 * A cryptographic hash implementing this protocol can be copied. The entire
 * state is copied, allowing to calculate a new hash from there. This is
 * especially useful for generating many hashes with a common prefix.
 */
@protocol OFCryptoHash <OFObject, OFCopying>
#ifdef OF_HAVE_CLASS_PROPERTIES
@property (class, readonly, nonatomic) size_t digestSize;
@property (class, readonly, nonatomic) size_t blockSize;
#endif

/**
 * @brief The digest size of the cryptographic hash, in bytes.







|
>







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 */

#import "OFObject.h"

OF_ASSUME_NONNULL_BEGIN

/**
 * @protocol OFCryptographicHash \
 *	     OFCryptographicHash.h ObjFW/OFCryptographicHash.h
 *
 * @brief A protocol for classes providing cryptographic hash functions.
 *
 * A cryptographic hash implementing this protocol can be copied. The entire
 * state is copied, allowing to calculate a new hash from there. This is
 * especially useful for generating many hashes with a common prefix.
 */
@protocol OFCryptographicHash <OFObject, OFCopying>
#ifdef OF_HAVE_CLASS_PROPERTIES
@property (class, readonly, nonatomic) size_t digestSize;
@property (class, readonly, nonatomic) size_t blockSize;
#endif

/**
 * @brief The digest size of the cryptographic hash, in bytes.
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
    OF_RETURNS_INNER_POINTER;

/**
 * @brief Creates a new cryptographic hash.
 *
 * @return A new autoreleased cryptographic hash
 */
+ (instancetype)cryptoHashWithAllowsSwappableMemory:
    (bool)allowsSwappableMemory;

/**
 * @brief Returns the digest size of the cryptographic hash, in bytes.
 *
 * @return The digest size of the cryptographic hash, in bytes
 */
+ (size_t)digestSize;







<
|







63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
    OF_RETURNS_INNER_POINTER;

/**
 * @brief Creates a new cryptographic hash.
 *
 * @return A new autoreleased cryptographic hash
 */

+ (instancetype)hashWithAllowsSwappableMemory: (bool)allowsSwappableMemory;

/**
 * @brief Returns the digest size of the cryptographic hash, in bytes.
 *
 * @return The digest size of the cryptographic hash, in bytes
 */
+ (size_t)digestSize;

Renamed and modified src/OFData+CryptoHashing.h [a5a229d49d] to src/OFData+CryptographicHashing.h [c987e02085].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
OF_ASSUME_NONNULL_BEGIN

@class OFString;

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFData_CryptoHashing_reference;
#ifdef __cplusplus
}
#endif

@interface OFData (CryptoHashing)
/**
 * @brief The MD5 hash of the data as a string.
 */
@property (readonly, nonatomic) OFString *MD5Hash;

/**
 * @brief The RIPEMD-160 hash of the data as a string.
 */
@property (readonly, nonatomic) OFString *RIPEMD160Hash;

/**
 * @brief The SHA-1 hash of the data as a string.
 */
@property (readonly, nonatomic) OFString *SHA1Hash;

/**
 * @brief The SHA-224 hash of the data as a string.
 */
@property (readonly, nonatomic) OFString *SHA224Hash;

/**
 * @brief The SHA-256 hash of the data as a string.
 */
@property (readonly, nonatomic) OFString *SHA256Hash;

/**
 * @brief The SHA-384 hash of the data as a string.
 */
@property (readonly, nonatomic) OFString *SHA384Hash;

/**
 * @brief The SHA-512 hash of the data as a string.
 */
@property (readonly, nonatomic) OFString *SHA512Hash;
@end

OF_ASSUME_NONNULL_END







|




|



|




|




|




|




|




|




|



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
OF_ASSUME_NONNULL_BEGIN

@class OFString;

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFData_CryptographicHashing_reference;
#ifdef __cplusplus
}
#endif

@interface OFData (CryptographicHashing)
/**
 * @brief The MD5 hash of the data as a string.
 */
@property (readonly, nonatomic) OFString *stringByMD5Hashing;

/**
 * @brief The RIPEMD-160 hash of the data as a string.
 */
@property (readonly, nonatomic) OFString *stringByRIPEMD160Hashing;

/**
 * @brief The SHA-1 hash of the data as a string.
 */
@property (readonly, nonatomic) OFString *stringBySHA1Hashing;

/**
 * @brief The SHA-224 hash of the data as a string.
 */
@property (readonly, nonatomic) OFString *stringBySHA224Hashing;

/**
 * @brief The SHA-256 hash of the data as a string.
 */
@property (readonly, nonatomic) OFString *stringBySHA256Hashing;

/**
 * @brief The SHA-384 hash of the data as a string.
 */
@property (readonly, nonatomic) OFString *stringBySHA384Hashing;

/**
 * @brief The SHA-512 hash of the data as a string.
 */
@property (readonly, nonatomic) OFString *stringBySHA512Hashing;
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFData+CryptoHashing.m [7bd2a07f00] to src/OFData+CryptographicHashing.m [6d7c26a863].

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFData+CryptoHashing.h"
#import "OFString.h"
#import "OFCryptoHash.h"
#import "OFMD5Hash.h"
#import "OFRIPEMD160Hash.h"
#import "OFSHA1Hash.h"
#import "OFSHA224Hash.h"
#import "OFSHA256Hash.h"
#import "OFSHA384Hash.h"
#import "OFSHA512Hash.h"

int _OFData_CryptoHashing_reference;

@implementation OFData (CryptoHashing)

- (OFString *)of_cryptoHashWithClass: (Class <OFCryptoHash>)class OF_DIRECT
{
	void *pool = objc_autoreleasePoolPush();
	id <OFCryptoHash> hash =
	    [class cryptoHashWithAllowsSwappableMemory: true];
	size_t digestSize = [class digestSize];
	const unsigned char *digest;
	char cString[digestSize * 2];

	[hash updateWithBuffer: _items length: _count * _itemSize];

	digest = hash.digest;

	for (size_t i = 0; i < digestSize; i++) {
		uint8_t high, low;

		high = digest[i] >> 4;
		low  = digest[i] & 0x0F;

		cString[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		cString[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
	}

	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: cString
				  encoding: OF_STRING_ENCODING_ASCII
				    length: digestSize * 2];
}

- (OFString *)MD5Hash
{
	return [self of_cryptoHashWithClass: [OFMD5Hash class]];
}

- (OFString *)RIPEMD160Hash
{
	return [self of_cryptoHashWithClass: [OFRIPEMD160Hash class]];
}

- (OFString *)SHA1Hash
{
	return [self of_cryptoHashWithClass: [OFSHA1Hash class]];
}

- (OFString *)SHA224Hash
{
	return [self of_cryptoHashWithClass: [OFSHA224Hash class]];
}

- (OFString *)SHA256Hash
{
	return [self of_cryptoHashWithClass: [OFSHA256Hash class]];
}

- (OFString *)SHA384Hash
{
	return [self of_cryptoHashWithClass: [OFSHA384Hash class]];
}

- (OFString *)SHA512Hash
{
	return [self of_cryptoHashWithClass: [OFSHA512Hash class]];
}
@end







|

|








|

|
>
|


|
|




|
>



















|

|


|

|


|

|


|

|


|

|


|

|


|

|


11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFData+CryptographicHashing.h"
#import "OFString.h"
#import "OFCryptographicHash.h"
#import "OFMD5Hash.h"
#import "OFRIPEMD160Hash.h"
#import "OFSHA1Hash.h"
#import "OFSHA224Hash.h"
#import "OFSHA256Hash.h"
#import "OFSHA384Hash.h"
#import "OFSHA512Hash.h"

int _OFData_CryptographicHashing_reference;

@implementation OFData (CryptographicHashing)
static OFString *
stringByHashing(Class <OFCryptographicHash> class, OFData *self)
{
	void *pool = objc_autoreleasePoolPush();
	id <OFCryptographicHash> hash =
	    [class hashWithAllowsSwappableMemory: true];
	size_t digestSize = [class digestSize];
	const unsigned char *digest;
	char cString[digestSize * 2];

	[hash updateWithBuffer: self->_items
			length: self->_count * self->_itemSize];
	digest = hash.digest;

	for (size_t i = 0; i < digestSize; i++) {
		uint8_t high, low;

		high = digest[i] >> 4;
		low  = digest[i] & 0x0F;

		cString[i * 2] = (high > 9 ? high - 10 + 'a' : high + '0');
		cString[i * 2 + 1] = (low > 9 ? low - 10 + 'a' : low + '0');
	}

	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: cString
				  encoding: OF_STRING_ENCODING_ASCII
				    length: digestSize * 2];
}

- (OFString *)stringByMD5Hashing
{
	return stringByHashing([OFMD5Hash class], self);
}

- (OFString *)stringByRIPEMD160Hashing
{
	return stringByHashing([OFRIPEMD160Hash class], self);
}

- (OFString *)stringBySHA1Hashing
{
	return stringByHashing([OFSHA1Hash class], self);
}

- (OFString *)stringBySHA224Hashing
{
	return stringByHashing([OFSHA224Hash class], self);
}

- (OFString *)stringBySHA256Hashing
{
	return stringByHashing([OFSHA256Hash class], self);
}

- (OFString *)stringBySHA384Hashing
{
	return stringByHashing([OFSHA384Hash class], self);
}

- (OFString *)stringBySHA512Hashing
{
	return stringByHashing([OFSHA512Hash class], self);
}
@end

Modified src/OFData.h from [91e9717290] to [5c1ed5a74d].

266
267
268
269
270
271
272








273
274
275
276
277
278
279
 *	  containing the data of the Base64-encoded string.
 *
 * @param string The string with the Base64-encoded data
 * @return An initialized OFData
 */
- (instancetype)initWithBase64EncodedString: (OFString *)string;









/**
 * @brief Returns a specific item of the OFData.
 *
 * @param index The number of the item to return
 * @return The specified item of the OFData
 */
- (const void *)itemAtIndex: (size_t)index OF_RETURNS_INNER_POINTER;







>
>
>
>
>
>
>
>







266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
 *	  containing the data of the Base64-encoded string.
 *
 * @param string The string with the Base64-encoded data
 * @return An initialized OFData
 */
- (instancetype)initWithBase64EncodedString: (OFString *)string;

/**
 * @brief Compares the data to other data.
 *
 * @param data Data to compare the data to
 * @return The result of the comparison
 */
- (of_comparison_result_t)compare: (OFData *)data;

/**
 * @brief Returns a specific item of the OFData.
 *
 * @param index The number of the item to return
 * @return The specified item of the OFData
 */
- (const void *)itemAtIndex: (size_t)index OF_RETURNS_INNER_POINTER;
319
320
321
322
323
324
325
326
327
 */
- (void)writeToURL: (OFURL *)URL;
@end

OF_ASSUME_NONNULL_END

#import "OFMutableData.h"
#import "OFData+CryptoHashing.h"
#import "OFData+MessagePackParsing.h"







|

327
328
329
330
331
332
333
334
335
 */
- (void)writeToURL: (OFURL *)URL;
@end

OF_ASSUME_NONNULL_END

#import "OFMutableData.h"
#import "OFData+CryptographicHashing.h"
#import "OFData+MessagePackParsing.h"

Modified src/OFData.m from [d34247ee72] to [8df6dac3bd].

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

#import "base64.h"

/* References for static linking */
void
_references_to_categories_of_OFData(void)
{
	_OFData_CryptoHashing_reference = 1;
	_OFData_MessagePackParsing_reference = 1;
}

@implementation OFData
@synthesize itemSize = _itemSize;

+ (instancetype)dataWithItems: (const void *)items count: (size_t)count







|







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

#import "base64.h"

/* References for static linking */
void
_references_to_categories_of_OFData(void)
{
	_OFData_CryptographicHashing_reference = 1;
	_OFData_MessagePackParsing_reference = 1;
}

@implementation OFData
@synthesize itemSize = _itemSize;

+ (instancetype)dataWithItems: (const void *)items count: (size_t)count

Modified src/OFDate.h from [e9a1a4ba66] to [dff8b1eb37].

263
264
265
266
267
268
269








270
271
272
273
274
275
276
 * @param string The string describing the date
 * @param format The format of the string describing the date
 * @return An initialized OFDate with the specified date and time
 */
- (instancetype)initWithLocalDateString: (OFString *)string
				 format: (OFString *)format;









/**
 * @brief Creates a string of the date with the specified format.
 *
 * See the man page for `strftime` for information on the format.
 *
 * @param format The format for the date string
 * @return A new, autoreleased OFString







>
>
>
>
>
>
>
>







263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
 * @param string The string describing the date
 * @param format The format of the string describing the date
 * @return An initialized OFDate with the specified date and time
 */
- (instancetype)initWithLocalDateString: (OFString *)string
				 format: (OFString *)format;

/**
 * @brief Compares the date to another date.
 *
 * @param date The date to compare the date to
 * @return The result of the comparison
 */
- (of_comparison_result_t)compare: (OFDate *)date;

/**
 * @brief Creates a string of the date with the specified format.
 *
 * See the man page for `strftime` for information on the format.
 *
 * @param format The format for the date string
 * @return A new, autoreleased OFString

Modified src/OFEnumerator.h from [26a2240303] to [a48f5dd585].

17
18
19
20
21
22
23
24
25
26




27
28
29
30
31
32
33
34
35

OF_ASSUME_NONNULL_BEGIN

@class OFArray OF_GENERIC(ObjectType);
@class OFEnumerator OF_GENERIC(ObjectType);

/**
 * @protocol OFEnumerating OFEnumerator.h ObjFW/OFEnumerator.h
 *
 * @brief A protocol for getting an enumerator for the object.




 */
@protocol OFEnumerating
/**
 * @brief Returns an OFEnumerator to enumerate through all objects of the
 *	  collection.
 *
 * @return An OFEnumerator to enumerate through all objects of the collection
 */
- (OFEnumerator *)objectEnumerator;







|


>
>
>
>

|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

OF_ASSUME_NONNULL_BEGIN

@class OFArray OF_GENERIC(ObjectType);
@class OFEnumerator OF_GENERIC(ObjectType);

/**
 * @protocol OFEnumeration OFEnumerator.h ObjFW/OFEnumerator.h
 *
 * @brief A protocol for getting an enumerator for the object.
 *
 * If the class conforming to OFEnumeration is using lightweight generics, the
 * only method, @ref objectEnumerator, should be overridden to use lightweight
 * generics.
 */
@protocol OFEnumeration
/**
 * @brief Returns an OFEnumerator to enumerate through all objects of the
 *	  collection.
 *
 * @return An OFEnumerator to enumerate through all objects of the collection
 */
- (OFEnumerator *)objectEnumerator;

Modified src/OFFileManager.h from [baf85f358e] to [056f59171f].

387
388
389
390
391
392
393
394

395
396
397
398
399
400
401
402
403
404
405
406
407
408
 * @param path The path to the directory whose items should be returned
 * @return An array of OFString with the items in the specified directory
 */
- (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtPath: (OFString *)path;
#endif

/**
 * @brief Returns an array with the items in the specified directory.

 *
 * @note `.` and `..` are not part of the returned array.
 *
 * @param URL The URL to the directory whose items should be returned
 * @return An array of OFString with the items in the specified directory
 */
- (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtURL: (OFURL *)URL;

#ifdef OF_HAVE_FILES
/**
 * @brief Changes the current working directory.
 *
 * @param path The new directory to change to
 */







|
>




|

|







387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
 * @param path The path to the directory whose items should be returned
 * @return An array of OFString with the items in the specified directory
 */
- (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtPath: (OFString *)path;
#endif

/**
 * @brief Returns an array with the URLs of the items in the specified
 *	  directory.
 *
 * @note `.` and `..` are not part of the returned array.
 *
 * @param URL The URL to the directory whose items should be returned
 * @return An array with the URLs of the items in the specified directory
 */
- (OFArray OF_GENERIC(OFURL *) *)contentsOfDirectoryAtURL: (OFURL *)URL;

#ifdef OF_HAVE_FILES
/**
 * @brief Changes the current working directory.
 *
 * @param path The new directory to change to
 */

Modified src/OFFileManager.m from [6804846ccf] to [89ccc3daf1].

452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476

477
478




479
480
481
482
483
484
485
	[self createDirectoryAtURL: [OFURL fileURLWithPath: path]
		     createParents: createParents];

	objc_autoreleasePoolPop(pool);
}
#endif

- (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtURL: (OFURL *)URL
{
	OFURLHandler *URLHandler;

	if (URL == nil)
		@throw [OFInvalidArgumentException exception];

	if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil)
		@throw [OFUnsupportedProtocolException exceptionWithURL: URL];

	return [URLHandler contentsOfDirectoryAtURL: URL];
}

#ifdef OF_HAVE_FILES
- (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFArray OF_GENERIC(OFString *) *ret;


	ret = [self contentsOfDirectoryAtURL: [OFURL fileURLWithPath: path]];





	[ret retain];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}







|
















|
>

|
>
>
>
>







452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
	[self createDirectoryAtURL: [OFURL fileURLWithPath: path]
		     createParents: createParents];

	objc_autoreleasePoolPop(pool);
}
#endif

- (OFArray OF_GENERIC(OFURL *) *)contentsOfDirectoryAtURL: (OFURL *)URL
{
	OFURLHandler *URLHandler;

	if (URL == nil)
		@throw [OFInvalidArgumentException exception];

	if ((URLHandler = [OFURLHandler handlerForURL: URL]) == nil)
		@throw [OFUnsupportedProtocolException exceptionWithURL: URL];

	return [URLHandler contentsOfDirectoryAtURL: URL];
}

#ifdef OF_HAVE_FILES
- (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFArray OF_GENERIC(OFURL *) *URLs;
	OFMutableArray OF_GENERIC(OFString *) *ret;

	URLs = [self contentsOfDirectoryAtURL: [OFURL fileURLWithPath: path]];
	ret = [OFMutableArray arrayWithCapacity: URLs.count];

	for (OFURL *URL in URLs)
		[ret addObject: URL.lastPathComponent];

	[ret retain];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
			    destinationURL: destination
				     errNo: e.errNo];
	}

	type = attributes.fileType;

	if ([type isEqual: of_file_type_directory]) {
		OFArray *contents;

		@try {
			[self createDirectoryAtURL: destination];

			@try {
				of_file_attribute_key_t key =
				    of_file_attribute_key_posix_permissions;







|







598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
			    destinationURL: destination
				     errNo: e.errNo];
	}

	type = attributes.fileType;

	if ([type isEqual: of_file_type_directory]) {
		OFArray OF_GENERIC(OFURL *) *contents;

		@try {
			[self createDirectoryAtURL: destination];

			@try {
				of_file_attribute_key_t key =
				    of_file_attribute_key_posix_permissions;
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
				    exceptionWithSourceURL: source
					    destinationURL: destination
						     errNo: [e errNo]];

			@throw e;
		}

		for (OFString *item in contents) {
			void *pool2 = objc_autoreleasePoolPush();
			OFURL *sourceURL, *destinationURL;

			sourceURL =
			    [source URLByAppendingPathComponent: item];
			destinationURL =
			    [destination URLByAppendingPathComponent: item];

			[self copyItemAtURL: sourceURL toURL: destinationURL];

			objc_autoreleasePoolPop(pool2);
		}
	} else if ([type isEqual: of_file_type_regular]) {
		size_t pageSize = [OFSystemInfo pageSize];
		OFStream *sourceStream = nil;
		OFStream *destinationStream = nil;







|

|
<
<
|
<
|

|







638
639
640
641
642
643
644
645
646
647


648

649
650
651
652
653
654
655
656
657
658
				    exceptionWithSourceURL: source
					    destinationURL: destination
						     errNo: [e errNo]];

			@throw e;
		}

		for (OFURL *item in contents) {
			void *pool2 = objc_autoreleasePoolPush();
			OFURL *destinationURL = [destination


			    URLByAppendingPathComponent:

			    item.lastPathComponent];

			[self copyItemAtURL: item toURL: destinationURL];

			objc_autoreleasePoolPop(pool2);
		}
	} else if ([type isEqual: of_file_type_regular]) {
		size_t pageSize = [OFSystemInfo pageSize];
		OFStream *sourceStream = nil;
		OFStream *destinationStream = nil;

Modified src/OFFileURLHandler.m from [5499dbdb21] to [db7a703dd2].

1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
		    exceptionWithURL: URL
			       errNo: errno];
#endif

	objc_autoreleasePoolPop(pool);
}

- (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtURL: (OFURL *)URL
{
	OFMutableArray *files = [OFMutableArray array];
	void *pool = objc_autoreleasePoolPush();
	OFString *path;

	if (URL == nil)
		@throw [OFInvalidArgumentException exception];

	if (![URL.scheme isEqual: _scheme])







|

|







1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
		    exceptionWithURL: URL
			       errNo: errno];
#endif

	objc_autoreleasePoolPop(pool);
}

- (OFArray OF_GENERIC(OFURL *) *)contentsOfDirectoryAtURL: (OFURL *)URL
{
	OFMutableArray *URLs = [OFMutableArray array];
	void *pool = objc_autoreleasePoolPush();
	OFString *path;

	if (URL == nil)
		@throw [OFInvalidArgumentException exception];

	if (![URL.scheme isEqual: _scheme])
1048
1049
1050
1051
1052
1053
1054
1055

1056
1057
1058
1059
1060
1061
1062
				if (wcscmp(fd.cFileName, L".") == 0 ||
				    wcscmp(fd.cFileName, L"..") == 0)
					continue;

				file = [[OFString alloc]
				    initWithUTF16String: fd.cFileName];
				@try {
					[files addObject: file];

				} @finally {
					[file release];
				}
			} while (FindNextFileW(handle, &fd));

			if (GetLastError() != ERROR_NO_MORE_FILES)
				@throw [OFReadFailedException







|
>







1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
				if (wcscmp(fd.cFileName, L".") == 0 ||
				    wcscmp(fd.cFileName, L"..") == 0)
					continue;

				file = [[OFString alloc]
				    initWithUTF16String: fd.cFileName];
				@try {
					[URLs addObject: [URL
					    URLByAppendingPathComponent: file]];
				} @finally {
					[file release];
				}
			} while (FindNextFileW(handle, &fd));

			if (GetLastError() != ERROR_NO_MORE_FILES)
				@throw [OFReadFailedException
1086
1087
1088
1089
1090
1091
1092
1093

1094
1095
1096
1097
1098
1099
1100
				    strcmp(fd.cFileName, "..") == 0)
					continue;

				file = [[OFString alloc]
				    initWithCString: fd.cFileName
					   encoding: encoding];
				@try {
					[files addObject: file];

				} @finally {
					[file release];
				}
			} while (FindNextFileA(handle, &fd));

			if (GetLastError() != ERROR_NO_MORE_FILES)
				@throw [OFReadFailedException







|
>







1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
				    strcmp(fd.cFileName, "..") == 0)
					continue;

				file = [[OFString alloc]
				    initWithCString: fd.cFileName
					   encoding: encoding];
				@try {
					[URLs addObject: [URL
					    URLByAppendingPathComponent: file]];
				} @finally {
					[file release];
				}
			} while (FindNextFileA(handle, &fd));

			if (GetLastError() != ERROR_NO_MORE_FILES)
				@throw [OFReadFailedException
1132
1133
1134
1135
1136
1137
1138
1139

1140
1141
1142
1143
1144
1145
1146
		@try {
			while ((ed = ExamineDir(context)) != NULL) {
				OFString *file = [[OFString alloc]
				    initWithCString: ed->Name
					   encoding: encoding];

				@try {
					[files addObject: file];

				} @finally {
					[file release];
				}
			}
		} @finally {
			ReleaseDirContext(context);
		}







|
>







1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
		@try {
			while ((ed = ExamineDir(context)) != NULL) {
				OFString *file = [[OFString alloc]
				    initWithCString: ed->Name
					   encoding: encoding];

				@try {
					[URLs addObject: [URL
					    URLByAppendingPathComponent: file]];
				} @finally {
					[file release];
				}
			}
		} @finally {
			ReleaseDirContext(context);
		}
1154
1155
1156
1157
1158
1159
1160
1161

1162
1163
1164
1165
1166
1167
1168
				       errNo: retrieveError()];

		while (ExNext(lock, &fib)) {
			OFString *file = [[OFString alloc]
			    initWithCString: fib.fib_FileName
				   encoding: encoding];
			@try {
				[files addObject: file];

			} @finally {
				[file release];
			}
		}
# endif

		if (IoErr() != ERROR_NO_MORE_ENTRIES)







|
>







1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
				       errNo: retrieveError()];

		while (ExNext(lock, &fib)) {
			OFString *file = [[OFString alloc]
			    initWithCString: fib.fib_FileName
				   encoding: encoding];
			@try {
				[URLs addObject:
				    [URL URLByAppendingPathComponent: file]];
			} @finally {
				[file release];
			}
		}
# endif

		if (IoErr() != ERROR_NO_MORE_ENTRIES)
1223
1224
1225
1226
1227
1228
1229
1230

1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
			if (strcmp(dirent->d_name, ".") == 0 ||
			    strcmp(dirent->d_name, "..") == 0)
				continue;

			file = [[OFString alloc] initWithCString: dirent->d_name
							encoding: encoding];
			@try {
				[files addObject: file];

			} @finally {
				[file release];
			}
		}
	} @finally {
		closedir(dir);
# if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS)
		[readdirMutex unlock];
# endif
	}
#endif

	[files makeImmutable];

	objc_autoreleasePoolPop(pool);

	return files;
}

- (void)removeItemAtURL: (OFURL *)URL
{
	void *pool = objc_autoreleasePoolPush();
	OFString *path;
	int error;







|
>












|



|







1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
			if (strcmp(dirent->d_name, ".") == 0 ||
			    strcmp(dirent->d_name, "..") == 0)
				continue;

			file = [[OFString alloc] initWithCString: dirent->d_name
							encoding: encoding];
			@try {
				[URLs addObject:
				    [URL URLByAppendingPathComponent: file]];
			} @finally {
				[file release];
			}
		}
	} @finally {
		closedir(dir);
# if !defined(HAVE_READDIR_R) && defined(OF_HAVE_THREADS)
		[readdirMutex unlock];
# endif
	}
#endif

	[URLs makeImmutable];

	objc_autoreleasePoolPop(pool);

	return URLs;
}

- (void)removeItemAtURL: (OFURL *)URL
{
	void *pool = objc_autoreleasePoolPush();
	OFString *path;
	int error;
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
	path = URL.fileSystemRepresentation;

	if ((error = of_lstat(path, &s)) != 0)
		@throw [OFRemoveItemFailedException exceptionWithURL: URL
							       errNo: error];

	if (S_ISDIR(s.st_mode)) {
		OFArray *contents;

		@try {
			contents = [self contentsOfDirectoryAtURL: URL];
		} @catch (id e) {
			/*
			 * Only convert exceptions to
			 * OFRemoveItemFailedException that have an errNo
			 * property. This covers all I/O related exceptions
			 * from the operations used to remove an item, all
			 * others should be left as is.
			 */
			if ([e respondsToSelector: @selector(errNo)])
				@throw [OFRemoveItemFailedException
				    exceptionWithURL: URL
					       errNo: [e errNo]];

			@throw e;
		}

		for (OFString *item in contents) {
			void *pool2 = objc_autoreleasePoolPush();

			[self removeItemAtURL: [OFURL fileURLWithPath:
			    [path stringByAppendingPathComponent: item]]];

			objc_autoreleasePoolPop(pool2);
		}

#ifndef OF_AMIGAOS
		int status;








|



















|


|
<







1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298

1299
1300
1301
1302
1303
1304
1305
	path = URL.fileSystemRepresentation;

	if ((error = of_lstat(path, &s)) != 0)
		@throw [OFRemoveItemFailedException exceptionWithURL: URL
							       errNo: error];

	if (S_ISDIR(s.st_mode)) {
		OFArray OF_GENERIC(OFURL *) *contents;

		@try {
			contents = [self contentsOfDirectoryAtURL: URL];
		} @catch (id e) {
			/*
			 * Only convert exceptions to
			 * OFRemoveItemFailedException that have an errNo
			 * property. This covers all I/O related exceptions
			 * from the operations used to remove an item, all
			 * others should be left as is.
			 */
			if ([e respondsToSelector: @selector(errNo)])
				@throw [OFRemoveItemFailedException
				    exceptionWithURL: URL
					       errNo: [e errNo]];

			@throw e;
		}

		for (OFURL *item in contents) {
			void *pool2 = objc_autoreleasePoolPush();

			[self removeItemAtURL: item];


			objc_autoreleasePoolPop(pool2);
		}

#ifndef OF_AMIGAOS
		int status;

Modified src/OFHMAC.h from [60aea49324] to [bca836378e].

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFObject.h"
#import "OFCryptoHash.h"

OF_ASSUME_NONNULL_BEGIN

/**
 * @class OFHMAC OFHMAC.h ObjFW/OFHMAC.h
 *
 * @brief A class which provides methods to calculate an HMAC.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFHMAC: OFObject
{
	Class <OFCryptoHash> _hashClass;
	bool _allowsSwappableMemory;
	id <OFCryptoHash> _Nullable _outerHash, _innerHash;
	id <OFCryptoHash> _Nullable _outerHashCopy, _innerHashCopy;
	bool _calculated;
}

/**
 * @brief The class for the cryptographic hash used by the HMAC.
 */
@property (readonly, nonatomic) Class <OFCryptoHash> hashClass;

/**
 * @brief Whether data may be stored in swappable memory.
 */
@property (readonly, nonatomic) bool allowsSwappableMemory;

/**







|











|

|
|






|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFObject.h"
#import "OFCryptographicHash.h"

OF_ASSUME_NONNULL_BEGIN

/**
 * @class OFHMAC OFHMAC.h ObjFW/OFHMAC.h
 *
 * @brief A class which provides methods to calculate an HMAC.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFHMAC: OFObject
{
	Class <OFCryptographicHash> _hashClass;
	bool _allowsSwappableMemory;
	id <OFCryptographicHash> _Nullable _outerHash, _innerHash;
	id <OFCryptographicHash> _Nullable _outerHashCopy, _innerHashCopy;
	bool _calculated;
}

/**
 * @brief The class for the cryptographic hash used by the HMAC.
 */
@property (readonly, nonatomic) Class <OFCryptographicHash> hashClass;

/**
 * @brief Whether data may be stored in swappable memory.
 */
@property (readonly, nonatomic) bool allowsSwappableMemory;

/**
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/**
 * @brief Returns a new OFHMAC with the specified hashing algorithm.
 *
 * @param hashClass The class of the hashing algorithm
 * @param allowsSwappableMemory Whether data may be stored in swappable memory
 * @return A new, autoreleased OFHMAC
 */
+ (instancetype)HMACWithHashClass: (Class <OFCryptoHash>)hashClass
	    allowsSwappableMemory: (bool)allowsSwappableMemory;

- (instancetype)init OF_UNAVAILABLE;

/**
 * @brief Initialized an already allocated OFHMAC with the specified hashing
 *	  algorithm.
 *
 * @param hashClass The class of the hashing algorithm
 * @param allowsSwappableMemory Whether data may be stored in swappable memory
 * @return An initialized OFHMAC
 */
- (instancetype)initWithHashClass: (Class <OFCryptoHash>)hashClass
	    allowsSwappableMemory: (bool)allowsSwappableMemory
    OF_DESIGNATED_INITIALIZER;

/**
 * @brief Sets the key for the HMAC.
 *
 * @note This resets the HMAC!







|












|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/**
 * @brief Returns a new OFHMAC with the specified hashing algorithm.
 *
 * @param hashClass The class of the hashing algorithm
 * @param allowsSwappableMemory Whether data may be stored in swappable memory
 * @return A new, autoreleased OFHMAC
 */
+ (instancetype)HMACWithHashClass: (Class <OFCryptographicHash>)hashClass
	    allowsSwappableMemory: (bool)allowsSwappableMemory;

- (instancetype)init OF_UNAVAILABLE;

/**
 * @brief Initialized an already allocated OFHMAC with the specified hashing
 *	  algorithm.
 *
 * @param hashClass The class of the hashing algorithm
 * @param allowsSwappableMemory Whether data may be stored in swappable memory
 * @return An initialized OFHMAC
 */
- (instancetype)initWithHashClass: (Class <OFCryptographicHash>)hashClass
	    allowsSwappableMemory: (bool)allowsSwappableMemory
    OF_DESIGNATED_INITIALIZER;

/**
 * @brief Sets the key for the HMAC.
 *
 * @note This resets the HMAC!

Modified src/OFHMAC.m from [a4fe560b23] to [23d069a3eb].

21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#import "OFHashAlreadyCalculatedException.h"
#import "OFInvalidArgumentException.h"

@implementation OFHMAC
@synthesize hashClass = _hashClass;
@synthesize allowsSwappableMemory = _allowsSwappableMemory;

+ (instancetype)HMACWithHashClass: (Class <OFCryptoHash>)class
	    allowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithHashClass: class
			  allowsSwappableMemory: allowsSwappableMemory]
	    autorelease];
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithHashClass: (Class <OFCryptoHash>)class
	    allowsSwappableMemory: (bool)allowsSwappableMemory
{
	self = [super init];

	_hashClass = class;
	_allowsSwappableMemory = allowsSwappableMemory;








|












|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#import "OFHashAlreadyCalculatedException.h"
#import "OFInvalidArgumentException.h"

@implementation OFHMAC
@synthesize hashClass = _hashClass;
@synthesize allowsSwappableMemory = _allowsSwappableMemory;

+ (instancetype)HMACWithHashClass: (Class <OFCryptographicHash>)class
	    allowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithHashClass: class
			  allowsSwappableMemory: allowsSwappableMemory]
	    autorelease];
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithHashClass: (Class <OFCryptographicHash>)class
	    allowsSwappableMemory: (bool)allowsSwappableMemory
{
	self = [super init];

	_hashClass = class;
	_allowsSwappableMemory = allowsSwappableMemory;

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
	[_innerHash release];
	[_outerHashCopy release];
	[_innerHashCopy release];
	_outerHash = _innerHash = _outerHashCopy = _innerHashCopy = nil;

	@try {
		if (length > blockSize) {
			id <OFCryptoHash> hash = [_hashClass
			    cryptoHashWithAllowsSwappableMemory:
			    _allowsSwappableMemory];
			[hash updateWithBuffer: key length: length];

			length = hash.digestSize;
			if OF_UNLIKELY (length > blockSize)
				length = blockSize;








|
|







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
	[_innerHash release];
	[_outerHashCopy release];
	[_innerHashCopy release];
	_outerHash = _innerHash = _outerHashCopy = _innerHashCopy = nil;

	@try {
		if (length > blockSize) {
			id <OFCryptographicHash> hash = [_hashClass
			    hashWithAllowsSwappableMemory:
			    _allowsSwappableMemory];
			[hash updateWithBuffer: key length: length];

			length = hash.digestSize;
			if OF_UNLIKELY (length > blockSize)
				length = blockSize;

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
		memset(innerKeyPadItems + length, 0, blockSize - length);

		for (size_t i = 0; i < blockSize; i++) {
			outerKeyPadItems[i] ^= 0x5C;
			innerKeyPadItems[i] ^= 0x36;
		}

		_outerHash = [[_hashClass cryptoHashWithAllowsSwappableMemory:
		    _allowsSwappableMemory] retain];
		_innerHash = [[_hashClass cryptoHashWithAllowsSwappableMemory:
		    _allowsSwappableMemory] retain];

		[_outerHash updateWithBuffer: outerKeyPadItems
				      length: blockSize];
		[_innerHash updateWithBuffer: innerKeyPadItems
				      length: blockSize];
	} @catch (id e) {







|

|







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
		memset(innerKeyPadItems + length, 0, blockSize - length);

		for (size_t i = 0; i < blockSize; i++) {
			outerKeyPadItems[i] ^= 0x5C;
			innerKeyPadItems[i] ^= 0x36;
		}

		_outerHash = [[_hashClass hashWithAllowsSwappableMemory:
		    _allowsSwappableMemory] retain];
		_innerHash = [[_hashClass hashWithAllowsSwappableMemory:
		    _allowsSwappableMemory] retain];

		[_outerHash updateWithBuffer: outerKeyPadItems
				      length: blockSize];
		[_innerHash updateWithBuffer: innerKeyPadItems
				      length: blockSize];
	} @catch (id e) {

Modified src/OFMD5Hash.h from [2ab0f29af9] to [308882c688].

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFCryptoHash.h"

OF_ASSUME_NONNULL_BEGIN

@class OFSecureData;

/**
 * @class OFMD5Hash OFMD5Hash.h ObjFW/OFMD5Hash.h
 *
 * @brief A class which provides methods to create an MD5 hash.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFMD5Hash: OFObject <OFCryptoHash>
{
	OFSecureData *_iVarsData;
	struct of_md5_hash_ivars {
		uint32_t state[4];
		uint64_t bits;
		union of_md5_hash_buffer {
			unsigned char bytes[64];







|











|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFCryptographicHash.h"

OF_ASSUME_NONNULL_BEGIN

@class OFSecureData;

/**
 * @class OFMD5Hash OFMD5Hash.h ObjFW/OFMD5Hash.h
 *
 * @brief A class which provides methods to create an MD5 hash.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFMD5Hash: OFObject <OFCryptographicHash>
{
	OFSecureData *_iVarsData;
	struct of_md5_hash_ivars {
		uint32_t state[4];
		uint64_t bits;
		union of_md5_hash_buffer {
			unsigned char bytes[64];

Modified src/OFMD5Hash.m from [bf7cb6efee] to [2c1eebf461].

131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
}

+ (size_t)blockSize
{
	return BLOCK_SIZE;
}

+ (instancetype)cryptoHashWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithAllowsSwappableMemory:
	    allowsSwappableMemory] autorelease];
}

- (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{







|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
}

+ (size_t)blockSize
{
	return BLOCK_SIZE;
}

+ (instancetype)hashWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithAllowsSwappableMemory:
	    allowsSwappableMemory] autorelease];
}

- (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{

Modified src/OFNumber.h from [428bdb0cc8] to [1390ca955e].

357
358
359
360
361
362
363








364
365
366
367
368
369
370
/**
 * @brief Initializes an already allocated OFNumber with the specified `double`.
 *
 * @param value The `double` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithDouble: (double)value;








@end

OF_ASSUME_NONNULL_END

#if !defined(NSINTEGER_DEFINED) && !__has_feature(modules)
/* Required for number literals to work */
@compatibility_alias NSNumber OFNumber;







>
>
>
>
>
>
>
>







357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
/**
 * @brief Initializes an already allocated OFNumber with the specified `double`.
 *
 * @param value The `double` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithDouble: (double)value;

/**
 * @brief Compares the number to another number.
 *
 * @param number The number to compare the number to
 * @return The result of the comparison
 */
- (of_comparison_result_t)compare: (OFNumber *)number;
@end

OF_ASSUME_NONNULL_END

#if !defined(NSINTEGER_DEFINED) && !__has_feature(modules)
/* Required for number literals to work */
@compatibility_alias NSNumber OFNumber;

Modified src/OFObject.h from [7b6e5395a2] to [846f3a0425].

1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
@end

/**
 * @protocol OFComparing OFObject.h ObjFW/OFObject.h
 *
 * @brief A protocol for comparing objects.
 *
 * This protocol is implemented by objects that can be compared.
 */
@protocol OFComparing
/**
 * @brief Compares the object with another object.
 *
 * @param object An object to compare the object to
 * @return The result of the comparison
 */
- (of_comparison_result_t)compare: (id <OFComparing>)object;
@end
#endif







|



|







1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
@end

/**
 * @protocol OFComparing OFObject.h ObjFW/OFObject.h
 *
 * @brief A protocol for comparing objects.
 *
 * This protocol is implemented by objects that can be compared. Its only method, @ref compare:, should be overridden with a stronger type.
 */
@protocol OFComparing
/**
 * @brief Compares the object to another object.
 *
 * @param object An object to compare the object to
 * @return The result of the comparison
 */
- (of_comparison_result_t)compare: (id <OFComparing>)object;
@end
#endif

Modified src/OFPlugin.h from [ac829978a7] to [6278a1d5c2].

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

/**
 * @brief Loads a plugin from a file.
 *
 * @param path Path to the plugin file. The suffix is appended automatically.
 * @return The loaded plugin
 */
+ (OF_KINDOF(OFPlugin *))pluginFromFile: (OFString *)path;
@end

#ifdef __cplusplus
extern "C" {
#endif
extern of_plugin_handle_t of_dlopen(OFString *path, int flags);
extern void *of_dlsym(of_plugin_handle_t handle, const char *symbol);







|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

/**
 * @brief Loads a plugin from a file.
 *
 * @param path Path to the plugin file. The suffix is appended automatically.
 * @return The loaded plugin
 */
+ (OF_KINDOF(OFPlugin *))pluginWithPath: (OFString *)path;
@end

#ifdef __cplusplus
extern "C" {
#endif
extern of_plugin_handle_t of_dlopen(OFString *path, int flags);
extern void *of_dlsym(of_plugin_handle_t handle, const char *symbol);

Modified src/OFPlugin.m from [12a642d8b0] to [8802d6d561].

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
				  encoding: [OFLocale encoding]];
#else
	return nil;
#endif
}

@implementation OFPlugin
+ (id)pluginFromFile: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	of_plugin_handle_t handle;
	init_plugin_t initPlugin;
	OFPlugin *plugin;

#if defined(OF_MACOS)







|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
				  encoding: [OFLocale encoding]];
#else
	return nil;
#endif
}

@implementation OFPlugin
+ (id)pluginWithPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	of_plugin_handle_t handle;
	init_plugin_t initPlugin;
	OFPlugin *plugin;

#if defined(OF_MACOS)

Modified src/OFRIPEMD160Hash.h from [294f0a5d27] to [222f93a653].

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFCryptoHash.h"

OF_ASSUME_NONNULL_BEGIN

@class OFSecureData;

/**
 * @class OFRIPEMD160Hash OFRIPEMD160Hash.h ObjFW/OFRIPEMD160Hash.h
 *
 * @brief A class which provides methods to create a RIPEMD-160 hash.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFRIPEMD160Hash: OFObject <OFCryptoHash>
{
	OFSecureData *_iVarsData;
	struct of_ripemd160_hash_ivars {
		uint32_t state[5];
		uint64_t bits;
		union of_ripemd160_hash_buffer {
			unsigned char bytes[64];







|











|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFCryptographicHash.h"

OF_ASSUME_NONNULL_BEGIN

@class OFSecureData;

/**
 * @class OFRIPEMD160Hash OFRIPEMD160Hash.h ObjFW/OFRIPEMD160Hash.h
 *
 * @brief A class which provides methods to create a RIPEMD-160 hash.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFRIPEMD160Hash: OFObject <OFCryptographicHash>
{
	OFSecureData *_iVarsData;
	struct of_ripemd160_hash_ivars {
		uint32_t state[5];
		uint64_t bits;
		union of_ripemd160_hash_buffer {
			unsigned char bytes[64];

Modified src/OFRIPEMD160Hash.m from [00be784cc9] to [c81097cb16].

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
}

+ (size_t)blockSize
{
	return BLOCK_SIZE;
}

+ (instancetype)cryptoHashWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithAllowsSwappableMemory:
	    allowsSwappableMemory] autorelease];
}

- (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{







|







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
}

+ (size_t)blockSize
{
	return BLOCK_SIZE;
}

+ (instancetype)hashWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithAllowsSwappableMemory:
	    allowsSwappableMemory] autorelease];
}

- (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{

Modified src/OFSHA1Hash.h from [1ea7850492] to [e3b92b0480].

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFCryptoHash.h"

OF_ASSUME_NONNULL_BEGIN

@class OFSecureData;

/**
 * @class OFSHA1Hash OFSHA1Hash.h ObjFW/OFSHA1Hash.h
 *
 * @brief A class which provides methods to create an SHA-1 hash.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFSHA1Hash: OFObject <OFCryptoHash>
{
	OFSecureData *_iVarsData;
	struct of_sha1_hash_ivars {
		uint32_t state[5];
		uint64_t bits;
		union of_sha1_hash_buffer {
			unsigned char bytes[64];







|











|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFCryptographicHash.h"

OF_ASSUME_NONNULL_BEGIN

@class OFSecureData;

/**
 * @class OFSHA1Hash OFSHA1Hash.h ObjFW/OFSHA1Hash.h
 *
 * @brief A class which provides methods to create an SHA-1 hash.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFSHA1Hash: OFObject <OFCryptographicHash>
{
	OFSecureData *_iVarsData;
	struct of_sha1_hash_ivars {
		uint32_t state[5];
		uint64_t bits;
		union of_sha1_hash_buffer {
			unsigned char bytes[64];

Modified src/OFSHA1Hash.m from [6dc47e8d09] to [79fab1d90f].

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
}

+ (size_t)blockSize
{
	return BLOCK_SIZE;
}

+ (instancetype)cryptoHashWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithAllowsSwappableMemory:
	    allowsSwappableMemory] autorelease];
}

- (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{







|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
}

+ (size_t)blockSize
{
	return BLOCK_SIZE;
}

+ (instancetype)hashWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithAllowsSwappableMemory:
	    allowsSwappableMemory] autorelease];
}

- (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{

Modified src/OFSHA224Or256Hash.h from [25d2fa7cb5] to [f40021c439].

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFCryptoHash.h"

OF_ASSUME_NONNULL_BEGIN

@class OFSecureData;

/**
 * @class OFSHA224Or256Hash OFSHA224Or256Hash.h ObjFW/OFSHA224Or256Hash.h
 *
 * @brief A base class for SHA-224 and SHA-256.
 */
@interface OFSHA224Or256Hash: OFObject <OFCryptoHash>
{
@private
	OFSecureData *_iVarsData;
@protected
	struct of_sha224_or_256_hash_ivars {
		uint32_t state[8];
		uint64_t bits;







|










|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFCryptographicHash.h"

OF_ASSUME_NONNULL_BEGIN

@class OFSecureData;

/**
 * @class OFSHA224Or256Hash OFSHA224Or256Hash.h ObjFW/OFSHA224Or256Hash.h
 *
 * @brief A base class for SHA-224 and SHA-256.
 */
@interface OFSHA224Or256Hash: OFObject <OFCryptographicHash>
{
@private
	OFSecureData *_iVarsData;
@protected
	struct of_sha224_or_256_hash_ivars {
		uint32_t state[8];
		uint64_t bits;

Modified src/OFSHA224Or256Hash.m from [e77f5555d4] to [1d1ad26ec5].

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
}

+ (size_t)blockSize
{
	return BLOCK_SIZE;
}

+ (instancetype)cryptoHashWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithAllowsSwappableMemory:
	    allowsSwappableMemory] autorelease];
}

- (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{







|







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
}

+ (size_t)blockSize
{
	return BLOCK_SIZE;
}

+ (instancetype)hashWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithAllowsSwappableMemory:
	    allowsSwappableMemory] autorelease];
}

- (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{

Modified src/OFSHA384Or512Hash.h from [f783b37416] to [a9ade386ad].

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFCryptoHash.h"

OF_ASSUME_NONNULL_BEGIN

@class OFSecureData;

/**
 * @class OFSHA384Or512Hash OFSHA384Or512Hash.h ObjFW/OFSHA384Or512Hash.h
 *
 * @brief A base class for SHA-384 and SHA-512.
 */
@interface OFSHA384Or512Hash: OFObject <OFCryptoHash>
{
@private
	OFSecureData *_iVarsData;
@protected
	struct of_sha384_or_512_hash_ivars {
		uint64_t state[8];
		uint64_t bits[2];







|










|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFCryptographicHash.h"

OF_ASSUME_NONNULL_BEGIN

@class OFSecureData;

/**
 * @class OFSHA384Or512Hash OFSHA384Or512Hash.h ObjFW/OFSHA384Or512Hash.h
 *
 * @brief A base class for SHA-384 and SHA-512.
 */
@interface OFSHA384Or512Hash: OFObject <OFCryptographicHash>
{
@private
	OFSecureData *_iVarsData;
@protected
	struct of_sha384_or_512_hash_ivars {
		uint64_t state[8];
		uint64_t bits[2];

Modified src/OFSHA384Or512Hash.m from [d2d324bc83] to [4e88edca81].

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
}

+ (size_t)blockSize
{
	return BLOCK_SIZE;
}

+ (instancetype)cryptoHashWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithAllowsSwappableMemory:
	    allowsSwappableMemory] autorelease];
}

- (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{







|







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
}

+ (size_t)blockSize
{
	return BLOCK_SIZE;
}

+ (instancetype)hashWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithAllowsSwappableMemory:
	    allowsSwappableMemory] autorelease];
}

- (instancetype)initWithAllowsSwappableMemory: (bool)allowsSwappableMemory
{

Modified src/OFSet.h from [a377c99f36] to [14327ba57e].

159
160
161
162
163
164
165







166
167
168
169
170
171
172
 * @param firstObject The first object for the set
 * @param arguments A va_list with the other objects
 * @return An initialized set with the specified object and va_list
 */
- (instancetype)initWithObject: (ObjectType)firstObject
		     arguments: (va_list)arguments;








/**
 * @brief Returns whether the receiver is a subset of the specified set.
 *
 * @return Whether the receiver is a subset of the specified set
 */
- (bool)isSubsetOfSet: (OFSet OF_GENERIC(ObjectType) *)set;








>
>
>
>
>
>
>







159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
 * @param firstObject The first object for the set
 * @param arguments A va_list with the other objects
 * @return An initialized set with the specified object and va_list
 */
- (instancetype)initWithObject: (ObjectType)firstObject
		     arguments: (va_list)arguments;

/**
 * @brief Returns an OFEnumerator to enumerate through all objects of the set.
 *
 * @return An OFEnumerator to enumerate through all objects of the set
 */
- (OFEnumerator OF_GENERIC(ObjectType) *)objectEnumerator;

/**
 * @brief Returns whether the receiver is a subset of the specified set.
 *
 * @return Whether the receiver is a subset of the specified set
 */
- (bool)isSubsetOfSet: (OFSet OF_GENERIC(ObjectType) *)set;

Renamed and modified src/OFString+CryptoHashing.h [562278ea0b] to src/OFString+CryptographicHashing.h [059d7ea04f].

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#import "OFString.h"

OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFString_CryptoHashing_reference;
#ifdef __cplusplus
}
#endif

@interface OFString (CryptoHashing)
/**
 * @brief The MD5 hash of the string as a string.
 */
@property (readonly, nonatomic) OFString *MD5Hash;

/**
 * @brief The RIPEMD-160 hash of the string as a string.
 */
@property (readonly, nonatomic) OFString *RIPEMD160Hash;

/**
 * @brief The SHA-1 hash of the string as a string.
 */
@property (readonly, nonatomic) OFString *SHA1Hash;

/**
 * @brief The SHA-224 hash of the string as a string.
 */
@property (readonly, nonatomic) OFString *SHA224Hash;

/**
 * @brief The SHA-256 hash of the string as a string.
 */
@property (readonly, nonatomic) OFString *SHA256Hash;

/**
 * @brief The SHA-384 hash of the string as a string.
 */
@property (readonly, nonatomic) OFString *SHA384Hash;

/**
 * @brief The SHA-512 hash of the string as a string.
 */
@property (readonly, nonatomic) OFString *SHA512Hash;
@end

OF_ASSUME_NONNULL_END







|




|



|




|




|




|




|




|




|



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#import "OFString.h"

OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFString_CryptographicHashing_reference;
#ifdef __cplusplus
}
#endif

@interface OFString (CryptographicHashing)
/**
 * @brief The MD5 hash of the string as a string.
 */
@property (readonly, nonatomic) OFString *stringByMD5Hashing;

/**
 * @brief The RIPEMD-160 hash of the string as a string.
 */
@property (readonly, nonatomic) OFString *stringByRIPEMD160Hashing;

/**
 * @brief The SHA-1 hash of the string as a string.
 */
@property (readonly, nonatomic) OFString *stringBySHA1Hashing;

/**
 * @brief The SHA-224 hash of the string as a string.
 */
@property (readonly, nonatomic) OFString *stringBySHA224Hashing;

/**
 * @brief The SHA-256 hash of the string as a string.
 */
@property (readonly, nonatomic) OFString *stringBySHA256Hashing;

/**
 * @brief The SHA-384 hash of the string as a string.
 */
@property (readonly, nonatomic) OFString *stringBySHA384Hashing;

/**
 * @brief The SHA-512 hash of the string as a string.
 */
@property (readonly, nonatomic) OFString *stringBySHA512Hashing;
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFString+CryptoHashing.m [826ee219c6] to src/OFString+CryptographicHashing.m [9f70fbd17b].

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
39
40
41
42
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFString.h"
#import "OFCryptoHash.h"
#import "OFMD5Hash.h"
#import "OFRIPEMD160Hash.h"
#import "OFSHA1Hash.h"
#import "OFSHA224Hash.h"
#import "OFSHA256Hash.h"
#import "OFSHA384Hash.h"
#import "OFSHA512Hash.h"

int _OFString_CryptoHashing_reference;

@implementation OFString (CryptoHashing)
- (OFString *)of_cryptoHashWithClass: (Class <OFCryptoHash>)class

{
	void *pool = objc_autoreleasePoolPush();
	id <OFCryptoHash> hash = [class
	    cryptoHashWithAllowsSwappableMemory: true];
	size_t digestSize = [class digestSize];
	const unsigned char *digest;
	char cString[digestSize * 2];

	[hash updateWithBuffer: self.UTF8String length: self.UTF8StringLength];
	digest = hash.digest;








|








|

|
|
>


|
|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "OFString.h"
#import "OFCryptographicHash.h"
#import "OFMD5Hash.h"
#import "OFRIPEMD160Hash.h"
#import "OFSHA1Hash.h"
#import "OFSHA224Hash.h"
#import "OFSHA256Hash.h"
#import "OFSHA384Hash.h"
#import "OFSHA512Hash.h"

int _OFString_CryptographicHashing_reference;

@implementation OFString (CryptographicHashing)
static OFString *
stringByHashing(Class <OFCryptographicHash> class, OFString *self)
{
	void *pool = objc_autoreleasePoolPush();
	id <OFCryptographicHash> hash =
	    [class hashWithAllowsSwappableMemory: true];
	size_t digestSize = [class digestSize];
	const unsigned char *digest;
	char cString[digestSize * 2];

	[hash updateWithBuffer: self.UTF8String length: self.UTF8StringLength];
	digest = hash.digest;

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: cString
				  encoding: OF_STRING_ENCODING_ASCII
				    length: digestSize * 2];
}

- (OFString *)MD5Hash
{
	return [self of_cryptoHashWithClass: [OFMD5Hash class]];
}

- (OFString *)RIPEMD160Hash
{
	return [self of_cryptoHashWithClass: [OFRIPEMD160Hash class]];
}

- (OFString *)SHA1Hash
{
	return [self of_cryptoHashWithClass: [OFSHA1Hash class]];
}

- (OFString *)SHA224Hash
{
	return [self of_cryptoHashWithClass: [OFSHA224Hash class]];
}

- (OFString *)SHA256Hash
{
	return [self of_cryptoHashWithClass: [OFSHA256Hash class]];
}

- (OFString *)SHA384Hash
{
	return [self of_cryptoHashWithClass: [OFSHA384Hash class]];
}

- (OFString *)SHA512Hash
{
	return [self of_cryptoHashWithClass: [OFSHA512Hash class]];
}
@end







|

|


|

|


|

|


|

|


|

|


|

|


|

|


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
	objc_autoreleasePoolPop(pool);

	return [OFString stringWithCString: cString
				  encoding: OF_STRING_ENCODING_ASCII
				    length: digestSize * 2];
}

- (OFString *)stringByMD5Hashing
{
	return stringByHashing([OFMD5Hash class], self);
}

- (OFString *)stringByRIPEMD160Hashing
{
	return stringByHashing([OFRIPEMD160Hash class], self);
}

- (OFString *)stringBySHA1Hashing
{
	return stringByHashing([OFSHA1Hash class], self);
}

- (OFString *)stringBySHA224Hashing
{
	return stringByHashing([OFSHA224Hash class], self);
}

- (OFString *)stringBySHA256Hashing
{
	return stringByHashing([OFSHA256Hash class], self);
}

- (OFString *)stringBySHA384Hashing
{
	return stringByHashing([OFSHA384Hash class], self);
}

- (OFString *)stringBySHA512Hashing
{
	return stringByHashing([OFSHA512Hash class], self);
}
@end

Modified src/OFString.h from [d557fd2664] to [9aa19fe6df].

880
881
882
883
884
885
886
887





888


889
890
891
892
893
894
895
896
897
898
899
900
 *
 * @param encoding The encoding for the string
 * @return The number of bytes the string needs in the specified encoding.
 */
- (size_t)cStringLengthWithEncoding: (of_string_encoding_t)encoding;

/**
 * @brief Compares the OFString to another OFString without caring about the





 *	  case.


 *
 * @param otherString A string to compare with
 * @return An of_comparison_result_t
 */
- (of_comparison_result_t)caseInsensitiveCompare: (OFString *)otherString;

/**
 * @brief Returns the Unicode character at the specified index.
 *
 * @param index The index of the Unicode character to return
 * @return The Unicode character at the specified index
 */







|
>
>
>
>
>
|
>
>

|
|

|







880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
 *
 * @param encoding The encoding for the string
 * @return The number of bytes the string needs in the specified encoding.
 */
- (size_t)cStringLengthWithEncoding: (of_string_encoding_t)encoding;

/**
 * @brief Compares the string to another string.
 *
 * @param string The string to compare the string to
 * @return The result of the comparison
 */
- (of_comparison_result_t)compare: (OFString *)string;

/**
 * @brief Compares the string to another string without caring about the case.
 *
 * @param string The string to compare the string to
 * @return The result of the comparison
 */
- (of_comparison_result_t)caseInsensitiveCompare: (OFString *)string;

/**
 * @brief Returns the Unicode character at the specified index.
 *
 * @param index The index of the Unicode character to return
 * @return The Unicode character at the specified index
 */
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
#endif

OF_ASSUME_NONNULL_END

#include "OFConstantString.h"
#include "OFMutableString.h"
#ifdef __OBJC__
# import "OFString+CryptoHashing.h"
# import "OFString+JSONParsing.h"
# ifdef OF_HAVE_FILES
#  import "OFString+PathAdditions.h"
# endif
# import "OFString+PropertyListParsing.h"
# import "OFString+Serialization.h"
# import "OFString+URLEncoding.h"







|







1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
#endif

OF_ASSUME_NONNULL_END

#include "OFConstantString.h"
#include "OFMutableString.h"
#ifdef __OBJC__
# import "OFString+CryptographicHashing.h"
# import "OFString+JSONParsing.h"
# ifdef OF_HAVE_FILES
#  import "OFString+PathAdditions.h"
# endif
# import "OFString+PropertyListParsing.h"
# import "OFString+Serialization.h"
# import "OFString+URLEncoding.h"

Modified src/OFString.m from [ff9b0b5a48] to [d43b0aa5cd].

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
extern bool of_unicode_to_koi8_u(const of_unichar_t *, unsigned char *,
    size_t, bool);

/* References for static linking */
void
_references_to_categories_of_OFString(void)
{
	_OFString_CryptoHashing_reference = 1;
	_OFString_JSONParsing_reference = 1;
#ifdef OF_HAVE_FILES
	_OFString_PathAdditions_reference = 1;
#endif
	_OFString_PropertyListParsing_reference = 1;
	_OFString_Serialization_reference = 1;
	_OFString_URLEncoding_reference = 1;







|







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
extern bool of_unicode_to_koi8_u(const of_unichar_t *, unsigned char *,
    size_t, bool);

/* References for static linking */
void
_references_to_categories_of_OFString(void)
{
	_OFString_CryptographicHashing_reference = 1;
	_OFString_JSONParsing_reference = 1;
#ifdef OF_HAVE_FILES
	_OFString_PathAdditions_reference = 1;
#endif
	_OFString_PropertyListParsing_reference = 1;
	_OFString_Serialization_reference = 1;
	_OFString_URLEncoding_reference = 1;

Modified src/OFTimer.h from [7ce735d772] to [4d79b8c7ef].

449
450
451
452
453
454
455








456
457
458
459
460
461
462
 */
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (of_time_interval_t)interval
			 repeats: (bool)repeats
			   block: (of_timer_block_t)block;
#endif









/**
 * @brief Fires the timer, meaning it will execute the specified selector on the
 *	  target.
 */
- (void)fire;

/**







>
>
>
>
>
>
>
>







449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
 */
- (instancetype)initWithFireDate: (OFDate *)fireDate
			interval: (of_time_interval_t)interval
			 repeats: (bool)repeats
			   block: (of_timer_block_t)block;
#endif

/**
 * @brief Compares the timer to another timer.
 *
 * @param timer The timer to compare the string to
 * @return The result of the comparison
 */
- (of_comparison_result_t)compare: (OFTimer *)timer;

/**
 * @brief Fires the timer, meaning it will execute the specified selector on the
 *	  target.
 */
- (void)fire;

/**

Modified src/OFURLHandler.h from [811c1948ca] to [9ec6927971].

133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
149
150
151
152
153
154
 * @brief Creates a directory at the specified URL.
 *
 * @param URL The URL of the directory to create
 */
- (void)createDirectoryAtURL: (OFURL *)URL;

/**
 * @brief Returns an array with the items in the specified directory.

 *
 * @note `.` and `..` are not part of the returned array.
 *
 * @param URL The URL to the directory whose items should be returned
 * @return An array of OFString with the items in the specified directory
 */
- (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtURL: (OFURL *)URL;

/**
 * @brief Removes the item at the specified URL.
 *
 * If the item at the specified URL is a directory, it is removed recursively.
 *
 * @param URL The URL to the item which should be removed







|
>




|

|







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
 * @brief Creates a directory at the specified URL.
 *
 * @param URL The URL of the directory to create
 */
- (void)createDirectoryAtURL: (OFURL *)URL;

/**
 * @brief Returns an array with the URLs of the items in the specified
 *	  directory.
 *
 * @note `.` and `..` are not part of the returned array.
 *
 * @param URL The URL to the directory whose items should be returned
 * @return An array with the URLs of the items in the specified directory
 */
- (OFArray OF_GENERIC(OFURL *) *)contentsOfDirectoryAtURL: (OFURL *)URL;

/**
 * @brief Removes the item at the specified URL.
 *
 * If the item at the specified URL is a directory, it is removed recursively.
 *
 * @param URL The URL to the item which should be removed

Modified src/OFURLHandler.m from [227a2dfab0] to [7996e25454].

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
}

- (void)createDirectoryAtURL: (OFURL *)URL
{
	OF_UNRECOGNIZED_SELECTOR
}

- (OFArray OF_GENERIC(OFString *) *)contentsOfDirectoryAtURL: (OFURL *)URL
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)removeItemAtURL: (OFURL *)URL
{
	OF_UNRECOGNIZED_SELECTOR







|







162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
}

- (void)createDirectoryAtURL: (OFURL *)URL
{
	OF_UNRECOGNIZED_SELECTOR
}

- (OFArray OF_GENERIC(OFURL *) *)contentsOfDirectoryAtURL: (OFURL *)URL
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)removeItemAtURL: (OFURL *)URL
{
	OF_UNRECOGNIZED_SELECTOR

Modified src/ObjFW.h from [68846bd58b] to [1463e20e85].

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# import "OFHTTPServer.h"
#endif

#ifdef OF_HAVE_SUBPROCESSES
# import "OFSubprocess.h"
#endif

#import "OFCryptoHash.h"
#import "OFMD5Hash.h"
#import "OFRIPEMD160Hash.h"
#import "OFSHA1Hash.h"
#import "OFSHA224Hash.h"
#import "OFSHA256Hash.h"
#import "OFSHA384Hash.h"
#import "OFSHA512Hash.h"







|







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# import "OFHTTPServer.h"
#endif

#ifdef OF_HAVE_SUBPROCESSES
# import "OFSubprocess.h"
#endif

#import "OFCryptographicHash.h"
#import "OFMD5Hash.h"
#import "OFRIPEMD160Hash.h"
#import "OFSHA1Hash.h"
#import "OFSHA224Hash.h"
#import "OFSHA256Hash.h"
#import "OFSHA384Hash.h"
#import "OFSHA512Hash.h"

Modified tests/OFDataTests.m from [5c0a7f22cc] to [145ac3ede5].

164
165
166
167
168
169
170

171
172
173
174
175
176

177
178
179

180
181
182

183
184
185

186
187
188


189
190
191
192
193
194
195

	EXPECT_EXCEPTION(@"-[subdataWithRange:] failing on out of range #1",
	    OFOutOfRangeException, [immutable subdataWithRange: of_range(7, 1)])

	EXPECT_EXCEPTION(@"-[subdataWithRange:] failing on out of range #2",
	    OFOutOfRangeException, [mutable subdataWithRange: of_range(6, 1)])


	TEST(@"-[MD5Hash]", [mutable.MD5Hash isEqual: @"abcde".MD5Hash])

	TEST(@"-[RIPEMD160Hash]", [mutable.RIPEMD160Hash
	    isEqual: @"abcde".RIPEMD160Hash])

	TEST(@"-[SHA1Hash]", [mutable.SHA1Hash isEqual: @"abcde".SHA1Hash])


	TEST(@"-[SHA224Hash]", [mutable.SHA224Hash
	    isEqual: @"abcde".SHA224Hash])


	TEST(@"-[SHA256Hash]", [mutable.SHA256Hash
	    isEqual: @"abcde".SHA256Hash])


	TEST(@"-[SHA384Hash]", [mutable.SHA384Hash
	    isEqual: @"abcde".SHA384Hash])


	TEST(@"-[SHA512Hash]", [mutable.SHA512Hash
	    isEqual: @"abcde".SHA512Hash])



	TEST(@"-[stringByBase64Encoding]",
	    [mutable.stringByBase64Encoding isEqual: @"YWJjZGU="])

	TEST(@"+[dataWithBase64EncodedString:]",
	    memcmp([[OFData dataWithBase64EncodedString: @"YWJjZGU="]
	    items], "abcde", 5) == 0)







>
|

|
|

|
>

|
|
>

|
|
>

|
|
>

|
|
>
>







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202

	EXPECT_EXCEPTION(@"-[subdataWithRange:] failing on out of range #1",
	    OFOutOfRangeException, [immutable subdataWithRange: of_range(7, 1)])

	EXPECT_EXCEPTION(@"-[subdataWithRange:] failing on out of range #2",
	    OFOutOfRangeException, [mutable subdataWithRange: of_range(6, 1)])

	TEST(@"-[stringByMD5Hashing]", [mutable.stringByMD5Hashing
	    isEqual: @"ab56b4d92b40713acc5af89985d4b786"])

	TEST(@"-[stringByRIPEMD160Hashing]", [mutable.stringByRIPEMD160Hashing
	    isEqual: @"973398b6e6c6cfa6b5e6a5173f195ce3274bf828"])

	TEST(@"-[stringBySHA1Hashing]", [mutable.stringBySHA1Hashing
	    isEqual: @"03de6c570bfe24bfc328ccd7ca46b76eadaf4334"])

	TEST(@"-[stringBySHA224Hashing]", [mutable.stringBySHA224Hashing
	    isEqual: @"bdd03d560993e675516ba5a50638b6531ac2ac3d5847c61916cfced6"
	    ])

	TEST(@"-[stringBySHA256Hashing]", [mutable.stringBySHA256Hashing
	    isEqual: @"36bbe50ed96841d10443bcb670d6554f0a34b761be67ec9c4a8ad2c0"
		     @"c44ca42c"])

	TEST(@"-[stringBySHA384Hashing]", [mutable.stringBySHA384Hashing
	    isEqual: @"4c525cbeac729eaf4b4665815bc5db0c84fe6300068a727cf74e2813"
		     @"521565abc0ec57a37ee4d8be89d097c0d2ad52f0"])

	TEST(@"-[stringBySHA512Hashing]", [mutable.stringBySHA512Hashing
	    isEqual: @"878ae65a92e86cac011a570d4c30a7eaec442b85ce8eca0c2952b5e3"
		     @"cc0628c2e79d889ad4d5c7c626986d452dd86374b6ffaa7cd8b67665"
		     @"bef2289a5c70b0a1"])

	TEST(@"-[stringByBase64Encoding]",
	    [mutable.stringByBase64Encoding isEqual: @"YWJjZGU="])

	TEST(@"+[dataWithBase64EncodedString:]",
	    memcmp([[OFData dataWithBase64EncodedString: @"YWJjZGU="]
	    items], "abcde", 5) == 0)

Modified tests/OFMD5HashTests.m from [b161ec4641] to [73092aedf1].

27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@implementation TestsAppDelegate (OFMD5HashTests)
- (void)MD5HashTests
{
	void *pool = objc_autoreleasePoolPush();
	OFMD5Hash *md5, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin" mode: @"r"];

	TEST(@"+[cryptoHashWithAllowsSwappableMemory:]",
	    (md5 = [OFMD5Hash cryptoHashWithAllowsSwappableMemory: true]))

	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf length: 64];
		[md5 updateWithBuffer: buf length: len];
	}
	[f close];







|
|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@implementation TestsAppDelegate (OFMD5HashTests)
- (void)MD5HashTests
{
	void *pool = objc_autoreleasePoolPush();
	OFMD5Hash *md5, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin" mode: @"r"];

	TEST(@"+[hashWithAllowsSwappableMemory:]",
	    (md5 = [OFMD5Hash hashWithAllowsSwappableMemory: true]))

	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf length: 64];
		[md5 updateWithBuffer: buf length: len];
	}
	[f close];

Modified tests/OFPluginTests.m from [5d4c7a32e2] to [79f8663f0b].

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

@implementation TestsAppDelegate (OFPluginTests)
- (void)pluginTests
{
	void *pool = objc_autoreleasePoolPush();
	TestPlugin *plugin;

	TEST(@"+[pluginFromFile:]",
	    (plugin = [OFPlugin pluginFromFile: PLUGIN_PATH]))

	TEST(@"TestPlugin's -[test:]", [plugin test: 1234] == 2468)

	objc_autoreleasePoolPop(pool);
}
@end







|
|






29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

@implementation TestsAppDelegate (OFPluginTests)
- (void)pluginTests
{
	void *pool = objc_autoreleasePoolPush();
	TestPlugin *plugin;

	TEST(@"+[pluginWithPath:]",
	    (plugin = [OFPlugin pluginWithPath: PLUGIN_PATH]))

	TEST(@"TestPlugin's -[test:]", [plugin test: 1234] == 2468)

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/OFRIPEMD160HashTests.m from [1bef7d37d4] to [4b2bd712b4].

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@implementation TestsAppDelegate (OFRIPEMD160HashTests)
- (void)RIPEMD160HashTests
{
	void *pool = objc_autoreleasePoolPush();
	OFRIPEMD160Hash *rmd160, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin" mode: @"r"];

	TEST(@"+[cryptoHashWithAllowsSwappableMemory:]",
	    (rmd160 = [OFRIPEMD160Hash
	    cryptoHashWithAllowsSwappableMemory: true]))

	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf length: 64];
		[rmd160 updateWithBuffer: buf length: len];
	}
	[f close];







|
|
<







28
29
30
31
32
33
34
35
36

37
38
39
40
41
42
43
@implementation TestsAppDelegate (OFRIPEMD160HashTests)
- (void)RIPEMD160HashTests
{
	void *pool = objc_autoreleasePoolPush();
	OFRIPEMD160Hash *rmd160, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin" mode: @"r"];

	TEST(@"+[hashWithAllowsSwappableMemory:]",
	    (rmd160 = [OFRIPEMD160Hash hashWithAllowsSwappableMemory: true]))


	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf length: 64];
		[rmd160 updateWithBuffer: buf length: len];
	}
	[f close];

Modified tests/OFSHA1HashTests.m from [145fd9ade0] to [3bceacae61].

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@implementation TestsAppDelegate (SHA1HashTests)
- (void)SHA1HashTests
{
	void *pool = objc_autoreleasePoolPush();
	OFSHA1Hash *sha1, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin" mode: @"r"];

	TEST(@"+[cryptoHashWithAllowsSwappableMemory:]",
	    (sha1 = [OFSHA1Hash cryptoHashWithAllowsSwappableMemory: true]))

	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf length: 64];
		[sha1 updateWithBuffer: buf length: len];
	}
	[f close];







|
|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@implementation TestsAppDelegate (SHA1HashTests)
- (void)SHA1HashTests
{
	void *pool = objc_autoreleasePoolPush();
	OFSHA1Hash *sha1, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin" mode: @"r"];

	TEST(@"+[hashWithAllowsSwappableMemory:]",
	    (sha1 = [OFSHA1Hash hashWithAllowsSwappableMemory: true]))

	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf length: 64];
		[sha1 updateWithBuffer: buf length: len];
	}
	[f close];

Modified tests/OFSHA224HashTests.m from [114b68c56f] to [4309676a79].

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@implementation TestsAppDelegate (SHA224HashTests)
- (void)SHA224HashTests
{
	void *pool = objc_autoreleasePoolPush();
	OFSHA224Hash *sha224, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin" mode: @"r"];

	TEST(@"+[cryptoHashWithAllowsSwappableMemory:]",
	    (sha224 = [OFSHA224Hash cryptoHashWithAllowsSwappableMemory: true]))

	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf length: 64];
		[sha224 updateWithBuffer: buf length: len];
	}
	[f close];







|
|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@implementation TestsAppDelegate (SHA224HashTests)
- (void)SHA224HashTests
{
	void *pool = objc_autoreleasePoolPush();
	OFSHA224Hash *sha224, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin" mode: @"r"];

	TEST(@"+[hashWithAllowsSwappableMemory:]",
	    (sha224 = [OFSHA224Hash hashWithAllowsSwappableMemory: true]))

	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf length: 64];
		[sha224 updateWithBuffer: buf length: len];
	}
	[f close];

Modified tests/OFSHA256HashTests.m from [2b578b5f30] to [2f9948771c].

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@implementation TestsAppDelegate (SHA256HashTests)
- (void)SHA256HashTests
{
	void *pool = objc_autoreleasePoolPush();
	OFSHA256Hash *sha256, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin" mode: @"r"];

	TEST(@"+[cryptoHashWithAllowsSwappableMemory:]",
	    (sha256 = [OFSHA256Hash cryptoHashWithAllowsSwappableMemory: true]))

	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf length: 64];
		[sha256 updateWithBuffer: buf length: len];
	}
	[f close];







|
|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@implementation TestsAppDelegate (SHA256HashTests)
- (void)SHA256HashTests
{
	void *pool = objc_autoreleasePoolPush();
	OFSHA256Hash *sha256, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin" mode: @"r"];

	TEST(@"+[hashWithAllowsSwappableMemory:]",
	    (sha256 = [OFSHA256Hash hashWithAllowsSwappableMemory: true]))

	while (!f.atEndOfStream) {
		char buf[64];
		size_t len = [f readIntoBuffer: buf length: 64];
		[sha256 updateWithBuffer: buf length: len];
	}
	[f close];

Modified tests/OFSHA384HashTests.m from [2c0ef0b0b7] to [fdfc8fecb8].

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@implementation TestsAppDelegate (SHA384HashTests)
- (void)SHA384HashTests
{
	void *pool = objc_autoreleasePoolPush();
	OFSHA384Hash *sha384, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin" mode: @"r"];

	TEST(@"+[cryptoHashWithAllowsSwappableMemory:]",
	    (sha384 = [OFSHA384Hash cryptoHashWithAllowsSwappableMemory: true]))

	while (!f.atEndOfStream) {
		char buf[128];
		size_t len = [f readIntoBuffer: buf length: 128];
		[sha384 updateWithBuffer: buf length: len];
	}
	[f close];







|
|







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@implementation TestsAppDelegate (SHA384HashTests)
- (void)SHA384HashTests
{
	void *pool = objc_autoreleasePoolPush();
	OFSHA384Hash *sha384, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin" mode: @"r"];

	TEST(@"+[hashWithAllowsSwappableMemory:]",
	    (sha384 = [OFSHA384Hash hashWithAllowsSwappableMemory: true]))

	while (!f.atEndOfStream) {
		char buf[128];
		size_t len = [f readIntoBuffer: buf length: 128];
		[sha384 updateWithBuffer: buf length: len];
	}
	[f close];

Modified tests/OFSHA512HashTests.m from [99450ee331] to [ff0238e62b].

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@implementation TestsAppDelegate (SHA512HashTests)
- (void)SHA512HashTests
{
	void *pool = objc_autoreleasePoolPush();
	OFSHA512Hash *sha512, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin" mode: @"r"];

	TEST(@"+[cryptoHashWithAllowsSwappableMemory:]",
	    (sha512 = [OFSHA512Hash cryptoHashWithAllowsSwappableMemory: true]))

	while (!f.atEndOfStream) {
		char buf[128];
		size_t len = [f readIntoBuffer: buf length: 128];
		[sha512 updateWithBuffer: buf length: len];
	}
	[f close];







|
|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@implementation TestsAppDelegate (SHA512HashTests)
- (void)SHA512HashTests
{
	void *pool = objc_autoreleasePoolPush();
	OFSHA512Hash *sha512, *copy;
	OFFile *f = [OFFile fileWithPath: @"testfile.bin" mode: @"r"];

	TEST(@"+[hashWithAllowsSwappableMemory:]",
	    (sha512 = [OFSHA512Hash hashWithAllowsSwappableMemory: true]))

	while (!f.atEndOfStream) {
		char buf[128];
		size_t len = [f readIntoBuffer: buf length: 128];
		[sha512 updateWithBuffer: buf length: len];
	}
	[f close];

Modified tests/OFStringTests.m from [e616a01e33] to [bc3d5b4b0a].

1204
1205
1206
1207
1208
1209
1210
1211
1212
1213

1214
1215
1216
1217
1218
1219
1220
1221
1222

1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234

1235
1236
1237
1238
1239
1240
1241
	TEST(@"-[UTF32String]", (ua = C(@"fööbär🀺").UTF32String) &&
	    !memcmp(ua, ucstr + 1, of_string_utf32_length(ucstr) * 4) &&
	    (ua = [C(@"fööbär🀺") UTF32StringWithByteOrder:
	    SWAPPED_BYTE_ORDER]) &&
	    !memcmp(ua, sucstr + 1, of_string_utf32_length(sucstr) * 4))
#undef SWAPPED_BYTE_ORDER

	TEST(@"-[MD5Hash]", [C(@"asdfoobar").MD5Hash
	    isEqual: @"184dce2ec49b5422c7cfd8728864db4c"])


	TEST(@"-[RIPEMD160Hash]", [C(@"asdfoobar").RIPEMD160Hash
	    isEqual: @"021d773b0fac06eb6755ca6aa58a580c980f7f13"])

	TEST(@"-[SHA1Hash]", [C(@"asdfoobar").SHA1Hash
	    isEqual: @"f5f81ac0a8b5cbfdc4585ec1ad32e7b3a12b9b49"])

	TEST(@"-[SHA224Hash]", [C(@"asdfoobar").SHA224Hash
	    isEqual:
	    @"5a06822dcbd5a874f67d062b80b9d8a9cb9b5b303960b9da9290c192"])


	TEST(@"-[SHA256Hash]", [C(@"asdfoobar").SHA256Hash isEqual:
	    @"28e65b1dcd7f6ce2ea6277b15f87b913"
	    @"628b5500bf7913a2bbf4cedcfa1215f6"])

	TEST(@"-[SHA384Hash]", [C(@"asdfoobar").SHA384Hash isEqual:
	    @"73286da882ffddca2f45e005cfa6b44f3fc65bfb26db1d08"
	    @"7ded2f9c279e5addf8be854044bca0cece073fce28eec7d9"])

	TEST(@"-[SHA512Hash]", [C(@"asdfoobar").SHA512Hash isEqual:
	    @"0464c427da158b02161bb44a3090bbfc594611ef6a53603640454b56412a9247c"
	    @"3579a329e53a5dc74676b106755e3394f9454a2d42273242615d32f80437d61"])


	cs = [OFCharacterSet characterSetWithCharactersInString: @"abfo'_~$🍏"];
	TEST(@"-[stringByURLEncodingWithAllowedCharacters:]",
	    [[C(@"foo\"ba'_~$]🍏🍌") stringByURLEncodingWithAllowedCharacters:
	    cs] isEqual: @"foo%22ba'_~$%5D🍏%F0%9F%8D%8C"])

	TEST(@"-[stringByURLDecoding]",







|


>
|


|


|
<
|
>

|
|
|

|
|
|

|
|
|
>







1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221

1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
	TEST(@"-[UTF32String]", (ua = C(@"fööbär🀺").UTF32String) &&
	    !memcmp(ua, ucstr + 1, of_string_utf32_length(ucstr) * 4) &&
	    (ua = [C(@"fööbär🀺") UTF32StringWithByteOrder:
	    SWAPPED_BYTE_ORDER]) &&
	    !memcmp(ua, sucstr + 1, of_string_utf32_length(sucstr) * 4))
#undef SWAPPED_BYTE_ORDER

	TEST(@"-[stringByMD5Hashing]", [C(@"asdfoobar").stringByMD5Hashing
	    isEqual: @"184dce2ec49b5422c7cfd8728864db4c"])

	TEST(@"-[stringByRIPEMD160Hashing]",
	    [C(@"asdfoobar").stringByRIPEMD160Hashing
	    isEqual: @"021d773b0fac06eb6755ca6aa58a580c980f7f13"])

	TEST(@"-[stringBySHA1Hashing]", [C(@"asdfoobar").stringBySHA1Hashing
	    isEqual: @"f5f81ac0a8b5cbfdc4585ec1ad32e7b3a12b9b49"])

	TEST(@"-[stringBySHA224Hashing]", [C(@"asdfoobar").stringBySHA224Hashing

	    isEqual: @"5a06822dcbd5a874f67d062b80b9d8a9cb9b5b303960b9da9290c192"
	    ])

	TEST(@"-[stringBySHA256Hashing]", [C(@"asdfoobar").stringBySHA256Hashing
	    isEqual: @"28e65b1dcd7f6ce2ea6277b15f87b913628b5500bf7913a2bbf4cedc"
		     @"fa1215f6"])

	TEST(@"-[stringBySHA384Hashing]", [C(@"asdfoobar").stringBySHA384Hashing
	    isEqual: @"73286da882ffddca2f45e005cfa6b44f3fc65bfb26db1d087ded2f9c"
		     @"279e5addf8be854044bca0cece073fce28eec7d9"])

	TEST(@"-[stringBySHA512Hashing]", [C(@"asdfoobar").stringBySHA512Hashing
	    isEqual: @"0464c427da158b02161bb44a3090bbfc594611ef6a53603640454b56"
		     @"412a9247c3579a329e53a5dc74676b106755e3394f9454a2d4227324"
		     @"2615d32f80437d61"])

	cs = [OFCharacterSet characterSetWithCharactersInString: @"abfo'_~$🍏"];
	TEST(@"-[stringByURLEncodingWithAllowedCharacters:]",
	    [[C(@"foo\"ba'_~$]🍏🍌") stringByURLEncodingWithAllowedCharacters:
	    cs] isEqual: @"foo%22ba'_~$%5D🍏%F0%9F%8D%8C"])

	TEST(@"-[stringByURLDecoding]",

Modified utils/ofhash/OFHash.m from [3a8fa1bdc6] to [871b144274].

47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
	    @"--sha384|--sha512] file1 [file2 ...]",
	    @"prog", [OFApplication programName])];

	[OFApplication terminateWithStatus: 1];
}

static void
printHash(OFString *algo, OFString *path, id <OFCryptoHash> hash)
{
	const unsigned char *digest = hash.digest;
	size_t digestSize = hash.digestSize;

	[of_stdout writeFormat: @"%@ ", algo];

	for (size_t i = 0; i < digestSize; i++)







|







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
	    @"--sha384|--sha512] file1 [file2 ...]",
	    @"prog", [OFApplication programName])];

	[OFApplication terminateWithStatus: 1];
}

static void
printHash(OFString *algo, OFString *path, id <OFCryptographicHash> hash)
{
	const unsigned char *digest = hash.digest;
	size_t digestSize = hash.digestSize;

	[of_stdout writeFormat: @"%@ ", algo];

	for (size_t i = 0; i < digestSize; i++)
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
	    !calculateSHA512)
		help();

	if (optionsParser.remainingArguments.count < 1)
		help();

	if (calculateMD5)
		MD5Hash = [OFMD5Hash cryptoHashWithAllowsSwappableMemory: true];
	if (calculateRIPEMD160)
		RIPEMD160Hash =
		    [OFRIPEMD160Hash cryptoHashWithAllowsSwappableMemory: true];
	if (calculateSHA1)
		SHA1Hash =
		    [OFSHA1Hash cryptoHashWithAllowsSwappableMemory: true];
	if (calculateSHA224)
		SHA224Hash =
		    [OFSHA224Hash cryptoHashWithAllowsSwappableMemory: true];
	if (calculateSHA256)
		SHA256Hash =
		    [OFSHA256Hash cryptoHashWithAllowsSwappableMemory: true];
	if (calculateSHA384)
		SHA384Hash =
		    [OFSHA384Hash cryptoHashWithAllowsSwappableMemory: true];
	if (calculateSHA512)
		SHA512Hash =
		    [OFSHA512Hash cryptoHashWithAllowsSwappableMemory: true];

	for (OFString *path in optionsParser.remainingArguments) {
		void *pool = objc_autoreleasePoolPush();
		OFStream *file;

		if ([path isEqual: @"-"])
			file = of_stdin;







|


|

<
|

<
|

<
|

<
|

<
|







144
145
146
147
148
149
150
151
152
153
154
155

156
157

158
159

160
161

162
163

164
165
166
167
168
169
170
171
	    !calculateSHA512)
		help();

	if (optionsParser.remainingArguments.count < 1)
		help();

	if (calculateMD5)
		MD5Hash = [OFMD5Hash hashWithAllowsSwappableMemory: true];
	if (calculateRIPEMD160)
		RIPEMD160Hash =
		    [OFRIPEMD160Hash hashWithAllowsSwappableMemory: true];
	if (calculateSHA1)

		SHA1Hash = [OFSHA1Hash hashWithAllowsSwappableMemory: true];
	if (calculateSHA224)

		SHA224Hash = [OFSHA224Hash hashWithAllowsSwappableMemory: true];
	if (calculateSHA256)

		SHA256Hash = [OFSHA256Hash hashWithAllowsSwappableMemory: true];
	if (calculateSHA384)

		SHA384Hash = [OFSHA384Hash hashWithAllowsSwappableMemory: true];
	if (calculateSHA512)

		SHA512Hash = [OFSHA512Hash hashWithAllowsSwappableMemory: true];

	for (OFString *path in optionsParser.remainingArguments) {
		void *pool = objc_autoreleasePoolPush();
		OFStream *file;

		if ([path isEqual: @"-"])
			file = of_stdin;

Modified utils/ofhttp/Makefile from [ca0ac82289] to [54490626b4].

12
13
14
15
16
17
18
19


20
21
22
23
24

${PROG}: ${LIBOBJFW_DEP_LVL2} ${LIBOBJFWRT_DEP_LVL2}

CPPFLAGS += -I../../src					\
	    -I../../src/runtime				\
	    -I../../src/exceptions			\
	    -I../..					\
	    -DLANGUAGE_DIR=\"${datadir}/ofhttp/lang\"


LIBS := -L../../src -lobjfw						\
	-L../../src/runtime -L../../src/runtime/linklib ${RUNTIME_LIBS}	\
	${LIBS}
LD = ${OBJC}
LDFLAGS += ${LDFLAGS_RPATH}







|
>
>





12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

${PROG}: ${LIBOBJFW_DEP_LVL2} ${LIBOBJFWRT_DEP_LVL2}

CPPFLAGS += -I../../src					\
	    -I../../src/runtime				\
	    -I../../src/exceptions			\
	    -I../..					\
	    -DLANGUAGE_DIR='"${datadir}/ofhttp/lang"'	\
	    -DLIB_PREFIX='"${LIB_PREFIX}"'		\
	    -DLIB_SUFFIX='"${LIB_SUFFIX}"'
LIBS := -L../../src -lobjfw						\
	-L../../src/runtime -L../../src/runtime/linklib ${RUNTIME_LIBS}	\
	${LIBS}
LD = ${OBJC}
LDFLAGS += ${LDFLAGS_RPATH}

Modified utils/ofhttp/OFHTTP.m from [596ef6416d] to [f445945689].

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
#ifdef OF_HAVE_PLUGINS
+ (void)initialize
{
	if (self != [OFHTTP class])
		return;

	/* Opportunistically try loading ObjOpenSSL and ignore any errors. */
	of_dlopen(@"objopenssl", OF_RTLD_LAZY);
}
#endif

- (instancetype)init
{
	self = [super init];








|







281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
#ifdef OF_HAVE_PLUGINS
+ (void)initialize
{
	if (self != [OFHTTP class])
		return;

	/* Opportunistically try loading ObjOpenSSL and ignore any errors. */
	of_dlopen(@LIB_PREFIX @"objopenssl" @LIB_SUFFIX, OF_RTLD_LAZY);
}
#endif

- (instancetype)init
{
	self = [super init];