ObjFW  Check-in [ff6eb7b6c3]

Overview
Comment:Merge trunk into branch "tagged-pointers"
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | tagged-pointers
Files: files | file ages | folders
SHA3-256: ff6eb7b6c3ea22ad9f8a70a36255734607022e934d6f26f909f35e891f52716e
User & Date: js on 2020-08-30 15:40:33
Other Links: branch diff | manifest | tags
Context
2020-08-30
16:22
OFNumber: Never access ivars after init check-in: bc9998913a user: js tags: tagged-pointers
15:40
Merge trunk into branch "tagged-pointers" check-in: ff6eb7b6c3 user: js tags: tagged-pointers
2020-08-29
23:17
ofhttp: Translate "Error!" message check-in: f79f04f882 user: js tags: trunk
2020-07-26
21:09
lookup-asm-x86_64-macho.S: Fix missing @GOTPCREL check-in: 4cf6858694 user: js tags: tagged-pointers
Changes

Modified .fossil-settings/clean-glob from [bcab2de1f3] to [8cc139c114].

23
24
25
26
27
28
29

30
31
32
33
34
35
36
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37







+







configure
docs
extra.mk
generators/gen_tables
src/Info.plist
src/bridge/Info.plist
src/objfw-defs.h
src/runtime/Info.plist
src/runtime/amiga-library-functable.inc
src/runtime/inline.h
tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
tests/objc_sync/objc_sync

Modified .fossil-settings/ignore-glob from [01fa00e105] to [9af6ddf1c8].

25
26
27
28
29
30
31

32
33
34
35
36
37
38
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39







+







configure
docs
extra.mk
generators/gen_tables
src/Info.plist
src/bridge/Info.plist
src/objfw-defs.h
src/runtime/Info.plist
src/runtime/amiga-library-functable.inc
src/runtime/inline.h
tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
tests/iOS.xcodeproj/*.pbxuser

Modified .gitignore from [65d8f91504] to [1a9a1a32ef].

25
26
27
28
29
30
31

32
33
34
35
36
37
38
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39







+







configure
docs
extra.mk
generators/gen_tables
src/Info.plist
src/bridge/Info.plist
src/objfw-defs.h
src/runtime/Info.plist
src/runtime/amiga-library-functable.inc
src/runtime/inline.h
tests/DerivedData
tests/EBOOT.PBP
tests/Info.plist
tests/PARAM.SFO
tests/iOS.xcodeproj/*.pbxuser

Modified README.md from [c7f0f5d8b7] to [08dca7b831].

117
118
119
120
121
122
123





124
125
126
127
128
129


130
131
132
133
134
135
136
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143







+
+
+
+
+






+
+








    $ fossil ui

  It's also possible to open the same local repository multiple times, so that
  you have multiple working directories all backed by the same local
  repository.

  In order to verify the signature of the currently checked out checkin, you
  can use:

    $ fossil artifact current | gpg --verify

<h2 id="cloning-git">Git</h2>

  To clone the Git repository, use the following:

    $ git clone https://github.com/ObjFW/ObjFW

  Git commits are not signed, so if you want to check the signature of an
  individual commit, branch head or tag, please use Fossil.

<h1 id="installation">Installation</h1>

  To install ObjFW, just run the following commands:

    $ ./configure
    $ make

Modified configure.ac from [69c688a7b0] to [64037d8825].

410
411
412
413
414
415
416

417
418
419
420
421
422
423
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424







+







])

AC_DEFINE_UNQUOTED(PLUGIN_SUFFIX, "$PLUGIN_SUFFIX", [Suffix for plugins])
AS_IF([test x"$enable_files" != x"no" -a x"$PLUGIN_SUFFIX" != x""], [
	AC_SUBST(USE_SRCS_PLUGINS, '${SRCS_PLUGINS}')
	AC_SUBST(TESTPLUGIN, "plugin")
	AC_DEFINE(OF_HAVE_PLUGINS, 1, [Whether we have plugin support])
	AC_CONFIG_FILES(tests/plugin/Info.plist)

	AS_IF([test x"$build_framework" = x"yes"], [
		TESTPLUGIN_LIBS="-F../../src -F../../src/runtime"
		TESTPLUGIN_LIBS="$TESTPLUGIN_LIBS -framework ObjFW"
		TESTPLUGIN_LIBS="$TESTPLUGIN_LIBS \${RUNTIME_FRAMEWORK_LIBS}"
	], [
		TESTPLUGIN_LIBS="-L../../src -L../../src/runtime"
520
521
522
523
524
525
526

527
528
529
530
531
532
533
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535







+







			OBJCFLAGS="$old_OBJCFLAGS $flag"
			OBJFW_OBJCFLAGS="$OBJFW_OBJCFLAGS $flag"
			AC_MSG_RESULT(no)
			old_compiler="yes"
		])

		AC_SUBST(RUNTIME, "runtime")
		AC_CONFIG_FILES(src/runtime/Info.plist)

		AS_IF([test x"$enable_shared" != x"no"], [
			AC_SUBST(OBJFWRT_SHARED_LIB,
				"${LIB_PREFIX}objfwrt${LIB_SUFFIX}")
		])

		AS_IF([test x"$enable_static" = x"yes"], [
1570
1571
1572
1573
1574
1575
1576

1577
1578
1579
1580
1581
1582
1583
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586







+







AC_CHECK_FUNC(pledge, [
	AC_DEFINE(OF_HAVE_PLEDGE, 1, [Whether we have pledge()])
])

AS_IF([test x"$objc_runtime" = x"Apple runtime"], [
	AC_CHECK_HEADER(Foundation/NSObject.h, [
		AC_SUBST(BRIDGE, "bridge")
		AC_CONFIG_FILES(src/bridge/Info.plist)

		AS_IF([test x"$enable_shared" != x"no"], [
			AC_SUBST(OBJFWBRIDGE_SHARED_LIB,
				"${LIB_PREFIX}objfwbridge${LIB_SUFFIX}")
		])
		AS_IF([test x"$enable_static" = x"yes" \
		    -o x"$enable_shared" = x"no"], [
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1908
1909
1910
1911
1912
1913
1914

1915

1916
1917
1918
1919
1920
1921
1922







-

-








AC_SUBST(TESTS_LIBS)

AC_CONFIG_FILES([
	buildsys.mk
	extra.mk
	src/Info.plist
	src/bridge/Info.plist
	tests/Info.plist
	tests/plugin/Info.plist
	utils/objfw-config
])
AC_CONFIG_HEADERS([config.h src/objfw-defs.h])
AC_OUTPUT

AS_IF([test x"$old_compiler" = x"yes"], [
	echo

Modified generators/TableGenerator.m from [8fbc15917b] to [ce006846a1].

117
118
119
120
121
122
123
124
125


126
127
128
129
130
131
132
133
134
135






136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153


154
155
156
157
158
159
160
117
118
119
120
121
122
123


124
125
126
127
128
129






130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151


152
153
154
155
156
157
158
159
160







-
-
+
+




-
-
-
-
-
-
+
+
+
+
+
+
















-
-
+
+








		components = [line componentsSeparatedByString: @";"];
		if (components.count != 15) {
			of_log(@"Invalid line: %@\n", line);
			[OFApplication terminateWithStatus: 1];
		}

		codePoint = (of_unichar_t)
		    [[components objectAtIndex: 0] hexadecimalValue];
		codePoint = (of_unichar_t)[[components objectAtIndex: 0]
		    unsignedLongLongValueWithBase: 16];

		if (codePoint > 0x10FFFF)
			@throw [OFOutOfRangeException exception];

		_uppercaseTable[codePoint] = (of_unichar_t)
		    [[components objectAtIndex: 12] hexadecimalValue];
		_lowercaseTable[codePoint] = (of_unichar_t)
		    [[components objectAtIndex: 13] hexadecimalValue];
		_titlecaseTable[codePoint] = (of_unichar_t)
		    [[components objectAtIndex: 14] hexadecimalValue];
		_uppercaseTable[codePoint] = (of_unichar_t)[[components
		    objectAtIndex: 12] unsignedLongLongValueWithBase: 16];
		_lowercaseTable[codePoint] = (of_unichar_t)[[components
		    objectAtIndex: 13] unsignedLongLongValueWithBase: 16];
		_titlecaseTable[codePoint] = (of_unichar_t)[[components
		    objectAtIndex: 14] unsignedLongLongValueWithBase: 16];

		if ([[components objectAtIndex: 5] length] > 0) {
			OFArray *decomposed = [[components objectAtIndex: 5]
			    componentsSeparatedByString: @" "];
			bool compat = false;
			OFMutableString *string;

			if ([decomposed.firstObject hasPrefix: @"<"]) {
				decomposed = [decomposed objectsInRange:
				    of_range(1, decomposed.count - 1)];
				compat = true;
			}

			string = [OFMutableString string];

			for (OFString *character in decomposed) {
				of_unichar_t unichar =
				    (of_unichar_t)character.hexadecimalValue;
				of_unichar_t unichar = (of_unichar_t)[character
				    unsignedLongLongValueWithBase: 16];

				[string appendCharacters: &unichar
						  length: 1];
			}

			[string makeImmutable];

200
201
202
203
204
205
206
207
208


209
210
211
212
213
214


215
216
217
218
219
220
221
200
201
202
203
204
205
206


207
208
209
210
211
212


213
214
215
216
217
218
219
220
221







-
-
+
+




-
-
+
+







			[OFApplication terminateWithStatus: 1];
		}

		if (![[components objectAtIndex: 1] isEqual: @"S"] &&
		    ![[components objectAtIndex: 1] isEqual: @"C"])
			continue;

		codePoint = (of_unichar_t)
		    [[components objectAtIndex: 0] hexadecimalValue];
		codePoint = (of_unichar_t)[[components objectAtIndex: 0]
		    unsignedLongLongValueWithBase: 16];

		if (codePoint > 0x10FFFF)
			@throw [OFOutOfRangeException exception];

		_casefoldingTable[codePoint] = (of_unichar_t)
		    [[components objectAtIndex: 2] hexadecimalValue];
		_casefoldingTable[codePoint] = (of_unichar_t)[[components
		    objectAtIndex: 2] unsignedLongLongValueWithBase: 16];

		objc_autoreleasePoolPop(pool2);
	}

	[of_stdout writeLine: @" done"];

	[self writeFiles];
263
264
265
266
267
268
269


270
271
272
273
274
275
276
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278







+
+








			if (changed) {
				[table[i] release];
				table[i] = [replacement copy];

				done = false;
			}

			objc_autoreleasePoolPop(pool);
		}
	} while (!done);
}

- (void)writeFiles
{
	OFURL *URL;

Modified src/Info.plist.in from [125685d722] to [4f293d51f7].

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22









-
+












<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleExecutable</key>
	<string>ObjFW</string>
	<key>CFBundleName</key>
	<string>ObjFW</string>
	<key>CFBundleIdentifier</key>
	<string>zone.heap.objfw</string>
	<string>im.nil.objfw</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundlePackageType</key>
	<string>FMWK</string>
	<key>CFBundleVersion</key>
	<string>@BUNDLE_VERSION@</string>
	<key>CFBundleShortVersionString</key>
	<string>@BUNDLE_SHORT_VERSION@</string>
	<key>MinimumOSVersion</key>
	<string>9.0</string>
</dict>
</plist>

Modified src/Makefile from [34c348d2c8] to [02fc344718].

25
26
27
28
29
30
31
32

33
34

35
36
37
38
39
40
41
25
26
27
28
29
30
31

32
33

34
35
36
37
38
39
40
41







-
+

-
+







       OFArray.m			\
       OFBlock.m			\
       OFCharacterSet.m			\
       OFColor.m			\
       OFConstantString.m		\
       OFCountedSet.m			\
       OFData.m				\
       OFData+ASN1DERValue.m		\
       OFData+ASN1DERParsing.m		\
       OFData+CryptoHashing.m		\
       OFData+MessagePackValue.m	\
       OFData+MessagePackParsing.m	\
       OFDate.m				\
       OFDictionary.m			\
       OFEnumerator.m			\
       OFFileManager.m			\
       OFGZIPStream.m			\
       OFHMAC.m				\
       OFInflate64Stream.m		\
82
83
84
85
86
87
88
89
90


91
92
93
94
95
96
97
82
83
84
85
86
87
88


89
90
91
92
93
94
95
96
97







-
-
+
+







       OFSHA384Or512Hash.m		\
       OFSHA512Hash.m			\
       OFSortedList.m			\
       OFStdIOStream.m			\
       OFStream.m			\
       OFString.m			\
       OFString+CryptoHashing.m		\
       OFString+JSONValue.m		\
       OFString+PropertyListValue.m	\
       OFString+JSONParsing.m		\
       OFString+PropertyListParsing.m	\
       OFString+Serialization.m		\
       OFString+URLEncoding.m		\
       OFString+XMLEscaping.m		\
       OFString+XMLUnescaping.m		\
       OFSystemInfo.m			\
       OFTarArchive.m			\
       OFTarArchiveEntry.m		\

Modified src/OFASN1Enumerated.h from [8d58cfdd70] to [b9ec14a4c3].

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
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







-
+





-
+




-
+


-
+







-
+


-
-
+








/*!
 * @brief An ASN.1 Enumerated.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFASN1Enumerated: OFObject
{
	intmax_t _integerValue;
	long long _longLongValue;
}

/*!
 * @brief The integer value.
 */
@property (readonly, nonatomic) intmax_t integerValue;
@property (readonly, nonatomic) long long longLongValue;

/*!
 * @brief Creates an ASN.1 Enumerated with the specified integer value.
 *
 * @param integerValue The integer value of the Enumerated
 * @param value The `long long` value of the Enumerated
 * @return A new, autoreleased OFASN1Enumerated
 */
+ (instancetype)enumeratedWithIntegerValue: (intmax_t)integerValue;
+ (instancetype)enumeratedWithLongLong: (long long)value;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @brief Initializes an already allocated ASN.1 Enumerated with the specified
 *	  integer value.
 *
 * @param integerValue The integer value of the Enumerated
 * @param value The `long long` value of the Enumerated
 * @return An initialized OFASN1Enumerated
 */
- (instancetype)initWithIntegerValue: (intmax_t)integerValue
    OF_DESIGNATED_INITIALIZER;
- (instancetype)initWithLongLong: (long long)value OF_DESIGNATED_INITIALIZER;

/*!
 * @brief Initializes an already allocated ASN.1 Enumerated with the specified
 *	  arguments.
 *
 * @param tagClass The tag class of the value's type
 * @param tagNumber The tag number of the value's type

Modified src/OFASN1Enumerated.m from [1b0ff0da1e] to [78253ff0bd].

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
98
99
100
101
102


103
104
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
98
99
100


101
102
103
104







-
+



-
+

-
+

-
+


-
+



-
+









-
+









-
+






-
+



















-
+







-
+




-
-
+
+



#import "OFASN1Enumerated.h"
#import "OFData.h"
#import "OFString.h"

#import "OFInvalidArgumentException.h"

extern intmax_t of_asn1_der_integer_parse(const unsigned char *buffer,
extern long long of_asn1_der_integer_parse(const unsigned char *buffer,
    size_t length);

@implementation OFASN1Enumerated
@synthesize integerValue = _integerValue;
@synthesize longLongValue = _longLongValue;

+ (instancetype)enumeratedWithIntegerValue: (intmax_t)integerValue
+ (instancetype)enumeratedWithLongLong: (long long)value
{
	return [[[self alloc] initWithIntegerValue: integerValue] autorelease];
	return [[[self alloc] initWithLongLong: value] autorelease];
}

- (instancetype)initWithIntegerValue: (intmax_t)integerValue
- (instancetype)initWithLongLong: (long long)value
{
	self = [super init];

	_integerValue = integerValue;
	_longLongValue = value;

	return self;
}

- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass
		       tagNumber: (of_asn1_tag_number_t)tagNumber
		     constructed: (bool)constructed
	      DEREncodedContents: (OFData *)DEREncodedContents
{
	intmax_t integerValue;
	long long value;

	@try {
		if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    tagNumber != OF_ASN1_TAG_NUMBER_ENUMERATED || constructed)
			@throw [OFInvalidArgumentException exception];

		if (DEREncodedContents.itemSize != 1)
			@throw [OFInvalidArgumentException exception];

		integerValue = of_asn1_der_integer_parse(
		value = of_asn1_der_integer_parse(
		    DEREncodedContents.items, DEREncodedContents.count);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return [self initWithIntegerValue: integerValue];
	return [self initWithLongLong: value];
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (bool)isEqual: (id)object
{
	OFASN1Enumerated *enumerated;

	if (object == self)
		return true;

	if (![object isKindOfClass: [OFASN1Enumerated class]])
		return false;

	enumerated = object;

	if (enumerated->_integerValue != _integerValue)
	if (enumerated->_longLongValue != _longLongValue)
		return false;

	return true;
}

- (uint32_t)hash
{
	return (uint32_t)_integerValue;
	return (uint32_t)_longLongValue;
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1Enumerated: %jd>",
					   _integerValue];
	return [OFString stringWithFormat: @"<OFASN1Enumerated: %lld>",
					   _longLongValue];
}
@end

Modified src/OFASN1Integer.h from [c737c6710d] to [ce3a4d009e].

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
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







-
+





-
+




-
+


-
+







-
+


-
-
+








/*!
 * @brief An ASN.1 Integer.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFASN1Integer: OFObject
{
	intmax_t _integerValue;
	long long _longLongValue;
}

/*!
 * @brief The Integer value.
 */
@property (readonly, nonatomic) intmax_t integerValue;
@property (readonly, nonatomic) long long longLongValue;

/*!
 * @brief Creates an ASN.1 Integer with the specified integer value.
 *
 * @param integerValue The integer value of the Integer
 * @param value The `long long` value of the Integer
 * @return A new, autoreleased OFASN1Integer
 */
+ (instancetype)integerWithIntegerValue: (intmax_t)integerValue;
+ (instancetype)integerWithLongLong: (long long)value;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @brief Initializes an already allocated ASN.1 Integer with the specified
 *	  integer value.
 *
 * @param integerValue The integer value of the Integer
 * @param value The `long long` value of the Integer
 * @return An initialized OFASN1Integer
 */
- (instancetype)initWithIntegerValue: (intmax_t)integerValue
    OF_DESIGNATED_INITIALIZER;
- (instancetype)initWithLongLong: (long long)value OF_DESIGNATED_INITIALIZER;

/*!
 * @brief Initializes an already allocated ASN.1 Integer with the specified
 *	  arguments.
 *
 * @param tagClass The tag class of the value's type
 * @param tagNumber The tag number of the value's type

Modified src/OFASN1Integer.m from [d8bb9bcba6] to [39a371a7d5].

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
98
99
100
101
102
103
104
105
106
107
108
109
110

111
112
113
114
115
116
117
118

119
120
121
122
123
124


125
126
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
98
99
100
101
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
117

118
119
120
121
122


123
124
125
126







-
+


-
+


-
-
+
+







-
+








-
+

-
+

-
+


-
+



-
+









-
+









-
+






-
+



















-
+







-
+




-
-
+
+


#import "OFData.h"
#import "OFString.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfRangeException.h"

intmax_t
long long
of_asn1_der_integer_parse(const unsigned char *buffer, size_t length)
{
	uintmax_t value = 0;
	unsigned long long value = 0;

	/* TODO: Support for big numbers */
	if (length > sizeof(uintmax_t) &&
	    (length != sizeof(uintmax_t) + 1 || buffer[0] != 0))
	if (length > sizeof(unsigned long long) &&
	    (length != sizeof(unsigned long long) + 1 || buffer[0] != 0))
		@throw [OFOutOfRangeException exception];

	if (length >= 2 && ((buffer[0] == 0 && !(buffer[1] & 0x80)) ||
	    (buffer[0] == 0xFF && buffer[1] & 0x80)))
		@throw [OFInvalidFormatException exception];

	if (length >= 1 && buffer[0] & 0x80)
		value = ~(uintmax_t)0;
		value = ~0ull;

	while (length--)
		value = (value << 8) | *buffer++;

	return value;
}

@implementation OFASN1Integer
@synthesize integerValue = _integerValue;
@synthesize longLongValue = _longLongValue;

+ (instancetype)integerWithIntegerValue: (intmax_t)integerValue
+ (instancetype)integerWithLongLong: (long long)value
{
	return [[[self alloc] initWithIntegerValue: integerValue] autorelease];
	return [[[self alloc] initWithLongLong: value] autorelease];
}

- (instancetype)initWithIntegerValue: (intmax_t)integerValue
- (instancetype)initWithLongLong: (long long)value
{
	self = [super init];

	_integerValue = integerValue;
	_longLongValue = value;

	return self;
}

- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass
		       tagNumber: (of_asn1_tag_number_t)tagNumber
		     constructed: (bool)constructed
	      DEREncodedContents: (OFData *)DEREncodedContents
{
	intmax_t integerValue;
	long long value;

	@try {
		if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    tagNumber != OF_ASN1_TAG_NUMBER_INTEGER || constructed)
			@throw [OFInvalidArgumentException exception];

		if (DEREncodedContents.itemSize != 1)
			@throw [OFInvalidArgumentException exception];

		integerValue = of_asn1_der_integer_parse(
		value = of_asn1_der_integer_parse(
		    DEREncodedContents.items, DEREncodedContents.count);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return [self initWithIntegerValue: integerValue];
	return [self initWithLongLong: value];
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (bool)isEqual: (id)object
{
	OFASN1Integer *integer;

	if (object == self)
		return true;

	if (![object isKindOfClass: [OFASN1Integer class]])
		return false;

	integer = object;

	if (integer->_integerValue != _integerValue)
	if (integer->_longLongValue != _longLongValue)
		return false;

	return true;
}

- (uint32_t)hash
{
	return (uint32_t)_integerValue;
	return (uint32_t)_longLongValue;
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1Integer: %jd>",
					   _integerValue];
	return [OFString stringWithFormat: @"<OFASN1Integer: %lld>",
					   _longLongValue];
}
@end

Modified src/OFASN1ObjectIdentifier.m from [64757d3fa2] to [13ae15fdce].

42
43
44
45
46
47
48
49

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

49
50
51
52
53
54
55
56







-
+







{
	self = [super init];

	@try {
		if (subidentifiers.count < 1)
			@throw [OFInvalidFormatException exception];

		switch ([[subidentifiers objectAtIndex: 0] intMaxValue]) {
		switch ([[subidentifiers objectAtIndex: 0] longLongValue]) {
		case 0:
		case 1:
		case 2:
			break;
		default:
			@throw [OFInvalidFormatException exception];
		}
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
98

99
100
101
102
103
104
105
106
107

108
109
110

111
112
113
114

115
116
117
118
119
120

121
122
123
124
125
126
127
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

98
99
100
101
102
103
104
105
106

107
108
109

110
111
112
113

114
115
116
117
118
119

120
121
122
123
124
125
126
127







-
+



















-
+








-
+


-
+



-
+





-
+







{
	void *pool = objc_autoreleasePoolPush();
	OFMutableArray OF_GENERIC(OFNumber *) *subidentifiers;

	@try {
		const unsigned char *items = DEREncodedContents.items;
		size_t count = DEREncodedContents.count;
		uintmax_t value = 0;
		unsigned long long value = 0;
		uint_fast8_t bits = 0;

		if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    tagNumber != OF_ASN1_TAG_NUMBER_OBJECT_IDENTIFIER ||
		    constructed)
			@throw [OFInvalidArgumentException exception];

		if (DEREncodedContents.itemSize != 1 || count == 0)
			@throw [OFInvalidArgumentException exception];

		subidentifiers = [OFMutableArray array];

		for (size_t i = 0; i < count; i++) {
			if (bits == 0 && items[i] == 0x80)
				@throw [OFInvalidFormatException exception];

			value = (value << 7) | (items[i] & 0x7F);
			bits += 7;

			if (bits > sizeof(uintmax_t) * 8)
			if (bits > sizeof(unsigned long long) * 8)
				@throw [OFOutOfRangeException exception];

			if (items[i] & 0x80)
				continue;

			if (subidentifiers.count == 0) {
				if (value < 40)
					[subidentifiers addObject:
					    [OFNumber numberWithUIntMax: 0]];
					    [OFNumber numberWithInt: 0]];
				else if (value < 80) {
					[subidentifiers addObject:
					    [OFNumber numberWithUIntMax: 1]];
					    [OFNumber numberWithInt: 1]];
					value -= 40;
				} else {
					[subidentifiers addObject:
					    [OFNumber numberWithUIntMax: 2]];
					    [OFNumber numberWithInt: 2]];
					value -= 80;
				}
			}

			[subidentifiers addObject:
			    [OFNumber numberWithUIntMax: value]];
			    [OFNumber numberWithUnsignedLongLong: value]];

			value = 0;
			bits = 0;
		}

		if (items[count - 1] & 0x80)
			@throw [OFInvalidFormatException exception];

Modified src/OFConstantString.m from [1a9a1e4686] to [0761b10d3a].

571
572
573
574
575
576
577



578












579
580
581
582

583
584
585

586
587
588
589
590
591

592
593
594
595
596
597
598
599
600
601
602
603
571
572
573
574
575
576
577
578
579
580

581
582
583
584
585
586
587
588
589
590
591
592
593
594
595

596
597
598

599
600
601
602



603





604
605
606
607
608
609
610







+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+



-
+


-
+



-
-
-
+
-
-
-
-
-







- (OFString *)stringByDeletingLastPathComponent
{
	[self finishInitialization];

	return self.stringByDeletingLastPathComponent;
}

- (long long)longLongValue
{
	[self finishInitialization];
- (intmax_t)decimalValue

	return self.longLongValue;
}

- (long long)longLongValueWithBase: (int)base
{
	[self finishInitialization];

	return [self longLongValueWithBase: base];
}

- (unsigned long long)unsignedLongLongValue
{
	[self finishInitialization];

	return self.decimalValue;
	return self.unsignedLongLongValue;
}

- (uintmax_t)hexadecimalValue
- (unsigned long long)unsignedLongLongValueWithBase: (int)base
{
	[self finishInitialization];

	return self.hexadecimalValue;
}

	return [self unsignedLongLongValueWithBase: base];
- (uintmax_t)octalValue
{
	[self finishInitialization];

	return self.octalValue;
}

- (float)floatValue
{
	[self finishInitialization];

	return self.floatValue;

Modified src/OFCountedMapTableSet.m from [5ffa3e62ea] to [72e0c09af3].

134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
150
151
152

153
154
155
156
157
158
159
160
161
162
163
134
135
136
137
138
139
140


141
142
143
144
145
146
147
148
149
150

151




152
153
154
155
156
157
158







-
-
+









-
+
-
-
-
-








		for (OFXMLElement *objectElement in
		    [element elementsForName: @"object"
				   namespace: OF_SERIALIZATION_NS]) {
			void *pool2 = objc_autoreleasePoolPush();
			OFXMLElement *object;
			OFXMLAttribute *countAttribute;
			intmax_t signedCount;
			uintmax_t count;
			unsigned long long count;

			object = [objectElement elementsForNamespace:
			    OF_SERIALIZATION_NS].firstObject;
			countAttribute =
			    [objectElement attributeForName: @"count"];

			if (object == nil || countAttribute == nil)
				@throw [OFInvalidFormatException exception];

			signedCount = countAttribute.decimalValue;
			count = countAttribute.unsignedLongLongValue;
			if (signedCount < 0)
			       @throw [OFOutOfRangeException exception];

			count = signedCount;
			if (count > SIZE_MAX || count > UINTPTR_MAX)
				@throw [OFOutOfRangeException exception];

			[_mapTable setObject: (void *)(uintptr_t)count
				      forKey: object.objectByDeserializing];

			objc_autoreleasePoolPop(pool2);

Modified src/OFDNSResolver.m from [6319b8ebc8] to [abd3a40827].

489
490
491
492
493
494
495
496

497
498
499
500
501
502
503
489
490
491
492
493
494
495

496
497
498
499
500
501
502
503







-
+







		_settings = [settings copy];
		_delegate = [delegate retain];

		queryData = [OFMutableData dataWithCapacity: 512];

		/* Header */

		tmp = OF_BSWAP16_IF_LE(_ID.uInt16Value);
		tmp = OF_BSWAP16_IF_LE(_ID.unsignedShortValue);
		[queryData addItems: &tmp
			      count: 2];

		/* RD */
		tmp = OF_BSWAP16_IF_LE(1u << 8);
		[queryData addItems: &tmp
			      count: 2];
810
811
812
813
814
815
816
817

818
819
820
821
822
823
824
810
811
812
813
814
815
816

817
818
819
820
821
822
823
824







-
+







{
	void *pool = objc_autoreleasePoolPush();
	OFNumber *ID;
	OFDNSResolverContext *context;

	/* Random, unused ID */
	do {
		ID = [OFNumber numberWithUInt16: of_random16()];
		ID = [OFNumber numberWithUnsignedShort: of_random16()];
	} while ([_queries objectForKey: ID] != nil);

	if (query.domainName.UTF8StringLength > 253)
		@throw [OFOutOfRangeException exception];

	if (_settings->_nameServers.count == 0) {
		id exception = [OFDNSQueryFailedException
909
910
911
912
913
914
915
916

917
918
919
920
921
922
923
909
910
911
912
913
914
915

916
917
918
919
920
921
922
923







-
+







	OFNumber *ID;
	OFDNSResolverContext *context;

	if (length < 2)
		/* We can't get the ID to get the context. Ignore packet. */
		return true;

	ID = [OFNumber numberWithUInt16: (buffer[0] << 8) | buffer[1]];
	ID = [OFNumber numberWithUnsignedShort: (buffer[0] << 8) | buffer[1]];
	context = [[[_queries objectForKey: ID] retain] autorelease];

	if (context == nil)
		return true;

	if (context->_TCPSocket != nil) {
		if ([_TCPQueries objectForKey: context->_TCPSocket] != context)

Modified src/OFDNSResolverSettings.m from [995314850c] to [aa15389045].

30
31
32
33
34
35
36

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







+







#ifdef OF_WINDOWS
# import "OFWindowsRegistryKey.h"
#endif

#import "OFInvalidFormatException.h"
#import "OFOpenItemFailedException.h"
#import "OFOutOfMemoryException.h"
#import "OFOutOfRangeException.h"

#ifdef OF_WINDOWS
# define interface struct
# include <iphlpapi.h>
# undef interface
#endif

234
235
236
237
238
239
240


241
242

243



244

245
246
247
248
249
250

251


252
253

254



255

256
257
258
259
260

261
262
263
264
265
266
267
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250

251

252
253
254
255

256
257
258
259
260
261
262
263
264
265
266

267
268
269
270
271

272
273
274
275
276
277
278
279







+
+


+

+
+
+
-
+
-




-
+

+
+


+

+
+
+
-
+




-
+







}

# if !defined(OF_WINDOWS) && !defined(OF_AMIGAOS4)
- (void)parseResolvConfOption: (OFString *)option
{
	@try {
		if ([option hasPrefix: @"ndots:"]) {
			unsigned long long number;

			option = [option substringWithRange:
			    of_range(6, option.length - 6)];
			number = option.unsignedLongLongValue;

			if (number > UINT_MAX)
				@throw [OFOutOfRangeException exception];

			_minNumberOfDotsInAbsoluteName =
			_minNumberOfDotsInAbsoluteName = (unsigned int)number;
			    (unsigned int)option.decimalValue;
		} else if ([option hasPrefix: @"timeout:"]) {
			option = [option substringWithRange:
			    of_range(8, option.length - 8)];

			_timeout = option.decimalValue;
			_timeout = option.unsignedLongLongValue;
		} else if ([option hasPrefix: @"attempts:"]) {
			unsigned long long number;

			option = [option substringWithRange:
			    of_range(9, option.length - 9)];
			number = option.unsignedLongLongValue;

			if (number > UINT_MAX)
				@throw [OFOutOfRangeException exception];

			_maxAttempts = (unsigned int)option.decimalValue;
			_maxAttempts = (unsigned int)number;
		} else if ([option hasPrefix: @"reload-period:"]) {
			option = [option substringWithRange:
			    of_range(14, option.length - 14)];

			_configReloadInterval = option.decimalValue;
			_configReloadInterval = option.unsignedLongLongValue;
		} else if ([option isEqual: @"tcp"])
			_usesTCP = true;
	} @catch (OFInvalidFormatException *e) {
	}
}

- (void)parseResolvConf: (OFString *)path

Modified src/OFDNSResourceRecord.m from [054747ac72] to [08b68e10ee].

77
78
79
80
81
82
83
84


85
86
87
88
89
90
91
77
78
79
80
81
82
83

84
85
86
87
88
89
90
91
92







-
+
+








	string = string.uppercaseString;

	if ([string isEqual: @"IN"])
		DNSClass = OF_DNS_CLASS_IN;
	else {
		@try {
			DNSClass = (of_dns_class_t)string.decimalValue;
			DNSClass = (of_dns_class_t)
			    [string unsignedLongLongValueWithBase: 0];
		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidArgumentException exception];
		}
	}

	objc_autoreleasePoolPop(pool);

121
122
123
124
125
126
127
128
129


130
131
132
133
134
135
136
122
123
124
125
126
127
128


129
130
131
132
133
134
135
136
137







-
-
+
+







		recordType = OF_DNS_RECORD_TYPE_AAAA;
	else if ([string isEqual: @"SRV"])
		recordType = OF_DNS_RECORD_TYPE_SRV;
	else if ([string isEqual: @"ALL"])
		recordType = OF_DNS_RECORD_TYPE_ALL;
	else {
		@try {
			recordType =
			    (of_dns_record_type_t)string.decimalValue;
			recordType = (of_dns_record_type_t)
			    [string unsignedLongLongValueWithBase: 0];
		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidArgumentException exception];
		}
	}

	objc_autoreleasePoolPop(pool);

Renamed and modified src/OFData+ASN1DERValue.h [f3069736d2] to src/OFData+ASN1DERParsing.h [edd796e7d5].

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
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







-
+




-
+







-
+











-
+



#import "OFASN1Value.h"

OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFData_ASN1DERValue_reference;
extern int _OFData_ASN1DERParsing_reference;
#ifdef __cplusplus
}
#endif

@interface OFData (ASN1DERValue)
@interface OFData (ASN1DERParsing)
/*!
 * @brief The data interpreted as ASN.1 in DER representation and parsed as an
 *	  object.
 *
 * This is either an OFArray (for a sequence), an OFSet (for a set) or an
 * OFASN1Value.
 */
@property (readonly, nonatomic) id ASN1DERValue;
@property (readonly, nonatomic) id objectByParsingASN1DER;

/*!
 * @brief Parses the ASN.1 DER representation and returns it as an object.
 *
 * This is either an OFArray (for a sequence), an OFSet (for a set) or an
 * OFASN1Value.
 *
 * @param depthLimit The maximum depth the parser should accept (defaults to 32
 *		     if not specified, 0 means no limit (insecure!))
 * @return The ASN.1 DER representation as an object
 */
- (id)ASN1DERValueWithDepthLimit: (size_t)depthLimit;
- (id)objectByParsingASN1DERWithDepthLimit: (size_t)depthLimit;
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFData+ASN1DERValue.m [e3b3051875] to src/OFData+ASN1DERParsing.m [31638813f3].

13
14
15
16
17
18
19
20

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

20
21
22
23
24
25
26
27







-
+







 * 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+ASN1DERValue.h"
#import "OFData+ASN1DERParsing.h"
#import "OFASN1BitString.h"
#import "OFASN1Boolean.h"
#import "OFASN1Enumerated.h"
#import "OFASN1IA5String.h"
#import "OFASN1Integer.h"
#import "OFASN1NumericString.h"
#import "OFASN1ObjectIdentifier.h"
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
38
39
40
41
42
43
44

45
46
47
48
49
50
51
52







-
+







#import "OFOutOfRangeException.h"
#import "OFTruncatedDataException.h"

enum {
	ASN1_TAG_CONSTRUCTED_MASK = 0x20
};

int _OFData_ASN1DERValue_reference;
int _OFData_ASN1DERParsing_reference;

static size_t parseObject(OFData *self, id *object, size_t depthLimit);

static OFArray *
parseSequence(OFData *contents, size_t depthLimit)
{
	OFMutableArray *ret = [OFMutableArray array];
221
222
223
224
225
226
227
228
229


230
231

232
233
234

235
236
237
238
239
240
241
221
222
223
224
225
226
227


228
229
230

231
232
233

234
235
236
237
238
239
240
241







-
-
+
+

-
+


-
+







	      initWithTagClass: tag >> 6
		     tagNumber: tag & 0x1F
		   constructed: tag & ASN1_TAG_CONSTRUCTED_MASK
	    DEREncodedContents: contents] autorelease];
	return bytesConsumed;
}

@implementation OFData (ASN1DERValue)
- (id)ASN1DERValue
@implementation OFData (ASN1DERParsing)
- (id)objectByParsingASN1DER
{
	return [self ASN1DERValueWithDepthLimit: 32];
	return [self objectByParsingASN1DERWithDepthLimit: 32];
}

- (id)ASN1DERValueWithDepthLimit: (size_t)depthLimit
- (id)objectByParsingASN1DERWithDepthLimit: (size_t)depthLimit
{
	void *pool = objc_autoreleasePoolPush();
	id object;

	if (self.itemSize != 1)
		@throw [OFInvalidArgumentException exception];

Renamed and modified src/OFData+MessagePackValue.h [2409c49524] to src/OFData+MessagePackParsing.h [6f2988f9a2].

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
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







-
+




-
+




-
+








-
+



#import "OFData.h"

OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFData_MessagePackValue_reference;
extern int _OFData_MessagePackParsing_reference;
#ifdef __cplusplus
}
#endif

@interface OFData (MessagePackValue)
@interface OFData (MessagePackParsing)
/*!
 * @brief The data interpreted as MessagePack representation and parsed as an
 *	  object.
 */
@property (readonly, nonatomic) id messagePackValue;
@property (readonly, nonatomic) id objectByParsingMessagePack;

/*!
 * @brief Parses the MessagePack representation and returns it as an object.
 *
 * @param depthLimit The maximum depth the parser should accept (defaults to 32
 *		     if not specified, 0 means no limit (insecure!))
 * @return The MessagePack representation as an object
 */
- (id)messagePackValueWithDepthLimit: (size_t)depthLimit;
- (id)objectByParsingMessagePackWithDepthLimit: (size_t)depthLimit;
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFData+MessagePackValue.m [caaaf51219] to src/OFData+MessagePackParsing.m [464ca7dfaa].

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
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







-
+













-
+







 * file.
 */

#include "config.h"

#include <string.h>

#import "OFData+MessagePackValue.h"
#import "OFData+MessagePackParsing.h"
#import "OFArray.h"
#import "OFDate.h"
#import "OFDictionary.h"
#import "OFMessagePackExtension.h"
#import "OFNull.h"
#import "OFNumber.h"
#import "OFString.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfRangeException.h"
#import "OFTruncatedDataException.h"

int _OFData_MessagePackValue_reference;
int _OFData_MessagePackParsing_reference;

static size_t parseObject(const unsigned char *buffer, size_t length,
    id *object, size_t depthLimit);

static uint16_t
readUInt16(const unsigned char *buffer)
{
189
190
191
192
193
194
195
196

197
198
199
200
201

202
203
204
205
206
207
208
189
190
191
192
193
194
195

196
197
198
199
200

201
202
203
204
205
206
207
208







-
+




-
+







	OFData *data;

	if (length < 1)
		@throw [OFTruncatedDataException exception];

	/* positive fixint */
	if ((buffer[0] & 0x80) == 0) {
		*object = [OFNumber numberWithUInt8: buffer[0] & 0x7F];
		*object = [OFNumber numberWithUnsignedChar: buffer[0] & 0x7F];
		return 1;
	}
	/* negative fixint */
	if ((buffer[0] & 0xE0) == 0xE0) {
		*object = [OFNumber numberWithInt8:
		*object = [OFNumber numberWithChar:
		    ((int8_t)(buffer[0] & 0x1F)) - 32];
		return 1;
	}

	/* fixstr */
	if ((buffer[0] & 0xE0) == 0xA0) {
		count = buffer[0] & 0x1F;
229
230
231
232
233
234
235
236

237
238
239
240
241
242


243
244
245
246
247
248


249
250
251
252
253
254


255
256
257
258
259
260
261

262
263
264
265
266
267

268
269
270
271
272
273

274
275
276
277
278
279

280
281
282
283
284
285
286
229
230
231
232
233
234
235

236
237
238
239
240
241

242
243
244
245
246
247
248

249
250
251
252
253
254
255

256
257
258
259
260
261
262
263

264
265
266
267
268
269

270
271
272
273
274
275

276
277
278
279
280
281

282
283
284
285
286
287
288
289







-
+





-
+
+





-
+
+





-
+
+






-
+





-
+





-
+





-
+







	/* Prefix byte */
	switch (buffer[0]) {
	/* Unsigned integers */
	case 0xCC: /* uint8 */
		if (length < 2)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithUInt8: buffer[1]];
		*object = [OFNumber numberWithUnsignedChar: buffer[1]];
		return 2;
	case 0xCD: /* uint 16 */
		if (length < 3)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithUInt16: readUInt16(buffer + 1)];
		*object = [OFNumber numberWithUnsignedShort:
		    readUInt16(buffer + 1)];
		return 3;
	case 0xCE: /* uint 32 */
		if (length < 5)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithUInt32: readUInt32(buffer + 1)];
		*object = [OFNumber numberWithUnsignedLong:
		    readUInt32(buffer + 1)];
		return 5;
	case 0xCF: /* uint 64 */
		if (length < 9)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithUInt64: readUInt64(buffer + 1)];
		*object = [OFNumber numberWithUnsignedLongLong:
		    readUInt64(buffer + 1)];
		return 9;
	/* Signed integers */
	case 0xD0: /* int 8 */
		if (length < 2)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithInt8: buffer[1]];
		*object = [OFNumber numberWithChar: buffer[1]];
		return 2;
	case 0xD1: /* int 16 */
		if (length < 3)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithInt16: readUInt16(buffer + 1)];
		*object = [OFNumber numberWithShort: readUInt16(buffer + 1)];
		return 3;
	case 0xD2: /* int 32 */
		if (length < 5)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithInt32: readUInt32(buffer + 1)];
		*object = [OFNumber numberWithLong: readUInt32(buffer + 1)];
		return 5;
	case 0xD3: /* int 64 */
		if (length < 9)
			@throw [OFTruncatedDataException exception];

		*object = [OFNumber numberWithInt64: readUInt64(buffer + 1)];
		*object = [OFNumber numberWithLongLong: readUInt64(buffer + 1)];
		return 9;
	/* Floating point */
	case 0xCA:; /* float 32 */
		float f;

		if (length < 5)
			@throw [OFTruncatedDataException exception];
538
539
540
541
542
543
544
545
546


547
548

549
550
551

552
553
554
555
556
557
558
541
542
543
544
545
546
547


548
549
550

551
552
553

554
555
556
557
558
559
560
561







-
-
+
+

-
+


-
+







		return parseTable(buffer + 5, length - 5, object,
		    readUInt32(buffer + 1), depthLimit) + 5;
	default:
		@throw [OFInvalidFormatException exception];
	}
}

@implementation OFData (MessagePackValue)
- (id)messagePackValue
@implementation OFData (MessagePackParsing)
- (id)objectByParsingMessagePack
{
	return [self messagePackValueWithDepthLimit: 32];
	return [self objectByParsingMessagePackWithDepthLimit: 32];
}

- (id)messagePackValueWithDepthLimit: (size_t)depthLimit
- (id)objectByParsingMessagePackWithDepthLimit: (size_t)depthLimit
{
	void *pool = objc_autoreleasePoolPush();
	size_t count = self.count;
	id object;

	if (self.itemSize != 1)
		@throw [OFInvalidArgumentException exception];

Modified src/OFData.h from [28777ad7ed] to [71ad4a3460].

323
324
325
326
327
328
329
330

331
332

323
324
325
326
327
328
329

330
331

332







-
+

-
+
 */
- (void)writeToURL: (OFURL *)URL;
@end

OF_ASSUME_NONNULL_END

#import "OFMutableData.h"
#import "OFData+ASN1DERValue.h"
#import "OFData+ASN1DERParsing.h"
#import "OFData+CryptoHashing.h"
#import "OFData+MessagePackValue.h"
#import "OFData+MessagePackParsing.h"

Modified src/OFData.m from [9637aa54ff] to [63de509839].

44
45
46
47
48
49
50
51

52
53

54
55
56
57
58
59
60
44
45
46
47
48
49
50

51
52

53
54
55
56
57
58
59
60







-
+

-
+








#import "base64.h"

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

@implementation OFData
@synthesize itemSize = _itemSize;

+ (instancetype)dataWithItems: (const void *)items
			count: (size_t)count
180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
195

196
197
198
199
200
201
202
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202







-
+







-
+







	return self;
}

#ifdef OF_HAVE_FILES
- (instancetype)initWithContentsOfFile: (OFString *)path
{
	char *buffer = NULL;
	uintmax_t size;
	unsigned long long size;

	@try {
		OFFile *file;

		size = [[OFFileManager defaultManager]
		    attributesOfItemAtPath: path].fileSize;

# if UINTMAX_MAX > SIZE_MAX
# if ULLONG_MAX > SIZE_MAX
		if (size > SIZE_MAX)
			@throw [OFOutOfRangeException exception];
# endif

		if ((buffer = malloc((size_t)size)) == NULL)
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: (size_t)size];

Modified src/OFDate.m from [8d4b356936] to [4f38b261b8].

483
484
485
486
487
488
489



490
491


492
493
494
495



496





497
498


499
500





501
502
503
504
505
506
507
483
484
485
486
487
488
489
490
491
492


493
494
495



496
497
498
499
500
501
502
503
504


505
506
507

508
509
510
511
512
513
514
515
516
517
518
519







+
+
+
-
-
+
+

-
-
-
+
+
+

+
+
+
+
+
-
-
+
+

-
+
+
+
+
+







		seconds = tmAndTzToTime(&tm, &tz);

	return [self initWithTimeIntervalSince1970: seconds];
}

- (instancetype)initWithSerialization: (OFXMLElement *)element
{
	of_time_interval_t seconds;

	@try {
	void *pool = objc_autoreleasePoolPush();
	of_time_interval_t seconds;
		void *pool = objc_autoreleasePoolPush();
		unsigned long long value;

	if (![element.name isEqual: @"OFDate"] ||
	    ![element.namespace isEqual: OF_SERIALIZATION_NS])
		@throw [OFInvalidArgumentException exception];
		if (![element.name isEqual: @"OFDate"] ||
		    ![element.namespace isEqual: OF_SERIALIZATION_NS])
			@throw [OFInvalidArgumentException exception];

		value = [element unsignedLongLongValueWithBase: 16];

		if (value > UINT64_MAX)
			@throw [OFOutOfRangeException exception];

	seconds = OF_BSWAP_DOUBLE_IF_LE(OF_INT_TO_DOUBLE_RAW(OF_BSWAP64_IF_LE(
	    element.hexadecimalValue)));
		seconds = OF_BSWAP_DOUBLE_IF_LE(OF_INT_TO_DOUBLE_RAW(
		    OF_BSWAP64_IF_LE(value)));

	objc_autoreleasePoolPop(pool);
		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return [self initWithTimeIntervalSince1970: seconds];
}

- (bool)isEqual: (id)object
{
	OFDate *otherDate;

Modified src/OFFileManager.h from [832085a76a] to [2be4d0719f].

574
575
576
577
578
579
580
581

582
583
584
585
586
587
588
589
590
591
592
593
594
595
596

597
598
599
600
601
602
603

604
605
606
607
608
609
610

611
612
613
614
615
616
617
574
575
576
577
578
579
580

581
582
583
584
585
586
587
588
589
590
591
592
593
594
595

596
597
598
599
600
601
602

603
604
605
606
607
608
609

610
611
612
613
614
615
616
617







-
+














-
+






-
+






-
+








@interface OFDictionary (FileAttributes)
/*!
 * @brief The @ref of_file_attribute_key_size key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) uintmax_t fileSize;
@property (readonly, nonatomic) unsigned long long fileSize;

/*!
 * @brief The @ref of_file_attribute_key_type key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) of_file_type_t fileType;

/*!
 * @brief The @ref of_file_attribute_key_posix_permissions key from the
 *	  dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) uint16_t filePOSIXPermissions;
@property (readonly, nonatomic) unsigned long filePOSIXPermissions;

/*!
 * @brief The @ref of_file_attribute_key_posix_uid key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) uint32_t filePOSIXUID;
@property (readonly, nonatomic) unsigned long filePOSIXUID;

/*!
 * @brief The @ref of_file_attribute_key_posix_gid key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) uint32_t filePOSIXGID;
@property (readonly, nonatomic) unsigned long filePOSIXGID;

/*!
 * @brief The @ref of_file_attribute_key_owner key from the dictionary.
 *
 * Raises an @ref OFUndefinedKeyException if the key is missing.
 */
@property (readonly, nonatomic) OFString *fileOwner;

Modified src/OFFileManager.m from [c5306f3b5d] to [d64d08867d].

934
935
936
937
938
939
940
941

942
943
944

945
946
947
948
949
950
951
952

953
954
955

956
957
958

959
960
961

962
963
964

965
966
967

968
969
970
971
972
973
974
934
935
936
937
938
939
940

941
942
943

944
945
946
947
948
949
950
951

952
953
954

955
956
957

958
959
960

961
962
963

964
965
966

967
968
969
970
971
972
973
974







-
+


-
+







-
+


-
+


-
+


-
+


-
+


-
+







- (unsigned int)retainCount
{
	return OF_RETAIN_COUNT_MAX;
}
@end

@implementation OFDictionary (FileAttributes)
- (uintmax_t)fileSize
- (unsigned long long)fileSize
{
	return [attributeForKeyOrException(self, of_file_attribute_key_size)
	    uIntMaxValue];
	    unsignedLongLongValue];
}

- (of_file_type_t)fileType
{
	return attributeForKeyOrException(self, of_file_attribute_key_type);
}

- (uint16_t)filePOSIXPermissions
- (unsigned long)filePOSIXPermissions
{
	return [attributeForKeyOrException(self,
	    of_file_attribute_key_posix_permissions) uInt16Value];
	    of_file_attribute_key_posix_permissions) unsignedLongValue];
}

- (uint32_t)filePOSIXUID
- (unsigned long)filePOSIXUID
{
	return [attributeForKeyOrException(self,
	    of_file_attribute_key_posix_uid) uInt32Value];
	    of_file_attribute_key_posix_uid) unsignedLongValue];
}

- (uint32_t)filePOSIXGID
- (unsigned long)filePOSIXGID
{
	return [attributeForKeyOrException(self,
	    of_file_attribute_key_posix_gid) uInt32Value];
	    of_file_attribute_key_posix_gid) unsignedLongValue];
}

- (OFString *)fileOwner
{
	return attributeForKeyOrException(self, of_file_attribute_key_owner);
}

Modified src/OFFileURLHandler.m from [b404d9c716] to [987947edfd].

407
408
409
410
411
412
413
414

415
416

417
418
419
420
421
422
423
407
408
409
410
411
412
413

414
415

416
417
418
419
420
421
422
423







-
+

-
+







}

static void
setOwnerAndGroupAttributes(of_mutable_file_attributes_t attributes,
    of_stat_t *s)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_OWNER
	[attributes setObject: [NSNumber numberWithUInt16: s->st_uid]
	[attributes setObject: [NSNumber numberWithUnsignedLong: s->st_uid]
		       forKey: of_file_attribute_key_posix_uid];
	[attributes setObject: [NSNumber numberWithUInt16: s->st_gid]
	[attributes setObject: [NSNumber numberWithUnsignedLong: s->st_gid]
		       forKey: of_file_attribute_key_posix_gid];

# ifdef OF_HAVE_THREADS
	[passwdMutex lock];
	@try {
# endif
		of_string_encoding_t encoding = [OFLocale encoding];
616
617
618
619
620
621
622
623

624
625
626
627
628

629
630
631
632
633
634
635
616
617
618
619
620
621
622

623
624
625
626
627

628
629
630
631
632
633
634
635







-
+




-
+







		@throw [OFRetrieveItemAttributesFailedException
		    exceptionWithURL: URL
			       errNo: errno];

	if (s.st_size < 0)
		@throw [OFOutOfRangeException exception];

	[ret setObject: [NSNumber numberWithUIntMax: s.st_size]
	[ret setObject: [NSNumber numberWithUnsignedLongLong: s.st_size]
		forKey: of_file_attribute_key_size];

	setTypeAttribute(ret, &s);

	[ret setObject: [NSNumber numberWithUInt16: s.st_mode & 07777]
	[ret setObject: [NSNumber numberWithUnsignedLong: s.st_mode]
		forKey: of_file_attribute_key_posix_permissions];

	setOwnerAndGroupAttributes(ret, &s);
	setDateAttributes(ret, &s);

#ifdef OF_FILE_MANAGER_SUPPORTS_SYMLINKS
	if (S_ISLNK(s.st_mode))
756
757
758
759
760
761
762
763

764
765
766
767
768
769
770
756
757
758
759
760
761
762

763
764
765
766
767
768
769
770







-
+







}

- (void)of_setPOSIXPermissions: (OFNumber *)permissions
		   ofItemAtURL: (OFURL *)URL
		    attributes: (of_file_attributes_t)attributes OF_DIRECT
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
	uint16_t mode = permissions.uInt16Value & 0777;
	mode_t mode = (mode_t)permissions.unsignedLongValue;
	OFString *path = URL.fileSystemRepresentation;
	int status;

# ifdef OF_WINDOWS
	if ([OFSystemInfo isWindowsNT])
		status = _wchmod(path.UTF16String, mode);
	else

Modified src/OFHTTPClient.m from [8dda35db24] to [561ec71175].

75
76
77
78
79
80
81
82

83
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103







-
+













-
+








OF_DIRECT_MEMBERS
@interface OFHTTPClientRequestBodyStream: OFStream <OFReadyForWritingObserving>
{
	OFHTTPClientRequestHandler *_handler;
	OFTCPSocket *_socket;
	bool _chunked;
	uintmax_t _toWrite;
	unsigned long long _toWrite;
	bool _atEndOfStream;
}

- (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler
			 socket: (OFTCPSocket *)sock;
@end

OF_DIRECT_MEMBERS
@interface OFHTTPClientResponse: OFHTTPResponse <OFReadyForReadingObserving>
{
	OFTCPSocket *_socket;
	bool _hasContentLength, _chunked, _keepAlive;
	bool _atEndOfStream, _setAtEndOfStream;
	intmax_t _toRead;
	long long _toRead;
}

@property (nonatomic, setter=of_setKeepAlive:) bool of_keepAlive;

- (instancetype)initWithSocket: (OFTCPSocket *)sock;
@end

441
442
443
444
445
446
447


448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467






468
469
470
471
472
473
474
441
442
443
444
445
446
447
448
449
450
451
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







+
+



















-
+
+
+
+
+
+







	} @catch (id e) {
		[self raiseException: e];
	}
}

- (bool)handleFirstLine: (OFString *)line
{
	long long status;

	/*
	 * It's possible that the write succeeds on a connection that is
	 * keep-alive, but the connection has already been closed by the remote
	 * end due to a timeout. In this case, we need to reconnect.
	 */
	if (line == nil) {
		[self closeAndReconnect];
		return false;
	}

	if (![line hasPrefix: @"HTTP/"] || line.length < 9 ||
	    [line characterAtIndex: 8] != ' ')
		@throw [OFInvalidServerReplyException exception];

	_version = [[line substringWithRange: of_range(5, 3)] copy];
	if (![_version isEqual: @"1.0"] && ![_version isEqual: @"1.1"])
		@throw [OFUnsupportedVersionException
		    exceptionWithVersion: _version];

	_status = (int)[line substringWithRange: of_range(9, 3)].decimalValue;
	status = [line substringWithRange: of_range(9, 3)].longLongValue;

	if (status < 0 || status > 599)
		@throw [OFInvalidServerReplyException exception];

	_status = (int)status;

	return true;
}

- (bool)handleServerHeader: (OFString *)line
		    socket: (OFTCPSocket *)sock
{
709
710
711
712
713
714
715
716

717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756

757
758
759
760
761
762
763
716
717
718
719
720
721
722

723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741

742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757





758
759
760
761
762
763
764
765







-
+


















-
















-
-
-
-
-
+







		} else {
			sock = [OFTCPSocket socket];
			port = 80;
		}

		URLPort = URL.port;
		if (URLPort != nil)
			port = URLPort.uInt16Value;
			port = URLPort.unsignedShortValue;

		sock.delegate = self;
		[sock asyncConnectToHost: URL.host
				    port: port];
	} @catch (id e) {
		[self raiseException: e];
	}
}
@end

@implementation OFHTTPClientRequestBodyStream
- (instancetype)initWithHandler: (OFHTTPClientRequestHandler *)handler
			 socket: (OFTCPSocket *)sock
{
	self = [super init];

	@try {
		OFDictionary OF_GENERIC(OFString *, OFString *) *headers;
		intmax_t contentLength;
		OFString *transferEncoding, *contentLengthString;

		_handler = [handler retain];
		_socket = [sock retain];

		headers = _handler->_request.headers;

		transferEncoding = [headers objectForKey: @"Transfer-Encoding"];
		_chunked = [transferEncoding isEqual: @"chunked"];

		contentLengthString = [headers objectForKey: @"Content-Length"];
		if (contentLengthString != nil) {
			if (_chunked || contentLengthString.length == 0)
				@throw [OFInvalidArgumentException
				    exception];

			contentLength = contentLengthString.decimalValue;
			if (contentLength < 0)
				@throw [OFOutOfRangeException exception];

			_toWrite = contentLength;
			_toWrite = contentLengthString.unsignedLongLongValue;
		} else if (!_chunked)
			@throw [OFInvalidArgumentException exception];
	} @catch (id e) {
		[self release];
		@throw e;
	}

891
892
893
894
895
896
897

898

899
900
901
902




903
904
905
906
907
908
909
893
894
895
896
897
898
899
900

901
902



903
904
905
906
907
908
909
910
911
912
913







+
-
+

-
-
-
+
+
+
+







	if (contentLength != nil) {
		if (_chunked || contentLength.length == 0)
			@throw [OFInvalidServerReplyException exception];

		_hasContentLength = true;

		@try {
			unsigned long long toRead =
			_toRead = contentLength.decimalValue;
			    contentLength.unsignedLongLongValue;

			if (_toRead < 0)
				@throw [OFInvalidServerReplyException
				    exception];
			if (toRead > LLONG_MAX)
				@throw [OFOutOfRangeException exception];

			_toRead = (long long)toRead;
		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidServerReplyException exception];
		}
	}
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer
922
923
924
925
926
927
928
929

930
931
932
933
934
935
936
926
927
928
929
930
931
932

933
934
935
936
937
938
939
940







-
+







	if (_socket.atEndOfStream)
		@throw [OFTruncatedDataException exception];

	/* Content-Length */
	if (!_chunked) {
		size_t ret;

		if (length > (uintmax_t)_toRead)
		if (length > (unsigned long long)_toRead)
			length = (size_t)_toRead;

		ret = [_socket readIntoBuffer: buffer
				       length: length];

		if (ret > length)
			@throw [OFOutOfRangeException exception];
977
978
979
980
981
982
983
984

985
986
987
988
989
990
991
981
982
983
984
985
986
987

988
989
990
991
992
993
994
995







-
+







		}

		if (_setAtEndOfStream && _toRead == 0)
			_atEndOfStream = true;

		return 0;
	} else if (_toRead > 0) {
		if (length > (uintmax_t)_toRead)
		if (length > (unsigned long long)_toRead)
			length = (size_t)_toRead;

		length = [_socket readIntoBuffer: buffer
					  length: length];

		_toRead -= length;

1022
1023
1024
1025
1026
1027
1028


1029


1030


1031
1032
1033
1034
1035
1036
1037
1026
1027
1028
1029
1030
1031
1032
1033
1034

1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046







+
+
-
+
+

+
+







				@throw [OFTruncatedDataException exception];
			else
				@throw [OFInvalidServerReplyException
				    exception];
		}

		@try {
			unsigned long long toRead =
			    [line unsignedLongLongValueWithBase: 16];
			if ((_toRead = line.hexadecimalValue) < 0)

			if (toRead > LLONG_MAX)
				@throw [OFOutOfRangeException exception];

			_toRead = (long long)toRead;
		} @catch (OFInvalidFormatException *e) {
			@throw [OFInvalidServerReplyException exception];
		}

		if (_toRead == 0) {
			_setAtEndOfStream = true;
			_toRead = -2;

Modified src/OFHTTPCookie.m from [1c4b9e560d] to [1fa52c5268].

34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
34
35
36
37
38
39
40

41
42
43
44
45
46
47
48







-
+







		if ([lowercaseName isEqual: @"expires"]) {
			OFDate *date = [OFDate
			    dateWithDateString: value
					format: @"%a, %d %b %Y %H:%M:%S %z"];
			cookie.expires = date;
		} else if ([lowercaseName isEqual: @"max-age"]) {
			OFDate *date = [OFDate dateWithTimeIntervalSinceNow:
			    value.decimalValue];
			    value.unsignedLongLongValue];
			cookie.expires = date;
		} else if ([lowercaseName isEqual: @"domain"])
			cookie.domain = value;
		else if ([lowercaseName isEqual: @"path"])
			cookie.path = value;
		else
			[cookie.extensions addObject:

Modified src/OFHTTPRequest.m from [2d1b69a80f] to [a65b94e9ae].

210
211
212
213
214
215
216
217

218
219
220
221
222
223
224


225
226

227
228
229
230
231
232
233
210
211
212
213
214
215
216

217
218
219
220
221
222


223
224
225

226
227
228
229
230
231
232
233







-
+





-
-
+
+

-
+







	return _protocolVersion;
}

- (void)setProtocolVersionString: (OFString *)string
{
	void *pool = objc_autoreleasePoolPush();
	OFArray *components = [string componentsSeparatedByString: @"."];
	intmax_t major, minor;
	unsigned long long major, minor;
	of_http_request_protocol_version_t protocolVersion;

	if (components.count != 2)
		@throw [OFInvalidFormatException exception];

	major = [components.firstObject decimalValue];
	minor = [components.lastObject decimalValue];
	major = [components.firstObject unsignedLongLongValue];
	minor = [components.lastObject unsignedLongLongValue];

	if (major < 0 || major > UINT8_MAX || minor < 0 || minor > UINT8_MAX)
	if (major > UINT8_MAX || minor > UINT8_MAX)
		@throw [OFOutOfRangeException exception];

	protocolVersion.major = (uint8_t)major;
	protocolVersion.minor = (uint8_t)minor;

	self.protocolVersion = protocolVersion;

Modified src/OFHTTPResponse.m from [1abecd6ce8] to [b38122cc28].

267
268
269
270
271
272
273
274

275
276
277
278
279
280
281


282
283

284
285
286
287
288
289
290
267
268
269
270
271
272
273

274
275
276
277
278
279


280
281
282

283
284
285
286
287
288
289
290







-
+





-
-
+
+

-
+







	return _protocolVersion;
}

- (void)setProtocolVersionString: (OFString *)string
{
	void *pool = objc_autoreleasePoolPush();
	OFArray *components = [string componentsSeparatedByString: @"."];
	intmax_t major, minor;
	unsigned long long major, minor;
	of_http_request_protocol_version_t protocolVersion;

	if (components.count != 2)
		@throw [OFInvalidFormatException exception];

	major = [components.firstObject decimalValue];
	minor = [components.lastObject decimalValue];
	major = [components.firstObject unsignedLongLongValue];
	minor = [components.lastObject unsignedLongLongValue];

	if (major < 0 || major > UINT8_MAX || minor < 0 || minor > UINT8_MAX)
	if (major > UINT8_MAX || minor > UINT8_MAX)
		@throw [OFOutOfRangeException exception];

	protocolVersion.major = (uint8_t)major;
	protocolVersion.minor = (uint8_t)minor;

	self.protocolVersion = protocolVersion;

302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320
321
322









323

324
325
326
327
328
329
330
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316
317
318
319
320


321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338







-
+











-
-
+
+
+
+
+
+
+
+
+

+







{
	return [self stringWithEncoding: OF_STRING_ENCODING_AUTODETECT];
}

- (OFString *)stringWithEncoding: (of_string_encoding_t)encoding
{
	void *pool = objc_autoreleasePoolPush();
	OFString *contentType, *contentLength, *ret;
	OFString *contentType, *contentLengthString, *ret;
	OFData *data;

	if (encoding == OF_STRING_ENCODING_AUTODETECT &&
	    (contentType = [_headers objectForKey: @"Content-Type"]) != nil)
		encoding = encodingForContentType(contentType);

	if (encoding == OF_STRING_ENCODING_AUTODETECT)
		encoding = OF_STRING_ENCODING_UTF_8;

	data = [self readDataUntilEndOfStream];

	if ((contentLength = [_headers objectForKey: @"Content-Length"]) != nil)
		if (data.count != (size_t)contentLength.decimalValue)
	contentLengthString = [_headers objectForKey: @"Content-Length"];
	if (contentLengthString != nil) {
		unsigned long long contentLength =
		    contentLengthString.unsignedLongLongValue;

		if (contentLength > SIZE_MAX)
			@throw [OFOutOfRangeException exception];

		if (data.count != (size_t)contentLength)
			@throw [OFTruncatedDataException exception];
	}

	ret = [[OFString alloc] initWithCString: (char *)data.items
				       encoding: encoding
					 length: data.count];

	objc_autoreleasePoolPop(pool);

Modified src/OFHTTPServer.m from [868929166e] to [abf9a790cd].

101
102
103
104
105
106
107
108

109
110
111
112
113
114

115
116
117
118
119
120
121
101
102
103
104
105
106
107

108
109
110
111
112
113

114
115
116
117
118
119
120
121







-
+





-
+







@end

OF_DIRECT_MEMBERS
@interface OFHTTPServerRequestBodyStream: OFStream <OFReadyForReadingObserving>
{
	OFStreamSocket *_socket;
	bool _chunked;
	intmax_t _toRead;
	long long _toRead;
	bool _atEndOfStream, _setAtEndOfStream;
}

- (instancetype)initWithSocket: (OFStreamSocket *)sock
		       chunked: (bool)chunked
		 contentLength: (uintmax_t)contentLength;
		 contentLength: (unsigned long long)contentLength;
@end

#ifdef OF_HAVE_THREADS
OF_DIRECT_MEMBERS
@interface OFHTTPServerThread: OFThread
- (void)stop;
@end
411
412
413
414
415
416
417
418

419
420
421
422
423
424
425
426

427
428
429
430
431
432
433
434
435
436
437
438
439
411
412
413
414
415
416
417

418
419
420
421
422
423
424
425

426
427
428
429



430
431
432
433
434
435
436







-
+







-
+



-
-
-







	size_t pos;

	if (line.length == 0) {
		bool chunked = [[_headers objectForKey: @"Transfer-Encoding"]
		    isEqual: @"chunked"];
		OFString *contentLengthString =
		    [_headers objectForKey: @"Content-Length"];
		intmax_t contentLength = 0;
		unsigned long long contentLength = 0;

		if (contentLengthString != nil) {
			if (chunked || contentLengthString.length == 0)
				return [self sendErrorAndClose: 400];

			@try {
				contentLength =
				    contentLengthString.decimalValue;
				    contentLengthString.unsignedLongLongValue;
			} @catch (OFInvalidFormatException *e) {
				return [self sendErrorAndClose: 400];
			}

			if (contentLength < 0)
				return [self sendErrorAndClose: 400];
		}

		if (chunked || contentLengthString != nil) {
			[_requestBody release];
			_requestBody = nil;
			_requestBody = [[OFHTTPServerRequestBodyStream alloc]
			    initWithSocket: _socket
478
479
480
481
482
483
484
485
486



487
488
489
490
491
492
493
475
476
477
478
479
480
481


482
483
484
485
486
487
488
489
490
491







-
-
+
+
+







			[_host release];
			_host = [[value substringWithRange:
			    of_range(0, pos)] retain];

			@try {
				of_range_t range =
				    of_range(pos + 1, value.length - pos - 1);
				intmax_t portTmp = [value
				    substringWithRange: range].decimalValue;
				unsigned long long portTmp =
				    [value substringWithRange: range]
				    .unsignedLongLongValue;

				if (portTmp < 1 || portTmp > UINT16_MAX)
					return [self sendErrorAndClose: 400];

				_port = (uint16_t)portTmp;
			} @catch (OFInvalidFormatException *e) {
				return [self sendErrorAndClose: 400];
541
542
543
544
545
546
547
548

549
550
551
552
553
554
555
539
540
541
542
543
544
545

546
547
548
549
550
551
552
553







-
+







		_port = [_server port];
	}

	URL = [OFMutableURL URL];
	URL.scheme = @"http";
	URL.host = _host;
	if (_port != 80)
		URL.port = [OFNumber numberWithUInt16: _port];
		URL.port = [OFNumber numberWithUnsignedShort: _port];

	if ((pos = [_path rangeOfString: @"?"].location) != OF_NOT_FOUND) {
		OFString *path, *query;

		path = [_path substringWithRange: of_range(0, pos)];
		query = [_path substringWithRange:
		    of_range(pos + 1, _path.length - pos - 1)];
581
582
583
584
585
586
587
588

589
590
591
592



593
594
595

596
597
598
599
600
601
602
579
580
581
582
583
584
585

586
587
588
589
590
591
592
593
594
595

596
597
598
599
600
601
602
603







-
+




+
+
+


-
+







	objc_autoreleasePoolPop(pool);
}
@end

@implementation OFHTTPServerRequestBodyStream
- (instancetype)initWithSocket: (OFStreamSocket *)sock
		       chunked: (bool)chunked
		 contentLength: (uintmax_t)contentLength
		 contentLength: (unsigned long long)contentLength
{
	self = [super init];

	@try {
		if (contentLength > LLONG_MAX)
			@throw [OFOutOfRangeException exception];

		_socket = [sock retain];
		_chunked = chunked;
		_toRead = contentLength;
		_toRead = (long long)contentLength;

		if (_chunked && _toRead > 0)
			@throw [OFInvalidArgumentException exception];
	} @catch (id e) {
		[self release];
		@throw e;
	}
629
630
631
632
633
634
635
636

637
638
639
640
641
642
643
630
631
632
633
634
635
636

637
638
639
640
641
642
643
644







-
+







	if (_socket.atEndOfStream)
		@throw [OFTruncatedDataException exception];

	/* Content-Length */
	if (!_chunked) {
		size_t ret;

		if (length > (uintmax_t)_toRead)
		if (length > (unsigned long long)_toRead)
			length = (size_t)_toRead;

		ret = [_socket readIntoBuffer: buffer
				       length: length];

		_toRead -= ret;

678
679
680
681
682
683
684
685

686
687
688
689
690
691
692
693
694
695
696
697
698
699
700

701
702
703
704
705
706
707
679
680
681
682
683
684
685

686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709







-
+















+







		}

		if (_setAtEndOfStream && _toRead == 0)
			_atEndOfStream = true;

		return 0;
	} else if (_toRead > 0) {
		if (length > (uintmax_t)_toRead)
		if (length > (unsigned long long)_toRead)
			length = (size_t)_toRead;

		length = [_socket readIntoBuffer: buffer
					  length: length];

		_toRead -= length;

		if (_toRead == 0)
			_toRead = -2;

		return length;
	} else {
		void *pool = objc_autoreleasePoolPush();
		OFString *line;
		of_range_t range;
		unsigned long long toRead;

		@try {
			line = [_socket tryReadLine];
		} @catch (OFInvalidEncodingException *e) {
			@throw [OFInvalidFormatException exception];
		}

721
722
723
724
725
726
727

728

729

730
731
732
733
734
735
736
723
724
725
726
727
728
729
730

731
732
733
734
735
736
737
738
739
740







+
-
+

+







			if (_socket.atEndOfStream &&
			    range.location == OF_NOT_FOUND)
				@throw [OFTruncatedDataException exception];
			else
				@throw [OFInvalidFormatException exception];
		}

		toRead = [line unsignedLongLongValueWithBase: 16];
		if ((_toRead = line.hexadecimalValue) < 0)
		if (toRead > LLONG_MAX)
			@throw [OFOutOfRangeException exception];
		_toRead = (long long)toRead;

		if (_toRead == 0) {
			_setAtEndOfStream = true;
			_toRead = -2;
		}

		objc_autoreleasePoolPop(pool);

Modified src/OFINICategory.h from [fee5b6cdbd] to [b224331a40].

77
78
79
80
81
82
83
84
85


86
87
88
89
90
91
92
77
78
79
80
81
82
83


84
85
86
87
88
89
90
91
92







-
-
+
+







 * the first key/value pair found is returned.
 *
 * @param key The key for which the integer value should be returned
 * @param defaultValue The value to return if the key does not exist
 * @return The integer value for the specified key or the specified default
 *	   value if it does not exist
 */
- (intmax_t)integerForKey: (OFString *)key
	     defaultValue: (intmax_t)defaultValue;
- (long long)integerForKey: (OFString *)key
	      defaultValue: (long long)defaultValue;

/*!
 * @brief Returns the bool value for the specified key or the specified default
 *	  value if it does not exist.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is returned.
159
160
161
162
163
164
165
166

167
168
169
170
171
172
173
159
160
161
162
163
164
165

166
167
168
169
170
171
172
173







-
+







 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is changed.
 *
 * @param integer The integer to which the value of the key should be set
 * @param key The key for which the new value should be set
 */
- (void)setInteger: (intmax_t)integer
- (void)setInteger: (long long)integer
	    forKey: (OFString *)key;

/*!
 * @brief Sets the value of the specified key to the specified bool.
 *
 * If the specified key is a multi-key (see @ref arrayForKey:), the value of
 * the first key/value pair found is changed.

Modified src/OFINICategory.m from [6f7f003a8d] to [4145f33ae0].

205
206
207
208
209
210
211
212
213


214
215
216
217
218

219
220

221
222
223


224
225
226
227
228
229
230
231
232
205
206
207
208
209
210
211


212
213
214
215
216
217

218
219

220



221
222


223
224
225
226
227
228
229







-
-
+
+




-
+

-
+
-
-
-
+
+
-
-







		if ([pair->_key isEqual: key])
			return [[pair->_value copy] autorelease];
	}

	return defaultValue;
}

- (intmax_t)integerForKey: (OFString *)key
	     defaultValue: (intmax_t)defaultValue
- (long long)integerForKey: (OFString *)key
	      defaultValue: (long long)defaultValue
{
	void *pool = objc_autoreleasePoolPush();
	OFString *value = [self stringForKey: key
				defaultValue: nil];
	intmax_t ret;
	long long ret;

	if (value != nil) {
	if (value != nil)
		if ([value hasPrefix: @"0x"] || [value hasPrefix: @"$"])
			ret = value.hexadecimalValue;
		else
		ret = [value longLongValueWithBase: 0];
	else
			ret = value.decimalValue;
	} else
		ret = defaultValue;

	objc_autoreleasePoolPop(pool);

	return ret;
}

350
351
352
353
354
355
356
357

358
359
360
361
362

363
364
365
366
367
368
369
347
348
349
350
351
352
353

354
355
356
357
358

359
360
361
362
363
364
365
366







-
+




-
+








		@throw e;
	}

	objc_autoreleasePoolPop(pool);
}

- (void)setInteger: (intmax_t)integer
- (void)setInteger: (long long)integer
	    forKey: (OFString *)key
{
	void *pool = objc_autoreleasePoolPush();

	[self setString: [OFString stringWithFormat: @"%jd", integer]
	[self setString: [OFString stringWithFormat: @"%lld", integer]
		 forKey: key];

	objc_autoreleasePoolPop(pool);
}

- (void)setBool: (bool)bool_
	 forKey: (OFString *)key

Modified src/OFINIFileSettings.m from [9d965e74da] to [c8fa651c4c].

84
85
86
87
88
89
90
91

92
93
94
95
96
97
98
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98







-
+








	[[_INIFile categoryForName: category] setString: string
						 forKey: key];

	objc_autoreleasePoolPop(pool);
}

- (void)setInteger: (intmax_t)integer
- (void)setInteger: (long long)integer
	   forPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;

	[self of_getCategory: &category
		      andKey: &key
182
183
184
185
186
187
188
189
190


191
192
193
194

195
196
197
198
199
200
201
182
183
184
185
186
187
188


189
190
191
192
193

194
195
196
197
198
199
200
201







-
-
+
+



-
+







						    defaultValue: defaultValue];

	[ret retain];
	objc_autoreleasePoolPop(pool);
	return [ret autorelease];
}

- (intmax_t)integerForPath: (OFString *)path
	      defaultValue: (intmax_t)defaultValue
- (long long)integerForPath: (OFString *)path
	       defaultValue: (long long)defaultValue
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;
	intmax_t ret;
	long long ret;

	[self of_getCategory: &category
		      andKey: &key
		     forPath: path];

	ret = [[_INIFile categoryForName: category]
	    integerForKey: key

Modified src/OFLHAArchiveEntry.m from [9cc455c13c] to [61acef2124].

123
124
125
126
127
128
129
130

131
132
133
134
135
136
137
123
124
125
126
127
128
129

130
131
132
133
134
135
136
137







-
+








	memcpy(&mode, (char *)extension.items + 1, 2);
	mode = OF_BSWAP16_IF_BE(mode);

	[entry->_mode release];
	entry->_mode = nil;

	entry->_mode = [[OFNumber alloc] initWithUInt16: mode];
	entry->_mode = [[OFNumber alloc] initWithUnsignedShort: mode];
}

static void
parseGIDUIDExtension(OFLHAArchiveEntry *entry, OFData *extension,
    of_string_encoding_t encoding)
{
	uint16_t UID, GID;
147
148
149
150
151
152
153
154
155


156
157
158
159
160
161
162
147
148
149
150
151
152
153


154
155
156
157
158
159
160
161
162







-
-
+
+








	[entry->_GID release];
	entry->_GID = nil;

	[entry->_UID release];
	entry->_UID = nil;

	entry->_GID = [[OFNumber alloc] initWithUInt16: GID];
	entry->_UID = [[OFNumber alloc] initWithUInt16: UID];
	entry->_GID = [[OFNumber alloc] initWithUnsignedShort: GID];
	entry->_UID = [[OFNumber alloc] initWithUnsignedShort: UID];
}

static void
parseGroupExtension(OFLHAArchiveEntry *entry, OFData *extension,
    of_string_encoding_t encoding)
{
	[entry->_group release];
651
652
653
654
655
656
657
658

659
660
661
662
663
664
665
666
667
668
669
670
671
672

673
674
675
676

677
678
679
680
681
682
683
651
652
653
654
655
656
657

658
659
660
661
662
663
664
665
666
667
668
669
670
671

672
673
674
675

676
677
678
679
680
681
682
683







-
+













-
+



-
+








	if (_mode != nil) {
		tmp16 = OF_BSWAP16_IF_BE(5);
		[data addItems: &tmp16
			 count: sizeof(tmp16)];
		[data addItem: "\x50"];

		tmp16 = OF_BSWAP16_IF_BE(_mode.uInt16Value);
		tmp16 = OF_BSWAP16_IF_BE(_mode.unsignedShortValue);
		[data addItems: &tmp16
			 count: sizeof(tmp16)];
	}

	if (_UID != nil || _GID != nil) {
		if (_UID == nil || _GID == nil)
			@throw [OFInvalidArgumentException exception];

		tmp16 = OF_BSWAP16_IF_BE(7);
		[data addItems: &tmp16
			 count: sizeof(tmp16)];
		[data addItem: "\x51"];

		tmp16 = OF_BSWAP16_IF_BE(_GID.uInt16Value);
		tmp16 = OF_BSWAP16_IF_BE(_GID.unsignedShortValue);
		[data addItems: &tmp16
			 count: sizeof(tmp16)];

		tmp16 = OF_BSWAP16_IF_BE(_UID.uInt16Value);
		tmp16 = OF_BSWAP16_IF_BE(_UID.unsignedShortValue);
		[data addItems: &tmp16
			 count: sizeof(tmp16)];
	}

	if (_group != nil) {
		size_t groupLength =
		    [_group cStringLengthWithEncoding: encoding];
757
758
759
760
761
762
763
764

765
766
767
768
769
770
771
757
758
759
760
761
762
763

764
765
766
767
768
769
770
771







-
+







	objc_autoreleasePoolPop(pool);
}

- (OFString *)description
{
	void *pool = objc_autoreleasePoolPush();
	OFString *mode = (_mode == nil ? nil
	    : [OFString stringWithFormat: @"%" PRIo16, _mode.uInt16Value]);
	    : [OFString stringWithFormat: @"%ho", _mode.unsignedShortValue]);
	OFString *extensions = [_extensions.description
	    stringByReplacingOccurrencesOfString: @"\n"
				      withString: @"\n\t"];
	OFString *ret = [OFString stringWithFormat:
	    @"<%@:\n"
	    @"\tFile name = %@\n"
	    @"\tCompression method = %@\n"

Modified src/OFLocale.m from [2f0ab9defe] to [b6b16348ac].

211
212
213
214
215
216
217
218
219



220
221
222
223
224
225
226
211
212
213
214
215
216
217


218
219
220
221
222
223
224
225
226
227







-
-
+
+
+







			else if ([token isEqual: @">="])
				var = [OFNumber numberWithBool: [first
				    compare: second] != OF_ORDERED_ASCENDING];
			else if ([token isEqual: @"+"])
				var = [OFNumber numberWithDouble:
				    [first doubleValue] + [second doubleValue]];
			else if ([token isEqual: @"%"])
				var = [OFNumber numberWithIntMax:
				    [first intMaxValue] % [second intMaxValue]];
				var = [OFNumber numberWithLongLong:
				    [first longLongValue] %
				    [second longLongValue]];
			else if ([token isEqual: @"&&"])
				var = [OFNumber numberWithBool:
				    [first boolValue] && [second boolValue]];
			else if ([token isEqual: @"||"])
				var = [OFNumber numberWithBool:
				    [first boolValue] || [second boolValue]];
			else
234
235
236
237
238
239
240
241


242
243
244
245
246
247
248
235
236
237
238
239
240
241

242
243
244
245
246
247
248
249
250







-
+
+







			first = stack.lastObject;

			if ([token isEqual: @"!"])
				var = [OFNumber numberWithBool:
				    ![first boolValue]];
			else if ([token isEqual: @"is_real"])
				var = [OFNumber numberWithBool:
				    [first doubleValue] != [first intMaxValue]];
				    ([first doubleValue] !=
				    [first longLongValue])];
			else
				OF_ENSURE(0);

			[stack replaceObjectAtIndex: stackSize - 1
					 withObject: var];
		} else
			[stack addObject: token];
506
507
508
509
510
511
512
513


514
515
516
517
518
519
520
508
509
510
511
512
513
514

515
516
517
518
519
520
521
522
523







-
+
+







	if (_language == nil)
		return;

	pool = objc_autoreleasePoolPush();

	mapPath = [path stringByAppendingPathComponent: @"languages.json"];
	@try {
		map = [[OFString stringWithContentsOfFile: mapPath] JSONValue];
		map = [[OFString stringWithContentsOfFile: mapPath]
		     objectByParsingJSON];
	} @catch (OFOpenItemFailedException *e) {
		objc_autoreleasePoolPop(pool);
		return;
	}

	language = _language.lowercaseString;
	territory = _territory.lowercaseString;
530
531
532
533
534
535
536
537
538


539
540
541
542
543
544
545
533
534
535
536
537
538
539


540
541
542
543
544
545
546
547
548







-
-
+
+







		objc_autoreleasePoolPop(pool);
		return;
	}

	languageFile = [path stringByAppendingPathComponent:
	    [languageFile stringByAppendingString: @".json"]];

	[_localizedStrings addObject:
	    [[OFString stringWithContentsOfFile: languageFile] JSONValue]];
	[_localizedStrings addObject: [[OFString stringWithContentsOfFile:
	    languageFile] objectByParsingJSON]];

	objc_autoreleasePoolPop(pool);
}
#endif

- (OFString *)localizedStringForID: (OFConstantString *)ID
			  fallback: (id)fallback, ...

Modified src/OFMutableTarArchiveEntry.h from [3fa49654d2] to [2a04d96f47].

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
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







-
+




-
+




-
+




-
+







 * @brief The file name of the entry.
 */
@property (readwrite, copy, nonatomic) OFString *fileName;

/*!
 * @brief The mode of the entry.
 */
@property (readwrite, nonatomic) uint32_t mode;
@property (readwrite, nonatomic) unsigned long mode;

/*!
 * @brief The UID of the owner.
 */
@property (readwrite, nonatomic) uint32_t UID;
@property (readwrite, nonatomic) unsigned long UID;

/*!
 * @brief The GID of the group.
 */
@property (readwrite, nonatomic) uint32_t GID;
@property (readwrite, nonatomic) unsigned long GID;

/*!
 * @brief The size of the file.
 */
@property (readwrite, nonatomic) uint64_t size;
@property (readwrite, nonatomic) unsigned long long size;

/*!
 * @brief The date of the last modification of the file.
 */
@property (readwrite, retain, nonatomic) OFDate *modificationDate;

/*!
82
83
84
85
86
87
88
89

90
91
92
93
94

95
96
97
98
99
100
101
102
103
82
83
84
85
86
87
88

89
90
91
92
93

94
95
96
97
98
99
100
101
102
103







-
+




-
+









 * @brief The group of the file.
 */
@property OF_NULLABLE_PROPERTY (readwrite, copy, nonatomic) OFString *group;

/*!
 * @brief The device major (if the file is a device).
 */
@property (readwrite, nonatomic) uint32_t deviceMajor;
@property (readwrite, nonatomic) unsigned long deviceMajor;

/*!
 * @brief The device major (if the file is a device).
 */
@property (readwrite, nonatomic) uint32_t deviceMinor;
@property (readwrite, nonatomic) unsigned long deviceMinor;

/*!
 * @brief Converts the OFMutableTarArchiveEntry to an immutable
 *	  OFTarArchiveEntry.
 */
- (void)makeImmutable;
@end

OF_ASSUME_NONNULL_END

Modified src/OFMutableTarArchiveEntry.m from [11e44c30db] to [1fdec748d1].

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
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







-
+




-
+




-
+




-
+







- (void)setFileName: (OFString *)fileName
{
	OFString *old = _fileName;
	_fileName = [fileName copy];
	[old release];
}

- (void)setMode: (uint32_t)mode
- (void)setMode: (unsigned long)mode
{
	_mode = mode;
}

- (void)setUID: (uint32_t)UID
- (void)setUID: (unsigned long)UID
{
	_UID = UID;
}

- (void)setGID: (uint32_t)GID
- (void)setGID: (unsigned long)GID
{
	_GID = GID;
}

- (void)setSize: (uint64_t)size
- (void)setSize: (unsigned long long)size
{
	_size = size;
}

- (void)setModificationDate: (OFDate *)modificationDate
{
	OFDate *old = _modificationDate;
90
91
92
93
94
95
96
97

98
99
100
101
102

103
104
105
106
107
108
109
110
111
90
91
92
93
94
95
96

97
98
99
100
101

102
103
104
105
106
107
108
109
110
111







-
+




-
+









- (void)setGroup: (OFString *)group
{
	OFString *old = _group;
	_group = [group copy];
	[old release];
}

- (void)setDeviceMajor: (uint32_t)deviceMajor
- (void)setDeviceMajor: (unsigned long)deviceMajor
{
	_deviceMajor = deviceMajor;
}

- (void)setDeviceMinor: (uint32_t)deviceMinor
- (void)setDeviceMinor: (unsigned long)deviceMinor
{
	_deviceMinor = deviceMinor;
}

- (void)makeImmutable
{
	object_setClass(self, [OFTarArchiveEntry class]);
}
@end

Modified src/OFNumber.h from [8668a7987f] to [5740ff4672].

45
46
47
48
49
50
51
52
53
54



55
56
57
58
59
60
61
45
46
47
48
49
50
51



52
53
54
55
56
57
58
59
60
61







-
-
-
+
+
+







#ifndef OF_NUMBER_M
OF_SUBCLASSING_RESTRICTED
#endif
@interface OFNumber: OFValue <OFComparing, OFSerialization,
    OFJSONRepresentation, OFMessagePackRepresentation>
{
	union of_number_value {
		double    float_;
		intmax_t  signed_;
		uintmax_t unsigned_;
		double float_;
		long long signed_;
		unsigned long long unsigned_;
	} _value;
	enum of_number_type {
		OF_NUMBER_TYPE_FLOAT = 1,
		OF_NUMBER_TYPE_SIGNED,
		OF_NUMBER_TYPE_UNSIGNED
	} _type;
	const char *_typeEncoding;
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
112
113
114
115
116
117
118











































































119
120
121
122
123
124
125







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







@property (readonly, nonatomic) unsigned long unsignedLongValue;

/*!
 * @brief The OFNumber as an `unsigned long long`.
 */
@property (readonly, nonatomic) unsigned long long unsignedLongLongValue;

/*!
 * @brief The OFNumber as an `int8_t`.
 */
@property (readonly, nonatomic) int8_t int8Value;

/*!
 * @brief The OFNumber as an `int16_t`.
 */
@property (readonly, nonatomic) int16_t int16Value;

/*!
 * @brief The OFNumber as an `int32_t`.
 */
@property (readonly, nonatomic) int32_t int32Value;

/*!
 * @brief The OFNumber as an `int64_t`.
 */
@property (readonly, nonatomic) int64_t int64Value;

/*!
 * @brief The OFNumber as a `uint8_t`.
 */
@property (readonly, nonatomic) uint8_t uInt8Value;

/*!
 * @brief The OFNumber as a `uint16_t`.
 */
@property (readonly, nonatomic) uint16_t uInt16Value;

/*!
 * @brief The OFNumber as a `uint32_t`.
 */
@property (readonly, nonatomic) uint32_t uInt32Value;

/*!
 * @brief The OFNumber as a `uint64_t`.
 */
@property (readonly, nonatomic) uint64_t uInt64Value;

/*!
 * @brief The OFNumber as a `size_t`.
 */
@property (readonly, nonatomic) size_t sizeValue;

/*!
 * @brief The OFNumber as an `ssize_t`.
 */
@property (readonly, nonatomic) ssize_t sSizeValue;

/*!
 * @brief The OFNumber as an `intmax_t`.
 */
@property (readonly, nonatomic) intmax_t intMaxValue;

/*!
 * @brief The OFNumber as a `uintmax_t`.
 */
@property (readonly, nonatomic) uintmax_t uIntMaxValue;

/*!
 * @brief The OFNumber as a `ptrdiff_t`.
 */
@property (readonly, nonatomic) ptrdiff_t ptrDiffValue;

/*!
 * @brief The OFNumber as an `intptr_t`.
 */
@property (readonly, nonatomic) intptr_t intPtrValue;

/*!
 * @brief The OFNumber as a `uintptr_t`.
 */
@property (readonly, nonatomic) uintptr_t uIntPtrValue;

/*!
 * @brief The OFNumber as a `float`.
 */
@property (readonly, nonatomic) float floatValue;

/*!
 * @brief The OFNumber as a `double`.
216
217
218
219
220
221
222
223

224
225
226

227
228
229
230
231

232
233
234

235
236
237
238
239

240
241
242

243
244
245
246
247

248
249
250

251
252
253
254
255

256
257
258

259
260
261
262
263

264
265
266

267
268
269
270
271

272
273
274

275
276
277
278
279

280
281
282

283
284
285
286
287

288
289
290

291
292
293
294
295

296
297
298

299
300
301
302
303

304
305
306

307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431

432
433
434

435
436
437
438
439

440
441
442

443
444
445
446
447
448
449
450
451
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
491
492

493
494
495

496
497
498
499
500
501

502
503
504

505
506
507
508
509
510

511
512
513

514
515
516
517
518
519

520
521
522

523
524
525
526
527
528

529
530
531

532
533
534
535
536
537

538
539
540

541
542
543
544
545
546

547
548
549

550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687

688
689
690

691
692
693
694
695

696
697
698

699
700
701
702
703
704
705
706
141
142
143
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
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
203

204
205
206

207
208
209
210
211

212
213
214

215
216
217
218
219

220
221
222

223
224
225
226
227

228
229
230

231
232
233
























































































































234
235

236
237
238

239
240
241
242
243

244
245
246

247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263

264
265
266

267
268
269
270
271
272

273
274
275

276
277
278
279
280

281
282
283

284
285
286
287
288

289
290
291

292
293
294
295
296

297
298
299

300
301
302
303
304
305

306
307
308

309
310
311
312
313
314

315
316
317

318
319
320
321
322
323

324
325
326

327
328
329
330
331
332

333
334
335

336
337
338
339
340
341

342
343
344

345
346
347
348
349
350

351
352
353

354





































































































































355
356
357
358

359
360
361

362
363
364
365
366

367
368
369

370
371
372
373
374
375
376
377
378







-
+


-
+




-
+


-
+




-
+


-
+




-
+


-
+




-
+


-
+




-
+


-
+




-
+


-
+




-
+


-
+




-
+


-
+




-
+


-
+




-
+


-
+


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


-
+


-
+




-
+


-
+
















-
+


-
+





-
+


-
+




-
+


-
+




-
+


-
+




-
+


-
+





-
+


-
+





-
+


-
+





-
+


-
+





-
+


-
+





-
+


-
+





-
+


-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-




-
+


-
+




-
+


-
+








+ (instancetype)valueWithDimension: (of_dimension_t)dimension OF_UNAVAILABLE;
+ (instancetype)valueWithRectangle: (of_rectangle_t)rectangle OF_UNAVAILABLE;
#endif

/*!
 * @brief Creates a new OFNumber with the specified `bool`.
 *
 * @param bool_ A `bool` which the OFNumber should contain
 * @param value The `bool` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithBool: (bool)bool_;
+ (instancetype)numberWithBool: (bool)value;

/*!
 * @brief Creates a new OFNumber with the specified `signed char`.
 *
 * @param sChar A `signed char` which the OFNumber should contain
 * @param value The `signed char` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithChar: (signed char)sChar;
+ (instancetype)numberWithChar: (signed char)value;

/*!
 * @brief Creates a new OFNumber with the specified `short`.
 *
 * @param sShort A `short` which the OFNumber should contain
 * @param value The `short` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithShort: (short)sShort;
+ (instancetype)numberWithShort: (short)value;

/*!
 * @brief Creates a new OFNumber with the specified `int`.
 *
 * @param sInt An `int` which the OFNumber should contain
 * @param value The `int` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithInt: (int)sInt;
+ (instancetype)numberWithInt: (int)value;

/*!
 * @brief Creates a new OFNumber with the specified `long`.
 *
 * @param sLong A `long` which the OFNumber should contain
 * @param value The `long` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithLong: (long)sLong;
+ (instancetype)numberWithLong: (long)value;

/*!
 * @brief Creates a new OFNumber with the specified `long long`.
 *
 * @param sLongLong A `long long` which the OFNumber should contain
 * @param value The `long long` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithLongLong: (long long)sLongLong;
+ (instancetype)numberWithLongLong: (long long)value;

/*!
 * @brief Creates a new OFNumber with the specified `unsigned char`.
 *
 * @param uChar An `unsigned char` which the OFNumber should contain
 * @param value The `unsigned char` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUnsignedChar: (unsigned char)uChar;
+ (instancetype)numberWithUnsignedChar: (unsigned char)value;

/*!
 * @brief Creates a new OFNumber with the specified `unsigned short`.
 *
 * @param uShort An `unsigned short` which the OFNumber should contain
 * @param value The `unsigned short` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUnsignedShort: (unsigned short)uShort;
+ (instancetype)numberWithUnsignedShort: (unsigned short)value;

/*!
 * @brief Creates a new OFNumber with the specified `unsigned int`.
 *
 * @param uInt An `unsigned int` which the OFNumber should contain
 * @param value The `unsigned int` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUnsignedInt: (unsigned int)uInt;
+ (instancetype)numberWithUnsignedInt: (unsigned int)value;

/*!
 * @brief Creates a new OFNumber with the specified `unsigned long`.
 *
 * @param uLong An `unsigned long` which the OFNumber should contain
 * @param value The `unsigned long` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUnsignedLong: (unsigned long)uLong;
+ (instancetype)numberWithUnsignedLong: (unsigned long)value;

/*!
 * @brief Creates a new OFNumber with the specified `unsigned long long`.
 *
 * @param uLongLong An `unsigned long long` which the OFNumber should contain
 * @param value The `unsigned long long` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUnsignedLongLong: (unsigned long long)uLongLong;
+ (instancetype)numberWithUnsignedLongLong: (unsigned long long)value;

/*!
 * @brief Creates a new OFNumber with the specified `int8_t`.
 *
 * @param int8 An `int8_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithInt8: (int8_t)int8;

/*!
 * @brief Creates a new OFNumber with the specified `int16_t`.
 *
 * @param int16 An `int16_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithInt16: (int16_t)int16;

/*!
 * @brief Creates a new OFNumber with the specified `int32_t`.
 *
 * @param int32 An `int32_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithInt32: (int32_t)int32;

/*!
 * @brief Creates a new OFNumber with the specified `int64_t`.
 *
 * @param int64 An `int64_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithInt64: (int64_t)int64;

/*!
 * @brief Creates a new OFNumber with the specified `uint8_t`.
 *
 * @param uInt8 A `uint8_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUInt8: (uint8_t)uInt8;

/*!
 * @brief Creates a new OFNumber with the specified `uint16_t`.
 *
 * @param uInt16 A `uint16_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUInt16: (uint16_t)uInt16;

/*!
 * @brief Creates a new OFNumber with the specified `uint32_t`.
 *
 * @param uInt32 A `uint32_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUInt32: (uint32_t)uInt32;

/*!
 * @brief Creates a new OFNumber with the specified `uint64_t`.
 *
 * @param uInt64 A `uint64_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUInt64: (uint64_t)uInt64;

/*!
 * @brief Creates a new OFNumber with the specified `size_t`.
 *
 * @param size A `size_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithSize: (size_t)size;

/*!
 * @brief Creates a new OFNumber with the specified `ssize_t`.
 *
 * @param sSize An `ssize_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithSSize: (ssize_t)sSize;

/*!
 * @brief Creates a new OFNumber with the specified `intmax_t`.
 *
 * @param intMax An `intmax_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithIntMax: (intmax_t)intMax;

/*!
 * @brief Creates a new OFNumber with the specified `uintmax_t`.
 *
 * @param uIntMax A `uintmax_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUIntMax: (uintmax_t)uIntMax;

/*!
 * @brief Creates a new OFNumber with the specified `ptrdiff_t`.
 *
 * @param ptrDiff A `ptrdiff_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithPtrDiff: (ptrdiff_t)ptrDiff;

/*!
 * @brief Creates a new OFNumber with the specified `intptr_t`.
 *
 * @param intPtr An `intptr_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithIntPtr: (intptr_t)intPtr;

/*!
 * @brief Creates a new OFNumber with the specified `uintptr_t`.
 *
 * @param uIntPtr A `uintptr_t` which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithUIntPtr: (uintptr_t)uIntPtr;

/*!
 * @brief Creates a new OFNumber with the specified `float`.
 *
 * @param float_ A `float` which the OFNumber should contain
 * @param value The `float` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithFloat: (float)float_;
+ (instancetype)numberWithFloat: (float)value;

/*!
 * @brief Creates a new OFNumber with the specified `double`.
 *
 * @param double_ A `double` which the OFNumber should contain
 * @param value The `double` value which the OFNumber should contain
 * @return A new autoreleased OFNumber
 */
+ (instancetype)numberWithDouble: (double)double_;
+ (instancetype)numberWithDouble: (double)value;

- (instancetype)init OF_UNAVAILABLE;
#ifdef OF_HAVE_UNAVAILABLE
- (instancetype)initWithBytes: (const void *)bytes
		     objCType: (const char *)objCType OF_UNAVAILABLE;
- (instancetype)initWithPointer: (const void *)pointer OF_UNAVAILABLE;
- (instancetype)initWithNonretainedObject: (id)object OF_UNAVAILABLE;
- (instancetype)initWithRange: (of_range_t)range OF_UNAVAILABLE;
- (instancetype)initWithPoint: (of_point_t)point OF_UNAVAILABLE;
- (instancetype)initWithDimension: (of_dimension_t)dimension OF_UNAVAILABLE;
- (instancetype)initWithRectangle: (of_rectangle_t)rectangle OF_UNAVAILABLE;
#endif

/*!
 * @brief Initializes an already allocated OFNumber with the specified `bool`.
 *
 * @param bool_ A `bool` which the OFNumber should contain
 * @param value The `bool` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithBool: (bool)bool_;
- (instancetype)initWithBool: (bool)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `signed char`.
 *
 * @param sChar A `signed char` which the OFNumber should contain
 * @param value The `signed char` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithChar: (signed char)sChar;
- (instancetype)initWithChar: (signed char)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `short`.
 *
 * @param sShort A `short` which the OFNumber should contain
 * @param value The `short` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithShort: (short)sShort;
- (instancetype)initWithShort: (short)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `int`.
 *
 * @param sInt An `int` which the OFNumber should contain
 * @param value The `int` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithInt: (int)sInt;
- (instancetype)initWithInt: (int)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `long`.
 *
 * @param sLong A `long` which the OFNumber should contain
 * @param value The `long` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithLong: (long)sLong;
- (instancetype)initWithLong: (long)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `long long`.
 *
 * @param sLongLong A `long long` which the OFNumber should contain
 * @param value The `long long` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithLongLong: (long long)sLongLong;
- (instancetype)initWithLongLong: (long long)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `unsigned char`.
 *
 * @param uChar An `unsigned char` which the OFNumber should contain
 * @param value The `unsigned char` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUnsignedChar: (unsigned char)uChar;
- (instancetype)initWithUnsignedChar: (unsigned char)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `unsigned short`.
 *
 * @param uShort An `unsigned short` which the OFNumber should contain
 * @param value The `unsigned short` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUnsignedShort: (unsigned short)uShort;
- (instancetype)initWithUnsignedShort: (unsigned short)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `unsigned int`.
 *
 * @param uInt An `unsigned int` which the OFNumber should contain
 * @param value The `unsigned int` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUnsignedInt: (unsigned int)uInt;
- (instancetype)initWithUnsignedInt: (unsigned int)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `unsigned long`.
 *
 * @param uLong An `unsigned long` which the OFNumber should contain
 * @param value The `unsigned long` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUnsignedLong: (unsigned long)uLong;
- (instancetype)initWithUnsignedLong: (unsigned long)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `unsigned long long`.
 *
 * @param uLongLong An `unsigned long long` which the OFNumber should contain
 * @param value The `unsigned long long` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUnsignedLongLong: (unsigned long long)uLongLong;
- (instancetype)initWithUnsignedLongLong: (unsigned long long)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `int8_t`.
 *
 * @param int8 An `int8_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithInt8: (int8_t)int8;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `int16_t`.
 *
 * @param int16 An `int16_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithInt16: (int16_t)int16;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `int32_t`.
 *
 * @param int32 An `int32_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithInt32: (int32_t)int32;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `int64_t`.
 *
 * @param int64 An `int64_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithInt64: (int64_t)int64;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `uint8_t`.
 *
 * @param uInt8 A `uint8_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUInt8: (uint8_t)uInt8;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `uint16_t`.
 *
 * @param uInt16 A `uint16_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUInt16: (uint16_t)uInt16;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `uint32_t`.
 *
 * @param uInt32 A `uint32_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUInt32: (uint32_t)uInt32;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `uint64_t`.
 *
 * @param uInt64 A `uint64_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUInt64: (uint64_t)uInt64;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `size_t`.
 *
 * @param size A `size_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithSize: (size_t)size;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `ssize_t`.
 *
 * @param sSize An `ssize_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithSSize: (ssize_t)sSize;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `intmax_t`.
 *
 * @param intMax An `intmax_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithIntMax: (intmax_t)intMax;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `uintmax_t`.
 *
 * @param uIntMax A `uintmax_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUIntMax: (uintmax_t)uIntMax;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `ptrdiff_t`.
 *
 * @param ptrDiff A `ptrdiff_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithPtrDiff: (ptrdiff_t)ptrDiff;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `intptr_t`.
 *
 * @param intPtr An `intptr_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithIntPtr: (intptr_t)intPtr;

/*!
 * @brief Initializes an already allocated OFNumber with the specified
 *	  `uintptr_t`.
 *
 * @param uIntPtr A `uintptr_t` which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithUIntPtr: (uintptr_t)uIntPtr;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `float`.
 *
 * @param float_ A `float` which the OFNumber should contain
 * @param value The `float` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithFloat: (float)float_;
- (instancetype)initWithFloat: (float)value;

/*!
 * @brief Initializes an already allocated OFNumber with the specified `double`.
 *
 * @param double_ A `double` which the OFNumber should contain
 * @param value The `double` value which the OFNumber should contain
 * @return An initialized OFNumber
 */
- (instancetype)initWithDouble: (double)double_;
- (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;
#endif

Modified src/OFNumber.m from [57186c2c7a] to [17a849254e].

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

98
99
100
101

102
103
104

105
106
107
108
109
110
111
112
113



114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
133







134
135
136
137
138
139
140
141
142

143
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
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
203
204
205

206
207
208

209
210

211
212
213
214
215
216




217
218
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233
234
235
236
237
238

239
240
241
242

243
244
245
246
247
248
249




250
251
252
253
254
255
256

257
258
259

260
261
262
263





264
265

266
267
268
269
270
271
272

273
274
275

276
277

278
279
280
281
282
283




284
285
286
287
288
289
290
291
292

293
294
295
296
297
298


299
300
301




302
303

304
305
306
307
308
309
310
311
312

313
314

315
316
317
318

319
320
321

322
323

324
325
326
327
328



329
330

331
332

333
334
335
336
337

338
339
340
341
342
343
344

345
346

347
348
349
350
351
352




353
354
355
356
357
358
359
360
361
362
363

364
365
366
367
368
369
370
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
98









99
100
101
102
103
104
105
106








107
108
109

110
111


112
113


114
115
116





117






118
119
120





121
122

123




124
125
126
127
128






129
130
131

132
133

134


135



136



137


138


139







140
141
142

143
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
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
203


204


205





206
207
208





209
210

211






212
213
214
215
216










217
218
219
220
221
222
223
224







-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
+
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
+
-
-
-
+
+
+
-

-
+

-
-
-
+
+
+


-
-
+
+




-
+

-
-
-
+
-
-
-
+
-
-
-
-
-
-
-
-
-
+
+
+

-
-
-
-
-
-
-
-
+


-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+

-
-
-
-
-
-
-
-
+


-
+

-
-
+

-
-
+
+

-
-
-
-
-
+
-
-
-
-
-
-
+
+
+
-
-
-
-
-
+

-
+
-
-
-
-
+
+
+
+

-
-
-
-
-
-
+


-
+

-
+
-
-
+
-
-
-
+
-
-
-
+
-
-
+
-
-
+
-
-
-
-
-
-
-
+


-
+

-
+
-
-
-
-
-
-
+
+
+
+

-
-
-
-
-
-
-
-
+

-
-
-
-
-
-
-

-
-
-
-
+

-
-
-
+
-
-
-
-
-
-
-
+
+
+
+

-
-
-
-
-
-
+


-
+

-
-
-
+
+
+
+
+
-
-
+
-
-
-
-
-
-
-
+


-
+

-
+
-
-
-
-
-
-
+
+
+
+

-
-
-
-
-
-
-
-
+

-
-
-
-
-
+
+
-
-
-
+
+
+
+
-
-
+
-
-
-
-
-
-
-
-
-
+
-
-
+
-
-
-
-
+


-
+

-
+
-
-
-
-
-
+
+
+
-
-
+
-
-
+
-
-
-
-
-
+


-
-
-
-
-
+

-
+
-
-
-
-
-
-
+
+
+
+

-
-
-
-
-
-
-
-
-
-
+







@interface OFNumberSingleton: OFNumber
@end

static struct {
	Class isa;
} placeholder;

static OFNumberSingleton *zeroNumber, *oneNumber, *twoNumber;
static OFNumberSingleton *trueNumber, *falseNumber;

static void
initZeroNumber(void)
{
	zeroNumber = [[OFNumberSingleton alloc] initWithUnsignedChar: 0];
}

#define SINGLETON(var, sel, val)				\
	static OFNumberSingleton *var;				\
								\
	static void						\
	var##Init(void)						\
	{							\
		var = [[OFNumberSingleton alloc] sel val];	\
	}
SINGLETON(falseNumber, initWithBool:, false)
static void
initOneNumber(void)
SINGLETON(trueNumber, initWithBool:, true)
{
	oneNumber = [[OFNumberSingleton alloc] initWithUnsignedChar: 1];
SINGLETON(charZeroNumber, initWithChar:, 0)
}

SINGLETON(shortZeroNumber, initWithShort:, 0)
static void
initTwoNumber(void)
SINGLETON(intZeroNumber, initWithInt:, 0)
{
	twoNumber = [[OFNumberSingleton alloc] initWithUnsignedChar: 2];
SINGLETON(longZeroNumber, initWithLong:, 0)
SINGLETON(longLongZeroNumber, initWithLongLong:, 0)
SINGLETON(unsignedCharZeroNumber, initWithUnsignedChar:, 0)
}

SINGLETON(unsignedShortZeroNumber, initWithUnsignedShort:, 0)
static void
initTrueNumber(void)
SINGLETON(unsignedIntZeroNumber, initWithUnsignedInt:, 0)
{
	trueNumber = [[OFNumberSingleton alloc] initWithBool: true];
SINGLETON(unsignedLongZeroNumber, initWithUnsignedLong:, 0)
}

SINGLETON(unsignedLongLongZeroNumber, initWithUnsignedLongLong:, 0)
static void
initFalseNumber(void)
SINGLETON(floatZeroNumber, initWithFloat:, 0)
{
	falseNumber = [[OFNumberSingleton alloc] initWithBool: false];
}
SINGLETON(doubleZeroNumber, initWithDouble:, 0)
#undef SINGLETON


@implementation OFNumberPlaceholder
- (instancetype)initWithBool: (bool)bool_
- (instancetype)initWithBool: (bool)value
{
	if (bool_) {
		static of_once_t once;
		of_once(&once, initTrueNumber);
	if (value) {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, trueNumberInit);
		return (id)trueNumber;
	} else {
		static of_once_t once;
		of_once(&once, initFalseNumber);
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, falseNumberInit);
		return (id)falseNumber;
	}
}

- (instancetype)initWithChar: (signed char)sChar
- (instancetype)initWithChar: (signed char)value
{
	if (sChar >= 0)
		return [self initWithUnsignedChar: sChar];

	if (value == 0) {
	return (id)[[OFNumber of_alloc] initWithChar: sChar];
}

		static of_once_t once = OF_ONCE_INIT;
- (instancetype)initWithShort: (short)sShort
{
	if (sShort >= 0)
		return [self initWithUnsignedShort: sShort];
	if (sShort >= SCHAR_MIN)
		return [self initWithChar: (signed char)sShort];

	return (id)[[OFNumber of_alloc] initWithShort: sShort];
}
		of_once(&once, charZeroNumberInit);
		return (id)charZeroNumber;
	}

- (instancetype)initWithInt: (int)sInt
{
	if (sInt >= 0)
		return [self initWithUnsignedInt: sInt];
	if (sInt >= SHRT_MIN)
		return [self initWithShort: (short)sInt];

	return (id)[[OFNumber of_alloc] initWithInt: sInt];
	return (id)[[OFNumber of_alloc] initWithChar: value];
}

- (instancetype)initWithLong: (long)sLong
{
	if (sLong >= 0)
		return [self initWithUnsignedLong: sLong];
	if (sLong >= INT_MIN)
		return [self initWithShort: (int)sLong];

	return (id)[[OFNumber of_alloc] initWithLong: sLong];
}
- (instancetype)initWithShort: (short)value
{
	if (value == 0) {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, shortZeroNumberInit);
		return (id)shortZeroNumber;
	}

- (instancetype)initWithLongLong: (long long)sLongLong
{
	if (sLongLong >= 0)
		return [self initWithUnsignedLongLong: sLongLong];
	if (sLongLong >= LONG_MIN)
		return [self initWithLong: (long)sLongLong];

	return (id)[[OFNumber of_alloc] initWithLongLong: sLongLong];
	return (id)[[OFNumber of_alloc] initWithShort: value];
}

- (instancetype)initWithUnsignedChar: (unsigned char)uChar
- (instancetype)initWithInt: (int)value
{
	switch (uChar) {
	case 0: {
	if (value == 0) {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, initZeroNumber);
		return (id)zeroNumber;
		of_once(&once, intZeroNumberInit);
		return (id)intZeroNumber;
	}
	case 1: {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, initOneNumber);
		return (id)oneNumber;
	}

	case 2: {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, initTwoNumber);
		return (id)twoNumber;
	}
	}
	return (id)[[OFNumber of_alloc] initWithInt: value];
}


	return (id)[[OFNumber of_alloc] initWithUnsignedChar: uChar];
}

- (instancetype)initWithUnsignedShort: (unsigned short)uShort
- (instancetype)initWithLong: (long)value
{
	if (uShort <= UCHAR_MAX)
	if (value == 0) {
		return [self initWithUnsignedChar: (unsigned char)uShort];

	return (id)[[OFNumber of_alloc] initWithUnsignedShort: uShort];
}
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, longZeroNumberInit);
		return (id)longZeroNumber;
	}

- (instancetype)initWithUnsignedInt: (unsigned int)uInt
{
	if (uInt <= USHRT_MAX)
		return [self initWithUnsignedShort: (unsigned short)uInt];

	return (id)[[OFNumber of_alloc] initWithUnsignedInt: uInt];
	return (id)[[OFNumber of_alloc] initWithLong: value];
}

- (instancetype)initWithUnsignedLong: (unsigned long)uLong
- (instancetype)initWithLongLong: (long long)value
{
	if (uLong <= UINT_MAX)
	if (value == 0) {
		return [self initWithUnsignedInt: (unsigned int)uLong];

		static of_once_t once = OF_ONCE_INIT;
	return (id)[[OFNumber of_alloc] initWithUnsignedLong: uLong];
}

		of_once(&once, longLongZeroNumberInit);
- (instancetype)initWithUnsignedLongLong: (unsigned long long)uLongLong
{
	if (uLongLong <= ULONG_MAX)
		return (id)longLongZeroNumber;
		return [self initWithUnsignedLong: (unsigned long)uLongLong];

	}
	return (id)[[OFNumber of_alloc] initWithUnsignedLongLong: uLongLong];
}


- (instancetype)initWithInt8: (int8_t)int8
{
	if (int8 >= 0)
		return [self initWithUInt8: int8];

	return (id)[[OFNumber of_alloc] initWithInt8: int8];
	return (id)[[OFNumber of_alloc] initWithLongLong: value];
}

- (instancetype)initWithInt16: (int16_t)int16
- (instancetype)initWithUnsignedChar: (unsigned char)value
{
	if (int16 >= 0)
	if (value == 0) {
		return [self initWithUInt16: int16];
	if (int16 >= INT8_MIN)
		return [self initWithInt8: (int8_t)int16];

	return (id)[[OFNumber of_alloc] initWithInt16: int16];
}
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, unsignedCharZeroNumberInit);
		return (id)unsignedCharZeroNumber;
	}

- (instancetype)initWithInt32: (int32_t)int32
{
	if (int32 >= 0)
		return [self initWithUInt32: int32];
	if (int32 >= INT16_MIN)
		return [self initWithInt16: (int16_t)int32];

	return (id)[[OFNumber of_alloc] initWithInt32: int32];
	return (id)[[OFNumber of_alloc] initWithUnsignedChar: value];
}

- (instancetype)initWithInt64: (int64_t)int64
{
	if (int64 >= 0)
		return [self initWithUInt64: int64];
	if (int64 >= INT32_MIN)
		return [self initWithInt32: (int32_t)int64];

	return (id)[[OFNumber of_alloc] initWithInt64: int64];
}

- (instancetype)initWithUInt8: (uint8_t)uInt8
- (instancetype)initWithUnsignedShort: (unsigned short)value
{
	return (id)[[OFNumber of_alloc] initWithUInt8: uInt8];
}

	if (value == 0) {
- (instancetype)initWithUInt16: (uint16_t)uInt16
{
	if (uInt16 <= UINT8_MAX)
		return [self initWithUInt8: (uint8_t)uInt16];

	return (id)[[OFNumber of_alloc] initWithUInt16: uInt16];
}
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, unsignedShortZeroNumberInit);
		return (id)unsignedShortZeroNumber;
	}

- (instancetype)initWithUInt32: (uint32_t)uInt32
{
	if (uInt32 <= UINT16_MAX)
		return [self initWithUInt16: (uint16_t)uInt32];

	return (id)[[OFNumber of_alloc] initWithUInt32: uInt32];
	return (id)[[OFNumber of_alloc] initWithUnsignedShort: value];
}

- (instancetype)initWithUInt64: (uint64_t)uInt64
- (instancetype)initWithUnsignedInt: (unsigned int)value
{
	if (uInt64 <= UINT32_MAX)
		return [self initWithUInt32: (uint32_t)uInt64];

	if (value == 0) {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, unsignedIntZeroNumberInit);
		return (id)unsignedIntZeroNumber;
	}
	return (id)[[OFNumber of_alloc] initWithUInt64: uInt64];
}


- (instancetype)initWithSize: (size_t)size
{
	if (size <= ULONG_MAX)
		return [self initWithUnsignedLong: (unsigned long)size];

	return (id)[[OFNumber of_alloc] initWithSize: size];
	return (id)[[OFNumber of_alloc] initWithUnsignedInt: value];
}

- (instancetype)initWithSSize: (ssize_t)sSize
- (instancetype)initWithUnsignedLong: (unsigned long)value
{
	if (sSize >= 0)
	if (value == 0) {
		return [self initWithSize: sSize];
	if (sSize <= LONG_MIN)
		return [self initWithLong: (long)sSize];

	return (id)[[OFNumber of_alloc] initWithSSize: sSize];
}
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, unsignedLongZeroNumberInit);
		return (id)unsignedLongZeroNumber;
	}

- (instancetype)initWithIntMax: (intmax_t)intMax
{
	if (intMax >= 0)
		return [self initWithUIntMax: intMax];
	if (intMax <= LLONG_MIN)
		return [self initWithLongLong: (long long)intMax];

	return (id)[[OFNumber of_alloc] initWithIntMax: intMax];
	return (id)[[OFNumber of_alloc] initWithUnsignedLong: value];
}

- (instancetype)initWithUIntMax: (uintmax_t)uIntMax
{
	if (uIntMax <= ULLONG_MAX)
		return [self initWithUnsignedLongLong:

- (instancetype)initWithUnsignedLongLong: (unsigned long long)value
		    (unsigned long long)uIntMax];

	return (id)[[OFNumber of_alloc] initWithUIntMax: uIntMax];
{
	if (value == 0) {
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, unsignedLongLongZeroNumberInit);
}

		return (id)unsignedLongLongZeroNumber;
#ifdef __clang__
/*
 * This warning should probably not exist at all, as it prevents checking
 * whether one type fits into another in a portable way.
 */
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wtautological-constant-out-of-range-compare"
#endif

	}
- (instancetype)initWithPtrDiff: (ptrdiff_t)ptrDiff
{

	if (ptrDiff >= LLONG_MIN && ptrDiff <= LLONG_MAX)
		return [self initWithLongLong: (long long)ptrDiff];

	return (id)[[OFNumber of_alloc] initWithPtrDiff: ptrDiff];
	return (id)[[OFNumber of_alloc] initWithUnsignedLongLong: value];
}

- (instancetype)initWithIntPtr: (intptr_t)intPtr
- (instancetype)initWithFloat: (float)value
{
	if (intPtr >= 0)
	if (value == 0) {
		return [self initWithUIntPtr: intPtr];
	if (intPtr >= LLONG_MIN)
		return [self initWithLongLong: (long long)intPtr];

	return (id)[[OFNumber of_alloc] initWithIntPtr: intPtr];
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, floatZeroNumberInit);
		return (id)floatZeroNumber;
}

	}
- (instancetype)initWithUIntPtr: (uintptr_t)uIntPtr
{

	if (uIntPtr <= ULLONG_MAX)
		return [self initWithUnsignedLongLong:
		    (unsigned long long)uIntPtr];

	return (id)[[OFNumber of_alloc] initWithUIntPtr: uIntPtr];
	return (id)[[OFNumber of_alloc] initWithFloat: value];
}

#ifdef __clang__
# pragma clang diagnostic pop
#endif

- (instancetype)initWithFloat: (float)float_
- (instancetype)initWithDouble: (double)value
{
	if (float_ == (uintmax_t)float_)
	if (value == 0) {
		return [self initWithUIntMax: (uintmax_t)float_];
	if (float_ == (intmax_t)float_)
		return [self initWithIntMax: (intmax_t)float_];

	return (id)[[OFNumber of_alloc] initWithFloat: float_];
}
		static of_once_t once = OF_ONCE_INIT;
		of_once(&once, doubleZeroNumberInit);
		return (id)doubleZeroNumber;
	}

- (instancetype)initWithDouble: (double)double_
{
	if (double_ == (uintmax_t)double_)
		return [self initWithUIntMax: (uintmax_t)double_];
	if (double_ == (intmax_t)double_)
		return [self initWithIntMax: (intmax_t)double_];
	if (double_ == (float)double_)
		return [self initWithFloat: (float)double_];

	return (id)[[OFNumber of_alloc] initWithDouble: double_];
	return (id)[[OFNumber of_alloc] initWithDouble: value];
}

- (instancetype)initWithSerialization: (OFXMLElement *)element
{
	return (id)[[OFNumber of_alloc] initWithSerialization: element];
}
@end
406
407
408
409
410
411
412
413

414
415

416
417
418

419
420

421
422
423

424
425

426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
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

491
492
493

494
495

496
497
498
499
500
501
502
503
504
505
506
507
508

509
510

511
512
513
514
515
516
517
518

519
520
521
522
523
524
525

526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543

544
545

546
547
548

549
550

551
552
553
554
555
556
557
558

559
560
561
562

563
564
565
566
567
568
569

570
571
572
573

574
575
576
577
578
579
580

581
582
583
584

585
586
587
588
589
590
591

592
593
594
595

596
597
598
599
600
601
602

603
604
605
606

607
608
609
610
611
612
613

614
615
616
617

618
619
620
621
622
623
624

625
626
627
628

629
630
631
632
633
634
635

636
637
638
639

640
641
642
643
644
645
646

647
648
649
650

651
652
653
654
655
656
657

658
659
660
661

662
663
664
665
666
667
668

669
670
671
672

673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811

812
813
814
815

816
817
818
819
820
821
822

823
824
825
826

827
828
829
830
831
832
833

834
835
836
837

838
839
840
841
842
843
844

845
846
847
848

849
850
851
852
853
854
855

856
857
858
859

860
861
862
863
864
865
866
260
261
262
263
264
265
266

267
268

269
270
271

272
273

274
275
276

277
278

279
280




















281






282
283

284
285
286











287
288

289
290
291

292
293

294
295
296

297




298



299
300
301

302
303

304
305
306

307
308

309
310
311











312
313

314





315
316

317
318






319
320
321
















322
323

324
325
326

327
328

329
330
331
332
333
334
335
336

337
338
339
340

341
342
343
344
345
346
347

348
349
350
351

352
353
354
355
356
357
358

359
360
361
362

363
364
365
366
367
368
369

370
371
372
373

374
375
376
377
378
379
380

381
382
383
384

385
386
387
388
389
390
391

392
393
394
395

396
397
398
399
400
401
402

403
404
405
406

407
408
409
410
411
412
413

414
415
416
417

418
419
420
421
422
423
424

425
426
427
428

429
430
431
432
433
434
435

436
437
438
439

440
441
442
443
444
445
446

447
448
449
450

451
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

491
492
493
494

495
496
497
498
499
500
501

502
503
504
505

506
507
508
509
510
511
512
513







-
+

-
+


-
+

-
+


-
+

-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

-
-
-
-
-
-
+

-
+


-
-
-
-
-
-
-
-
-
-
-
+

-
+


-
+

-
+


-
+
-
-
-
-
+
-
-
-
+


-
+

-
+


-
+

-
+


-
-
-
-
-
-
-
-
-
-
-
+

-
+
-
-
-
-
-


-
+

-
-
-
-
-
-
+


-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+

-
+


-
+

-
+







-
+



-
+






-
+



-
+






-
+



-
+






-
+



-
+






-
+



-
+






-
+



-
+






-
+



-
+






-
+



-
+






-
+



-
+






-
+



-
+






-
+



-
+






-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+



-
+






-
+



-
+






-
+



-
+






-
+



-
+






-
+



-
+







{
	if (self == [OFNumber class])
		return (id)&placeholder;

	return [super alloc];
}

+ (instancetype)numberWithBool: (bool)bool_
+ (instancetype)numberWithBool: (bool)value
{
	return [[[self alloc] initWithBool: bool_] autorelease];
	return [[[self alloc] initWithBool: value] autorelease];
}

+ (instancetype)numberWithChar: (signed char)sChar
+ (instancetype)numberWithChar: (signed char)value
{
	return [[[self alloc] initWithChar: sChar] autorelease];
	return [[[self alloc] initWithChar: value] autorelease];
}

+ (instancetype)numberWithShort: (short)sShort
+ (instancetype)numberWithShort: (short)value
{
	return [[[self alloc] initWithShort: sShort] autorelease];
	return [[[self alloc] initWithShort: value] autorelease];
}

+ (instancetype)numberWithInt: (int)sInt
{
	return [[[self alloc] initWithInt: sInt] autorelease];
}

+ (instancetype)numberWithLong: (long)sLong
{
	return [[[self alloc] initWithLong: sLong] autorelease];
}

+ (instancetype)numberWithLongLong: (long long)sLongLong
{
	return [[[self alloc] initWithLongLong: sLongLong] autorelease];
}

+ (instancetype)numberWithUnsignedChar: (unsigned char)uChar
{
	return [[[self alloc] initWithUnsignedChar: uChar] autorelease];
}

+ (instancetype)numberWithUnsignedShort: (unsigned short)uShort
{
	return [[[self alloc] initWithUnsignedShort: uShort] autorelease];
}

+ (instancetype)numberWithUnsignedInt: (unsigned int)uInt
+ (instancetype)numberWithInt: (int)value
{
	return [[[self alloc] initWithUnsignedInt: uInt] autorelease];
	return [[[self alloc] initWithInt: value] autorelease];
}

+ (instancetype)numberWithUnsignedLong: (unsigned long)uLong
{
	return [[[self alloc] initWithUnsignedLong: uLong] autorelease];
}

+ (instancetype)numberWithUnsignedLongLong: (unsigned long long)uLongLong
{
	return [[[self alloc] initWithUnsignedLongLong: uLongLong] autorelease];
}

+ (instancetype)numberWithInt8: (int8_t)int8
+ (instancetype)numberWithLong: (long)value
{
	return [[[self alloc] initWithInt8: int8] autorelease];
	return [[[self alloc] initWithLong: value] autorelease];
}

+ (instancetype)numberWithInt16: (int16_t)int16
+ (instancetype)numberWithLongLong: (long long)value
{
	return [[[self alloc] initWithInt16: int16] autorelease];
	return [[[self alloc] initWithLongLong: value] autorelease];
}

+ (instancetype)numberWithInt32: (int32_t)int32
+ (instancetype)numberWithUnsignedChar: (unsigned char)value
{
	return [[[self alloc] initWithInt32: int32] autorelease];
}

{
+ (instancetype)numberWithInt64: (int64_t)int64
{
	return [[[self alloc] initWithInt64: int64] autorelease];
	return [[[self alloc] initWithUnsignedChar: value] autorelease];
}

+ (instancetype)numberWithUInt8: (uint8_t)uInt8
+ (instancetype)numberWithUnsignedShort: (unsigned short)value
{
	return [[[self alloc] initWithUInt8: uInt8] autorelease];
	return [[[self alloc] initWithUnsignedShort: value] autorelease];
}

+ (instancetype)numberWithUInt16: (uint16_t)uInt16
+ (instancetype)numberWithUnsignedInt: (unsigned int)value
{
	return [[[self alloc] initWithUInt16: uInt16] autorelease];
	return [[[self alloc] initWithUnsignedInt: value] autorelease];
}

+ (instancetype)numberWithUInt32: (uint32_t)uInt32
{
	return [[[self alloc] initWithUInt32: uInt32] autorelease];
}

+ (instancetype)numberWithUInt64: (uint64_t)uInt64
{
	return [[[self alloc] initWithUInt64: uInt64] autorelease];
}

+ (instancetype)numberWithSize: (size_t)size
+ (instancetype)numberWithUnsignedLong: (unsigned long)value
{
	return [[[self alloc] initWithSize: size] autorelease];
	return [[[self alloc] initWithUnsignedLong: value] autorelease];
}

+ (instancetype)numberWithSSize: (ssize_t)sSize
{
	return [[[self alloc] initWithSSize: sSize] autorelease];
}

+ (instancetype)numberWithIntMax: (intmax_t)intMax
+ (instancetype)numberWithUnsignedLongLong: (unsigned long long)value
{
	return [[[self alloc] initWithIntMax: intMax] autorelease];
}

+ (instancetype)numberWithUIntMax: (uintmax_t)uIntMax
{
	return [[[self alloc] initWithUIntMax: uIntMax] autorelease];
	return [[[self alloc] initWithUnsignedLongLong: value] autorelease];
}

+ (instancetype)numberWithPtrDiff: (ptrdiff_t)ptrDiff
{
	return [[[self alloc] initWithPtrDiff: ptrDiff] autorelease];
}

+ (instancetype)numberWithIntPtr: (intptr_t)intPtr
{
	return [[[self alloc] initWithIntPtr: intPtr] autorelease];
}

+ (instancetype)numberWithUIntPtr: (uintptr_t)uIntPtr
{
	return [[[self alloc] initWithUIntPtr: uIntPtr] autorelease];
}

+ (instancetype)numberWithFloat: (float)float_
+ (instancetype)numberWithFloat: (float)value
{
	return [[[self alloc] initWithFloat: float_] autorelease];
	return [[[self alloc] initWithFloat: value] autorelease];
}

+ (instancetype)numberWithDouble: (double)double_
+ (instancetype)numberWithDouble: (double)value
{
	return [[[self alloc] initWithDouble: double_] autorelease];
	return [[[self alloc] initWithDouble: value] autorelease];
}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithBool: (bool)bool_
- (instancetype)initWithBool: (bool)value
{
	self = [super init];

	_value.unsigned_ = bool_;
	_value.unsigned_ = value;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(bool);

	return self;
}

- (instancetype)initWithChar: (signed char)sChar
- (instancetype)initWithChar: (signed char)value
{
	self = [super init];

	_value.signed_ = sChar;
	_value.signed_ = value;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(signed char);

	return self;
}

- (instancetype)initWithShort: (short)sShort
- (instancetype)initWithShort: (short)value
{
	self = [super init];

	_value.signed_ = sShort;
	_value.signed_ = value;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(short);

	return self;
}

- (instancetype)initWithInt: (int)sInt
- (instancetype)initWithInt: (int)value
{
	self = [super init];

	_value.signed_ = sInt;
	_value.signed_ = value;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(int);

	return self;
}

- (instancetype)initWithLong: (long)sLong
- (instancetype)initWithLong: (long)value
{
	self = [super init];

	_value.signed_ = sLong;
	_value.signed_ = value;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(long);

	return self;
}

- (instancetype)initWithLongLong: (long long)sLongLong
- (instancetype)initWithLongLong: (long long)value
{
	self = [super init];

	_value.signed_ = sLongLong;
	_value.signed_ = value;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(long long);

	return self;
}

- (instancetype)initWithUnsignedChar: (unsigned char)uChar
- (instancetype)initWithUnsignedChar: (unsigned char)value
{
	self = [super init];

	_value.unsigned_ = uChar;
	_value.unsigned_ = value;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(unsigned long);

	return self;
}

- (instancetype)initWithUnsignedShort: (unsigned short)uShort
- (instancetype)initWithUnsignedShort: (unsigned short)value
{
	self = [super init];

	_value.unsigned_ = uShort;
	_value.unsigned_ = value;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(unsigned short);

	return self;
}

- (instancetype)initWithUnsignedInt: (unsigned int)uInt
- (instancetype)initWithUnsignedInt: (unsigned int)value
{
	self = [super init];

	_value.unsigned_ = uInt;
	_value.unsigned_ = value;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(unsigned int);

	return self;
}

- (instancetype)initWithUnsignedLong: (unsigned long)uLong
- (instancetype)initWithUnsignedLong: (unsigned long)value
{
	self = [super init];

	_value.unsigned_ = uLong;
	_value.unsigned_ = value;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(unsigned long);

	return self;
}

- (instancetype)initWithUnsignedLongLong: (unsigned long long)uLongLong
- (instancetype)initWithUnsignedLongLong: (unsigned long long)value
{
	self = [super init];

	_value.unsigned_ = uLongLong;
	_value.unsigned_ = value;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(unsigned long long);

	return self;
}

- (instancetype)initWithInt8: (int8_t)int8
{
	self = [super init];

	_value.signed_ = int8;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(int8_t);

	return self;
}

- (instancetype)initWithInt16: (int16_t)int16
{
	self = [super init];

	_value.signed_ = int16;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(int16_t);

	return self;
}

- (instancetype)initWithInt32: (int32_t)int32
{
	self = [super init];

	_value.signed_ = int32;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(int32_t);

	return self;
}

- (instancetype)initWithInt64: (int64_t)int64
{
	self = [super init];

	_value.signed_ = int64;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(int64_t);

	return self;
}

- (instancetype)initWithUInt8: (uint8_t)uInt8
{
	self = [super init];

	_value.unsigned_ = uInt8;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(uint8_t);

	return self;
}

- (instancetype)initWithUInt16: (uint16_t)uInt16
{
	self = [super init];

	_value.unsigned_ = uInt16;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(uint16_t);

	return self;
}

- (instancetype)initWithUInt32: (uint32_t)uInt32
{
	self = [super init];

	_value.unsigned_ = uInt32;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(uint32_t);

	return self;
}

- (instancetype)initWithUInt64: (uint64_t)uInt64
{
	self = [super init];

	_value.unsigned_ = uInt64;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(uint64_t);

	return self;
}

- (instancetype)initWithSize: (size_t)size
{
	self = [super init];

	_value.unsigned_ = size;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(size_t);

	return self;
}

- (instancetype)initWithSSize: (ssize_t)sSize
{
	self = [super init];

	_value.signed_ = sSize;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(ssize_t);

	return self;
}

- (instancetype)initWithIntMax: (intmax_t)intMax
{
	self = [super init];

	_value.signed_ = intMax;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(intmax_t);

	return self;
}

- (instancetype)initWithUIntMax: (uintmax_t)uIntMax
{
	self = [super init];

	_value.unsigned_ = uIntMax;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(uintmax_t);

	return self;
}

- (instancetype)initWithPtrDiff: (ptrdiff_t)ptrDiff
- (instancetype)initWithPtrDiff: (ptrdiff_t)value
{
	self = [super init];

	_value.signed_ = ptrDiff;
	_value.signed_ = value;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(ptrdiff_t);

	return self;
}

- (instancetype)initWithIntPtr: (intptr_t)intPtr
- (instancetype)initWithIntPtr: (intptr_t)value
{
	self = [super init];

	_value.signed_ = intPtr;
	_value.signed_ = value;
	_type = OF_NUMBER_TYPE_SIGNED;
	_typeEncoding = @encode(intptr_t);

	return self;
}

- (instancetype)initWithUIntPtr: (uintptr_t)uIntPtr
- (instancetype)initWithUIntPtr: (uintptr_t)value
{
	self = [super init];

	_value.unsigned_ = uIntPtr;
	_value.unsigned_ = value;
	_type = OF_NUMBER_TYPE_UNSIGNED;
	_typeEncoding = @encode(uintptr_t);

	return self;
}

- (instancetype)initWithFloat: (float)float_
- (instancetype)initWithFloat: (float)value
{
	self = [super init];

	_value.float_ = float_;
	_value.float_ = value;
	_type = OF_NUMBER_TYPE_FLOAT;
	_typeEncoding = @encode(float);

	return self;
}

- (instancetype)initWithDouble: (double)double_
- (instancetype)initWithDouble: (double)value
{
	self = [super init];

	_value.float_ = double_;
	_value.float_ = value;
	_type = OF_NUMBER_TYPE_FLOAT;
	_typeEncoding = @encode(double);

	return self;
}

- (instancetype)initWithSerialization: (OFXMLElement *)element
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
528
529
530
531
532
533
534

535
536
537
538
539
540
541
542

543



544
545
546





547
548
549
550
551
552
553
554
555







-
+
+
+
+
+
+
+

-
+
-
-
-
+
+

-
-
-
-
-
+
+







			OFString *stringValue = element.stringValue;
			if ([stringValue isEqual: @"true"])
				self = [self initWithBool: true];
			else if ([stringValue isEqual: @"false"])
				self = [self initWithBool: false];
			else
				@throw [OFInvalidArgumentException exception];
		} else if ([typeString isEqual: @"float"])
		} else if ([typeString isEqual: @"float"]) {
			unsigned long long value =
			    [element unsignedLongLongValueWithBase: 16];

			if (value > UINT64_MAX)
				@throw [OFOutOfRangeException exception];

			self = [self initWithDouble: OF_BSWAP_DOUBLE_IF_LE(
			    OF_INT_TO_DOUBLE_RAW(OF_BSWAP64_IF_LE(
			    OF_INT_TO_DOUBLE_RAW(OF_BSWAP64_IF_LE(value)))];
			    (uint64_t)element.hexadecimalValue)))];
		else if ([typeString isEqual: @"signed"])
			self = [self initWithIntMax: element.doubleValue];
		} else if ([typeString isEqual: @"signed"])
			self = [self initWithLongLong: element.longLongValue];
		else if ([typeString isEqual: @"unsigned"])
			/*
			 * FIXME: This will fail if the value is bigger than
			 *	  INTMAX_MAX!
			 */
			self = [self initWithUIntMax: element.decimalValue];
			self = [self initWithUnsignedLongLong:
			    element.unsignedLongLongValue];
		else
			@throw [OFInvalidArgumentException exception];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
658
659
660
661
662
663
664











































































665
666
667
668
669
670
671







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-







}

- (unsigned long long)unsignedLongLongValue
{
	RETURN_AS(unsigned long long)
}

- (int8_t)int8Value
{
	RETURN_AS(int8_t)
}

- (int16_t)int16Value
{
	RETURN_AS(int16_t)
}

- (int32_t)int32Value
{
	RETURN_AS(int32_t)
}

- (int64_t)int64Value
{
	RETURN_AS(int64_t)
}

- (uint8_t)uInt8Value
{
	RETURN_AS(uint8_t)
}

- (uint16_t)uInt16Value
{
	RETURN_AS(uint16_t)
}

- (uint32_t)uInt32Value
{
	RETURN_AS(uint32_t)
}

- (uint64_t)uInt64Value
{
	RETURN_AS(uint64_t)
}

- (size_t)sizeValue
{
	RETURN_AS(size_t)
}

- (ssize_t)sSizeValue
{
	RETURN_AS(ssize_t)
}

- (intmax_t)intMaxValue
{
	RETURN_AS(intmax_t)
}

- (uintmax_t)uIntMaxValue
{
	RETURN_AS(uintmax_t)
}

- (ptrdiff_t)ptrDiffValue
{
	RETURN_AS(ptrdiff_t)
}

- (intptr_t)intPtrValue
{
	RETURN_AS(intptr_t)
}

- (uintptr_t)uIntPtrValue
{
	RETURN_AS(uintptr_t)
}

- (float)floatValue
{
	RETURN_AS(float)
}

- (double)doubleValue
{
1122
1123
1124
1125
1126
1127
1128
1129

1130
1131

1132
1133
1134
1135
1136
1137
1138
696
697
698
699
700
701
702

703
704

705
706
707
708
709
710
711
712







-
+

-
+







			return false;

		return (value1 == value2);
	}

	if (_type == OF_NUMBER_TYPE_SIGNED ||
	    number->_type == OF_NUMBER_TYPE_SIGNED)
		return (number.intMaxValue == self.intMaxValue);
		return (number.longLongValue == self.longLongValue);

	return (number.uIntMaxValue == self.uIntMaxValue);
	return (number.unsignedLongLongValue == self.unsignedLongLongValue);
}

- (of_comparison_result_t)compare: (id <OFComparing>)object
{
	OFNumber *number;

	if (![(id)object isKindOfClass: [OFNumber class]])
1149
1150
1151
1152
1153
1154
1155
1156
1157


1158
1159
1160
1161
1162
1163
1164
1165
1166
1167


1168
1169
1170
1171
1172
1173
1174
723
724
725
726
727
728
729


730
731
732
733
734
735
736
737
738
739


740
741
742
743
744
745
746
747
748







-
-
+
+








-
-
+
+







			return OF_ORDERED_DESCENDING;
		if (double1 < double2)
			return OF_ORDERED_ASCENDING;

		return OF_ORDERED_SAME;
	} else if (_type == OF_NUMBER_TYPE_SIGNED ||
	    number->_type == OF_NUMBER_TYPE_SIGNED) {
		intmax_t int1 = self.intMaxValue;
		intmax_t int2 = number.intMaxValue;
		long long int1 = self.longLongValue;
		long long int2 = number.longLongValue;

		if (int1 > int2)
			return OF_ORDERED_DESCENDING;
		if (int1 < int2)
			return OF_ORDERED_ASCENDING;

		return OF_ORDERED_SAME;
	} else {
		uintmax_t uint1 = self.uIntMaxValue;
		uintmax_t uint2 = number.uIntMaxValue;
		unsigned long long uint1 = self.unsignedLongLongValue;
		unsigned long long uint2 = number.unsignedLongLongValue;

		if (uint1 > uint2)
			return OF_ORDERED_DESCENDING;
		if (uint1 < uint2)
			return OF_ORDERED_ASCENDING;

		return OF_ORDERED_SAME;
1188
1189
1190
1191
1192
1193
1194
1195

1196
1197
1198
1199
1200
1201
1202
1203
1204
1205


1206
1207
1208
1209



1210
1211
1212
1213
1214
1215
1216
762
763
764
765
766
767
768

769










770
771
772



773
774
775
776
777
778
779
780
781
782







-
+
-
-
-
-
-
-
-
-
-
-
+
+

-
-
-
+
+
+







		if (isnan(self.doubleValue))
			return 0;

		d = OF_BSWAP_DOUBLE_IF_BE(self.doubleValue);

		for (uint_fast8_t i = 0; i < sizeof(double); i++)
			OF_HASH_ADD(hash, ((char *)&d)[i]);
	} else if (type == OF_NUMBER_TYPE_SIGNED) {
	} else if (type == OF_NUMBER_TYPE_SIGNED ||
		intmax_t v = self.intMaxValue * -1;

		while (v != 0) {
			OF_HASH_ADD(hash, v & 0xFF);
			v >>= 8;
		}

		OF_HASH_ADD(hash, 1);
	} else if (type == OF_NUMBER_TYPE_UNSIGNED) {
		uintmax_t v = self.uIntMaxValue;
	    type == OF_NUMBER_TYPE_UNSIGNED) {
		unsigned long long value = self.unsignedLongLongValue;

		while (v != 0) {
			OF_HASH_ADD(hash, v & 0xFF);
			v >>= 8;
		while (value != 0) {
			OF_HASH_ADD(hash, value & 0xFF);
			value >>= 8;
		}
	} else
		@throw [OFInvalidFormatException exception];

	OF_HASH_FINALIZE(hash);

	return hash;
1229
1230
1231
1232
1233
1234
1235
1236

1237
1238

1239
1240
1241
1242
1243
1244
1245
795
796
797
798
799
800
801

802
803

804
805
806
807
808
809
810
811







-
+

-
+







- (OFString *)stringValue
{
	if (*_typeEncoding == 'B')
		return (_value.unsigned_ ? @"true" : @"false");
	if (_type == OF_NUMBER_TYPE_FLOAT)
		return [OFString stringWithFormat: @"%g", _value.float_];
	if (_type == OF_NUMBER_TYPE_SIGNED)
		return [OFString stringWithFormat: @"%jd", _value.signed_];
		return [OFString stringWithFormat: @"%lld", _value.signed_];
	if (_type == OF_NUMBER_TYPE_UNSIGNED)
		return [OFString stringWithFormat: @"%ju", _value.unsigned_];
		return [OFString stringWithFormat: @"%llu", _value.unsigned_];

	@throw [OFInvalidFormatException exception];
}

- (OFXMLElement *)XMLElementBySerializing
{
	void *pool = objc_autoreleasePoolPush();
1335
1336
1337
1338
1339
1340
1341
1342

1343
1344
1345
1346
1347
1348
1349
901
902
903
904
905
906
907

908
909
910
911
912
913
914
915







-
+







		data = [OFMutableData dataWithItemSize: 1
					      capacity: 9];

		[data addItem: &type];
		[data addItems: &tmp
			 count: sizeof(tmp)];
	} else if (_type == OF_NUMBER_TYPE_SIGNED) {
		intmax_t value = self.intMaxValue;
		long long value = self.longLongValue;

		if (value >= -32 && value < 0) {
			uint8_t tmp = 0xE0 | ((uint8_t)(value - 32) & 0x1F);

			data = [OFMutableData dataWithItems: &tmp
						      count: 1];
		} else if (value >= INT8_MIN && value <= INT8_MAX) {
1384
1385
1386
1387
1388
1389
1390
1391

1392
1393
1394
1395
1396
1397
1398
950
951
952
953
954
955
956

957
958
959
960
961
962
963
964







-
+








			[data addItem: &type];
			[data addItems: &tmp
				 count: sizeof(tmp)];
		} else
			@throw [OFOutOfRangeException exception];
	} else if (_type == OF_NUMBER_TYPE_UNSIGNED) {
		uintmax_t value = self.uIntMaxValue;
		unsigned long long value = self.unsignedLongLongValue;

		if (value <= 127) {
			uint8_t tmp = ((uint8_t)value & 0x7F);

			data = [OFMutableData dataWithItems: &tmp
						      count: 1];
		} else if (value <= UINT8_MAX) {

Modified src/OFSettings.h from [2c70a1f69b] to [a4eaab9bfc].

79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93







-
+








/*!
 * @brief Sets the specified path to the specified integer.
 *
 * @param integer The integer to set
 * @param path The path to store the integer at
 */
- (void)setInteger: (intmax_t)integer
- (void)setInteger: (long long)integer
	   forPath: (OFString *)path;

/*!
 * @brief Sets the specified path to the specified bool.
 *
 * @param bool_ The bool to set
 * @param path The path to store the bool at
146
147
148
149
150
151
152
153
154


155
156
157
158
159
160
161
146
147
148
149
150
151
152


153
154
155
156
157
158
159
160
161







-
-
+
+







 * @brief Returns the integer for the specified path, or the default value if
 *	  the path does not exist.
 *
 * @param path The path for which the integer value should be returned
 * @param defaultValue The default value to return if the path does not exist
 * @return The integer value of the specified path
 */
- (intmax_t)integerForPath: (OFString *)path
	      defaultValue: (intmax_t)defaultValue;
- (long long)integerForPath: (OFString *)path
	       defaultValue: (long long)defaultValue;

/*!
 * @brief Returns the bool for the specified path, or the default value if the
 *	  path does not exist.
 *
 * @param path The path for which the bool value should be returned
 * @param defaultValue The default value to return if the path does not exist

Modified src/OFSettings.m from [760331490f] to [5da0b0a891].

66
67
68
69
70
71
72
73

74
75
76
77
78
79
80
66
67
68
69
70
71
72

73
74
75
76
77
78
79
80







-
+








- (void)setString: (OFString *)string
	  forPath: (OFString *)path
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)setInteger: (intmax_t)integer
- (void)setInteger: (long long)integer
	   forPath: (OFString *)path
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)setBool: (bool)bool_
	forPath: (OFString *)path
108
109
110
111
112
113
114
115
116


117
118
119
120
121
122
123
108
109
110
111
112
113
114


115
116
117
118
119
120
121
122
123







-
-
+
+








- (OFString *)stringForPath: (OFString *)path
	       defaultValue: (OFString *)defaultValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (intmax_t)integerForPath: (OFString *)path
	      defaultValue: (intmax_t)defaultValue
- (long long)integerForPath: (OFString *)path
	       defaultValue: (long long)defaultValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (bool)boolForPath: (OFString *)path
       defaultValue: (bool)defaultValue
{

Renamed and modified src/OFString+JSONValue.h [311031a35c] to src/OFString+JSONParsing.h [bc722e0fb3].

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
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







-
+




-
+















-
+







#import "OFString.h"

OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFString_JSONValue_reference;
extern int _OFString_JSONParsing_reference;
#ifdef __cplusplus
}
#endif

@interface OFString (JSONValue)
@interface OFString (JSONParsing)
/*!
 * @brief The string interpreted as JSON and parsed as an object.
 *
 * @note This also allows parsing JSON5, an extension of JSON. See
 *	 http://json5.org/ for more details.
 *
 * @warning Although not specified by the JSON specification, this can also
 *          return primitives like strings and numbers. The rationale behind
 *          this is that most JSON parsers allow JSON data just consisting of a
 *          single primitive, leading to real world JSON files sometimes only
 *          consisting of a single primitive. Therefore, you should not make any
 *          assumptions about the object returned by this method if you don't
 *          want your program to terminate due to a message not understood, but
 *          instead check the returned object using @ref isKindOfClass:.
 */
@property (readonly, nonatomic) id JSONValue;
@property (readonly, nonatomic) id objectByParsingJSON;

/*!
 * @brief Creates an object from the JSON value of the string.
 *
 * @note This also allows parsing JSON5, an extension of JSON. See
 *	 http://json5.org/ for more details.
 *
61
62
63
64
65
66
67
68

69
70
71
61
62
63
64
65
66
67

68
69
70
71







-
+



 *          instead check the returned object using @ref isKindOfClass:.
 *
 * @param depthLimit The maximum depth the parser should accept (defaults to 32
 *		     if not specified, 0 means no limit (insecure!))
 *
 * @return An object
 */
- (id)JSONValueWithDepthLimit: (size_t)depthLimit;
- (id)objectByParsingJSONWithDepthLimit: (size_t)depthLimit;
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFString+JSONValue.m [ac798fd712] to src/OFString+JSONParsing.m [706b49d04b].

20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
35

36
37
38
39
40
41
42
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34

35
36
37
38
39
40
41
42







-
+







-
+







#include <stdlib.h>
#include <string.h>

#include <math.h>

#include <assert.h>

#import "OFString+JSONValue.h"
#import "OFString+JSONParsing.h"
#import "OFArray.h"
#import "OFDictionary.h"
#import "OFNumber.h"
#import "OFNull.h"

#import "OFInvalidJSONException.h"

int _OFString_JSONValue_reference;
int _OFString_JSONParsing_reference;

static id nextObject(const char **pointer, const char *stop, size_t *line,
    size_t depthLimit);

static void
skipWhitespaces(const char **pointer, const char *stop, size_t *line)
{
524
525
526
527
528
529
530
531

532
533
534
535
536
537
538
524
525
526
527
528
529
530

531
532
533
534
535
536
537
538







-
+








	return dictionary;
}

static inline OFNumber *
parseNumber(const char **pointer, const char *stop, size_t *line)
{
	bool isHex = (*pointer + 1 < stop && (*pointer)[1] == 'x');
	bool isNegative = (*pointer < stop && (*pointer)[0] == '-');
	bool hasDecimal = false;
	size_t i;
	OFString *string;
	OFNumber *number;

	for (i = 0; *pointer + i < stop; i++) {
		if ((*pointer)[i] == '.')
553
554
555
556
557
558
559
560
561
562
563
564
565
566



567
568
569


570
571
572
573
574
575
576
553
554
555
556
557
558
559



560
561
562
563
564
565
566
567


568
569
570
571
572
573
574
575
576







-
-
-




+
+
+

-
-
+
+







					       length: i];
	*pointer += i;

	@try {
		if (hasDecimal)
			number = [OFNumber numberWithDouble:
			    string.doubleValue];
		else if (isHex)
			number = [OFNumber numberWithIntMax:
			    string.hexadecimalValue];
		else if ([string isEqual: @"Infinity"])
			number = [OFNumber numberWithDouble: INFINITY];
		else if ([string isEqual: @"-Infinity"])
			number = [OFNumber numberWithDouble: -INFINITY];
		else if (isNegative)
			number = [OFNumber numberWithLongLong:
			    [string longLongValueWithBase: 0]];
		else
			number = [OFNumber numberWithIntMax:
			    string.decimalValue];
			number = [OFNumber numberWithUnsignedLongLong:
			    [string unsignedLongLongValueWithBase: 0]];
	} @finally {
		[string release];
	}

	return number;
}

637
638
639
640
641
642
643
644
645


646
647

648
649
650

651
652
653
654
655
656
657
637
638
639
640
641
642
643


644
645
646

647
648
649

650
651
652
653
654
655
656
657







-
-
+
+

-
+


-
+







	case 'I':
		return parseNumber(pointer, stop, line);
	default:
		return nil;
	}
}

@implementation OFString (JSONValue)
- (id)JSONValue
@implementation OFString (JSONParsing)
- (id)objectByParsingJSON
{
	return [self JSONValueWithDepthLimit: 32];
	return [self objectByParsingJSONWithDepthLimit: 32];
}

- (id)JSONValueWithDepthLimit: (size_t)depthLimit
- (id)objectByParsingJSONWithDepthLimit: (size_t)depthLimit
{
	void *pool = objc_autoreleasePoolPush();
	const char *pointer = self.UTF8String;
	const char *stop = pointer + self.UTF8StringLength;
	id object;
	size_t line = 1;

Renamed and modified src/OFString+PropertyListValue.h [6c64f3e60f] to src/OFString+PropertyListParsing.h [e83b475868].

18
19
20
21
22
23
24
25

26
27
28
29
30

31
32
33
34
35
36

37
38
39
18
19
20
21
22
23
24

25
26
27
28
29

30
31
32
33
34
35

36
37
38
39







-
+




-
+





-
+



#import "OFString.h"

OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern int _OFString_PropertyListValue_reference;
extern int _OFString_PropertyListParsing_reference;
#ifdef __cplusplus
}
#endif

@interface OFString (PropertyListValue)
@interface OFString (PropertyListParsing)
/*!
 * @brief The string interpreted as a property list and parsed as an object.
 *
 * @note This only supports XML property lists!
 */
@property (readonly, nonatomic) id propertyListValue;
@property (readonly, nonatomic) id objectByParsingPropertyList;
@end

OF_ASSUME_NONNULL_END

Renamed and modified src/OFString+PropertyListValue.m [30b7ec9161] to src/OFString+PropertyListParsing.m [3c0b0b5b63].

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
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







-
+











-
+







 * 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 "OFString+PropertyListValue.h"
#import "OFString+PropertyListParsing.h"
#import "OFArray.h"
#import "OFData.h"
#import "OFDate.h"
#import "OFDictionary.h"
#import "OFNumber.h"
#import "OFXMLAttribute.h"
#import "OFXMLElement.h"

#import "OFInvalidFormatException.h"
#import "OFUnsupportedVersionException.h"

int _OFString_PropertyListValue_reference;
int _OFString_PropertyListParsing_reference;

static id parseElement(OFXMLElement *element);

static OFArray *
parseArrayElement(OFXMLElement *element)
{
	OFMutableArray *ret = [OFMutableArray array];
121
122
123
124
125
126
127









128








129
130
131
132
133
134
135
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

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







+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+







{
	return [OFNumber numberWithDouble: element.doubleValue];
}

static OFNumber *
parseIntegerElement(OFXMLElement *element)
{
	void *pool = objc_autoreleasePoolPush();
	OFString *stringValue;
	OFNumber *ret;

	stringValue = element.stringValue.stringByDeletingEnclosingWhitespaces;

	if ([stringValue hasPrefix: @"-"])
		ret = [OFNumber numberWithLongLong: stringValue.longLongValue];
	else
	return [OFNumber numberWithIntMax: element.decimalValue];
		ret = [OFNumber numberWithUnsignedLongLong:
		    stringValue.unsignedLongLongValue];

	[ret retain];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}

static id
parseElement(OFXMLElement *element)
{
	OFString *elementName;

156
157
158
159
160
161
162
163
164


165
166
167
168
169
170
171
172
173
174
175
176
177
178


179
180
181
182
183
184
185
186
187







-
-
+
+







		return parseRealElement(element);
	else if ([elementName isEqual: @"integer"])
		return parseIntegerElement(element);
	else
		@throw [OFInvalidFormatException exception];
}

@implementation OFString (PropertyListValue)
- (id)propertyListValue
@implementation OFString (PropertyListParsing)
- (id)objectByParsingPropertyList
{
	void *pool = objc_autoreleasePoolPush();
	OFXMLElement *rootElement = [OFXMLElement elementWithXMLString: self];
	OFXMLAttribute *versionAttribute;
	OFArray OF_GENERIC(OFXMLElement *) *elements;
	id ret;

Modified src/OFString+Serialization.m from [49a22d9861] to [0b468db6b6].

48
49
50
51
52
53
54
55

56
57
58
59
60
61
62
48
49
50
51
52
53
54

55
56
57
58
59
60
61
62







-
+







		@throw [OFInvalidArgumentException exception];
	}

	version = [root attributeForName: @"version"].stringValue;
	if (version == nil)
		@throw [OFInvalidArgumentException exception];

	if (version.decimalValue != 1)
	if (version.unsignedLongLongValue != 1)
		@throw [OFUnsupportedVersionException
		    exceptionWithVersion: version];

	elements = [root elementsForNamespace: OF_SERIALIZATION_NS];

	if (elements.count != 1)
		@throw [OFInvalidArgumentException exception];

Modified src/OFString.h from [18fc9bbd71] to [7689800b1d].

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
203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
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
203
204







-
+






-
+


-
+


-
+






-
+


-
-
-
-
-
-
-
-
-
-
-
-
-
-
+







 * @note This only considers spaces, tabs and newlines to be word delimiters!
 *	 Also note that this might change in the future to all word delimiters
 *	 specified by Unicode!
 */
@property (readonly, nonatomic) OFString *capitalizedString;

/*!
 * @brief The decimal value of the string as an `intmax_t`.
 * @brief The decimal value of the string as a `long long`.
 *
 * Leading and trailing whitespaces are ignored.
 *
 * If the string contains any non-number characters, an
 * @ref OFInvalidFormatException is thrown.
 *
 * If the number is too big to fit into an `intmax_t`, an
 * If the number is too big to fit into a `long long`, an
 * @ref OFOutOfRangeException is thrown.
 */
@property (readonly, nonatomic) intmax_t decimalValue;
@property (readonly, nonatomic) long long longLongValue;

/*!
 * @brief The hexadecimal value of the string as an `uintmax_t`.
 * @brief The decimal value of the string as an `unsigned long long`.
 *
 * Leading and trailing whitespaces are ignored.
 *
 * If the string contains any non-number characters, an
 * @ref OFInvalidFormatException is thrown.
 *
 * If the number is too big to fit into an `uintmax_t`, an
 * If the number is too big to fit into an `unsigned long long`, an
 * @ref OFOutOfRangeException is thrown.
 */
@property (readonly, nonatomic) uintmax_t hexadecimalValue;

/*!
 * @brief The octal value of the string as an `uintmax_t`.
 *
 * Leading and trailing whitespaces are ignored.
 *
 * If the string contains any non-number characters, an
 * @ref OFInvalidFormatException is thrown.
 *
 * If the number is too big to fit into an `uintmax_t`, an
 * @ref OFOutOfRangeException is thrown.
 */
@property (readonly, nonatomic) uintmax_t octalValue;
@property (readonly, nonatomic) unsigned long long unsignedLongLongValue;

/*!
 * @brief The float value of the string as a float.
 *
 * If the string contains any non-number characters, an
 * @ref OFInvalidFormatException is thrown.
 */
1021
1022
1023
1024
1025
1026
1027







































1028
1029
1030
1031
1032
1033
1034
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







 * @brief Creates a substring with the specified range.
 *
 * @param range The range of the substring
 * @return The substring as a new autoreleased OFString
 */
- (OFString *)substringWithRange: (of_range_t)range;

/*!
 * @brief The value of the string in the specified base as a `long long`.
 *
 * Leading and trailing whitespaces are ignored.
 *
 * If the string contains any non-number characters, an
 * @ref OFInvalidFormatException is thrown.
 *
 * If the number is too big to fit into a `long long`, an
 * @ref OFOutOfRangeException is thrown.
 *
 * @param base The base to use. If the base is 0, base 16 is assumed if the
 * 	       string starts with 0x (after stripping white spaces). If the
 * 	       string starts with 0, base 8 is assumed. Otherwise, base 10 is
 * 	       assumed.
 * @return The value of the string in the specified base
 */
- (long long)longLongValueWithBase: (int)base;

/*!
 * @brief The value of the string in the specified base as an
 *	  `unsigned long long`.
 *
 * Leading and trailing whitespaces are ignored.
 *
 * If the string contains any non-number characters, an
 * @ref OFInvalidFormatException is thrown.
 *
 * If the number is too big to fit into an `unsigned long long`, an
 * @ref OFOutOfRangeException is thrown.
 *
 * @param base The base to use. If the base is 0, base 16 is assumed if the
 * 	       string starts with 0x (after stripping white spaces). If the
 * 	       string starts with 0, base 8 is assumed. Otherwise, base 10 is
 * 	       assumed.
 * @return The value of the string in the specified base
 */
- (unsigned long long)unsignedLongLongValueWithBase: (int)base;

/*!
 * @brief Creates a new string by appending another string.
 *
 * @param string The string to append
 * @return A new, autoreleased OFString with the specified string appended
 */
- (OFString *)stringByAppendingString: (OFString *)string;
1250
1251
1252
1253
1254
1255
1256
1257

1258
1259
1260
1261

1262
1263
1264
1265
1266
1267
1268
1276
1277
1278
1279
1280
1281
1282

1283
1284
1285
1286

1287
1288
1289
1290
1291
1292
1293
1294







-
+



-
+








OF_ASSUME_NONNULL_END

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

#if defined(__OBJC__) && !defined(NSINTEGER_DEFINED) && !__has_feature(modules)

Modified src/OFString.m from [e1b9c425c7] to [ed5bfcb060].

13
14
15
16
17
18
19

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







+







 * 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"

#include <ctype.h>
#include <errno.h>
#include <math.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#if defined(HAVE_STRTOF_L) || defined(HAVE_STRTOD_L)
122
123
124
125
126
127
128
129

130
131
132
133

134
135
136
137
138
139
140
123
124
125
126
127
128
129

130
131
132
133

134
135
136
137
138
139
140
141







-
+



-
+







    size_t, bool);

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

void
986
987
988
989
990
991
992
993

994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011

1012
1013
1014
1015
1016
1017
1018
987
988
989
990
991
992
993

994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011

1012
1013
1014
1015
1016
1017
1018
1019







-
+

















-
+







				   encoding: OF_STRING_ENCODING_UTF_8];
}

- (instancetype)initWithContentsOfFile: (OFString *)path
			      encoding: (of_string_encoding_t)encoding
{
	char *tmp;
	uintmax_t fileSize;
	unsigned long long fileSize;

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFFile *file = nil;

		@try {
			fileSize = [[OFFileManager defaultManager]
			    attributesOfItemAtPath: path].fileSize;
		} @catch (OFRetrieveItemAttributesFailedException *e) {
			@throw [OFOpenItemFailedException
			    exceptionWithPath: path
					 mode: @"r"
					errNo: e.errNo];
		}

		objc_autoreleasePoolPop(pool);

# if UINTMAX_MAX > SIZE_MAX
# if ULLONG_MAX > SIZE_MAX
		if (fileSize > SIZE_MAX)
			@throw [OFOutOfRangeException exception];
#endif

		/*
		 * We need one extra byte for the terminating zero if we want
		 * to use -[initWithUTF8StringNoCopy:length:freeWhenDone:].
2309
2310
2311
2312
2313
2314
2315
2316

2317
2318
2319
2320
2321

2322
2323

2324
2325
2326
2327
2328



2329
2330

2331
2332
2333
2334


2335

2336
2337
2338
2339
2340
2341


2342
2343
2344


2345
2346
2347
2348

2349
2350
2351
2352





2353
2354

2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365

2366
2367
2368
2369
2370

2371
2372

2373
2374
2375
2376
2377



2378
2379

2380
2381
2382

2383
2384
2385
2386
2387

2388
2389
2390

2391
2392
2393
2394
2395
2396
2397

2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413

2414
2415
2416

2417
2418
2419


2420
2421
2422
2423
2424

2425
2426
2427

2428
2429

2430
2431
2432
2433

2434
2435

2436
2437
2438
2439
2440


2441
2442
2443
2444
2445

2446
2447
2448

2449
2450
2451
2452

2453
2454
2455

2456
2457
2458
2459
2460
2461
2462

2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507

2508
2509
2510
2511
2512



2513
2514
2515
2516

2517

2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557

2558
2559
2560
2561
2562
2563



2564
2565
2566

2567

2568
2569
2570
2571
2572
2573
2574
2310
2311
2312
2313
2314
2315
2316

2317
2318




2319


2320





2321
2322
2323


2324




2325
2326

2327
2328





2329
2330



2331
2332




2333
2334



2335
2336
2337
2338
2339


2340




2341
2342
2343
2344
2345
2346

2347
2348




2349


2350





2351
2352
2353


2354



2355





2356



2357



2358



2359
















2360



2361



2362
2363

2364
2365


2366



2367


2368




2369


2370





2371
2372





2373



2374




2375



2376







2377






2378
2379
2380
2381
2382
2383
2384
2385
2386


2387
2388
2389
2390
2391
2392
2393
2394

2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410



2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424

2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435


2436
2437
2438
2439
2440
2441
2442
2443

2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459



2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473

2474
2475
2476
2477
2478
2479
2480
2481







-
+

-
-
-
-
+
-
-
+
-
-
-
-
-
+
+
+
-
-
+
-
-
-
-
+
+
-
+

-
-
-
-
-
+
+
-
-
-
+
+
-
-
-
-
+

-
-
-
+
+
+
+
+
-
-
+
-
-
-
-






-
+

-
-
-
-
+
-
-
+
-
-
-
-
-
+
+
+
-
-
+
-
-
-
+
-
-
-
-
-
+
-
-
-
+
-
-
-

-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
-
-
-
+
+
-


-
-
+
-
-
-
+
-
-
+
-
-
-
-
+
-
-
+
-
-
-
-
-
+
+
-
-
-
-
-
+
-
-
-
+
-
-
-
-
+
-
-
-
+
-
-
-
-
-
-
-
+
-
-
-
-
-
-









-
-








-
















-
-
-
+





+
+
+




+
-
+










-
-








-
















-
-
-
+






+
+
+



+
-
+







	[array makeImmutable];

	objc_autoreleasePoolPop(pool);

	return array;
}

- (intmax_t)decimalValue
- (long long)longLongValue
{
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = self.characters;
	size_t i = 0, length = self.length;
	intmax_t value = 0;
	return [self longLongValueWithBase: 10];
	bool expectWhitespace = false;

}
	while (length > 0 && of_ascii_isspace(*characters)) {
		characters++;
		length--;
	}


- (long long)longLongValueWithBase: (int)base
{
	if (length == 0) {
		objc_autoreleasePoolPop(pool);
	void *pool = objc_autoreleasePoolPush();
		return 0;
	}

	if (characters[0] == '-' || characters[0] == '+')
	const char *UTF8String = self.UTF8String;
	char *endPointer = NULL;
		i++;
	long long value;

	for (; i < length; i++) {
		if (expectWhitespace) {
			if (of_ascii_isspace(characters[i]))
				continue;

	errno = 0;
	value = strtoll(UTF8String, &endPointer, base);
			@throw [OFInvalidFormatException exception];
		}


	if ((value == LLONG_MIN || value == LLONG_MAX) && errno == ERANGE)
		if (characters[i] >= '0' && characters[i] <= '9') {
			if (INTMAX_MAX / 10 < value ||
			    INTMAX_MAX - value * 10 < characters[i] - '0')
				@throw [OFOutOfRangeException exception];
		@throw [OFOutOfRangeException exception];

			value = (value * 10) + (characters[i] - '0');
		} else if (of_ascii_isspace(characters[i]))
			expectWhitespace = true;
	/* Check if there are any invalid chars left */
	if (endPointer != NULL)
		for (; *endPointer != '\0'; endPointer++)
			/* Use isspace since strtoll uses the same. */
			if (!isspace((unsigned char)*endPointer))
		else
			@throw [OFInvalidFormatException exception];
				@throw [OFInvalidFormatException exception];
	}

	if (characters[0] == '-')
		value *= -1;

	objc_autoreleasePoolPop(pool);

	return value;
}

- (uintmax_t)hexadecimalValue
- (unsigned long long)unsignedLongLongValue
{
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = self.characters;
	size_t i = 0, length = self.length;
	uintmax_t value = 0;
	return [self unsignedLongLongValueWithBase: 10];
	bool expectWhitespace = false, foundValue = false;

}
	while (length > 0 && of_ascii_isspace(*characters)) {
		characters++;
		length--;
	}


- (unsigned long long)unsignedLongLongValueWithBase: (int)base
{
	if (length == 0) {
		objc_autoreleasePoolPop(pool);
	void *pool = objc_autoreleasePoolPush();
		return 0;
	}

	const char *UTF8String = self.UTF8String;
	if (length >= 2 && characters[0] == '0' && characters[1] == 'x')
		i = 2;
	else if (length >= 1 && (characters[0] == 'x' || characters[0] == '$'))
		i = 1;

	char *endPointer = NULL;
	for (; i < length; i++) {
		uintmax_t newValue;

	unsigned long long value;
		if (expectWhitespace) {
			if (of_ascii_isspace(characters[i]))
				continue;

			@throw [OFInvalidFormatException exception];
		}

	/* Use isspace since strtoull uses the same. */
		if (characters[i] >= '0' && characters[i] <= '9') {
			newValue = (value << 4) | (characters[i] - '0');
			foundValue = true;
		} else if (characters[i] >= 'A' && characters[i] <= 'F') {
			newValue = (value << 4) | (characters[i] - 'A' + 10);
			foundValue = true;
		} else if (characters[i] >= 'a' && characters[i] <= 'f') {
			newValue = (value << 4) | (characters[i] - 'a' + 10);
			foundValue = true;
		} else if (characters[i] == 'h' ||
		    of_ascii_isspace(characters[i])) {
			expectWhitespace = true;
			continue;
		} else
			@throw [OFInvalidFormatException exception];

	while (isspace((unsigned char)*UTF8String))
		if (newValue < value)
			@throw [OFOutOfRangeException exception];

		UTF8String++;
		value = newValue;
	}


	if (*UTF8String == '-')
	if (!foundValue)
		@throw [OFInvalidFormatException exception];

	objc_autoreleasePoolPop(pool);

	errno = 0;
	return value;
}

	value = strtoull(UTF8String, &endPointer, base);
- (uintmax_t)octalValue
{

	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = self.characters;
	size_t i = 0, length = self.length;
	uintmax_t value = 0;
	if (value == ULLONG_MAX && errno == ERANGE)
	bool expectWhitespace = false;

		@throw [OFOutOfRangeException exception];
	while (length > 0 && of_ascii_isspace(*characters)) {
		characters++;
		length--;
	}


	/* Check if there are any invalid chars left */
	if (length == 0) {
		objc_autoreleasePoolPop(pool);
		return 0;
	}

	if (endPointer != NULL)
	for (; i < length; i++) {
		uintmax_t newValue;

		for (; *endPointer != '\0'; endPointer++)
		if (expectWhitespace) {
			if (of_ascii_isspace(characters[i]))
				continue;

			/* Use isspace since strtoull uses the same. */
			@throw [OFInvalidFormatException exception];
		}

			if (!isspace((unsigned char)*endPointer))
		if (characters[i] >= '0' && characters[i] <= '7')
			newValue = (value << 3) | (characters[i] - '0');
		else if (of_ascii_isspace(characters[i])) {
			expectWhitespace = true;
			continue;
		} else
			@throw [OFInvalidFormatException exception];
				@throw [OFInvalidFormatException exception];

		if (newValue < value)
			@throw [OFOutOfRangeException exception];

		value = newValue;
	}

	objc_autoreleasePoolPop(pool);

	return value;
}

- (float)floatValue
{
	void *pool = objc_autoreleasePoolPush();

#if defined(OF_AMIGAOS_M68K) || defined(OF_MORPHOS)
	OFString *stripped = self.stringByDeletingEnclosingWhitespaces;

	if ([stripped caseInsensitiveCompare: @"INF"] == OF_ORDERED_SAME ||
	    [stripped caseInsensitiveCompare: @"INFINITY"] == OF_ORDERED_SAME)
		return INFINITY;
	if ([stripped caseInsensitiveCompare: @"-INF"] == OF_ORDERED_SAME ||
	    [stripped caseInsensitiveCompare: @"-INFINITY"] == OF_ORDERED_SAME)
		return -INFINITY;
#endif

#ifdef HAVE_STRTOF_L
	const char *UTF8String = self.UTF8String;
#else
	/*
	 * If we have no strtof_l, we have no other choice but to replace "."
	 * with the locale's decimal point.
	 */
	OFString *decimalPoint = [OFLocale decimalPoint];
	const char *UTF8String = [self
	    stringByReplacingOccurrencesOfString: @"."
				      withString: decimalPoint].UTF8String;
#endif
	char *endPointer = NULL;
	float value;

	while (of_ascii_isspace(*UTF8String))
		UTF8String++;

	errno = 0;
#ifdef HAVE_STRTOF_L
	value = strtof_l(UTF8String, &endPointer, cLocale);
#else
	value = strtof(UTF8String, &endPointer);
#endif

	if (value == HUGE_VALF && errno == ERANGE)
		@throw [OFOutOfRangeException exception];

	/* Check if there are any invalid chars left */
	if (endPointer != NULL)
		for (; *endPointer != '\0'; endPointer++)
			/* Use isspace since strtof uses the same. */
			if (!of_ascii_isspace(*endPointer))
			if (!isspace((unsigned char)*endPointer))
				@throw [OFInvalidFormatException exception];

	objc_autoreleasePoolPop(pool);

	return value;
}

- (double)doubleValue
{
	void *pool = objc_autoreleasePoolPush();

#if defined(OF_AMIGAOS_M68K) || defined(OF_MORPHOS)
	OFString *stripped = self.stringByDeletingEnclosingWhitespaces;

	if ([stripped caseInsensitiveCompare: @"INF"] == OF_ORDERED_SAME ||
	    [stripped caseInsensitiveCompare: @"INFINITY"] == OF_ORDERED_SAME)
		return INFINITY;
	if ([stripped caseInsensitiveCompare: @"-INF"] == OF_ORDERED_SAME ||
	    [stripped caseInsensitiveCompare: @"-INFINITY"] == OF_ORDERED_SAME)
		return -INFINITY;
#endif

#ifdef HAVE_STRTOD_L
	const char *UTF8String = self.UTF8String;
#else
	/*
	 * If we have no strtod_l, we have no other choice but to replace "."
	 * with the locale's decimal point.
	 */
	OFString *decimalPoint = [OFLocale decimalPoint];
	const char *UTF8String = [self
	    stringByReplacingOccurrencesOfString: @"."
				      withString: decimalPoint].UTF8String;
#endif
	char *endPointer = NULL;
	double value;

	while (of_ascii_isspace(*UTF8String))
		UTF8String++;

	errno = 0;
#ifdef HAVE_STRTOD_L
	value = strtod_l(UTF8String, &endPointer, cLocale);
#else
	value = strtod(UTF8String, &endPointer);
#endif

	if (value == HUGE_VAL && errno == ERANGE)
		@throw [OFOutOfRangeException exception];

	/* Check if there are any invalid chars left */
	if (endPointer != NULL)
		for (; *endPointer != '\0'; endPointer++)
			/* Use isspace since strtod uses the same. */
			if (!of_ascii_isspace(*endPointer))
			if (!isspace((unsigned char)*endPointer))
				@throw [OFInvalidFormatException exception];

	objc_autoreleasePoolPop(pool);

	return value;
}

Modified src/OFSystemInfo.m from [0f92abda7c] to [4e15025453].

148
149
150
151
152
153
154
155

156
157
158
159
160
161
162
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162







-
+







#if defined(OF_IOS) || defined(OF_MACOS)
# ifdef OF_HAVE_FILES
	void *pool = objc_autoreleasePoolPush();

	@try {
		OFDictionary *propertyList = [OFString stringWithContentsOfFile:
		    @"/System/Library/CoreServices/SystemVersion.plist"]
		    .propertyListValue;
		    .objectByParsingPropertyList;

		operatingSystemVersion = [[propertyList
		    objectForKey: @"ProductVersion"] copy];
	} @finally {
		objc_autoreleasePoolPop(pool);
	}
# endif

Modified src/OFTarArchiveEntry.h from [77a315dfd8] to [c15723d4d0].

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
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







-
-
-
+
+
+




-
+











-
+




-
+




-
+




-
+







 * @class OFTarArchiveEntry OFTarArchiveEntry.h ObjFW/OFTarArchiveEntry.h
 *
 * @brief A class which represents an entry of a tar archive.
 */
@interface OFTarArchiveEntry: OFObject <OFCopying, OFMutableCopying>
{
	OFString *_fileName;
	uint32_t _mode;
	uint64_t _size;
	uint32_t _UID, _GID;
	unsigned long _mode;
	unsigned long long _size;
	unsigned long _UID, _GID;
	OFDate *_modificationDate;
	of_tar_archive_entry_type_t _type;
	OFString *_Nullable _targetFileName;
	OFString *_Nullable _owner, *_Nullable _group;
	uint32_t _deviceMajor, _deviceMinor;
	unsigned long _deviceMajor, _deviceMinor;
	OF_RESERVE_IVARS(4)
}

/*!
 * @brief The file name of the entry.
 */
@property (readonly, copy, nonatomic) OFString *fileName;

/*!
 * @brief The mode of the entry.
 */
@property (readonly, nonatomic) uint32_t mode;
@property (readonly, nonatomic) unsigned long mode;

/*!
 * @brief The UID of the owner.
 */
@property (readonly, nonatomic) uint32_t UID;
@property (readonly, nonatomic) unsigned long UID;

/*!
 * @brief The GID of the group.
 */
@property (readonly, nonatomic) uint32_t GID;
@property (readonly, nonatomic) unsigned long GID;

/*!
 * @brief The size of the file.
 */
@property (readonly, nonatomic) uint64_t size;
@property (readonly, nonatomic) unsigned long long size;

/*!
 * @brief The date of the last modification of the file.
 */
@property (readonly, retain, nonatomic) OFDate *modificationDate;

/*!
116
117
118
119
120
121
122
123

124
125
126
127
128

129
130
131
132
133
134
135
116
117
118
119
120
121
122

123
124
125
126
127

128
129
130
131
132
133
134
135







-
+




-
+







 * @brief The group of the file.
 */
@property OF_NULLABLE_PROPERTY (readonly, copy, nonatomic) OFString *group;

/*!
 * @brief The device major (if the file is a device).
 */
@property (readonly, nonatomic) uint32_t deviceMajor;
@property (readonly, nonatomic) unsigned long deviceMajor;

/*!
 * @brief The device major (if the file is a device).
 */
@property (readonly, nonatomic) uint32_t deviceMinor;
@property (readonly, nonatomic) unsigned long deviceMinor;

/*!
 * @brief Creates a new OFTarArchiveEntry with the specified file name.
 *
 * @param fileName The file name for the OFTarArchiveEntry
 * @return A new, autoreleased OFTarArchiveEntry
 */

Modified src/OFTarArchiveEntry.m from [aa73e544ea] to [5e09222260].

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
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







-
-
+
+
+

-
+








-
-
+
+








	memcpy(buffer, [string cStringWithEncoding: encoding], cStringLength);

	for (size_t i = cStringLength; i < length; i++)
		buffer[i] = '\0';
}

static uintmax_t
octalValueFromBuffer(const unsigned char *buffer, size_t length, uintmax_t max)
static unsigned long long
octalValueFromBuffer(const unsigned char *buffer, size_t length,
    unsigned long long max)
{
	uintmax_t value = 0;
	unsigned long long value = 0;

	if (length == 0)
		return 0;

	if (buffer[0] == 0x80) {
		for (size_t i = 1; i < length; i++)
			value = (value << 8) | buffer[i];
	} else
		value = stringFromBuffer(buffer, length,
		    OF_STRING_ENCODING_ASCII).octalValue;
		value = [stringFromBuffer(buffer, length,
		    OF_STRING_ENCODING_ASCII) unsignedLongLongValueWithBase: 8];

	if (value > max)
		@throw [OFOutOfRangeException exception];

	return value;
}

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105








106
107
108
109

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130




131
132
133
134
135
136
137
92
93
94
95
96
97
98








99
100
101
102
103
104
105
106
107
108
109

110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127




128
129
130
131
132
133
134
135
136
137
138







-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+



-
+

















-
-
-
-
+
+
+
+







	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFString *targetFileName;

		_fileName = [stringFromBuffer(header, 100, encoding) copy];
		_mode = (uint32_t)octalValueFromBuffer(
		    header + 100, 8, UINT32_MAX);
		_UID = (uint32_t)octalValueFromBuffer(
		    header + 108, 8, UINT32_MAX);
		_GID = (uint32_t)octalValueFromBuffer(
		    header + 116, 8, UINT32_MAX);
		_size = (uint64_t)octalValueFromBuffer(
		    header + 124, 12, UINT64_MAX);
		_mode = (unsigned long)octalValueFromBuffer(
		    header + 100, 8, ULONG_MAX);
		_UID = (unsigned long)octalValueFromBuffer(
		    header + 108, 8, ULONG_MAX);
		_GID = (unsigned long)octalValueFromBuffer(
		    header + 116, 8, ULONG_MAX);
		_size = (unsigned long long)octalValueFromBuffer(
		    header + 124, 12, ULLONG_MAX);
		_modificationDate = [[OFDate alloc]
		    initWithTimeIntervalSince1970:
		    (of_time_interval_t)octalValueFromBuffer(
		    header + 136, 12, UINTMAX_MAX)];
		    header + 136, 12, ULLONG_MAX)];
		_type = header[156];

		targetFileName = stringFromBuffer(header + 157, 100, encoding);
		if (targetFileName.length > 0)
			_targetFileName = [targetFileName copy];

		if (_type == '\0')
			_type = OF_TAR_ARCHIVE_ENTRY_TYPE_FILE;

		if (memcmp(header + 257, "ustar\0" "00", 8) == 0) {
			OFString *prefix;

			_owner = [stringFromBuffer(header + 265, 32, encoding)
			    copy];
			_group = [stringFromBuffer(header + 297, 32, encoding)
			    copy];

			_deviceMajor = (uint32_t)octalValueFromBuffer(
			    header + 329, 8, UINT32_MAX);
			_deviceMinor = (uint32_t)octalValueFromBuffer(
			    header + 337, 8, UINT32_MAX);
			_deviceMajor = (unsigned long)octalValueFromBuffer(
			    header + 329, 8, ULONG_MAX);
			_deviceMinor = (unsigned long)octalValueFromBuffer(
			    header + 337, 8, ULONG_MAX);

			prefix = stringFromBuffer(header + 345, 155, encoding);
			if (prefix.length > 0) {
				OFString *fileName = [OFString
				    stringWithFormat: @"%@/%@",
						      prefix, _fileName];
				[_fileName release];
204
205
206
207
208
209
210
211

212
213
214
215
216

217
218
219
220
221

222
223
224
225
226

227
228
229
230
231
232
233
205
206
207
208
209
210
211

212
213
214
215
216

217
218
219
220
221

222
223
224
225
226

227
228
229
230
231
232
233
234







-
+




-
+




-
+




-
+







}

- (OFString *)fileName
{
	return _fileName;
}

- (uint32_t)mode
- (unsigned long)mode
{
	return _mode;
}

- (uint32_t)UID
- (unsigned long)UID
{
	return _UID;
}

- (uint32_t)GID
- (unsigned long)GID
{
	return _GID;
}

- (uint64_t)size
- (unsigned long long)size
{
	return _size;
}

- (OFDate *)modificationDate
{
	return _modificationDate;
249
250
251
252
253
254
255
256

257
258
259
260
261

262
263
264
265
266
267
268
250
251
252
253
254
255
256

257
258
259
260
261

262
263
264
265
266
267
268
269







-
+




-
+







}

- (OFString *)group
{
	return _group;
}

- (uint32_t)deviceMajor
- (unsigned long)deviceMajor
{
	return _deviceMajor;
}

- (uint32_t)deviceMinor
- (unsigned long)deviceMinor
{
	return _deviceMinor;
}

- (OFString *)description
{
	void *pool = objc_autoreleasePoolPush();
290
291
292
293
294
295
296
297

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
291
292
293
294
295
296
297

298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315

316
317
318
319
320
321
322
323







-
+

















-
+







	return [ret autorelease];
}

- (void)of_writeToStream: (OFStream *)stream
		encoding: (of_string_encoding_t)encoding
{
	unsigned char buffer[512];
	uint64_t modificationDate;
	unsigned long long modificationDate;
	uint16_t checksum = 0;

	stringToBuffer(buffer, _fileName, 100, encoding);
	stringToBuffer(buffer + 100,
	    [OFString stringWithFormat: @"%06" PRIo16 " ", _mode], 8,
	    OF_STRING_ENCODING_ASCII);
	stringToBuffer(buffer + 108,
	    [OFString stringWithFormat: @"%06" PRIo16 " ", _UID], 8,
	    OF_STRING_ENCODING_ASCII);
	stringToBuffer(buffer + 116,
	    [OFString stringWithFormat: @"%06" PRIo16 " ", _GID], 8,
	    OF_STRING_ENCODING_ASCII);
	stringToBuffer(buffer + 124,
	    [OFString stringWithFormat: @"%011" PRIo64 " ", _size], 12,
	    OF_STRING_ENCODING_ASCII);
	modificationDate = _modificationDate.timeIntervalSince1970;
	stringToBuffer(buffer + 136,
	    [OFString stringWithFormat: @"%011" PRIo64 " ", modificationDate],
	    [OFString stringWithFormat: @"%011llo", modificationDate],
	    12, OF_STRING_ENCODING_ASCII);

	/*
	 * During checksumming, the checksum field is expected to be set to 8
	 * spaces.
	 */
	memset(buffer + 148, ' ', 8);

Modified src/OFURL.m from [2524e037d6] to [a6ef5631a2].

484
485
486
487
488
489
490
491

492
493
494
495
496


497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512

513
514
515
516


517
518
519
520
521
522
523
484
485
486
487
488
489
490

491
492
493
494


495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511

512
513
514


515
516
517
518
519
520
521
522
523







-
+



-
-
+
+















-
+


-
-
+
+







				}

				portString = [OFString
				    stringWithUTF8String: tmp2
						  length: UTF8String - tmp2];

				if (portString.length == 0 ||
				    portString.decimalValue > 65535)
				    portString.unsignedLongLongValue > 65535)
					@throw [OFInvalidFormatException
					    exception];

				_port = [[OFNumber alloc] initWithUInt16:
				    (uint16_t)portString.decimalValue];
				_port = [[OFNumber alloc] initWithUnsignedShort:
				    portString.unsignedLongLongValue];
			} else if (*UTF8String != '\0')
				@throw [OFInvalidFormatException exception];

			isIPv6Host = true;
		} else if ((tmp2 = strchr(UTF8String, ':')) != NULL) {
			OFString *portString;

			*tmp2 = '\0';
			tmp2++;

			_URLEncodedHost = [[OFString alloc]
			    initWithUTF8String: UTF8String];

			portString = [OFString stringWithUTF8String: tmp2];

			if (portString.decimalValue > 65535)
			if (portString.unsignedLongLongValue > 65535)
				@throw [OFInvalidFormatException exception];

			_port = [[OFNumber alloc] initWithUInt16:
			    (uint16_t)portString.decimalValue];
			_port = [[OFNumber alloc] initWithUnsignedShort:
			    portString.unsignedLongLongValue];
		} else
			_URLEncodedHost = [[OFString alloc]
			    initWithUTF8String: UTF8String];

		if (!isIPv6Host)
			of_url_verify_escaped(_URLEncodedHost,
			    [OFCharacterSet URLHostAllowedCharacterSet]);

Modified src/OFXMLNode.h from [d1608da1d3] to [fb7dfbb539].

37
38
39
40
41
42
43
44

45
46

47
48
49

50
51

52
53
54
55
56
57
58
37
38
39
40
41
42
43

44
45

46
47
48

49
50

51
52
53
54
55
56
57
58







-
+

-
+


-
+

-
+







 *
 * For an @ref OFXMLElement, setting it removes all children and creates a
 * single child with the specified string value.
 */
@property (nonatomic, copy) OFString *stringValue;

/*!
 * @brief The contents of the receiver as a decimal value.
 * @brief The contents of the receiver as a `long long` value.
 */
@property (readonly, nonatomic) intmax_t decimalValue;
@property (readonly, nonatomic) long long longLongValue;

/*!
 * @brief The contents of the receiver as a hexadecimal value.
 * @brief The contents of the receiver as an `unsigned long long` value.
 */
@property (readonly, nonatomic) uintmax_t hexadecimalValue;
@property (readonly, nonatomic) unsigned long long unsignedLongLongValue;

/*!
 * @brief The contents of the receiver as a float value.
 */
@property (readonly, nonatomic) float floatValue;

/*!
85
86
87
88
89
90
91


























92
93
94
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



 * @param indentation The indentation for the XML string
 * @param level The level of indentation
 * @return An OFString representing the OFXMLNode as an XML string with
 *	   indentation
 */
- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
				 level: (unsigned int)level;

/*!
 * @brief The contents of the receiver as a `long long` value in the specified
 *	  base.
 *
 * @param base The base to use. If the base is 0, base 16 is assumed if the
 * 	       string starts with 0x (after stripping white spaces). If the
 * 	       string starts with 0, base 8 is assumed. Otherwise, base 10 is
 * 	       assumed.
 * @return The contents of the receiver as a `long long` value in the specified
 *	   base
 */
- (long long)longLongValueWithBase: (int)base;

/*!
 * @brief The contents of the receiver as an `unsigned long long` value in the
 *	  specified base.
 *
 * @param base The base to use. If the base is 0, base 16 is assumed if the
 * 	       string starts with 0x (after stripping white spaces). If the
 * 	       string starts with 0, base 8 is assumed. Otherwise, base 10 is
 * 	       assumed.
 * @return The contents of the receiver as an `unsigned long long` value in the
 * 	   specified base
 */
- (unsigned long long)unsignedLongLongValueWithBase: (int)base;
@end

OF_ASSUME_NONNULL_END

Modified src/OFXMLNode.m from [8f7acafb9c] to [089c365f8a].

42
43
44
45
46
47
48
49

50
51

52
53




54


55
56






57
58
59
60
61
62
63
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







-
+

-
+


+
+
+
+
-
+
+

-
+
+
+
+
+
+







}

- (void)setStringValue: (OFString *)stringValue
{
	OF_UNRECOGNIZED_SELECTOR
}

- (intmax_t)decimalValue
- (long long)longLongValue
{
	return self.stringValue.decimalValue;
	return self.stringValue.longLongValue;
}

- (long long)longLongValueWithBase: (int)base
{
	return [self.stringValue longLongValueWithBase: base];
}
- (uintmax_t)hexadecimalValue

- (unsigned long long)unsignedLongLongValue
{
	return self.stringValue.hexadecimalValue;
	return self.stringValue.unsignedLongLongValue;
}

- (unsigned long long)unsignedLongLongValueWithBase: (int)base
{
	return [self.stringValue unsignedLongLongValueWithBase: base];
}

- (float)floatValue
{
	return self.stringValue.floatValue;
}

Modified src/bridge/Info.plist.in from [8dcff1a319] to [41c8e4dc54].

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22









-
+












<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleExecutable</key>
	<string>ObjFWBridge</string>
	<key>CFBundleName</key>
	<string>ObjFWBridge</string>
	<key>CFBundleIdentifier</key>
	<string>zone.heap.objfw.bridge</string>
	<string>im.nil.objfw.bridge</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundlePackageType</key>
	<string>FMWK</string>
	<key>CFBundleVersion</key>
	<string>@BUNDLE_VERSION@</string>
	<key>CFBundleShortVersionString</key>
	<string>@BUNDLE_SHORT_VERSION@</string>
	<key>MinimumOSVersion</key>
	<string>9.0</string>
</dict>
</plist>

Added src/runtime/Info.plist.in version [0388a9733c].























1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleExecutable</key>
	<string>ObjFWRT</string>
	<key>CFBundleName</key>
	<string>ObjFWRT</string>
	<key>CFBundleIdentifier</key>
	<string>im.nil.objfw.rt</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundlePackageType</key>
	<string>FMWK</string>
	<key>CFBundleVersion</key>
	<string>@BUNDLE_VERSION@</string>
	<key>CFBundleShortVersionString</key>
	<string>@BUNDLE_SHORT_VERSION@</string>
	<key>MinimumOSVersion</key>
	<string>9.0</string>
</dict>
</plist>

Modified src/runtime/Makefile from [578f05e231] to [0941bab434].

1
2
3
4
5

6
7
8
9
10
11
12
1
2
3
4
5
6
7
8
9
10
11
12
13





+







include ../../extra.mk

SUBDIRS = lookup-asm
SUBDIRS_AFTER = ${LINKLIB}
CLEAN = amiga-library-functable.inc inline.h
DISTCLEAN = Info.plist

SHARED_LIB = ${OBJFWRT_SHARED_LIB}
STATIC_LIB = ${OBJFWRT_STATIC_LIB}
FRAMEWORK = ${OBJFWRT_FRAMEWORK}
AMIGA_LIB = ${OBJFWRT_AMIGA_LIB}
LIB_MAJOR = ${OBJFWRT_LIB_MAJOR}
LIB_MINOR = ${OBJFWRT_LIB_MINOR}

Modified src/socket.m from [fb89efec65] to [0757bca949].

372
373
374
375
376
377
378
379

380
381
382
383
384
385
386
387
388

389
390

391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406

407
408
409
410
411
412

413
414
415
416
417
418
419
372
373
374
375
376
377
378

379
380
381
382
383
384
385
386
387

388
389

390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405

406
407
408
409
410
411

412
413
414
415
416
417
418
419







-
+








-
+

-
+















-
+





-
+








	if (components.count != 4)
		@throw [OFInvalidFormatException exception];

	addr = 0;

	for (OFString *component in components) {
		intmax_t number;
		unsigned long long number;

		if (component.length == 0)
			@throw [OFInvalidFormatException exception];

		if ([component indexOfCharacterFromSet:
		    whitespaceCharacterSet] != OF_NOT_FOUND)
			@throw [OFInvalidFormatException exception];

		number = component.decimalValue;
		number = component.unsignedLongLongValue;

		if (number < 0 || number > UINT8_MAX)
		if (number > UINT8_MAX)
			@throw [OFInvalidFormatException exception];

		addr = (addr << 8) | (number & 0xFF);
	}

	addrIn->sin_addr.s_addr = OF_BSWAP32_IF_LE(addr);

	objc_autoreleasePoolPop(pool);

	return ret;
}

static uint16_t
parseIPv6Component(OFString *component)
{
	uintmax_t number;
	unsigned long long number;

	if ([component indexOfCharacterFromSet:
	    [OFCharacterSet whitespaceCharacterSet]] != OF_NOT_FOUND)
		@throw [OFInvalidFormatException exception];

	number = component.hexadecimalValue;
	number = [component unsignedLongLongValueWithBase: 16];

	if (number > UINT16_MAX)
		@throw [OFInvalidFormatException exception];

	return (uint16_t)number;
}

Modified tests/Info.plist.in from [f12e2c6ff1] to [90a9f008a2].

9
10
11
12
13
14
15
16

17
18

19
20
21
22
23
24
25
9
10
11
12
13
14
15

16
17

18
19
20
21
22
23
24
25







-
+

-
+







	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleVersion</key>
	<string>@PACKAGE_VERSION@</string>
	<string>@BUNDLE_VERSION@</string>
	<key>CFBundleShortVersionString</key>
	<string>@PACKAGE_VERSION@</string>
	<string>@BUNDLE_SHORT_VERSION@</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
	<key>UILaunchStoryboardName</key>
	<string>LaunchScreen</string>
	<key>UIMainStoryboardFile</key>
	<string>Main</string>
	<key>UIRequiredDeviceCapabilities</key>

Modified tests/Makefile from [5e05094c6b] to [198bd5cd10].

1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

16
17
18
19
20
21
22













+

-







include ../extra.mk

SUBDIRS = ${TESTPLUGIN}

CLEAN = EBOOT.PBP		\
	boot.dol		\
	${PROG_NOINST}.arm9	\
	${PROG_NOINST}.nds
DISTCLEAN = Info.plist

PROG_NOINST = tests${PROG_SUFFIX}
STATIC_LIB_NOINST = ${TESTS_STATIC_LIB}
SRCS = ForwardingTests.m		\
       OFASN1DERParsingTests.m		\
       OFASN1DERRepresentationTests.m	\
       OFASN1DERValueTests.m		\
       OFArrayTests.m			\
       ${OF_BLOCK_TESTS_M}		\
       OFCharacterSetTests.m		\
       OFDataTests.m			\
       OFDateTests.m			\
       OFDictionaryTests.m		\
       OFInvocationTests.m		\

Renamed and modified tests/OFASN1DERValueTests.m [668efc201f] to tests/OFASN1DERParsingTests.m [dd4c3da7d2].

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
98

99
100

101
102
103

104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124



125
126
127
128



129
130
131
132
133
134

135
136
137
138



139
140
141
142
143
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
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
203







204
205
206
207



208
209
210
211



212
213
214
215
216
217

218
219
220
221



222
223
224
225
226


227
228


229

230

231
232


233

234
235
236
237
238






239
240
241
242



243
244
245
246



247
248
249
250



251
252
253
254
255
256

257
258
259
260



261
262
263
264
265
266


267
268
269
270
271
272
273
274





275
276
277
278
279
280

281
282
283
284



285
286
287
288



289
290
291
292



293
294
295
296
297
298
299
300

301
302
303
304
305

306
307
308

309
310

311
312
313
314
315



316
317
318
319
320

321
322
323
324
325

326
327
328

329
330
331

332
333
334
335
336
337

338
339
340
341



342
343
344
345
346

347
348
349
350
351
352


353
354
355
356

357
358
359
360




361
362
363
364
365

366
367
368
369
370
371

372
373
374
375



376
377
378
379
380
381


382
383
384
385
386
387
388
389





390
391
392
393
394

395
396
397
398
399
400

401
402
403
404



405
406
407
408
409
410


411
412
413
414
415
416
417
418





419
420
421
422
423

424
425
426
427
428
429

430
431
432
433



434
435
436
437
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
98
99
100
101
102

103
104
105


106
107
108
109
110
111
112

113
114

115
116
117

118
119
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
137


138
139
140
141
142


143
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
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
203
204

205
206


207
208
209

210
211


212
213
214
215

216
217







218
219
220
221
222
223
224
225
226


227
228
229
230
231


232
233
234
235
236
237
238
239

240
241
242


243
244
245
246
247
248
249

250
251
252

253
254
255
256

257
258

259
260
261
262





263
264
265
266
267
268
269
270


271
272
273
274
275


276
277
278
279
280


281
282
283
284
285
286
287
288

289
290
291


292
293
294
295
296
297
298


299
300
301
302
303
304




305
306
307
308
309
310
311
312
313
314

315
316
317


318
319
320
321
322


323
324
325
326
327


328
329
330
331
332
333
334
335
336
337

338
339
340
341
342

343
344
345

346
347

348
349
350
351


352
353
354
355
356
357
358

359
360
361
362
363

364
365
366

367
368
369

370
371
372
373
374
375

376
377
378


379
380
381
382
383
384
385

386
387
388
389
390


391
392
393
394
395
396
397




398
399
400
401
402
403
404
405

406
407
408
409
410
411

412
413
414


415
416
417
418
419
420
421


422
423
424
425
426
427




428
429
430
431
432
433
434
435
436

437
438
439
440
441
442

443
444
445


446
447
448
449
450
451
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







-
+

-
-
+
+










+
-
+

-
+


-
-
+
+
+


-
-
+
+
+


-
-
+
+
+


-
-
+
+
+




+
-
+

+
-
+

+
-
+

+
-
+

+
-
-
-
-
-
+
+
+
+
+
+


-
-
+
+
+


-
-
+
+
+


-
-
+
+
+





-
+


-
-
+
+
+




-
+

-
+


-
+









-
+









-
-
+
+
+


-
-
+
+
+





-
+


-
-
+
+
+




-
-
-
+
+
+




+
-
-
-
-
+
+
+
+
-
-
+





-
+


-
-
+
+
+




+
-
+


-
-
+
+
+




-
+

-
-
+
+

-
+

-
-
+
+

-
+

-
-
+
+


-
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+


-
-
+
+
+


-
-
+
+
+





-
+


-
-
+
+
+




-
+
+

-
+
+

+
-
+

-
+
+

+
-
-
-
-
-
+
+
+
+
+
+


-
-
+
+
+


-
-
+
+
+


-
-
+
+
+





-
+


-
-
+
+
+




-
-
+
+




-
-
-
-
+
+
+
+
+





-
+


-
-
+
+
+


-
-
+
+
+


-
-
+
+
+







-
+




-
+


-
+

-
+



-
-
+
+
+




-
+




-
+


-
+


-
+





-
+


-
-
+
+
+




-
+




-
-
+
+




+
-
-
-
-
+
+
+
+




-
+





-
+


-
-
+
+
+




-
-
+
+




-
-
-
-
+
+
+
+
+




-
+





-
+


-
-
+
+
+




-
-
+
+




-
-
-
-
+
+
+
+
+




-
+





-
+


-
-
+
+
+




 * file.
 */

#include "config.h"

#import "TestsAppDelegate.h"

static OFString *module = @"OFData+ASN1DERValue";
static OFString *module = @"OFData+ASN1DERParsing";

@implementation TestsAppDelegate (OFASN1DERValueTests)
- (void)ASN1DERValueTests
@implementation TestsAppDelegate (OFASN1DERParsingTests)
- (void)ASN1DERParsingTests
{
	void *pool = objc_autoreleasePoolPush();
	OFASN1BitString *bitString;
	OFArray *array;
	OFSet *set;
	OFEnumerator *enumerator;

	/* Boolean */
	TEST(@"Parsing of boolean",
	    ![[[OFData dataWithItems: "\x01\x01\x00"
			       count: 3] objectByParsingASN1DER]
			       count: 3] ASN1DERValue] booleanValue] &&
	    booleanValue] &&
	    [[[OFData dataWithItems: "\x01\x01\xFF"
			      count: 3] ASN1DERValue] booleanValue])
			      count: 3] objectByParsingASN1DER] booleanValue])

	EXPECT_EXCEPTION(@"Detection of invalid boolean #1",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x01\x01\x01"
						       count: 3] ASN1DERValue])
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x01\x01\x01"
			     count: 3] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid boolean #2",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x01\x02\x00\x00"
						       count: 4] ASN1DERValue])
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x01\x02\x00\x00"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid boolean #3",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x01\x00"
						       count: 2] ASN1DERValue])
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x01\x00"
			     count: 2] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated boolean",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x01\x01"
						       count: 2] ASN1DERValue])
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x01\x01"
			     count: 2] objectByParsingASN1DER])

	/* Integer */
	TEST(@"Parsing of integer",
	    [[[OFData dataWithItems: "\x02\x00"
			      count: 2] objectByParsingASN1DER]
			      count: 2] ASN1DERValue] integerValue] == 0 &&
	    longLongValue] == 0 &&
	    [[[OFData dataWithItems: "\x02\x01\x01"
			      count: 3] objectByParsingASN1DER]
			      count: 3] ASN1DERValue] integerValue] == 1 &&
	    longLongValue] == 1 &&
	    [[[OFData dataWithItems: "\x02\x02\x01\x04"
			      count: 4] objectByParsingASN1DER]
			      count: 4] ASN1DERValue] integerValue] == 260 &&
	    longLongValue] == 260 &&
	    [[[OFData dataWithItems: "\x02\x01\xFF"
			      count: 3] objectByParsingASN1DER]
			      count: 3] ASN1DERValue] integerValue] == -1 &&
	    longLongValue] == -1 &&
	    [[[OFData dataWithItems: "\x02\x03\xFF\x00\x00"
			      count: 5] objectByParsingASN1DER]
			      count: 5] ASN1DERValue] integerValue] == -65536 &&
	    (uintmax_t)[[[OFData dataWithItems: "\x02\x09\x00\xFF\xFF\xFF\xFF"
						"\xFF\xFF\xFF\xFF"
					 count: 11] ASN1DERValue]
	    integerValue] == UINTMAX_MAX)
	    longLongValue] == -65536 &&
	    (unsigned long long)[[[OFData dataWithItems: "\x02\x09\x00\xFF\xFF"
							 "\xFF\xFF\xFF\xFF\xFF"
							 "\xFF"
						  count: 11]
	    objectByParsingASN1DER] longLongValue] == ULLONG_MAX)

	EXPECT_EXCEPTION(@"Detection of invalid integer #1",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x02\x02\x00\x00"
						       count: 4] ASN1DERValue])
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x02\x02\x00\x00"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid integer #2",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x02\x02\x00\x7F"
						       count: 4] ASN1DERValue])
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x02\x02\x00\x7F"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid integer #3",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x02\x02\xFF\x80"
						       count: 4] ASN1DERValue])
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x02\x02\xFF\x80"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of out of range integer",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x02\x09\x01"
				    "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
			     count: 11] ASN1DERValue])
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated integer",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x02\x02\x00"
						       count: 3] ASN1DERValue])
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x02\x02\x00"
			     count: 3] objectByParsingASN1DER])

	/* Bit string */
	TEST(@"Parsing of bit string",
	    (bitString = [[OFData dataWithItems: "\x03\x01\x00"
					  count: 3] ASN1DERValue]) &&
					  count: 3] objectByParsingASN1DER]) &&
	    [bitString.bitStringValue isEqual: [OFData dataWithItems: ""
					count: 0]] &&
							       count: 0]] &&
	    bitString.bitStringLength == 0 &&
	    (bitString = [[OFData dataWithItems: "\x03\x0D\x01Hello World\x80"
					  count: 15] ASN1DERValue]) &&
					  count: 15] objectByParsingASN1DER]) &&
	    [bitString.bitStringValue
	    isEqual: [OFData dataWithItems: "Hello World\x80"
				     count: 12]] &&
	    bitString.bitStringLength == 95 &&
	    (bitString = [[OFData dataWithItems: "\x03\x81\x80\x00xxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
						 "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
					  count: 131] ASN1DERValue]) &&
					 count: 131] objectByParsingASN1DER]) &&
	    [bitString.bitStringValue
	    isEqual: [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxx"
				     count: 127]] &&
	    bitString.bitStringLength == 127 * 8)

	EXPECT_EXCEPTION(@"Detection of invalid bit string #1",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x03\x00"
						       count: 2] ASN1DERValue])
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x03\x00"
			     count: 2] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid bit string #2",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x03\x01\x01"
						       count: 3] ASN1DERValue])
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x03\x01\x01"
			     count: 3] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of out of range bit string",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x03\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] ASN1DERValue])
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated bit string",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x03\x01"
						       count: 2] ASN1DERValue])
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x03\x01"
			     count: 2] objectByParsingASN1DER])

	/* Octet string */
	TEST(@"Parsing of octet string",
	    [[[[OFData dataWithItems: "\x04\x0CHello World!"
			      count: 14] ASN1DERValue] octetStringValue]
	    isEqual: [OFData dataWithItems: "Hello World!"
				     count: 12]] &&
			       count: 14] objectByParsingASN1DER]
	    octetStringValue] isEqual: [OFData dataWithItems: "Hello World!"
						       count: 12]] &&
	    [[[[OFData dataWithItems: "\x04\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxx"
			       count: 131] objectByParsingASN1DER]
			       count: 131] ASN1DERValue] octetStringValue]
	    isEqual: [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
	    octetStringValue] isEqual:
	    [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				   "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				   "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
					    "xxxxxxxxxxxxxxxxxxxxxxxxxx"
				     count: 128]])
			    count: 128]])

	EXPECT_EXCEPTION(@"Detection of out of range octet string",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x04\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] ASN1DERValue])
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated octet string",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x04\x01"
						       count: 2] ASN1DERValue])
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x04\x01"
			     count: 2] objectByParsingASN1DER])

	/* Null */
	TEST(@"Parsing of null",
	    [[[OFData dataWithItems: "\x05\x00"
			      count: 2] objectByParsingASN1DER]
			      count: 2] ASN1DERValue] isEqual: [OFNull null]])
	    isEqual: [OFNull null]])

	EXPECT_EXCEPTION(@"Detection of invalid null",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x05\x01\x00"
						       count: 3] ASN1DERValue])
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x05\x01\x00"
			     count: 3] objectByParsingASN1DER])

	/* Object Identifier */
	TEST(@"Parsing of Object Identifier",
	    (array = [[[OFData dataWithItems: "\x06\x01\x27"
				       count: 3] ASN1DERValue]
				       count: 3] objectByParsingASN1DER]
	    subidentifiers]) && array.count == 2 &&
	    [[array objectAtIndex: 0] uIntMaxValue] == 0 &&
	    [[array objectAtIndex: 1] uIntMaxValue] == 39 &&
	    [[array objectAtIndex: 0] unsignedLongLongValue] == 0 &&
	    [[array objectAtIndex: 1] unsignedLongLongValue] == 39 &&
	    (array = [[[OFData dataWithItems: "\x06\x01\x4F"
				       count: 3] ASN1DERValue]
				       count: 3] objectByParsingASN1DER]
	    subidentifiers]) && array.count == 2 &&
	    [[array objectAtIndex: 0] uIntMaxValue] == 1 &&
	    [[array objectAtIndex: 1] uIntMaxValue] == 39 &&
	    [[array objectAtIndex: 0] unsignedLongLongValue] == 1 &&
	    [[array objectAtIndex: 1] unsignedLongLongValue] == 39 &&
	    (array = [[[OFData dataWithItems: "\x06\x02\x88\x37"
				       count: 4] ASN1DERValue]
				       count: 4] objectByParsingASN1DER]
	    subidentifiers]) && array.count == 2 &&
	    [[array objectAtIndex: 0] uIntMaxValue] == 2 &&
	    [[array objectAtIndex: 1] uIntMaxValue] == 999 &&
	    [[array objectAtIndex: 0] unsignedLongLongValue] == 2 &&
	    [[array objectAtIndex: 1] unsignedLongLongValue] == 999 &&
	    (array = [[[OFData dataWithItems: "\x06\x09\x2A\x86\x48\x86\xF7\x0D"
					      "\x01\x01\x0B"
				       count: 11] ASN1DERValue]
				       count: 11] objectByParsingASN1DER]
	    subidentifiers]) && array.count == 7 &&
	    [[array objectAtIndex: 0] uIntMaxValue] == 1 &&
	    [[array objectAtIndex: 1] uIntMaxValue] == 2 &&
	    [[array objectAtIndex: 2] uIntMaxValue] == 840 &&
	    [[array objectAtIndex: 3] uIntMaxValue] == 113549 &&
	    [[array objectAtIndex: 4] uIntMaxValue] == 1 &&
	    [[array objectAtIndex: 5] uIntMaxValue] == 1 &&
	    [[array objectAtIndex: 6] uIntMaxValue] == 11)
	    [[array objectAtIndex: 0] unsignedLongLongValue] == 1 &&
	    [[array objectAtIndex: 1] unsignedLongLongValue] == 2 &&
	    [[array objectAtIndex: 2] unsignedLongLongValue] == 840 &&
	    [[array objectAtIndex: 3] unsignedLongLongValue] == 113549 &&
	    [[array objectAtIndex: 4] unsignedLongLongValue] == 1 &&
	    [[array objectAtIndex: 5] unsignedLongLongValue] == 1 &&
	    [[array objectAtIndex: 6] unsignedLongLongValue] == 11)

	EXPECT_EXCEPTION(@"Detection of invalid Object Identifier #1",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x06\x01\x81"
						       count: 3] ASN1DERValue])
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x06\x01\x81"
			     count: 3] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid Object Identifier #2",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x06\x02\x80\x01"
						       count: 4] ASN1DERValue])
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x06\x02\x80\x01"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of out of range Object Identifier",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x06\x0A\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
				    "\xFF\x7F"
			     count: 12] ASN1DERValue])
			     count: 12] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated Object Identifier",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x06\x02\x00"
						       count: 3] ASN1DERValue])
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x06\x02\x00"
			     count: 3] objectByParsingASN1DER])

	/* Enumerated */
	TEST(@"Parsing of enumerated",
	    [[[OFData dataWithItems: "\x0A\x00"
			      count: 2] ASN1DERValue] integerValue] == 0 &&
			     count: 2] objectByParsingASN1DER] longLongValue] ==
	    0 &&
	    [[[OFData dataWithItems: "\x0A\x01\x01"
			      count: 3] ASN1DERValue] integerValue] == 1 &&
			     count: 3] objectByParsingASN1DER] longLongValue] ==
	    1 &&
	    [[[OFData dataWithItems: "\x0A\x02\x01\x04"
			     count: 4] objectByParsingASN1DER] longLongValue] ==
			      count: 4] ASN1DERValue] integerValue] == 260 &&
	    260 &&
	    [[[OFData dataWithItems: "\x0A\x01\xFF"
			      count: 3] ASN1DERValue] integerValue] == -1 &&
			     count: 3] objectByParsingASN1DER] longLongValue] ==
	    -1 &&
	    [[[OFData dataWithItems: "\x0A\x03\xFF\x00\x00"
			     count: 5] objectByParsingASN1DER] longLongValue] ==
			      count: 5] ASN1DERValue] integerValue] == -65536 &&
	    (uintmax_t)[[[OFData dataWithItems: "\x0A\x09\x00\xFF\xFF\xFF\xFF"
						"\xFF\xFF\xFF\xFF"
					 count: 11] ASN1DERValue]
	    integerValue] == UINTMAX_MAX)
	    -65536 &&
	    (unsigned long long)[[[OFData dataWithItems: "\x0A\x09\x00\xFF\xFF"
							 "\xFF\xFF\xFF\xFF\xFF"
							 "\xFF"
						  count: 11]
	    objectByParsingASN1DER] longLongValue] == ULLONG_MAX)

	EXPECT_EXCEPTION(@"Detection of invalid enumerated #1",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x0A\x02\x00\x00"
						       count: 4] ASN1DERValue])
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x0A\x02\x00\x00"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid enumerated #2",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x0A\x02\x00\x7F"
						       count: 4] ASN1DERValue])
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x0A\x02\x00\x7F"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid enumerated #3",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x0A\x02\xFF\x80"
						       count: 4] ASN1DERValue])
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x0A\x02\xFF\x80"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of out of range enumerated",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x0A\x09\x01"
				    "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
			     count: 11] ASN1DERValue])
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated enumerated",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x0A\x02\x00"
						       count: 3] ASN1DERValue])
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x0A\x02\x00"
			     count: 3] objectByParsingASN1DER])

	/* UTF-8 string */
	TEST(@"Parsing of UTF-8 string",
	    [[[[OFData dataWithItems: "\x0C\x0EHällo Wörld!"
			       count: 16] ASN1DERValue] UTF8StringValue]
	    isEqual: @"Hällo Wörld!"] &&
			       count: 16] objectByParsingASN1DER]
	    UTF8StringValue] isEqual: @"Hällo Wörld!"] &&
	    [[[[OFData dataWithItems: "\x0C\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxx"
			       count: 131] ASN1DERValue] UTF8StringValue]
	    isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
		     @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
		     @"xxxxxxxxxxxxxxxx"])
			       count: 131] objectByParsingASN1DER]
	    UTF8StringValue] isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      @"xxxxxxxxxxx"])

	EXPECT_EXCEPTION(@"Detection of out of range UTF-8 string",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x0C\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] ASN1DERValue])
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated UTF-8 string",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x0C\x01"
						       count: 2] ASN1DERValue])
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x0C\x01"
			     count: 2] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated length",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x0C\x83\x01\x01"
						       count: 4] ASN1DERValue])
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x0C\x83\x01\x01"
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #1",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x0C\x81\x7F"
						       count: 3] ASN1DERValue])
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x0C\x81\x7F"
			     count: 3] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #2",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x0C\x82\x00\x80xxxxxxxxxxxxxxxxxxxxxxxxxx"
				    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				    "xxxxxxxxxxxxxxxxxx"
			     count: 132] ASN1DERValue])
			     count: 132] objectByParsingASN1DER])

	/* Sequence */
	TEST(@"Parsing of sequence",
	    (array = [[OFData dataWithItems: "\x30\x00"
				      count: 2] ASN1DERValue]) &&
				      count: 2] objectByParsingASN1DER]) &&
	    [array isKindOfClass: [OFArray class]] && array.count == 0 &&
	    (array = [[OFData dataWithItems: "\x30\x09\x02\x01\x7B\x0C\x04Test"
				      count: 11] ASN1DERValue]) &&
				      count: 11] objectByParsingASN1DER]) &&
	    [array isKindOfClass: [OFArray class]] && array.count == 2 &&
	    [[array objectAtIndex: 0] integerValue] == 123 &&
	    [[array objectAtIndex: 0] longLongValue] == 123 &&
	    [[[array objectAtIndex: 1] stringValue] isEqual: @"Test"])

	EXPECT_EXCEPTION(@"Detection of truncated sequence #1",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x30\x01"
						       count: 2] ASN1DERValue])
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x30\x01"
			     count: 2] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated sequence #2",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x30\x04\x02\x01\x01\x00\x00"
			     count: 7] ASN1DERValue])
			     count: 7] objectByParsingASN1DER])

	/* Set */
	TEST(@"Parsing of set",
	    (set = [[OFData dataWithItems: "\x31\x00"
				    count: 2] ASN1DERValue]) &&
				    count: 2] objectByParsingASN1DER]) &&
	    [set isKindOfClass: [OFSet class]] && set.count == 0 &&
	    (set = [[OFData dataWithItems: "\x31\x09\x02\x01\x7B\x0C\x04Test"
				    count: 11] ASN1DERValue]) &&
				    count: 11] objectByParsingASN1DER]) &&
	    [set isKindOfClass: [OFSet class]] && set.count == 2 &&
	    (enumerator = [set objectEnumerator]) &&
	    [[enumerator nextObject] integerValue] == 123 &&
	    [[enumerator nextObject] longLongValue] == 123 &&
	    [[[enumerator nextObject] stringValue] isEqual: @"Test"])

	EXPECT_EXCEPTION(@"Detection of invalid set",
	    OFInvalidFormatException,
	    [[OFData dataWithItems: "\x31\x06\x02\x01\x02\x02\x01\x01"
			     count: 8] ASN1DERValue])
			     count: 8] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated set #1",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x31\x01"
						       count: 2] ASN1DERValue])
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x31\x01"
			     count: 2] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated set #2",
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x31\x04\x02\x01\x01\x00\x00"
			     count: 7] ASN1DERValue])
			     count: 7] objectByParsingASN1DER])

	/* NumericString */
	TEST(@"Parsing of NumericString",
	    [[[[OFData dataWithItems: "\x12\x0B" "12345 67890"
			      count: 13] ASN1DERValue] numericStringValue]
	    isEqual: @"12345 67890"] &&
			       count: 13] objectByParsingASN1DER]
	    numericStringValue] isEqual: @"12345 67890"] &&
	    [[[[OFData dataWithItems: "\x12\x81\x80" "0000000000000000000000000"
				      "0000000000000000000000000000000000000000"
				      "0000000000000000000000000000000000000000"
				      "00000000000000000000000"
			       count: 131] objectByParsingASN1DER]
			       count: 131] ASN1DERValue] numericStringValue]
	    isEqual: @"00000000000000000000000000000000000000000000000000000000"
		     @"00000000000000000000000000000000000000000000000000000000"
		     @"0000000000000000"])
	    numericStringValue] isEqual: @"000000000000000000000000000000000000"
					 @"000000000000000000000000000000000000"
					 @"000000000000000000000000000000000000"
					 @"00000000000000000000"])

	EXPECT_EXCEPTION(@"Detection of invalid NumericString",
	    OFInvalidEncodingException,
	    [[OFData dataWithItems: "\x12\x02."
			     count: 4] ASN1DERValue])
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of out of range NumericString",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x12\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] ASN1DERValue])
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated NumericString",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x12\x01"
						       count: 2] ASN1DERValue])
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x12\x01"
			     count: 2] objectByParsingASN1DER])

	/* PrintableString */
	TEST(@"Parsing of PrintableString",
	    [[[[OFData dataWithItems: "\x13\x0CHello World."
			       count: 14] ASN1DERValue] printableStringValue]
	    isEqual: @"Hello World."] &&
			       count: 14] objectByParsingASN1DER]
	    printableStringValue] isEqual: @"Hello World."] &&
	    [[[[OFData dataWithItems: "\x13\x81\x80 '()+,-./:=?abcdefghijklmnop"
				      "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '()"
				      "+,-./:=?abcdefghijklmnopqrstuvwxyzABCDEF"
				      "GHIJKLMNOPQRSTUVWXYZ"
			       count: 131] ASN1DERValue] printableStringValue]
	    isEqual: @" '()+,-./:=?abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQR"
		     @"STUVWXYZ '()+,-./:=?abcdefghijklmnopqrstuvwxyzABCDEFGHIJ"
		     @"KLMNOPQRSTUVWXYZ"])
			       count: 131] objectByParsingASN1DER]
	    printableStringValue] isEqual: @" '()+,-./:=?abcdefghijklmnopqrstuv"
					   @"wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '()"
					   @"+,-./:=?abcdefghijklmnopqrstuvwxyz"
					   @"ABCDEFGHIJKLMNOPQRSTUVWXYZ"])

	EXPECT_EXCEPTION(@"Detection of invalid PrintableString",
	    OFInvalidEncodingException,
	    [[OFData dataWithItems: "\x13\x02;"
			     count: 4] ASN1DERValue])
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of out of range PrintableString",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x13\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] ASN1DERValue])
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated PrintableString",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x13\x01"
						       count: 2] ASN1DERValue])
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x13\x01"
			     count: 2] objectByParsingASN1DER])

	/* IA5String */
	TEST(@"Parsing of IA5String",
	    [[[[OFData dataWithItems: "\x16\x0CHello World!"
			       count: 14] ASN1DERValue] IA5StringValue]
	    isEqual: @"Hello World!"] &&
			       count: 14] objectByParsingASN1DER]
	    IA5StringValue] isEqual: @"Hello World!"] &&
	    [[[[OFData dataWithItems: "\x16\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				      "xxxxxxxxxxxxxxxxxxxx"
			       count: 131] ASN1DERValue] IA5StringValue]
	    isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
		     @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
		     @"xxxxxxxxxxxxxxxx"])
			       count: 131] objectByParsingASN1DER]
	    IA5StringValue] isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				     @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				     @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
				     @"xxxxxxxx"])

	EXPECT_EXCEPTION(@"Detection of invalid IA5String",
	    OFInvalidEncodingException,
	    [[OFData dataWithItems: "\x16\x02ä"
			     count: 4] ASN1DERValue])
			     count: 4] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of out of range IA5String",
	    OFOutOfRangeException,
	    [[OFData dataWithItems: "\x16\x89"
				    "\x01\x01\x01\x01\x01\x01\x01\x01\x01"
			     count: 11] ASN1DERValue])
			     count: 11] objectByParsingASN1DER])

	EXPECT_EXCEPTION(@"Detection of truncated IA5String",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x16\x01"
						       count: 2] ASN1DERValue])
	    OFTruncatedDataException,
	    [[OFData dataWithItems: "\x16\x01"
			     count: 2] objectByParsingASN1DER])

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/OFArrayTests.m from [52ca507d81] to [650205073d].

418
419
420
421
422
423
424
425
426


427
428

429
430
431
432
433
434
435
418
419
420
421
422
423
424


425
426
427

428
429
430
431
432
433
434
435







-
-
+
+

-
+







		return left;
	    }])
#endif

	TEST(@"-[valueForKey:]",
	    [[[arrayClass arrayWithObjects: @"foo", @"bar", @"quxqux", nil]
	    valueForKey: @"length"] isEqual:
	    [arrayClass arrayWithObjects: [OFNumber numberWithSize: 3],
	    [OFNumber numberWithSize: 3], [OFNumber numberWithSize: 6], nil]] &&
	    [arrayClass arrayWithObjects: [OFNumber numberWithInt: 3],
	    [OFNumber numberWithInt: 3], [OFNumber numberWithInt: 6], nil]] &&
	    [[[arrayClass arrayWithObjects: @"1", @"2", nil]
	    valueForKey: @"@count"] isEqual: [OFNumber numberWithSize: 2]])
	    valueForKey: @"@count"] isEqual: [OFNumber numberWithInt: 2]])

	m[0] = [mutableArrayClass arrayWithObjects:
	    [OFMutableURL URLWithString: @"http://foo.bar/"],
	    [OFMutableURL URLWithString: @"http://bar.qux/"],
	    [OFMutableURL URLWithString: @"http://qux.quxqux/"], nil];
	TEST(@"-[setValue:forKey:]",
	    R([m[0] setValue: [OFNumber numberWithShort: 1234]

Modified tests/OFDictionaryTests.m from [f19c5b9455] to [a25483183f].

178
179
180
181
182
183
184
185

186
187
188
189
190
191
192
178
179
180
181
182
183
184

185
186
187
188
189
190
191
192







-
+







	    [[mutDict objectForKey: keys[0]] isEqual: values[0]] &&
	    [[mutDict objectForKey: keys[1]] isEqual: values[1]] &&
	    [mutDict objectForKey: @"key3"] == nil)

	TEST(@"-[valueForKey:]",
	    [[mutDict valueForKey: keys[0]] isEqual: values[0]] &&
	    [[mutDict valueForKey: @"@count"] isEqual:
	    [OFNumber numberWithSize: 2]])
	    [OFNumber numberWithInt: 2]])

	EXPECT_EXCEPTION(@"Catching -[setValue:forKey:] on immutable "
	    @"dictionary", OFUndefinedKeyException,
	    [[dictionaryClass dictionary] setValue: @"x"
					    forKey: @"x"])

	TEST(@"-[containsObject:]",

Modified tests/OFJSONTests.m from [9395f43f69] to [dda895677f].

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
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







-
+













-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+

-
+

-
+

















-
+

-
+




	    [OFNumber numberWithInt: 0xF],
	    [OFNull null],
	    @"foo",
	    [OFNumber numberWithBool: false],
	    nil],
	    nil];

	TEST(@"-[JSONValue] #1", [s.JSONValue isEqual: d])
	TEST(@"-[objectByParsingJSON] #1", [s.objectByParsingJSON isEqual: d])

	TEST(@"-[JSONRepresentation]", [[d JSONRepresentation] isEqual:
	    @"{\"x\":[0.5,15,null,\"foo\",false],\"foo\":\"b\\na\\r\"}"])

	TEST(@"OF_JSON_REPRESENTATION_PRETTY",
	    [[d JSONRepresentationWithOptions: OF_JSON_REPRESENTATION_PRETTY]
	    isEqual: @"{\n\t\"x\": [\n\t\t0.5,\n\t\t15,\n\t\tnull,\n\t\t"
		     @"\"foo\",\n\t\tfalse\n\t],\n\t\"foo\": \"b\\na\\r\"\n}"])

	TEST(@"OF_JSON_REPRESENTATION_JSON5",
	    [[d JSONRepresentationWithOptions: OF_JSON_REPRESENTATION_JSON5]
	    isEqual: @"{x:[0.5,15,null,\"foo\",false],foo:\"b\\\na\\r\"}"])

	EXPECT_EXCEPTION(@"-[JSONValue] #2", OFInvalidJSONException,
	    [@"{" JSONValue])
	EXPECT_EXCEPTION(@"-[JSONValue] #3", OFInvalidJSONException,
	    [@"]" JSONValue])
	EXPECT_EXCEPTION(@"-[JSONValue] #4", OFInvalidJSONException,
	    [@"bar" JSONValue])
	EXPECT_EXCEPTION(@"-[JSONValue] #5", OFInvalidJSONException,
	    [@"[\"a\" \"b\"]" JSONValue])
	EXPECT_EXCEPTION(@"-[objectByParsingJSON] #2", OFInvalidJSONException,
	    [@"{" objectByParsingJSON])
	EXPECT_EXCEPTION(@"-[objectByParsingJSON] #3", OFInvalidJSONException,
	    [@"]" objectByParsingJSON])
	EXPECT_EXCEPTION(@"-[objectByParsingJSON] #4", OFInvalidJSONException,
	    [@"bar" objectByParsingJSON])
	EXPECT_EXCEPTION(@"-[objectByParsingJSON] #5", OFInvalidJSONException,
	    [@"[\"a\" \"b\"]" objectByParsingJSON])

	TEST(@"-[JSONValue] #6",
	TEST(@"-[objectByParsingJSON] #6",
	    [@"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
	    .JSONValue isEqual: [OFArray arrayWithObject:
	    .objectByParsingJSON isEqual: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject: [OFArray arrayWithObject:
	    [OFArray arrayWithObject:
	    [OFDictionary dictionary]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]])

	EXPECT_EXCEPTION(@"-[JSONValue] #7", OFInvalidJSONException,
	EXPECT_EXCEPTION(@"-[objectByParsingJSON] #7", OFInvalidJSONException,
	    [@"[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[{}]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]"
	    JSONValue])
	    objectByParsingJSON])

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/OFNumberTests.m from [dde130d271] to [ccb8cb8682].

23
24
25
26
27
28
29
30
31


32
33
34

35
36
37
38
39
40
41
42
43
44
23
24
25
26
27
28
29


30
31
32
33

34
35
36
37
38
39
40
41
42
43
44







-
-
+
+


-
+











@implementation TestsAppDelegate (OFNumberTests)
- (void)numberTests
{
	void *pool = objc_autoreleasePoolPush();
	OFNumber *num;

	TEST(@"+[numberWithIntMax:]",
	    (num = [OFNumber numberWithIntMax: 123456789]))
	TEST(@"+[numberWithLongLong:]",
	    (num = [OFNumber numberWithLongLong: 123456789]))

	TEST(@"-[isEqual:]",
	    [num isEqual: [OFNumber numberWithUInt32: 123456789]])
	    [num isEqual: [OFNumber numberWithLong: 123456789]])

	TEST(@"-[hash]", num.hash == 0x82D8BC42)

	TEST(@"-[charValue]", num.charValue == 21)

	TEST(@"-[doubleValue]", num.doubleValue == 123456789.L)

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/OFPropertyListTests.m from [709f5222a8] to [0566a8c454].

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
98

99
100

101
102
103

104
105

106
107
108

109
110


111
112
113

114
115


116
117
118
119
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

98
99

100
101
102

103
104

105
106
107

108
109

110
111
112
113

114
115

116
117
118
119
120
121







-
-
+
+

-
-
+
+

-
-
+
+





-
+



-
+


-
+

-
+


-
+

-
+


-
+

-
+


-
+

-
+
+


-
+

-
+
+




	    [OFDate dateWithTimeIntervalSince1970: 1521030896],
	    [OFNumber numberWithBool: true],
	    [OFNumber numberWithBool: false],
	    [OFNumber numberWithFloat: 12.25],
	    [OFNumber numberWithInt: -10],
	    nil];

	TEST(@"-[propertyListValue:] #1",
	    [PLIST1.propertyListValue isEqual: @"Hello"])
	TEST(@"-[objectByParsingPropertyList:] #1",
	    [PLIST1.objectByParsingPropertyList isEqual: @"Hello"])

	TEST(@"-[propertyListValue:] #2",
	    [PLIST2.propertyListValue isEqual: array])
	TEST(@"-[objectByParsingPropertyList:] #2",
	    [PLIST2.objectByParsingPropertyList isEqual: array])

	TEST(@"-[propertyListValue:] #3",
	    [PLIST3.propertyListValue isEqual:
	TEST(@"-[objectByParsingPropertyList:] #3",
	    [PLIST3.objectByParsingPropertyList isEqual:
	    [OFDictionary dictionaryWithKeysAndObjects:
	    @"array", array,
	    @"foo", @"bar",
	    nil]])

	EXPECT_EXCEPTION(@"-[propertyListValue] detecting unsupported version",
	EXPECT_EXCEPTION(@"Detecting unsupported version",
	    OFUnsupportedVersionException,
	    [[PLIST(@"<string/>") stringByReplacingOccurrencesOfString: @"1.0"
							    withString: @"1.1"]
	    propertyListValue])
	    objectByParsingPropertyList])

	EXPECT_EXCEPTION(
	    @"-[propertyListValue] detecting invalid format #1",
	    @"-[objectByParsingPropertyList] detecting invalid format #1",
	    OFInvalidFormatException,
	    [PLIST(@"<string x='b'/>") propertyListValue])
	    [PLIST(@"<string x='b'/>") objectByParsingPropertyList])

	EXPECT_EXCEPTION(
	    @"-[propertyListValue] detecting invalid format #2",
	    @"-[objectByParsingPropertyList] detecting invalid format #2",
	    OFInvalidFormatException,
	    [PLIST(@"<string xmlns='foo'/>") propertyListValue])
	    [PLIST(@"<string xmlns='foo'/>") objectByParsingPropertyList])

	EXPECT_EXCEPTION(
	    @"-[propertyListValue] detecting invalid format #3",
	    @"-[objectByParsingPropertyList] detecting invalid format #3",
	    OFInvalidFormatException,
	    [PLIST(@"<dict count='0'/>") propertyListValue])
	    [PLIST(@"<dict count='0'/>") objectByParsingPropertyList])

	EXPECT_EXCEPTION(
	    @"-[propertyListValue] detecting invalid format #4",
	    @"-[objectByParsingPropertyList] detecting invalid format #4",
	    OFInvalidFormatException,
	    [PLIST(@"<dict><key/><string/><key/></dict>") propertyListValue])
	    [PLIST(@"<dict><key/><string/><key/></dict>")
	    objectByParsingPropertyList])

	EXPECT_EXCEPTION(
	    @"-[propertyListValue] detecting invalid format #5",
	    @"-[objectByParsingPropertyList] detecting invalid format #5",
	    OFInvalidFormatException,
	    [PLIST(@"<dict><key x='x'/><string/></dict>") propertyListValue])
	    [PLIST(@"<dict><key x='x'/><string/></dict>")
	    objectByParsingPropertyList])

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/OFSetTests.m from [5ad06a7715] to [1aa6d32b7b].

274
275
276
277
278
279
280
281
282


283
284

285
286
287
288
289
290
291
274
275
276
277
278
279
280


281
282
283

284
285
286
287
288
289
290
291







-
-
+
+

-
+







	}

	TEST(@"Detection of mutation during Fast Enumeration", ok);

	TEST(@"-[valueForKey:]",
	    [(set1 = [[setClass setWithObjects: @"a", @"ab", @"abc", @"b", nil]
	    valueForKey: @"length"]) isEqual: [setClass setWithObjects:
	    [OFNumber numberWithSize: 1], [OFNumber numberWithSize: 2],
	    [OFNumber numberWithSize: 3], nil]] &&
	    [OFNumber numberWithInt: 1], [OFNumber numberWithInt: 2],
	    [OFNumber numberWithInt: 3], nil]] &&
	    [[set1 valueForKey: @"@count"] isEqual:
	    [OFNumber numberWithSize: 3]])
	    [OFNumber numberWithInt: 3]])

	objc_autoreleasePoolPop(pool);
}

- (void)setTests
{
	module = @"OFSet";

Modified tests/OFStringTests.m from [bf0332c491] to [1ca0b0e0e8].

1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077







1078
1079
1080
1081
1082
1083
1084





1085
1086
1087
1088
1089










1090
1091
1092
1093
1094
1095
1096
1065
1066
1067
1068
1069
1070
1071






1072
1073
1074
1075
1076
1077
1078







1079
1080
1081
1082
1083
1084




1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101







-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+

-
-
-
-
+
+
+
+
+
+
+
+
+
+







	    [C(@"\\\\foo\\..\\bar\\qux").stringByStandardizingPath
	    isEqual: @"\\\\bar\\qux"] &&
	    [C(@"c:\\..\\asd").stringByStandardizingPath
	    isEqual: @"c:\\..\\asd"])
# endif
#endif

	TEST(@"-[decimalValue]",
	    C(@"1234").decimalValue == 1234 &&
	    C(@"\r\n+123  ").decimalValue == 123 &&
	    C(@"-500\t").decimalValue == -500 &&
	    C(@"\t\t\r\n").decimalValue == 0)

	TEST(@"-[longLongValue]",
	    C(@"1234").longLongValue == 1234 &&
	    C(@"\r\n+123  ").longLongValue == 123 &&
	    C(@"-500\t").longLongValue == -500 &&
	    [C(@"-0x10\t") longLongValueWithBase: 0] == -0x10 &&
	    C(@"\t\t\r\n").longLongValue == 0 &&
	    [C(@"123f") longLongValueWithBase: 16] == 0x123f &&
	TEST(@"-[hexadecimalValue]",
	    C(@"123f").hexadecimalValue == 0x123f &&
	    C(@"\t\n0xABcd\r").hexadecimalValue == 0xABCD &&
	    C(@"  xbCDE").hexadecimalValue == 0xBCDE &&
	    C(@"$CdEf").hexadecimalValue == 0xCDEF &&
	    C(@"\rFeh ").hexadecimalValue == 0xFE &&
	    C(@"\r\t").hexadecimalValue == 0)
	    [C(@"\t\n0xABcd\r") longLongValueWithBase: 0] == 0xABCD &&
	    [C(@"1234567") longLongValueWithBase: 8] == 01234567 &&
	    [C(@"\r\n0123") longLongValueWithBase: 0] == 0123 &&
	    [C(@"765\t") longLongValueWithBase: 8] == 0765 &&
	    [C(@"\t\t\r\n") longLongValueWithBase: 8] == 0)

	TEST(@"-[octalValue]",
	    C(@"1234567").octalValue == 01234567 &&
	    C(@"\r\n123").octalValue == 0123 &&
	    C(@"765\t").octalValue == 0765 && C(@"\t\t\r\n").octalValue == 0)
	TEST(@"-[unsignedLongLongValue]",
	    C(@"1234").unsignedLongLongValue == 1234 &&
	    C(@"\r\n+123  ").unsignedLongLongValue == 123 &&
	    C(@"\t\t\r\n").unsignedLongLongValue == 0 &&
	    [C(@"123f") unsignedLongLongValueWithBase: 16] == 0x123f &&
	    [C(@"\t\n0xABcd\r") unsignedLongLongValueWithBase: 0] == 0xABCD &&
	    [C(@"1234567") unsignedLongLongValueWithBase: 8] == 01234567 &&
	    [C(@"\r\n0123") unsignedLongLongValueWithBase: 0] == 0123 &&
	    [C(@"765\t") unsignedLongLongValueWithBase: 8] == 0765 &&
	    [C(@"\t\t\r\n") unsignedLongLongValueWithBase: 8] == 0)

	/*
	 * These test numbers can be generated without rounding if we have IEEE
	 * floating point numbers, thus we can use == on them.
	 */
	TEST(@"-[floatValue]",
	    C(@"\t-0.25 ").floatValue == -0.25 &&
1105
1106
1107
1108
1109
1110
1111
1112

1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132






1133
1134

1135
1136
1137

1138
1139
1140
1141



1142
1143
1144
1145
1146
1147
1148
1110
1111
1112
1113
1114
1115
1116

1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131






1132
1133
1134
1135
1136
1137


1138



1139




1140
1141
1142
1143
1144
1145
1146
1147
1148
1149







-
+














-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
-
-
-
+
-
-
-
-
+
+
+







#else
/* Android, Solaris, DJGPP and AmigaOS3 do not accept 0x for strtod() */
# if (!defined(OF_SOLARIS) || !defined(OF_X86)) && !defined(OF_AMIGAOS_M68K)
#  define INPUT @"\t-0.123456789 "
#  define EXPECTED -0.123456789
# else
/*
 * Solaris' strtod() has weird rounding on x86, but not on x86_64/
 * Solaris' strtod() has weird rounding on x86, but not on x86_64.
 * AmigaOS 3 with libnix has weird rounding as well.
 */
#  define INPUT @"\t-0.125 "
#  define EXPECTED -0.125
# endif
#endif
	TEST(@"-[doubleValue]",
	    INPUT.doubleValue == EXPECTED &&
	    C(@"\r\n\tINF\t\n").doubleValue == INFINITY &&
	    C(@"\r -INFINITY\n").doubleValue == -INFINITY &&
	    isnan(C(@"   NAN\t\t").doubleValue))
#undef INPUT
#undef EXPECTED

	EXPECT_EXCEPTION(@"Detect invalid characters in -[decimalValue] #1",
	    OFInvalidFormatException, [C(@"abc") decimalValue])
	EXPECT_EXCEPTION(@"Detect invalid characters in -[decimalValue] #2",
	    OFInvalidFormatException, [C(@"0a") decimalValue])
	EXPECT_EXCEPTION(@"Detect invalid characters in -[decimalValue] #3",
	    OFInvalidFormatException, [C(@"0 1") decimalValue])
	EXPECT_EXCEPTION(@"Detect invalid chars in -[longLongValue] #1",
	    OFInvalidFormatException, [C(@"abc") longLongValue])
	EXPECT_EXCEPTION(@"Detect invalid chars in -[longLongValue] #2",
	    OFInvalidFormatException, [C(@"0a") longLongValue])
	EXPECT_EXCEPTION(@"Detect invalid chars in -[longLongValue] #3",
	    OFInvalidFormatException, [C(@"0 1") longLongValue])

	EXPECT_EXCEPTION(@"Detect invalid chars in -[hexadecimalValue] #1",
	EXPECT_EXCEPTION(@"Detect invalid chars in -[longLongValue] #4",
	    OFInvalidFormatException, [C(@"0xABCDEFG") hexadecimalValue])
	EXPECT_EXCEPTION(@"Detect invalid chars in -[hexadecimalValue] #2",
	    OFInvalidFormatException, [C(@"0x") hexadecimalValue])
	    OFInvalidFormatException,
	EXPECT_EXCEPTION(@"Detect invalid chars in -[hexadecimalValue] #3",
	    OFInvalidFormatException, [C(@"$") hexadecimalValue])
	EXPECT_EXCEPTION(@"Detect invalid chars in -[hexadecimalValue] #4",
	    OFInvalidFormatException, [C(@"$ ") hexadecimalValue])
	    [C(@"0xABCDEFG") longLongValueWithBase: 0])
	EXPECT_EXCEPTION(@"Detect invalid chars in -[longLongValue] #5",
	    OFInvalidFormatException, [C(@"0x") longLongValueWithBase: 0])

	EXPECT_EXCEPTION(@"Detect invalid chars in -[floatValue] #1",
	    OFInvalidFormatException, [C(@"0.0a") floatValue])
	EXPECT_EXCEPTION(@"Detect invalid chars in -[floatValue] #2",
	    OFInvalidFormatException, [C(@"0 0") floatValue])
#ifdef HAVE_STRTOF_L
	/*
1162
1163
1164
1165
1166
1167
1168
1169

1170
1171

1172
1173

1174
1175

1176
1177
1178
1179

1180
1181
1182
1183
1184
1185
1186
1163
1164
1165
1166
1167
1168
1169

1170
1171

1172
1173

1174
1175

1176
1177
1178
1179

1180
1181
1182
1183
1184
1185
1186
1187







-
+

-
+

-
+

-
+



-
+







	 * Only do this if we have strtod_l, as the locale might allow the
	 * comma.
	 */
	EXPECT_EXCEPTION(@"Detect invalid chars in -[doubleValue] #3",
	    OFInvalidFormatException, [C(@"0,0") doubleValue])
#endif

	EXPECT_EXCEPTION(@"Detect out of range in -[decimalValue]",
	EXPECT_EXCEPTION(@"Detect out of range in -[longLongValue]",
	    OFOutOfRangeException,
	    [C(@"12345678901234567890123456789012345678901234567890"
	    [C(@"-12345678901234567890123456789012345678901234567890"
	       @"12345678901234567890123456789012345678901234567890")
	    decimalValue])
	    longLongValueWithBase: 16])

	EXPECT_EXCEPTION(@"Detect out of range in -[hexadecimalValue]",
	EXPECT_EXCEPTION(@"Detect out of range in -[unsignedLongLongValue]",
	    OFOutOfRangeException,
	    [C(@"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"
	       @"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF")
	    hexadecimalValue])
	    unsignedLongLongValueWithBase: 16])

	TEST(@"-[characters]", (ua = C(@"fööbär🀺").characters) &&
	    !memcmp(ua, ucstr + 1, sizeof(ucstr) - 8))

#ifdef OF_BIG_ENDIAN
# define SWAPPED_BYTE_ORDER OF_BYTE_ORDER_LITTLE_ENDIAN
#else

Modified tests/OFURLTests.m from [8b6c1d8b68] to [52cea266a3].

152
153
154
155
156
157
158
159
160


161
162
163
164
165
166
167
168
152
153
154
155
156
157
158


159
160

161
162
163
164
165
166
167







-
-
+
+
-








	TEST(@"-[user]", [u1.user isEqual: @"us:er"] && u4.user == nil)
	TEST(@"-[password]",
	    [u1.password isEqual: @"p@w"] && u4.password == nil)
	TEST(@"-[host]", [u1.host isEqual: @"ho:st"] &&
	    [u6.host isEqual: @"12:34::56:abcd"] &&
	    [u7.host isEqual: @"12:34::56:abcd"])
	TEST(@"-[port]", [u1.port isEqual: [OFNumber numberWithUInt16: 1234]] &&
	    [u4 port] == nil &&
	TEST(@"-[port]", u1.port.unsignedShortValue == 1234 &&
	    [u4 port] == nil && u7.port.unsignedShortValue == 234)
	    [u7.port isEqual: [OFNumber numberWithUInt16: 234]])
	TEST(@"-[path]",
	    [u1.path isEqual: @"/pa?th"] && [u4.path isEqual: @"/etc/passwd"])
	TEST(@"-[pathComponents]",
	    [u1.pathComponents isEqual:
	    [OFArray arrayWithObjects: @"/", @"pa?th", nil]] &&
	    [u4.pathComponents isEqual:
	    [OFArray arrayWithObjects: @"/", @"etc", @"passwd", nil]] &&

Modified tests/TestsAppDelegate.h from [9cb5b35481] to [0e4b40ac71].

66
67
68
69
70
71
72
73
74


75
76
77
78
79
80
81
66
67
68
69
70
71
72


73
74
75
76
77
78
79
80
81







-
-
+
+







	     inModule: (OFString *)module;
- (void)outputSuccess: (OFString *)test
	     inModule: (OFString *)module;
- (void)outputFailure: (OFString *)test
	     inModule: (OFString *)module;
@end

@interface TestsAppDelegate (OFASN1DERValueTests)
- (void)ASN1DERValueTests;
@interface TestsAppDelegate (OFASN1DERParsingTests)
- (void)ASN1DERParsingTests;
@end

@interface TestsAppDelegate (OFASN1DERRepresentationTests)
- (void)ASN1DERRepresentationTests;
@end

@interface TestsAppDelegate (OFArrayTests)

Modified tests/TestsAppDelegate.m from [3cf677c3a1] to [6a1c29e396].

376
377
378
379
380
381
382
383

384
385
386
387
388
389
390
376
377
378
379
380
381
382

383
384
385
386
387
388
389
390







-
+







	[self XMLNodeTests];
	[self XMLElementBuilderTests];
#ifdef OF_HAVE_FILES
	[self serializationTests];
#endif
	[self JSONTests];
	[self propertyListTests];
	[self ASN1DERValueTests];
	[self ASN1DERParsingTests];
	[self ASN1DERRepresentationTests];
#if defined(OF_HAVE_PLUGINS)
	[self pluginTests];
#endif
#ifdef OF_WINDOWS
	[self windowsRegistryKeyTests];
#endif

Modified tests/iOS.xcodeproj/project.pbxproj from [f9b1054ae0] to [feb9f04764].

302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329

330
331
332
333
334
335
336
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328

329
330
331
332
333
334
335
336







-
+



















-
+







				INFOPLIST_FILE = Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
				LIBRARY_SEARCH_PATHS = (
					"$(inherited)",
					"$(PROJECT_DIR)",
				);
				OTHER_LDFLAGS = "-ObjC";
				PRODUCT_BUNDLE_IDENTIFIER = zone.heap.objfw.tests;
				PRODUCT_BUNDLE_IDENTIFIER = im.nil.objfw.tests;
				PRODUCT_NAME = "$(TARGET_NAME)";
				TARGETED_DEVICE_FAMILY = "1,2";
			};
			name = Debug;
		};
		4BEBFB732013934E002E8710 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				CODE_SIGN_STYLE = Automatic;
				DEVELOPMENT_TEAM = MXKNFCKFL6;
				FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../src";
				INFOPLIST_FILE = Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
				LIBRARY_SEARCH_PATHS = (
					"$(inherited)",
					"$(PROJECT_DIR)",
				);
				OTHER_LDFLAGS = "-ObjC";
				PRODUCT_BUNDLE_IDENTIFIER = zone.heap.objfw.tests;
				PRODUCT_BUNDLE_IDENTIFIER = im.nil.objfw.tests;
				PRODUCT_NAME = "$(TARGET_NAME)";
				TARGETED_DEVICE_FAMILY = "1,2";
			};
			name = Release;
		};
/* End XCBuildConfiguration section */

Modified tests/plugin/Info.plist.in from [e94bac378f] to [bbe65d4bbd].

1
2
3
4
5
6
7
8
9
10

11
12
13
14
15
16
17
18
19
20
21
22
1
2
3
4
5
6
7
8
9

10
11
12
13
14
15
16
17
18
19
20
21
22









-
+












<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleExecutable</key>
	<string>TestPlugin</string>
	<key>CFBundleName</key>
	<string>TestPlugin</string>
	<key>CFBundleIdentifier</key>
	<string>zone.heap.objfw.testplugin</string>
	<string>im.nil.objfw.tests.plugin</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundlePackageType</key>
	<string>BNDL</string>
	<key>CFBundleVersion</key>
	<string>@BUNDLE_VERSION@</string>
	<key>CFBundleShortVersionString</key>
	<string>@BUNDLE_SHORT_VERSION@</string>
	<key>MinimumOSVersion</key>
	<string>9.0</string>
</dict>
</plist>

Modified tests/serialization.xml from [904cd48eb0] to [c1b84078b7].

13
14
15
16
17
18
19
20

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

20
21
22
23
24
25
26
27







-
+







    <object>
      <OFString>data</OFString>
    </object>
    <key>
      <OFArray>
        <OFString>Qu&quot;xbar
test</OFString>
        <OFNumber type='unsigned'>1234</OFNumber>
        <OFNumber type='signed'>1234</OFNumber>
        <OFNumber type='float'>40934a456d5cfaad</OFNumber>
        <OFMutableString>asd</OFMutableString>
        <OFDate>40934a456d5cfaad</OFDate>
      </OFArray>
    </key>
    <object>
      <OFString>Hello</OFString>

Modified utils/ofarc/LHAArchive.m from [b717d78c4a] to [da084987c7].

42
43
44
45
46
47
48



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







+
+
+







setPermissions(OFString *path, OFLHAArchiveEntry *entry)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
	OFNumber *mode = entry.mode;

	if (mode == nil)
		return;

	mode = [OFNumber numberWithUnsignedShort:
	    mode.unsignedShortValue & 0777];

	of_file_attributes_t attributes = [OFDictionary
	    dictionaryWithObject: mode
			  forKey: of_file_attribute_key_posix_permissions];

	[[OFFileManager defaultManager] setAttributes: attributes
					 ofItemAtPath: path];
141
142
143
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
177
178
179
180
181
182
183
184

185
186
187
188
189
190
191
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
177
178
179
180
181
182
183
184
185
186

187
188
189
190
191
192
193
194







-
-
-
-
-
-
-
+
+
+
+
+
+
+




-
-
-
-
-
-
-
+
+
+
+
+
+
+


















-
+







			    @"%" PRIu32, entry.uncompressedSize];
			OFString *CRC16 = [OFString stringWithFormat:
			    @"%04" PRIX16, entry.CRC16];

			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_compressed_size",
			    [@"["
			     @"    'Compressed: ',"
			     @"    ["
			     @"        {'size == 1': '1 byte'},"
			     @"        {'': '%[size] bytes'}"
			     @"    ]"
			     @"]" JSONValue],
			    @"["
			    @"    'Compressed: ',"
			    @"    ["
			    @"        {'size == 1': '1 byte'},"
			    @"        {'': '%[size] bytes'}"
			    @"    ]"
			    @"]".objectByParsingJSON,
			    @"size", compressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_uncompressed_size",
			    [@"["
			     @"    'Uncompressed: ',"
			     @"    ["
			     @"        {'size == 1': '1 byte'},"
			     @"        {'': '%[size] bytes'}"
			     @"    ]"
			     @"]" JSONValue],
			    @"["
			    @"    'Uncompressed: ',"
			    @"    ["
			    @"        {'size == 1': '1 byte'},"
			    @"        {'': '%[size] bytes'}"
			    @"    ]"
			    @"]".objectByParsingJSON,
			    @"size", uncompressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_compression_method",
			    @"Compression method: %[method]",
			    @"method", entry.compressionMethod)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_crc16",
			    @"CRC16: %[crc16]",
			    @"crc16", CRC16)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_date",
			    @"Date: %[date]",
			    @"date", date)];

			if (entry.mode != nil) {
				OFString *modeString = [OFString
				    stringWithFormat:
				    @"%" PRIo16, entry.mode.uInt16Value];
				    @"%ho", entry.mode.unsignedShortValue];

				[of_stdout writeString: @"\t"];
				[of_stdout writeLine: OF_LOCALIZED(@"list_mode",
				    @"Mode: %[mode]",
				    @"mode", modeString)];
			}
			if (entry.UID != nil) {
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
491

492

493
494
495
496
497
498
499
468
469
470
471
472
473
474

475
476
477
478
479
480
481

482
483

484
485
486
487
488
489
490
491
492
493
494
495

496
497
498
499
500
501
502
503







-
+






-
+

-
+










+
-
+







			    @"file", fileName)];

		attributes = [fileManager attributesOfItemAtPath: fileName];
		type = attributes.fileType;
		entry = [OFMutableLHAArchiveEntry entryWithFileName: fileName];

#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
		entry.mode = [OFNumber numberWithUInt16:
		entry.mode = [OFNumber numberWithUnsignedLong:
		    attributes.filePOSIXPermissions];
#endif
		entry.date = attributes.fileModificationDate;

#ifdef OF_FILE_MANAGER_SUPPORTS_OWNER
		entry.UID =
		    [OFNumber numberWithUInt16: attributes.filePOSIXUID];
		    [OFNumber numberWithUnsignedLong: attributes.filePOSIXUID];
		entry.GID =
		    [OFNumber numberWithUInt16: attributes.filePOSIXGID];
		    [OFNumber numberWithUnsignedLong: attributes.filePOSIXGID];
		entry.owner = attributes.fileOwner;
		entry.group = attributes.fileGroup;
#endif

		if ([type isEqual: of_file_type_directory])
			entry.compressionMethod = @"-lhd-";

		output = [_archive streamForWritingEntry: entry];

		if ([type isEqual: of_file_type_regular]) {
			unsigned long long written = 0;
			uintmax_t written = 0, size = attributes.fileSize;
			unsigned long long size = attributes.fileSize;
			int8_t percent = -1, newPercent;

			OFFile *input = [OFFile fileWithPath: fileName
							mode: @"r"];

			while (!input.atEndOfStream) {
				ssize_t length = [app

Modified utils/ofarc/TarArchive.m from [ed61f78528] to [3ca97fcaef].

31
32
33
34
35
36
37

38
39

40
41
42
43
44
45
46
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47







+

-
+








static OFArc *app;

static void
setPermissions(OFString *path, OFTarArchiveEntry *entry)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
	OFNumber *mode = [OFNumber numberWithUnsignedShort: entry.mode & 0777];
	of_file_attributes_t attributes = [OFDictionary
	    dictionaryWithObject: [OFNumber numberWithUInt16: entry.mode]
	    dictionaryWithObject: mode
			  forKey: of_file_attribute_key_posix_permissions];

	[[OFFileManager defaultManager] setAttributes: attributes
					 ofItemAtPath: path];
#endif
}

122
123
124
125
126
127
128
129
130
131
132
133
134
135







136
137
138
139
140
141
142
123
124
125
126
127
128
129







130
131
132
133
134
135
136
137
138
139
140
141
142
143







-
-
-
-
-
-
-
+
+
+
+
+
+
+







			OFString *UID = [OFString stringWithFormat:
			    @"%u", entry.UID];
			OFString *GID = [OFString stringWithFormat:
			    @"%u", entry.GID];

			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_size",
			    [@"["
			     @"    'Size: ',"
			     @"    ["
			     @"        {'size == 1': '1 byte'},"
			     @"        {'': '%[size] bytes'}"
			     @"    ]"
			     @"]" JSONValue],
			    @"["
			    @"    'Size: ',"
			    @"    ["
			    @"        {'size == 1': '1 byte'},"
			    @"        {'': '%[size] bytes'}"
			    @"    ]"
			    @"]".objectByParsingJSON,
			    @"size", size)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_mode",
			    @"Mode: %[mode]",
			    @"mode", mode)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(@"list_uid",

Modified utils/ofarc/ZIPArchive.m from [251b5d4973] to [4b4d3715d0].

40
41
42
43
44
45
46

47

48
49
50
51

52
53
54
55
56
57
58
40
41
42
43
44
45
46
47

48
49
50
51

52
53
54
55
56
57
58
59







+
-
+



-
+








static void
setPermissions(OFString *path, OFZIPArchiveEntry *entry)
{
#ifdef OF_FILE_MANAGER_SUPPORTS_PERMISSIONS
	if ((entry.versionMadeBy >> 8) ==
	    OF_ZIP_ARCHIVE_ENTRY_ATTR_COMPAT_UNIX) {
		OFNumber *mode = [OFNumber numberWithUnsignedShort:
		uint16_t mode = entry.versionSpecificAttributes >> 16;
		    (entry.versionSpecificAttributes >> 16) & 0777];
		of_file_attribute_key_t key =
		    of_file_attribute_key_posix_permissions;
		of_file_attributes_t attributes = [OFDictionary
		    dictionaryWithObject: [OFNumber numberWithUInt16: mode]
		    dictionaryWithObject: mode
				  forKey: key];

		[[OFFileManager defaultManager] setAttributes: attributes
						 ofItemAtPath: path];
	}
#endif
}
134
135
136
137
138
139
140
141
142
143
144
145
146
147







148
149
150
151
152
153
154
155
156
157
158







159
160
161
162
163
164
165
135
136
137
138
139
140
141







142
143
144
145
146
147
148
149
150
151
152







153
154
155
156
157
158
159
160
161
162
163
164
165
166







-
-
-
-
-
-
-
+
+
+
+
+
+
+




-
-
-
-
-
-
-
+
+
+
+
+
+
+







			    stringWithFormat: @"%08" PRIX32, entry.CRC32];
			OFString *modificationDate = [entry.modificationDate
			    localDateStringWithFormat: @"%Y-%m-%d %H:%M:%S"];

			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_compressed_size",
			    [@"["
			     @"    'Compressed: ',"
			     @"    ["
			     @"        {'size == 1': '1 byte'},"
			     @"        {'': '%[size] bytes'}"
			     @"    ]"
			     @"]" JSONValue],
			    @"["
			    @"    'Compressed: ',"
			    @"    ["
			    @"        {'size == 1': '1 byte'},"
			    @"        {'': '%[size] bytes'}"
			    @"    ]"
			    @"]".objectByParsingJSON,
			    @"size", compressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_uncompressed_size",
			    [@"["
			     @"    'Uncompressed: ',"
			     @"    ["
			     @"        {'size == 1': '1 byte'},"
			     @"        {'': '%[size] bytes'}"
			     @"    ]"
			     @"]" JSONValue],
			    @"["
			    @"    'Uncompressed: ',"
			    @"    ["
			    @"        {'size == 1': '1 byte'},"
			    @"        {'': '%[size] bytes'}"
			    @"    ]"
			    @"]".objectByParsingJSON,
			    @"size", uncompressedSize)];
			[of_stdout writeString: @"\t"];
			[of_stdout writeLine: OF_LOCALIZED(
			    @"list_compression_method",
			    @"Compression method: %[method]",
			    @"method", compressionMethod)];
			[of_stdout writeString: @"\t"];
417
418
419
420
421
422
423
424

425
426
427
428
429
430
431
418
419
420
421
422
423
424

425
426
427
428
429
430
431
432







-
+







	for (OFString *localFileName in files) {
		void *pool = objc_autoreleasePoolPush();
		OFArray OF_GENERIC (OFString *) *components;
		OFString *fileName;
		of_file_attributes_t attributes;
		bool isDirectory = false;
		OFMutableZIPArchiveEntry *entry;
		uintmax_t size;
		unsigned long long size;
		OFStream *output;

		components = localFileName.pathComponents;
		fileName = [components componentsJoinedByString: @"/"];

		attributes = [fileManager
		    attributesOfItemAtPath: localFileName];
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
455
456
457
458
459
460
461

462
463
464
465
466
467
468
469







-
+







		entry.modificationDate = attributes.fileModificationDate;

		[entry makeImmutable];

		output = [_archive streamForWritingEntry: entry];

		if (!isDirectory) {
			uintmax_t written = 0;
			unsigned long long written = 0;
			int8_t percent = -1, newPercent;

			OFFile *input = [OFFile fileWithPath: fileName
							mode: @"r"];

			while (!input.atEndOfStream) {
				ssize_t length = [app

Modified utils/ofhttp/OFHTTP.m from [da5c2f66e5] to [d4c7821db4].

24
25
26
27
28
29
30



31
32
33
34
35
36
37
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40







+
+
+







#import "OFFile.h"
#import "OFFileManager.h"
#import "OFHTTPClient.h"
#import "OFHTTPRequest.h"
#import "OFHTTPResponse.h"
#import "OFLocale.h"
#import "OFOptionsParser.h"
#ifdef OF_HAVE_PLUGINS
# import "OFPlugin.h"
#endif
#import "OFSandbox.h"
#import "OFStdIOStream.h"
#import "OFSystemInfo.h"
#import "OFTCPSocket.h"
#import "OFTLSSocket.h"
#import "OFURL.h"

65
66
67
68
69
70
71
72

73
74
75
76
77
78
79
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82







-
+







	bool _detectedFileName, _quiet, _verbose, _insecure;
	OFStream *_body;
	of_http_request_method_t _method;
	OFMutableDictionary *_clientHeaders;
	OFHTTPClient *_HTTPClient;
	char *_buffer;
	OFStream *_output;
	intmax_t _received, _length, _resumedFrom;
	unsigned long long _received, _length, _resumedFrom;
	ProgressBar *_progressBar;
}

- (void)downloadNextURL;
@end

OF_APPLICATION_DELEGATE(OFHTTP)
270
271
272
273
274
275
276











277
278
279
280
281
282
283
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297







+
+
+
+
+
+
+
+
+
+
+








	[fileName retain];
	objc_autoreleasePoolPop(pool);
	return [fileName autorelease];
}

@implementation OFHTTP
#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];

	@try {
		_method = OF_HTTP_REQUEST_METHOD_GET;

330
331
332
333
334
335
336

337

338
339
340
341
342
343
344
344
345
346
347
348
349
350
351

352
353
354
355
356
357
358
359







+
-
+







	if ([path isEqual: @"-"])
		_body = [of_stdin copy];
	else {
		_body = [[OFFile alloc] initWithPath: path
						mode: @"r"];

		@try {
			unsigned long long fileSize =
			uintmax_t fileSize = [[OFFileManager defaultManager]
			    [[OFFileManager defaultManager]
			    attributesOfItemAtPath: path].fileSize;

			contentLength =
			    [OFString stringWithFormat: @"%ju", fileSize];
			[_clientHeaders setObject: contentLength
					   forKey: @"Content-Length"];
		} @catch (OFRetrieveItemAttributesFailedException *e) {
372
373
374
375
376
377
378
379

380
381
382
383
384
385
386


387
388
389
390
391
392
393
387
388
389
390
391
392
393

394
395
396
397
398
399


400
401
402
403
404
405
406
407
408







-
+





-
-
+
+







- (void)setProxy: (OFString *)proxy
{
	@try {
		size_t pos = [proxy
		    rangeOfString: @":"
			  options: OF_STRING_SEARCH_BACKWARDS].location;
		OFString *host;
		intmax_t port;
		unsigned long long port;

		if (pos == OF_NOT_FOUND)
			@throw [OFInvalidFormatException exception];

		host = [proxy substringWithRange: of_range(0, pos)];
		port = [proxy substringWithRange:
		    of_range(pos + 1, proxy.length - pos - 1)].decimalValue;
		port = [proxy substringWithRange: of_range(pos + 1,
		    proxy.length - pos - 1)].unsignedLongLongValue;

		if (port > UINT16_MAX)
			@throw [OFOutOfRangeException exception];

		[OFTCPSocket setSOCKS5Host: host];
		[OFTCPSocket setSOCKS5Port: (uint16_t)port];
	} @catch (OFInvalidFormatException *e) {
717
718
719
720
721
722
723
724
725





726
727
728
729
730
731
732
732
733
734
735
736
737
738


739
740
741
742
743
744
745
746
747
748
749
750







-
-
+
+
+
+
+







		OFString *URL;

		[_progressBar stop];
		[_progressBar draw];
		[_progressBar release];
		_progressBar = nil;

		if (!_quiet)
			[of_stdout writeString: @"\n  Error!\n"];
		if (!_quiet) {
			[of_stdout writeString: @"\n  "];
			[of_stdout writeLine: OF_LOCALIZED(@"download_error",
			    @"Error!")];
		}

		URL = [_URLs objectAtIndex: _URLIndex - 1];
		[of_stderr writeLine: OF_LOCALIZED(
		    @"download_failed_exception",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  %[exception]",
		    @"prog", [OFApplication programName],
781
782
783
784
785
786
787
788

789
790
791
792
793
794
795
799
800
801
802
803
804
805

806
807
808
809
810
811
812
813







-
+








		[of_stdout writeFormat: @" ➜ %d\n", statusCode];

		if (type == nil)
			type = OF_LOCALIZED(@"type_unknown", @"unknown");

		if (lengthString != nil) {
			_length = lengthString.decimalValue;
			_length = lengthString.unsignedLongLongValue;

			if (_resumedFrom + _length >= GIBIBYTE) {
				lengthString = [OFString stringWithFormat:
				    @"%,.2f",
				    (float)(_resumedFrom + _length) / GIBIBYTE];
				lengthString = OF_LOCALIZED(@"size_gib",
				    @"%[num] GiB",
808
809
810
811
812
813
814
815
816
817
818
819
820






821
822
823
824
825
826
827
826
827
828
829
830
831
832






833
834
835
836
837
838
839
840
841
842
843
844
845







-
-
-
-
-
-
+
+
+
+
+
+







				lengthString = OF_LOCALIZED(@"size_kib",
				    @"%[num] KiB",
				    @"num", lengthString);
			} else {
				lengthString = [OFString stringWithFormat:
				    @"%jd", _resumedFrom + _length];
				lengthString = OF_LOCALIZED(@"size_bytes",
				    [@"["
				     @"    ["
				     @"        {'num == 1': '1 byte'},"
				     @"        {'': '%[num] bytes'}"
				     @"    ]"
				     @"]" JSONValue],
				    @"["
				    @"    ["
				    @"        {'num == 1': '1 byte'},"
				    @"        {'': '%[num] bytes'}"
				    @"    ]"
				    @"]".objectByParsingJSON,
				    @"num", lengthString);
			}
		} else
			lengthString =
			    OF_LOCALIZED(@"size_unknown", @"unknown");

		if (_verbose) {
1006
1007
1008
1009
1010
1011
1012

1013

1014
1015
1016
1017

1018
1019
1020

1021
1022
1023
1024
1025
1026
1027
1024
1025
1026
1027
1028
1029
1030
1031

1032
1033
1034
1035

1036
1037
1038

1039
1040
1041
1042
1043
1044
1045
1046







+
-
+



-
+


-
+







		_currentFileName = [_outputPath copy];

	if (_currentFileName == nil)
		_currentFileName = [URL.path.lastPathComponent copy];

	if (_continue) {
		@try {
			unsigned long long size =
			uintmax_t size = [[OFFileManager defaultManager]
			    [[OFFileManager defaultManager]
			    attributesOfItemAtPath: _currentFileName].fileSize;
			OFString *range;

			if (size > INTMAX_MAX)
			if (size > ULLONG_MAX)
				@throw [OFOutOfRangeException exception];

			_resumedFrom = (intmax_t)size;
			_resumedFrom = (unsigned long long)size;

			range = [OFString stringWithFormat: @"bytes=%jd-",
							    _resumedFrom];
			[clientHeaders setObject: range
					  forKey: @"Range"];
		} @catch (OFRetrieveItemAttributesFailedException *e) {
		}

Modified utils/ofhttp/ProgressBar.h from [5832428778] to [187685081a].

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
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







+
+



-
+





+
+


-
-
-
+
+
+




 * file.
 */

#import "OFObject.h"

@class OFDate;
@class OFTimer;

#define BPS_WINDOW_SIZE 10

@interface ProgressBar: OFObject
{
	intmax_t _received, _lastReceived, _length, _resumedFrom;
	unsigned long long _received, _lastReceived, _length, _resumedFrom;
	OFDate *_startDate, *_lastReceivedDate;
	OFTimer *_drawTimer, *_BPSTimer;
	bool _stopped;
	float _BPS;
	double _ETA;
	float _BPSWindow[BPS_WINDOW_SIZE];
	size_t _BPSWindowIndex, _BPSWindowLength;
}

- (instancetype)initWithLength: (intmax_t)length
		   resumedFrom: (intmax_t)resumedFrom;
- (void)setReceived: (intmax_t)received;
- (instancetype)initWithLength: (unsigned long long)length
		   resumedFrom: (unsigned long long)resumedFrom;
- (void)setReceived: (unsigned long long)received;
- (void)draw;
- (void)calculateBPSAndETA;
- (void)stop;
@end

Modified utils/ofhttp/ProgressBar.m from [813833df71] to [814de8c246].

29
30
31
32
33
34
35
36
37


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


36
37
38
39
40
41
42
43
44







-
-
+
+







#define GIBIBYTE (1024 * 1024 * 1024)
#define MEBIBYTE (1024 * 1024)
#define KIBIBYTE (1024)

#define UPDATE_INTERVAL 0.1

@implementation ProgressBar
- (instancetype)initWithLength: (intmax_t)length
		   resumedFrom: (intmax_t)resumedFrom
- (instancetype)initWithLength: (unsigned long long)length
		   resumedFrom: (unsigned long long)resumedFrom
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();

		_length = length;
74
75
76
77
78
79
80
81

82
83
84
85
86
87
88
74
75
76
77
78
79
80

81
82
83
84
85
86
87
88







-
+







	[_lastReceivedDate release];
	[_drawTimer release];
	[_BPSTimer release];

	[super dealloc];
}

- (void)setReceived: (intmax_t)received
- (void)setReceived: (unsigned long long)received
{
	_received = received;
}

- (void)_drawProgress
{
	float bars, percent;
200
201
202
203
204
205
206
207
208
209
210
211
212






213
214
215
216
217
218
219
200
201
202
203
204
205
206






207
208
209
210
211
212
213
214
215
216
217
218
219







-
-
-
-
-
-
+
+
+
+
+
+







		[of_stdout writeString: OF_LOCALIZED(@"progress_kib",
		    @"%[num] KiB",
		    @"num", num)];
	} else {
		OFString *num = [OFString stringWithFormat:
		    @"%jd", _resumedFrom + _received];
		[of_stdout writeString: OF_LOCALIZED(@"progress_bytes",
		    [@"["
		     @"    ["
		     @"        {'num == 1': '1 byte '},"
		     @"        {'': '%[num] bytes'}"
		     @"    ]"
		     @"]" JSONValue],
		    @"["
		    @"    ["
		    @"        {'num == 1': '1 byte '},"
		    @"        {'': '%[num] bytes'}"
		    @"    ]"
		    @"]".objectByParsingJSON,
		    @"num", num)];
	}

	[of_stdout writeString: @" "];

	if (_stopped)
		_BPS = (float)_received /
252
253
254
255
256
257
258

259

260









261
262
263
264
265
266
267
252
253
254
255
256
257
258
259

260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277







+
-
+

+
+
+
+
+
+
+
+
+







		[self _drawProgress];
	else
		[self _drawReceived];
}

- (void)calculateBPSAndETA
{
	_BPSWindow[_BPSWindowIndex++ % BPS_WINDOW_SIZE] =
	_BPS = (float)(_received - _lastReceived) /
	    (float)(_received - _lastReceived) /
	    -(float)_lastReceivedDate.timeIntervalSinceNow;

	if (_BPSWindowLength < BPS_WINDOW_SIZE)
		_BPSWindowLength++;

	_BPS = 0;
	for (size_t i = 0; i < _BPSWindowLength; i++)
		_BPS += _BPSWindow[i];
	_BPS /= _BPSWindowLength;

	_ETA = (double)(_length - _received) / _BPS;

	_lastReceived = _received;
	[_lastReceivedDate release];
	_lastReceivedDate = [[OFDate alloc] init];
}

Modified utils/ofhttp/lang/de.json from [ef4298a3ca] to [ccf7a0ea89].

64
65
66
67
68
69
70

71
72
73
74
75
76
77
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78







+







        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  %[error]: %[exception]"
    ],
    "download_failed": [
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  HTTP Status-Code: %[code]"
    ],
    "download_error": "Fehler!",
    "download_failed_exception": [
        "%[prog]: Fehler beim Download von <%[url]>!\n",
        "  %[exception]"
    ],
    "download_done": "Fertig!",
    "invalid_url": "%[prog]: Ungültige URL: <%[url]>!",
    "invalid_scheme": "%[prog]: Ungültiges Schema: <%[url]>!",

Modified utils/ofsock/OFSock.m from [0c75e9be8d] to [9ce3b460c5].

58
59
60
61
62
63
64
65

66
67
68
69
70
71
72
58
59
60
61
62
63
64

65
66
67
68
69
70
71
72







-
+








		if (URL.port == nil) {
			[of_stderr writeLine: @"Need a port!"];
			[OFApplication terminateWithStatus: 1];
		}

		[sock connectToHost: URL.host
			       port: URL.port.uInt16Value];
			       port: URL.port.shortValue];

		return [OFPair pairWithFirstObject: sock
				      secondObject: sock];
	}

	[of_stderr writeFormat: @"Invalid protocol: %@\n", scheme];
	[OFApplication terminateWithStatus: 1];