ObjFW  Check-in [25a6c00b82]

Overview
Comment:Merge trunk into branch "amiga-library"
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | amiga-library
Files: files | file ages | folders
SHA3-256: 25a6c00b828ac6bfd45fdbc1bb85b1ca2565bfcbf0bb580e3905446aed811975
User & Date: js on 2020-11-14 11:45:24
Other Links: branch diff | manifest | tags
Context
2020-11-14
12:07
Add new functions to Amiga library check-in: 8e9dc9523c user: js tags: amiga-library
11:45
Merge trunk into branch "amiga-library" check-in: 25a6c00b82 user: js tags: amiga-library
2020-11-12
00:37
Add a test for weak references check-in: 171461008d user: js tags: trunk
2020-10-04
15:00
Merge trunk into branch "amiga-library" check-in: 92335940e9 user: js tags: amiga-library
Changes

Modified .travis.yml from [159ce14eb5] to [0619e15749].

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
240
241
242
243
244
245
246










247

248



























249









250










































































































































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

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

-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
      dist: bionic
      env:
        - config=wii

services: docker

before_install:
  - if [ "$TRAVIS_OS_NAME" = "linux" -a -z "$config" ]; then
            case "$TRAVIS_CPU_ARCH" in
                    amd64 | s390x)
                            pkgs="gobjc-multilib";
                            ;;
                    *)
                            pkgs="gobjc";
                            ;;
            esac;

  - .travis/before_install.sh
            pkgs="$pkgs libsctp-dev";

            if grep precise /etc/lsb-release >/dev/null; then
                    pkgs="$pkgs ipx";
            fi;

            if ! sudo apt-get -qq install -y $pkgs >/tmp/apt_log 2>&1; then
                    cat /tmp/apt_log;
                    exit 1;
            fi;

            if grep precise /etc/lsb-release >/dev/null; then
                    sudo ipx_internal_net add 1234 123456;
            fi;
    fi

  - if [ "$config" = "nintendo_3ds" -o "$config" = "nintendo_ds" ]; then
            docker pull devkitpro/devkitarm;
    fi

  - if [ "$config" = "wii" ]; then
            docker pull devkitpro/devkitppc;
    fi

  - if [ "$config" = "amigaos" ]; then
            wget -q https://franke.ms/download/amiga-gcc.tgz;
            tar -C / -xzf amiga-gcc.tgz;
    fi

script:
  - build() {
            if ! git clean -fxd >/tmp/clean_log 2>&1; then
                    cat /tmp/clean_log;
                    exit 1;
            fi;
            ./autogen.sh || exit 1;
            .travis/build.sh "$@" || exit 1;
    }

  - .travis/script.sh
  - if [ "$TRAVIS_OS_NAME" = "linux" -a -z "$config" ]; then
            build_32_64() {
                    build OBJC="$CC" $@;

                    case "$TRAVIS_CPU_ARCH" in
                            amd64)
                                    build OBJC="$CC -m32"
                                          --host=i686-pc-linux-gnu $@;
                                    ;;
                            s390x)
                                    build OBJC="$CC -m31"
                                          --host=s390-pc-linux-gnu $@;
                                    ;;
                    esac
            };

            build_32_64;
            build_32_64 --enable-seluid24;
            build_32_64 --disable-compiler-tls;

            true The following are not CPU-dependent, so only run them on amd64;
            if [ "$TRAVIS_CPU_ARCH" = "amd64" ]; then
                    build_32_64 --disable-threads;
                    build_32_64 --disable-threads --disable-sockets;
                    build_32_64 --disable-threads --disable-files;
                    build_32_64 --disable-threads --disable-sockets
                                --disable-files;
                    build_32_64 --disable-sockets;
                    build_32_64 --disable-sockets --disable-files;
                    build_32_64 --disable-files;
                    build_32_64 --disable-shared;
                    build_32_64 --disable-shared --enable-seluid24;
                    build_32_64 --disable-compiler-tls --disable-threads;
            fi;
    fi

  - if [ "$TRAVIS_OS_NAME" = "osx" -a -z "$config" ]; then
            build_mac_32_64() {
                    build $@;
                    if [ -z "$no32bit" ]; then
                            build OBJC="clang -m32" --host=i386-apple-darwin $@;
                    fi;
            };

            if xcodebuild -version | grep 'Xcode 6' >/dev/null; then
                    export CPPFLAGS="-D_Nullable=__nullable
                                     -D_Nonnull=__nonnull
                                     -D_Null_unspecified=__null_unspecified";
            fi;

            build_mac_32_64;
            build_mac_32_64 --disable-threads;
            build_mac_32_64 --disable-threads --disable-sockets;
            build_mac_32_64 --disable-threads --disable-files;
            build_mac_32_64 --disable-threads --disable-sockets --disable-files;
            build_mac_32_64 --disable-sockets;
            build_mac_32_64 --disable-sockets --disable-files;
            build_mac_32_64 --disable-files;
            build_mac_32_64 --disable-shared;
            if [ -z "$noruntime" ]; then
                    build_mac_32_64 --enable-runtime;
                    build_mac_32_64 --enable-runtime --enable-seluid24;
                    build_mac_32_64 --enable-runtime --disable-threads;
                    build_mac_32_64 --enable-runtime --disable-threads
                                    --disable-sockets;
                    build_mac_32_64 --enable-runtime --disable-threads
                                    --disable-files;
                    build_mac_32_64 --enable-runtime --disable-threads
                                    --disable-sockets --disable-files;
                    build_mac_32_64 --enable-runtime --disable-sockets;
                    build_mac_32_64 --enable-runtime --disable-sockets
                                    --disable-files;
                    build_mac_32_64 --enable-runtime --disable-files;
                    build_mac_32_64 --enable-runtime --disable-shared;
                    build_mac_32_64 --enable-runtime --disable-shared
                                    --enable-seluid24;
            fi;
    fi

  - if [ "$config" = "ios" ]; then
            if xcodebuild -version | grep 'Xcode 6' >/dev/null; then
                    export CPPFLAGS="-D_Nullable=__nullable
                                     -D_Nonnull=__nonnull
                                     -D_Null_unspecified=__null_unspecified";
            fi;

            export IPHONEOS_DEPLOYMENT_TARGET="9.0";
            clang="clang -isysroot $(xcrun --sdk iphoneos --show-sdk-path)";
            export OBJC="$clang -arch armv7 -arch arm64";
            export OBJCPP="$clang -arch armv7 -E";
            build --host=arm-apple-darwin --enable-static;

            sysroot="$(xcrun --sdk iphonesimulator --show-sdk-path)";
            clang="clang -isysroot $sysroot";
            export OBJC="$clang -arch i386 -arch x86_64";
            export OBJCPP="$clang -arch i386 -E";
            build WRAPPER=true --host=i386-apple-darwin --enable-static;
    fi

  - if [ "$config" = "amigaos" ]; then
            export PATH="/opt/amiga/bin:$PATH";

            build --host=m68k-amigaos;
            build --host=m68k-amigaos --disable-amiga-lib;
            build --host=m68k-amigaos --enable-static;
    fi

  - if [ "$config" = "nintendo_3ds" ]; then
            ./autogen.sh;
            docker run -e DEVKITPRO=/opt/devkitpro
                    -e PATH="/opt/devkitpro/devkitARM/bin:$PATH"
                    -v $TRAVIS_BUILD_DIR:/objfw devkitpro/devkitarm
                    /objfw/.travis/build.sh --host=arm-none-eabi --with-3ds;
    fi

  - if [ "$config" = "nintendo_ds" ]; then
            ./autogen.sh;
            docker run -e DEVKITPRO=/opt/devkitpro
                    -e PATH="/opt/devkitpro/devkitARM/bin:$PATH"
                    -v $TRAVIS_BUILD_DIR:/objfw devkitpro/devkitarm
                    /objfw/.travis/build.sh --host=arm-none-eabi --with-nds;
    fi

  - if [ "$config" = "wii" ]; then
            ./autogen.sh;
            docker run -e DEVKITPRO=/opt/devkitpro
                    -e PATH="/opt/devkitpro/devkitPPC/bin:$PATH"
                    -v $TRAVIS_BUILD_DIR:/objfw devkitpro/devkitppc
                    /objfw/.travis/build.sh ac_cv_prog_wiiload=
                    --host=powerpc-eabi --with-wii;
    fi

Added .travis/before_install.sh version [479fa2374a].
















































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#!/bin/sh
if [ "$TRAVIS_OS_NAME" = "linux" -a -z "$config" ]; then
	case "$TRAVIS_CPU_ARCH" in
		amd64 | s390x)
			pkgs="gobjc-multilib"
			;;
		*)
			pkgs="gobjc"
			;;
	esac

	pkgs="$pkgs libsctp-dev"

	if grep precise /etc/lsb-release >/dev/null; then
		pkgs="$pkgs ipx"
	fi

	# We don't need any of them and they're often broken.
	sudo rm -f /etc/apt/sources.list.d/*

	if ! sudo apt-get -qq update >/tmp/apt_log 2>&1; then
		cat /tmp/apt_log
		exit 1
	fi

	if ! sudo apt-get -qq install -y $pkgs >>/tmp/apt_log 2>&1; then
		cat /tmp/apt_log
		exit 1
	fi

	if grep precise /etc/lsb-release >/dev/null; then
		sudo ipx_internal_net add 1234 123456
	fi
fi

if [ "$config" = "nintendo_3ds" -o "$config" = "nintendo_ds" ]; then
	docker pull devkitpro/devkitarm
fi

if [ "$config" = "wii" ]; then
	docker pull devkitpro/devkitppc
fi

if [ "$config" = "amigaos" ]; then
	wget -q https://franke.ms/download/amiga-gcc.tgz
	tar -C / -xzf amiga-gcc.tgz
fi

Added .travis/script.sh version [6432052d0a].
















































































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#!/bin/sh
build() {
	if ! git clean -fxd >/tmp/clean_log 2>&1; then
		cat /tmp/clean_log
		exit 1
	fi

	./autogen.sh || exit 1
	.travis/build.sh "$@" || exit 1
}

if [ "$TRAVIS_OS_NAME" = "linux" -a -z "$config" ]; then
	build_32_64() {
		build OBJC="$CC" $@

		case "$TRAVIS_CPU_ARCH" in
			amd64)
				build OBJC="$CC -m32" \
					--host=i686-pc-linux-gnu $@
				;;
			s390x)
				build OBJC="$CC -m31" \
					--host=s390-pc-linux-gnu $@
				;;
		esac
	}

	build_32_64
	build_32_64 --enable-seluid24
	build_32_64 --disable-compiler-tls

	# The following are not CPU-dependent, so only run them on amd64
	if [ "$TRAVIS_CPU_ARCH" = "amd64" ]; then
		build_32_64 --disable-threads
		build_32_64 --disable-threads --disable-sockets
		build_32_64 --disable-threads --disable-files
		build_32_64 --disable-threads --disable-sockets --disable-files
		build_32_64 --disable-sockets
		build_32_64 --disable-sockets --disable-files
		build_32_64 --disable-files
		build_32_64 --disable-shared
		build_32_64 --disable-shared --enable-seluid24
		build_32_64 --disable-compiler-tls --disable-threads
	fi
fi

if [ "$TRAVIS_OS_NAME" = "osx" -a -z "$config" ]; then
	build_mac_32_64() {
		build $@

		if [ -z "$no32bit" ]; then
			build OBJC="clang -m32" --host=i386-apple-darwin $@
		fi
	}

	if xcodebuild -version | grep 'Xcode 6' >/dev/null; then
		export CPPFLAGS="-D_Null_unspecified=__null_unspecified"
		export CPPFLAGS="$CPPFLAGS -D_Nullable=__nullable"
		export CPPFLAGS="$CPPFLAGS -D_Nonnull=__nonnull"
	fi

	build_mac_32_64
	build_mac_32_64 --disable-threads
	build_mac_32_64 --disable-threads --disable-sockets
	build_mac_32_64 --disable-threads --disable-files
	build_mac_32_64 --disable-threads --disable-sockets --disable-files
	build_mac_32_64 --disable-sockets
	build_mac_32_64 --disable-sockets --disable-files
	build_mac_32_64 --disable-files
	build_mac_32_64 --disable-shared

	if [ -z "$noruntime" ]; then
		build_mac_32_64 --enable-runtime
		build_mac_32_64 --enable-runtime --enable-seluid24
		build_mac_32_64 --enable-runtime --disable-threads
		build_mac_32_64 --enable-runtime --disable-threads \
				--disable-sockets
		build_mac_32_64 --enable-runtime --disable-threads \
				--disable-files
		build_mac_32_64 --enable-runtime --disable-threads \
				--disable-sockets --disable-files
		build_mac_32_64 --enable-runtime --disable-sockets
		build_mac_32_64 --enable-runtime --disable-sockets \
				--disable-files
		build_mac_32_64 --enable-runtime --disable-files
		build_mac_32_64 --enable-runtime --disable-shared
		build_mac_32_64 --enable-runtime --disable-shared \
				--enable-seluid24
	fi
fi

if [ "$config" = "ios" ]; then
	if xcodebuild -version | grep 'Xcode 6' >/dev/null; then
		export CPPFLAGS="-D_Null_unspecified=__null_unspecified"
		export CPPFLAGS="$CPPFLAGS -D_Nullable=__nullable"
		export CPPFLAGS="$CPPFLAGS -D_Nonnull=__nonnull"
	fi

	export IPHONEOS_DEPLOYMENT_TARGET="9.0"
	clang="clang -isysroot $(xcrun --sdk iphoneos --show-sdk-path)"
	export OBJC="$clang -arch armv7 -arch arm64"
	export OBJCPP="$clang -arch armv7 -E"
	build --host=arm-apple-darwin --enable-static

	sysroot="$(xcrun --sdk iphonesimulator --show-sdk-path)"
	clang="clang -isysroot $sysroot"
	export OBJC="$clang -arch i386 -arch x86_64"
	export OBJCPP="$clang -arch i386 -E"
	build WRAPPER=true --host=i386-apple-darwin --enable-static
fi

if [ "$config" = "amigaos" ]; then
	export PATH="/opt/amiga/bin:$PATH"

	build --host=m68k-amigaos
	build --host=m68k-amigaos --disable-amiga-lib
	build --host=m68k-amigaos --enable-static
fi

if [ "$config" = "nintendo_3ds" ]; then
	./autogen.sh
	docker run -e DEVKITPRO=/opt/devkitpro				\
		-e PATH="/opt/devkitpro/devkitARM/bin:$PATH"		\
		-v $TRAVIS_BUILD_DIR:/objfw devkitpro/devkitarm		\
		/objfw/.travis/build.sh --host=arm-none-eabi --with-3ds
fi

if [ "$config" = "nintendo_ds" ]; then
	./autogen.sh
	docker run -e DEVKITPRO=/opt/devkitpro				\
		-e PATH="/opt/devkitpro/devkitARM/bin:$PATH"		\
		-v $TRAVIS_BUILD_DIR:/objfw devkitpro/devkitarm		\
		/objfw/.travis/build.sh --host=arm-none-eabi --with-nds
fi

if [ "$config" = "wii" ]; then
	./autogen.sh
	docker run -e DEVKITPRO=/opt/devkitpro				\
		-e PATH="/opt/devkitpro/devkitPPC/bin:$PATH"		\
		-v $TRAVIS_BUILD_DIR:/objfw devkitpro/devkitppc		\
		/objfw/.travis/build.sh ac_cv_prog_wiiload=		\
		--host=powerpc-eabi --with-wii
fi

Modified configure.ac from [24223ba57b] to [e6767228be].

652
653
654
655
656
657
658



659
660
661
662
663
664


665
666
667
668
669
670
671
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







+
+
+






+
+







		AC_CHECK_LIB(objc, objc_msgSend, [
			AC_SUBST(RUNTIME_LIBS, "-lobjc")
			AC_SUBST(RUNTIME_FRAMEWORK_LIBS, "-lobjc")
		], [
			AC_MSG_ERROR([libobjc not found!])
		])

		old_OBJCFLAGS="$OBJCFLAGS"
		OBJCFLAGS="$OBJCFLAGS -lobjc"

		AC_CHECK_FUNC(objc_autoreleasePoolPush, [], [
			AC_SUBST(RUNTIME_AUTORELEASE_M, "runtime/autorelease.m")
		])
		AC_CHECK_FUNC(objc_constructInstance, [], [
			AC_SUBST(RUNTIME_INSTANCE_M, "runtime/instance.m")
		])

		OBJCFLAGS="$old_OBJCFLAGS"
		;;
esac

AC_CHECK_FUNCS(_Unwind_Backtrace)

case "$host_os" in
	darwin*)
694
695
696
697
698
699
700



































701
702
703
704
705
706
707
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








		AS_IF([test x"$host_is_ios" = x"yes"], [
			AC_SUBST(TESTS_STATIC_LIB, tests.a)
			TESTS_LIBS="$TESTS_LIBS -framework CoreFoundation"
		])
		;;
esac

AC_MSG_CHECKING(whether Objective C compiler supports ARC)
old_OBJCFLAGS="$OBJCFLAGS"
OBJCFLAGS="$OBJCFLAGS -fobjc-arc -fobjc-arc-exceptions"
AC_TRY_COMPILE([
	#ifdef __has_attribute
	# if __has_attribute(objc_root_class)
	__attribute__((__objc_root_class__))
	# endif
	#endif
	@interface Foo
	{
		struct objc_class *_isa;
	}

	+ (id)alloc;
	@end

	@implementation Foo
	+ (id)alloc
	{
		return (id)0;
	}
	@end
], [
	__weak id foo = [Foo alloc];
	(void)foo;
], [
	AC_MSG_RESULT(yes)
	AC_DEFINE(COMPILER_SUPPORTS_ARC, 1, [Whether the compiler supports ARC])
	AC_SUBST(RUNTIME_ARC_TESTS_M, RuntimeARCTests.m)
], [
	AC_MSG_RESULT(no)
])
OBJCFLAGS="$old_OBJCFLAGS"

AC_C_BIGENDIAN([
	AC_DEFINE(OF_BIG_ENDIAN, 1, [Whether we are big endian])
])
AS_IF([test x"$ac_cv_c_bigendian" = x"universal"], [
	AC_DEFINE(OF_UNIVERSAL, 1, [Whether we are building a universal binary])
])

Modified extra.mk.in from [5a63549510] to [8008f49817].

73
74
75
76
77
78
79

80
81
82
83
84
85
86
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87







+







OF_POLL_KERNEL_EVENT_OBSERVER_M = @OF_POLL_KERNEL_EVENT_OBSERVER_M@
OF_PROCESS_M = @OF_PROCESS_M@
OF_SCTP_SOCKET_M = @OF_SCTP_SOCKET_M@
OF_SELECT_KERNEL_EVENT_OBSERVER_M = @OF_SELECT_KERNEL_EVENT_OBSERVER_M@
REEXPORT_RUNTIME = @REEXPORT_RUNTIME@
REEXPORT_RUNTIME_FRAMEWORK = @REEXPORT_RUNTIME_FRAMEWORK@
RUNTIME = @RUNTIME@
RUNTIME_ARC_TESTS_M = @RUNTIME_ARC_TESTS_M@
RUNTIME_AUTORELEASE_M = @RUNTIME_AUTORELEASE_M@
RUNTIME_FRAMEWORK_LIBS = @RUNTIME_FRAMEWORK_LIBS@
RUNTIME_INSTANCE_M = @RUNTIME_INSTANCE_M@
RUNTIME_LIBS = @RUNTIME_LIBS@
RUN_TESTS = @RUN_TESTS@
SFDC_INLINE_H = @SFDC_INLINE_H@
SFDC_TARGET = @SFDC_TARGET@

Modified generators/TableGenerator.m from [ce006846a1] to [e134a30212].

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







+

+
+
+












-
-
-
-
-
-
-







	    [OFURL URLWithString: UNICODE_DATA_URL]];
	[_HTTPClient asyncPerformRequest: request];
}

-      (void)client: (OFHTTPClient *)client
  didPerformRequest: (OFHTTPRequest *)request
	   response: (OFHTTPResponse *)response
	  exception: (id)exception
{
	if (exception != nil)
		@throw exception;

	[of_stdout writeLine: @" done"];

	switch (_state) {
	case STATE_UNICODE_DATA:
		[self parseUnicodeData: response];
		break;
	case STATE_CASE_FOLDING:
		[self parseCaseFolding: response];
		break;
	}
}

-	  (void)client: (OFHTTPClient *)client
  didFailWithException: (id)exception
	       request: (OFHTTPRequest *)request
{
	@throw exception;
}

- (void)parseUnicodeData: (OFHTTPResponse *)response
{
	OFString *line;
	OFHTTPRequest *request;

	[of_stdout writeString: @"Parsing UnicodeData.txt…"];

Modified src/OFASN1BitString.m from [2a56c21bf5] to [58adebf4a8].

168
169
170
171
172
173
174
175

176
177

178
179
180
181
182
183
184
185
168
169
170
171
172
173
174

175
176

177
178
179
180
181
182
183
184
185







-
+

-
+








		return false;
	if (bitString->_bitStringLength != _bitStringLength)
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	return _bitStringValue.hash + (uint32_t)_bitStringLength;
	return _bitStringValue.hash + (unsigned long)_bitStringLength;
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1BitString: %@ (%zu bits)>",
					   _bitStringValue, _bitStringLength];
}
@end

Modified src/OFASN1Boolean.m from [435f978afe] to [ab43e337d1].

100
101
102
103
104
105
106
107

108
109

110
111
112
113
114
115
116
117
118
100
101
102
103
104
105
106

107
108

109
110
111
112
113
114
115
116
117
118







-
+

-
+










	if (boolean->_booleanValue != _booleanValue)
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	return (uint32_t)_booleanValue;
	return _booleanValue;
}

- (OFString *)description
{
	return (_booleanValue
	    ? @"<OFASN1Boolean: true>"
	    : @"<OFASN1Boolean: false>");
}
@end

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

87
88
89
90
91
92
93
94

95
96

97
98
99
100
101
102
103
104
87
88
89
90
91
92
93

94
95

96
97
98
99
100
101
102
103
104







-
+

-
+









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

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	return (uint32_t)_longLongValue;
	return (unsigned long)_longLongValue;
}

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

Modified src/OFASN1IA5String.m from [c986963291] to [6816147795].

108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
123
124
125
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
125







-
+











	if (![IA5String->_IA5StringValue isEqual: _IA5StringValue])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	return _IA5StringValue.hash;
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1IA5String: %@>",
					   _IA5StringValue];
}
@end

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

109
110
111
112
113
114
115
116

117
118

119
120
121
122
123
124
125
126
109
110
111
112
113
114
115

116
117

118
119
120
121
122
123
124
125
126







-
+

-
+









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

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	return (uint32_t)_longLongValue;
	return (unsigned long)_longLongValue;
}

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

Modified src/OFASN1NumericString.m from [bebd01e80f] to [1f3277f085].

120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135
136
137
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137







-
+











	if (![numericString->_numericStringValue isEqual: _numericStringValue])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	return _numericStringValue.hash;
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1NumericString: %@>",
					   _numericStringValue];
}
@end

Modified src/OFASN1ObjectIdentifier.m from [13ae15fdce] to [0496bf5735].

165
166
167
168
169
170
171
172

173
174
175
176
177
178
179
180
181
182
183
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179
180
181
182
183







-
+












	if (![objectIdentifier->_subidentifiers isEqual: _subidentifiers])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	return _subidentifiers.hash;
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"<OFASN1ObjectIdentifier: %@>",
	    [_subidentifiers componentsJoinedByString: @"."]];
}
@end

Modified src/OFASN1OctetString.m from [72ec0acbc8] to [3d5ad35b08].

93
94
95
96
97
98
99
100

101
102
103
104
105
106
107
108
109
110
93
94
95
96
97
98
99

100
101
102
103
104
105
106
107
108
109
110







-
+











	if (![octetString->_octetStringValue isEqual: _octetStringValue])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	return _octetStringValue.hash;
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1OctetString: %@>",
					   _octetStringValue];
}
@end

Modified src/OFASN1PrintableString.m from [fb2d5a3a36] to [d326d7d84e].

140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
155
156
157
140
141
142
143
144
145
146

147
148
149
150
151
152
153
154
155
156
157







-
+










	if (![printableString->_printableStringValue isEqual:
	    _printableStringValue])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	return _printableStringValue.hash;
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1PrintableString: %@>",
					   _printableStringValue];
}
@end

Modified src/OFASN1UTF8String.m from [7ebbe5d5f6] to [fe525c2cd3].

107
108
109
110
111
112
113
114

115
116
117
118
119
120
121
122
123
124
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124







-
+











	if (![UTF8String->_UTF8StringValue isEqual: _UTF8StringValue])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	return _UTF8StringValue.hash;
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1UTF8String: %@>",
					   _UTF8StringValue];
}
@end

Modified src/OFASN1Value.m from [2cb0a2171f] to [e6d6355cac].

95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
95
96
97
98
99
100
101

102
103
104
105
106
107
108
109







-
+







		return false;
	if (![value->_DEREncodedContents isEqual: _DEREncodedContents])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD(hash, _tagClass & 0xFF);
	OF_HASH_ADD(hash, _tagNumber & 0xFF);

Modified src/OFAdjacentArray.m from [8ce426fd6f] to [b6ccf04769].

304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318







-
+







	for (size_t i = 0; i < count; i++)
		if (![objects[i] isEqual: otherObjects[i]])
			return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	id const *objects = _array.items;
	size_t count = _array.count;
	uint32_t hash;

	OF_HASH_INIT(hash);

Modified src/OFApplication.m from [818d93f949] to [ba8b4a32b1].

255
256
257
258
259
260
261
262

263
264

265
266
267
268
269
270
271
272
255
256
257
258
259
260
261

262


263

264
265
266
267
268
269
270







-
+
-
-
+
-







				if (pos == OF_NOT_FOUND) {
					fprintf(stderr,
					    "Warning: Invalid environment "
					    "variable: %s\n", tmp.UTF8String);
					continue;
				}

				key = [tmp substringWithRange:
				key = [tmp substringToIndex: pos];
				    of_range(0, pos)];
				value = [tmp substringWithRange:
				value = [tmp substringFromRange: pos + 1];
				    of_range(pos + 1, tmp.length - pos - 1)];

				[_environment setObject: value
						 forKey: key];

				objc_autoreleasePoolPop(pool);
			}

301
302
303
304
305
306
307
308

309
310

311
312
313
314
315
316
317
318
299
300
301
302
303
304
305

306


307

308
309
310
311
312
313
314







-
+
-
-
+
-







				if (pos == OF_NOT_FOUND) {
					fprintf(stderr,
					    "Warning: Invalid environment "
					    "variable: %s\n", tmp.UTF8String);
					continue;
				}

				key = [tmp substringWithRange:
				key = [tmp substringToIndex: pos];
				    of_range(0, pos)];
				value = [tmp substringWithRange:
				value = [tmp substringFromIndex: pos + 1];
				    of_range(pos + 1, tmp.length - pos - 1)];

				[_environment setObject: value
						 forKey: key];

				objc_autoreleasePoolPop(pool);
			}

Modified src/OFArray.m from [76b22a5fc0] to [6e7407d49b].

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







-
-
-
+
+

-
-
-
-
-
-
-
+
+
+

+
+
+
+
+
-
+
+
+







{
	for (size_t i = 0; i < range.length; i++)
		buffer[i] = [self objectAtIndex: range.location + i];
}

- (id const *)objects
{
	OFObject *container;
	size_t count;
	id *buffer;
	size_t count = self.count;
	id *buffer = of_malloc(count, sizeof(id));

	container = [[[OFObject alloc] init] autorelease];
	count = self.count;
	buffer = [container allocMemoryWithSize: sizeof(*buffer)
					  count: count];

	[self getObjects: buffer
		 inRange: of_range(0, count)];
	@try {
		[self getObjects: buffer
			 inRange: of_range(0, count)];

		return [[OFData dataWithItemsNoCopy: buffer
					      count: count
					   itemSize: sizeof(id)
				       freeWhenDone: true] items];
	} @catch (id e) {
	return buffer;
		free(buffer);
		@throw e;
	}
}

- (id)copy
{
	return [self retain];
}

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
379
380
381
382
383
384
385


386

387
388
389
390
391
392
393

394
395
396
397
398
399
400
401







-
-
+
-







-
+







	    range.location + range.length < self.count)
		@throw [OFOutOfRangeException exception];

	if (![self isKindOfClass: [OFMutableArray class]])
		return [OFSubarray arrayWithArray: self
					    range: range];

	buffer = [self allocMemoryWithSize: sizeof(*buffer)
				     count: range.length];
	buffer = of_malloc(range.length, sizeof(*buffer));

	@try {
		[self getObjects: buffer
			 inRange: range];

		ret = [OFArray arrayWithObjects: buffer
					  count: range.length];
	} @finally {
		[self freeMemory: buffer];
		free(buffer);
	}

	return ret;
}

- (OFString *)componentsJoinedByString: (OFString *)separator
{
511
512
513
514
515
516
517
518

519
520
521
522
523
524
525
511
512
513
514
515
516
517

518
519
520
521
522
523
524
525







-
+







		if (![[self objectAtIndex: i] isEqual:
		    [otherArray objectAtIndex: i]])
			return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	for (id object in self)
		OF_HASH_ADD_HASH(hash, [object hash]);
854
855
856
857
858
859
860
861

862
863
864
865
866
867
868
869
870
871
872
873

874
875
876
877
878
879
880
881
882
883

884
885
886
887
888
889
890
891
892
893
894
895
896
897
898

899
900
901
902
903
904
905
854
855
856
857
858
859
860

861

862
863
864
865
866
867
868
869
870
871

872
873
874
875
876
877
878
879
880
881

882

883
884
885
886
887
888
889
890
891
892
893
894
895

896
897
898
899
900
901
902
903







-
+
-










-
+









-
+
-













-
+







}

#ifdef OF_HAVE_BLOCKS
- (OFArray *)mappedArrayUsingBlock: (of_array_map_block_t)block
{
	OFArray *ret;
	size_t count = self.count;
	id *tmp = [self allocMemoryWithSize: sizeof(id)
	id *tmp = of_malloc(count, sizeof(id));
				      count: count];

	@try {
		[self enumerateObjectsUsingBlock: ^ (id object, size_t idx,
		    bool *stop) {
			tmp[idx] = block(object, idx);
		}];

		ret = [OFArray arrayWithObjects: tmp
					  count: count];
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}

	return ret;
}

- (OFArray *)filteredArrayUsingBlock: (of_array_filter_block_t)block
{
	OFArray *ret;
	size_t count = self.count;
	id *tmp = [self allocMemoryWithSize: sizeof(id)
	id *tmp = of_malloc(count, sizeof(id));
				      count: count];

	@try {
		__block size_t i = 0;

		[self enumerateObjectsUsingBlock: ^ (id object, size_t idx,
		    bool *stop) {
			if (block(object, idx))
				tmp[i++] = object;
		}];

		ret = [OFArray arrayWithObjects: tmp
					  count: i];
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}

	return ret;
}

- (id)foldUsingBlock: (of_array_fold_block_t)block
{

Modified src/OFBitSetCharacterSet.m from [a3efdbfddb] to [a0186359ac].

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







-
+
-
















+
+
+
+
+
+
+










				if (UINT32_MAX - c < 1)
					@throw [OFOutOfRangeException
					    exception];

				newSize = OF_ROUND_UP_POW2(8, c + 1) / 8;

				_bitset = [self resizeMemory: _bitset
				_bitset = of_realloc(_bitset, newSize, 1);
							size: newSize];
				memset(_bitset + _size, '\0', newSize - _size);

				_size = newSize;
			}

			of_bitset_set(_bitset, c);
		}

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

	return self;
}

- (void)dealloc
{
	free(_bitset);

	[super dealloc];
}

- (bool)characterIsMember: (of_unichar_t)character
{
	if (character / 8 >= _size)
		return false;

	return of_bitset_isset(_bitset, character);
}
@end

Modified src/OFBlock.m from [a597363d01] to [d3c798f275].

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
435
436
437
438
439
440
441





























442
443
444
445
446
447
448







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







}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (void *)allocMemoryWithSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)allocMemoryWithSize: (size_t)size
			count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)resizeMemory: (void *)ptr
		  size: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)resizeMemory: (void *)ptr
		  size: (size_t)size
		 count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)freeMemory: (void *)ptr
{
	OF_UNRECOGNIZED_SELECTOR
}

- (instancetype)retain
{
	if ([self isMemberOfClass: (Class)&_NSConcreteMallocBlock])
		return Block_copy(self);

	return self;
}

Modified src/OFBytesValue.m from [812d7bedad] to [54953a495e].

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







-
+









+
+
+
+
+
+
+










		     objCType: (const char *)objCType
{
	self = [super init];

	@try {
		_size = of_sizeof_type_encoding(objCType);
		_objCType = objCType;
		_bytes = [self allocMemoryWithSize: _size];
		_bytes = of_malloc(1, _size);

		memcpy(_bytes, bytes, _size);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	free(_bytes);

	[super dealloc];
}

- (void)getValue: (void *)value
	    size: (size_t)size
{
	if (size != _size)
		@throw [OFOutOfRangeException exception];

	memcpy(value, _bytes, _size);
}
@end

Modified src/OFColor.m from [cc4d687d8e] to [442896ccaa].

118
119
120
121
122
123
124
125

126
127
128
129
130
131
132
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132







-
+







		return false;
	if (other->_alpha != _alpha)
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;
	float tmp;

	OF_HASH_INIT(hash);

	tmp = OF_BSWAP_FLOAT_IF_LE(_red);

Modified src/OFConstantString.m from [0761b10d3a] to [4db8f4cb59].

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
50
51
52
53
54
55
56





























57
58
59
60
61
62
63







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








@implementation OFConstantUTF8String
+ (instancetype)alloc
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)allocMemoryWithSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)allocMemoryWithSize: (size_t)size
			count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
		 count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)freeMemory: (void *)pointer
{
	OF_UNRECOGNIZED_SELECTOR
}

- (instancetype)retain
{
	return self;
}

- (instancetype)autorelease
{
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
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







-
+
-
-
-




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









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







{
	@synchronized (self) {
		struct of_string_utf8_ivars *ivars;

		if ([self isMemberOfClass: [OFConstantUTF8String class]])
			return;

		if ((ivars = calloc(1, sizeof(*ivars))) == NULL)
		ivars = of_calloc(1, sizeof(*ivars));
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: sizeof(*ivars)];

		ivars->cString = _cString;
		ivars->cStringLength = _cStringLength;

		switch (of_string_utf8_check(ivars->cString,
		    ivars->cStringLength,
		    ivars->cStringLength, &ivars->length)) {
			&ivars->length)) {
			case 1:
				ivars->isUTF8 = true;
				break;
			case -1:
				free(ivars);
				@throw [OFInvalidEncodingException exception];
		case 1:
			ivars->isUTF8 = true;
			break;
		case -1:
			free(ivars);
			@throw [OFInvalidEncodingException exception];
		}

		_cString = (char *)ivars;
		object_setClass(self, [OFConstantUTF8String class]);
	}
}

+ (instancetype)alloc
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)allocMemoryWithSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)allocMemoryWithSize: (size_t)size
			count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
		 count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)freeMemory: (void *)pointer
{
	OF_UNRECOGNIZED_SELECTOR
}

- (instancetype)retain
{
	return self;
}
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208







-
+







- (bool)isEqual: (id)object
{
	[self finishInitialization];

	return [self isEqual: object];
}

- (uint32_t)hash
- (unsigned long)hash
{
	[self finishInitialization];

	return self.hash;
}

- (OFString *)description
400
401
402
403
404
405
406














407
408
409
410
411
412
413
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+








- (bool)containsString: (OFString *)string
{
	[self finishInitialization];

	return [self containsString: string];
}

- (OFString *)substringFromIndex: (size_t)idx
{
	[self finishInitialization];

	return [self substringFromIndex: idx];
}

- (OFString *)substringToIndex: (size_t)idx
{
	[self finishInitialization];

	return [self substringToIndex: idx];
}

- (OFString *)substringWithRange: (of_range_t)range
{
	[self finishInitialization];

	return [self substringWithRange: range];
}

Modified src/OFDNSQuery.m from [fef90630f2] to [7b9ce87bc6].

89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103







-
+







		return false;
	if (query->_recordType != _recordType)
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);
	OF_HASH_ADD_HASH(hash, _domainName.hash);
	OF_HASH_ADD(hash, _DNSClass);
	OF_HASH_ADD(hash, _recordType);

Modified src/OFDNSResolver.m from [abd3a40827] to [3373845de9].

555
556
557
558
559
560
561

562
563
564
565
566
567
568
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569







+







	[_query release];
	[_ID release];
	[_settings release];
	[_delegate release];
	[_queryData release];
	[_TCPSocket release];
	[_TCPQueryData release];
	free(_TCPBuffer);
	[_cancelTimer release];

	[super dealloc];
}
@end

@implementation OFDNSResolver
1133
1134
1135
1136
1137
1138
1139
1140

1141
1142
1143
1144
1145
1146
1147
1148
1134
1135
1136
1137
1138
1139
1140

1141

1142
1143
1144
1145
1146
1147
1148







-
+
-







		[context->_TCPSocket release];
		context->_TCPSocket = nil;
		context->_responseLength = 0;
		return nil;
	}

	if (context->_TCPBuffer == nil)
		context->_TCPBuffer =
		context->_TCPBuffer = of_malloc(MAX_DNS_RESPONSE_LENGTH, 1);
		    [context allocMemoryWithSize: MAX_DNS_RESPONSE_LENGTH];

	[sock asyncReadIntoBuffer: context->_TCPBuffer
		      exactLength: 2];
	return nil;
}

-      (bool)stream: (OFStream *)stream

Modified src/OFDNSResolverSettings.m from [92fa7c4194] to [7c81772fe9].

91
92
93
94
95
96
97
98

99
100
101
102
103
104
105
106
91
92
93
94
95
96
97

98

99
100
101
102
103
104
105







-
+
-







	} @catch (OFInvalidFormatException *e) {
		/* Not an IP address -> we can use it if it contains a dot. */
		size_t pos = [domain rangeOfString: @"."].location;

		if (pos == OF_NOT_FOUND)
			return nil;

		ret = [domain substringWithRange:
		ret = [domain substringFromIndex: pos + 1];
		    of_range(pos + 1, domain.length - pos - 1)];
	}

	return ret;
}
#endif

@implementation OFDNSResolverSettings
190
191
192
193
194
195
196
197

198
199
200
201
202
203
204
189
190
191
192
193
194
195

196
197
198
199
200
201
202
203







-
+







		void *pool2 = objc_autoreleasePoolPush();
		OFArray *components, *hosts;
		size_t pos;
		OFString *address;

		pos = [line rangeOfString: @"#"].location;
		if (pos != OF_NOT_FOUND)
			line = [line substringWithRange: of_range(0, pos)];
			line = [line substringToIndex: pos];

		components = [line
		    componentsSeparatedByCharactersInSet: whitespaceCharacterSet
						 options: OF_STRING_SKIP_EMPTY];

		if (components.count < 2) {
			objc_autoreleasePoolPop(pool2);
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
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







-
+
-







-
+
-





-
+
-







-
+
-







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

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

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

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

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

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

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

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

			_configReloadInterval = option.unsignedLongLongValue;
		} else if ([option isEqual: @"tcp"])
			_usesTCP = true;
	} @catch (OFInvalidFormatException *e) {
	}
}
304
305
306
307
308
309
310
311

312
313
314
315
316
317
318
299
300
301
302
303
304
305

306
307
308
309
310
311
312
313







-
+







		void *pool2 = objc_autoreleasePoolPush();
		size_t pos;
		OFArray *components, *arguments;
		OFString *option;

		pos = [line indexOfCharacterFromSet: commentCharacters];
		if (pos != OF_NOT_FOUND)
			line = [line substringWithRange: of_range(0, pos)];
			line = [line substringToIndex: pos];

		components = [line
		    componentsSeparatedByCharactersInSet: whitespaceCharacterSet
						 options: OF_STRING_SKIP_EMPTY];

		if (components.count < 2) {
			objc_autoreleasePoolPop(pool2);

Modified src/OFDNSResourceRecord.m from [08b68e10ee] to [2126cc3910].

239
240
241
242
243
244
245
246

247
248
249
250
251
252
253
239
240
241
242
243
244
245

246
247
248
249
250
251
252
253







-
+








	if (!of_socket_address_equal(&record->_address, &_address))
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, _name.hash);
	OF_HASH_ADD(hash, _DNSClass >> 8);
325
326
327
328
329
330
331
332

333
334
335
336
337
338
339
325
326
327
328
329
330
331

332
333
334
335
336
337
338
339







-
+








	if (!of_socket_address_equal(&record->_address, &_address))
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, _name.hash);
	OF_HASH_ADD(hash, _DNSClass >> 8);
421
422
423
424
425
426
427
428

429
430
431
432
433
434
435
421
422
423
424
425
426
427

428
429
430
431
432
433
434
435







-
+








	if (record->_alias != _alias && ![record->_alias isEqual: _alias])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, _name.hash);
	OF_HASH_ADD(hash, _DNSClass >> 8);
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







-
+








	if (record->_OS != _OS && ![record->_OS isEqual: _OS])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, _name.hash);
	OF_HASH_ADD(hash, _DNSClass >> 8);
629
630
631
632
633
634
635
636

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

636
637
638
639
640
641
642
643







-
+







	if (record->_mailExchange != _mailExchange &&
	    ![record->_mailExchange isEqual: _mailExchange])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, _name.hash);
	OF_HASH_ADD(hash, _DNSClass >> 8);
730
731
732
733
734
735
736
737

738
739
740
741
742
743
744
730
731
732
733
734
735
736

737
738
739
740
741
742
743
744







-
+







	if (record->_authoritativeHost != _authoritativeHost &&
	    ![record->_authoritativeHost isEqual: _authoritativeHost])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, _name.hash);
	OF_HASH_ADD(hash, _DNSClass >> 8);
828
829
830
831
832
833
834
835

836
837
838
839
840
841
842
828
829
830
831
832
833
834

835
836
837
838
839
840
841
842







-
+







	if (record->_domainName != _domainName &&
	    ![record->_domainName isEqual: _domainName])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, _name.hash);
	OF_HASH_ADD(hash, _DNSClass >> 8);
933
934
935
936
937
938
939
940

941
942
943
944
945
946
947
933
934
935
936
937
938
939

940
941
942
943
944
945
946
947







-
+







	if (record->_TXTDomainName != _TXTDomainName &&
	    ![record->_TXTDomainName isEqual: _TXTDomainName])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, _name.hash);
	OF_HASH_ADD(hash, _DNSClass >> 8);
1069
1070
1071
1072
1073
1074
1075
1076

1077
1078
1079
1080
1081
1082
1083
1069
1070
1071
1072
1073
1074
1075

1076
1077
1078
1079
1080
1081
1082
1083







-
+








	if (record->_minTTL != _minTTL)
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, _name.hash);
	OF_HASH_ADD(hash, _DNSClass >> 8);
1210
1211
1212
1213
1214
1215
1216
1217

1218
1219
1220
1221
1222
1223
1224
1210
1211
1212
1213
1214
1215
1216

1217
1218
1219
1220
1221
1222
1223
1224







-
+








	if (record->_port != _port)
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, _name.hash);
	OF_HASH_ADD(hash, _DNSClass >> 8);
1315
1316
1317
1318
1319
1320
1321
1322

1323
1324
1325
1326
1327
1328
1329
1315
1316
1317
1318
1319
1320
1321

1322
1323
1324
1325
1326
1327
1328
1329







-
+







	if (record->_textStrings != _textStrings &&
	    ![record->_textStrings isEqual: _textStrings])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, _name.hash);
	OF_HASH_ADD(hash, _DNSClass >> 8);

Modified src/OFDNSResponse.m from [2d2248bdf2] to [f58f953bdc].

98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
98
99
100
101
102
103
104

105
106
107
108
109
110
111
112







-
+







	if (response->_additionalRecords != _additionalRecords &&
	    ![response->_additionalRecords isEqual: _additionalRecords])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);
	OF_HASH_ADD_HASH(hash, _domainName.hash);
	OF_HASH_ADD_HASH(hash, [_answerRecords hash]);
	OF_HASH_ADD_HASH(hash, [_authorityRecords hash]);

Modified src/OFData.h from [bbb0884145] to [7785f4eec7].

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







-

+



-
-
+
+




















-

+





-

+







			count: (size_t)count;

/**
 * @brief Creates a new OFData with the specified `count` items of the
 *	  specified size.
 *
 * @param items The items to store in the OFData
 * @param itemSize The item size of a single item in bytes
 * @param count The number of items
 * @param itemSize The item size of a single item in bytes
 * @return A new autoreleased OFData
 */
+ (instancetype)dataWithItems: (const void *)items
		     itemSize: (size_t)itemSize
			count: (size_t)count;
			count: (size_t)count
		     itemSize: (size_t)itemSize;

/**
 * @brief Creates a new OFData with the specified `count` items of size 1 by
 *	  taking over ownership of the specified items pointer.
 *
 * @param items The items to store in the OFData
 * @param count The number of items
 * @param freeWhenDone Whether to free the pointer when it is no longer needed
 *		       by the OFData
 * @return A new autoreleased OFData
 */
+ (instancetype)dataWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone;

/**
 * @brief Creates a new OFData with the specified `count` items of the
 *	  specified size by taking ownership of the specified items pointer.
 *
 * @param items The items to store in the OFData
 * @param itemSize The item size of a single item in bytes
 * @param count The number of items
 * @param itemSize The item size of a single item in bytes
 * @param freeWhenDone Whether to free the pointer when it is no longer needed
 *		       by the OFData
 * @return A new autoreleased OFData
 */
+ (instancetype)dataWithItemsNoCopy: (void *)items
			   itemSize: (size_t)itemSize
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone;

#ifdef OF_HAVE_FILES
/**
 * @brief Creates a new OFData with an item size of 1, containing the data of
 *	  the specified file.
 *
192
193
194
195
196
197
198
199
200

201
202
203
204
205


206
207
208
209
210
211
212
192
193
194
195
196
197
198

199
200
201
202
203


204
205
206
207
208
209
210
211
212







-

+



-
-
+
+







			count: (size_t)count;

/**
 * @brief Initialized an already allocated OFData with the specified `count`
 *	  items of the specified size.
 *
 * @param items The items to store in the OFData
 * @param itemSize The item size of a single item in bytes
 * @param count The number of items
 * @param itemSize The item size of a single item in bytes
 * @return An initialized OFData
 */
- (instancetype)initWithItems: (const void *)items
		     itemSize: (size_t)itemSize
			count: (size_t)count;
			count: (size_t)count
		     itemSize: (size_t)itemSize;

/**
 * @brief Initializes an already allocated OFData with the specified `count`
 *	  items of size 1 by taking over ownership of the specified items
 *	  pointer.
 *
 * @param items The items to store in the OFData
221
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236

237
238
239
240
241
242
243
221
222
223
224
225
226
227

228
229
230
231
232
233
234

235
236
237
238
239
240
241
242
243







-

+





-

+








/**
 * @brief Initializes an already allocated OFData with the specified `count`
 *	  items of the specified size by taking ownership of the specified
 *	  items pointer.
 *
 * @param items The items to store in the OFData
 * @param itemSize The item size of a single item in bytes
 * @param count The number of items
 * @param itemSize The item size of a single item in bytes
 * @param freeWhenDone Whether to free the pointer when it is no longer needed
 *		       by the OFData
 * @return An initialized OFData
 */
- (instancetype)initWithItemsNoCopy: (void *)items
			   itemSize: (size_t)itemSize
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone;

#ifdef OF_HAVE_FILES
/**
 * @brief Initializes an already allocated OFData with an item size of 1,
 *	  containing the data of the specified file.
 *

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

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







-

+


+
-
+
-












-

+



-

+







			count: (size_t)count
{
	return [[[self alloc] initWithItems: items
				      count: count] autorelease];
}

+ (instancetype)dataWithItems: (const void *)items
		     itemSize: (size_t)itemSize
			count: (size_t)count
		     itemSize: (size_t)itemSize
{
	return [[[self alloc] initWithItems: items
				      count: count
				   itemSize: itemSize
				   itemSize: itemSize] autorelease];
				      count: count] autorelease];
}

+ (instancetype)dataWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone
{
	return [[[self alloc] initWithItemsNoCopy: items
					    count: count
				     freeWhenDone: freeWhenDone] autorelease];
}

+ (instancetype)dataWithItemsNoCopy: (void *)items
			   itemSize: (size_t)itemSize
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	return [[[self alloc] initWithItemsNoCopy: items
					 itemSize: itemSize
					    count: count
					 itemSize: itemSize
				     freeWhenDone: freeWhenDone] autorelease];
}

#ifdef OF_HAVE_FILES
+ (instancetype)dataWithContentsOfFile: (OFString *)path
{
	return [[[self alloc] initWithContentsOfFile: path] autorelease];
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
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







+
-
+
-



-

+







-
-
+
+

-
+















-

+




-

+









-

+







	return [[[self alloc] initWithBase64EncodedString: string] autorelease];
}

- (instancetype)initWithItems: (const void *)items
			count: (size_t)count
{
	return [self initWithItems: items
			     count: count
			  itemSize: 1
			  itemSize: 1];
			     count: count];
}

- (instancetype)initWithItems: (const void *)items
		     itemSize: (size_t)itemSize
			count: (size_t)count
		     itemSize: (size_t)itemSize
{
	self = [super init];

	@try {
		if (itemSize == 0)
			@throw [OFInvalidArgumentException exception];

		_items = [self allocMemoryWithSize: itemSize
					     count: count];
		_items = of_malloc(count, itemSize);
		_count = count;
		_itemSize = itemSize;
		_count = count;
		_freeWhenDone = true;

		memcpy(_items, items, count * itemSize);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone
{
	return [self initWithItemsNoCopy: items
				itemSize: 1
				   count: count
				itemSize: 1
			    freeWhenDone: freeWhenDone];
}

- (instancetype)initWithItemsNoCopy: (void *)items
			   itemSize: (size_t)itemSize
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	self = [super init];

	@try {
		if (itemSize == 0)
			@throw [OFInvalidArgumentException exception];

		_items = (unsigned char *)items;
		_itemSize = itemSize;
		_count = count;
		_itemSize = itemSize;
		_freeWhenDone = freeWhenDone;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
193
194
195
196
197
198
199
200

201
202
203
204
205
206
207
208
209
210
193
194
195
196
197
198
199

200



201
202
203
204
205
206
207







-
+
-
-
-







		    attributesOfItemAtPath: path].fileSize;

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

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

		file = [[OFFile alloc] initWithPath: path
					       mode: @"r"];
		@try {
			[file readIntoBuffer: buffer
				 exactLength: (size_t)size];
		} @finally {
			[file release];
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
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







+

-
+


-
+

+
-
-
-
+
+
+
+

-
-
+
+
+

-
-
-
-
+
+
+
+
+
+







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

		stream = [URLHandler openItemAtURL: URL
					      mode: @"r"];

		_count = 0;
		_itemSize = 1;
		_count = 0;
		_freeWhenDone = true;

		pageSize = [OFSystemInfo pageSize];
		buffer = [self allocMemoryWithSize: pageSize];
		buffer = of_malloc(1, pageSize);

		@try {
		while (!stream.atEndOfStream) {
			size_t length = [stream readIntoBuffer: buffer
							length: pageSize];
			while (!stream.atEndOfStream) {
				size_t length = [stream
				    readIntoBuffer: buffer
					    length: pageSize];

			if (SIZE_MAX - _count < length)
				@throw [OFOutOfRangeException exception];
				if (SIZE_MAX - _count < length)
					@throw [OFOutOfRangeException
					    exception];

			_items = [self resizeMemory: _items
					       size: _count + length];
			memcpy(_items + _count, buffer, length);
			_count += length;
				_items = of_realloc(_items, _count + length, 1);
				memcpy(_items + _count, buffer, length);
				_count += length;
			}
		} @finally {
			free(buffer);
		}

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}
285
286
287
288
289
290
291
292


293
294

295
296
297
298
299
300
301
288
289
290
291
292
293
294

295
296
297

298
299
300
301
302
303
304
305







-
+
+

-
+







		const char *cString;

		if (count % 2 != 0)
			@throw [OFInvalidFormatException exception];

		count /= 2;

		_items = [self allocMemoryWithSize: count];
		_items = of_malloc(count, 1);
		_count = count;
		_itemSize = 1;
		_count = count;
		_freeWhenDone = true;

		cString = [string
		    cStringWithEncoding: OF_STRING_ENCODING_ASCII];

		for (size_t i = 0; i < count; i++) {
			uint8_t c1 = cString[2 * i];
			uint8_t c2 = cString[2 * i + 1];
428
429
430
431
432
433
434

435

436
437
438
439
440
441
442
443
432
433
434
435
436
437
438
439

440

441
442
443
444
445
446
447







+
-
+
-







{
	return [self retain];
}

- (id)mutableCopy
{
	return [[OFMutableData alloc] initWithItems: _items
					      count: _count
					   itemSize: _itemSize
					   itemSize: _itemSize];
					      count: _count];
}

- (bool)isEqual: (id)object
{
	OFData *data;

	if (object == self)
485
486
487
488
489
490
491
492

493
494
495
496
497
498
499
489
490
491
492
493
494
495

496
497
498
499
500
501
502
503







-
+








	if (comparison > 0)
		return OF_ORDERED_DESCENDING;
	else
		return OF_ORDERED_ASCENDING;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	for (size_t i = 0; i < _count * _itemSize; i++)
		OF_HASH_ADD(hash, ((uint8_t *)_items)[i]);
508
509
510
511
512
513
514
515
516

517
518
519
520
521
522
523
512
513
514
515
516
517
518

519
520
521
522
523
524
525
526
527







-

+







	OFData *ret;

	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length > _count)
		@throw [OFOutOfRangeException exception];

	ret = [OFData dataWithItemsNoCopy: _items + (range.location * _itemSize)
				 itemSize: _itemSize
				    count: range.length
				 itemSize: _itemSize
			     freeWhenDone: false];
	ret->_parentData = [(_parentData != nil ? _parentData : self) copy];

	return ret;
}

- (OFString *)description

Modified src/OFDate.h from [975839f73c] to [b56f401ff6].

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







-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+







@property (class, readonly, nonatomic) OFDate *distantFuture;
@property (class, readonly, nonatomic) OFDate *distantPast;
#endif

/**
 * @brief The microsecond of the date.
 */
@property (readonly, nonatomic) uint32_t microsecond;
@property (readonly, nonatomic) unsigned long microsecond;

/**
 * @brief The second of the date.
 */
@property (readonly, nonatomic) uint8_t second;
@property (readonly, nonatomic) unsigned char second;

/**
 * @brief The minute of the date.
 */
@property (readonly, nonatomic) uint8_t minute;
@property (readonly, nonatomic) unsigned char minute;

/**
 * @brief The minute of the date in local time.
 */
@property (readonly, nonatomic) uint8_t localMinute;
@property (readonly, nonatomic) unsigned char localMinute;

/**
 * @brief The hour of the date.
 */
@property (readonly, nonatomic) uint8_t hour;
@property (readonly, nonatomic) unsigned char hour;

/**
 * @brief The hour of the date in local time.
 */
@property (readonly, nonatomic) uint8_t localHour;
@property (readonly, nonatomic) unsigned char localHour;

/**
 * @brief The day of the month of the date.
 */
@property (readonly, nonatomic) uint8_t dayOfMonth;
@property (readonly, nonatomic) unsigned char dayOfMonth;

/**
 * @brief The day of the month of the date in local time.
 */
@property (readonly, nonatomic) uint8_t localDayOfMonth;
@property (readonly, nonatomic) unsigned char localDayOfMonth;

/**
 * @brief The month of the year of the date.
 */
@property (readonly, nonatomic) uint8_t monthOfYear;
@property (readonly, nonatomic) unsigned char monthOfYear;

/**
 * @brief The month of the year of the date in local time.
 */
@property (readonly, nonatomic) uint8_t localMonthOfYear;
@property (readonly, nonatomic) unsigned char localMonthOfYear;

/**
 * @brief The year of the date.
 */
@property (readonly, nonatomic) uint16_t year;
@property (readonly, nonatomic) unsigned short year;

/**
 * @brief The year of the date in local time.
 */
@property (readonly, nonatomic) uint16_t localYear;
@property (readonly, nonatomic) unsigned short localYear;

/**
 * @brief The day of the week of the date.
 */
@property (readonly, nonatomic) uint8_t dayOfWeek;
@property (readonly, nonatomic) unsigned char dayOfWeek;

/**
 * @brief The day of the week of the date in local time.
 */
@property (readonly, nonatomic) uint8_t localDayOfWeek;
@property (readonly, nonatomic) unsigned char localDayOfWeek;

/**
 * @brief The day of the year of the date.
 */
@property (readonly, nonatomic) uint16_t dayOfYear;
@property (readonly, nonatomic) unsigned short dayOfYear;

/**
 * @brief The day of the year of the date in local time.
 */
@property (readonly, nonatomic) uint16_t localDayOfYear;
@property (readonly, nonatomic) unsigned short localDayOfYear;

/**
 * @brief The seconds since 1970-01-01T00:00:00Z.
 */
@property (readonly, nonatomic) of_time_interval_t timeIntervalSince1970;

/**

Modified src/OFDate.m from [996b4908b2] to [cf1b1da641].

219
220
221
222
223
224
225
226

227
228
229
230
231
232
233
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233







-
+







	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
	31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,
};

static double
tmAndTzToTime(struct tm *tm, int16_t *tz)
tmAndTzToTime(const struct tm *tm, short tz)
{
	double seconds;

	/* Years */
	seconds = (int64_t)(tm->tm_year - 70) * 31536000;
	/* Days of leap years, excluding the year to look at */
	seconds += (((tm->tm_year + 1899) / 4) - 492) * 86400;
247
248
249
250
251
252
253
254

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

254
255
256
257
258
259
260
261







-
+







	/* Hours */
	seconds += tm->tm_hour * 3600;
	/* Minutes */
	seconds += tm->tm_min * 60;
	/* Seconds */
	seconds += tm->tm_sec;
	/* Time zone */
	seconds += -(double)*tz * 60;
	seconds += -(double)tz * 60;

	return seconds;
}

@implementation OFDateSingleton
- (instancetype)autorelease
{
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
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







-
+







-
+









-
+



-
+






-
+












-
+








- (instancetype)initWithDateString: (OFString *)string
			    format: (OFString *)format
{
	void *pool = objc_autoreleasePoolPush();
	const char *UTF8String = string.UTF8String;
	struct tm tm = { .tm_isdst = -1 };
	int16_t tz = 0;
	short tz = 0;

	if (of_strptime(UTF8String, format.UTF8String, &tm, &tz) !=
	    UTF8String + string.UTF8StringLength)
		@throw [OFInvalidFormatException exception];

	objc_autoreleasePoolPop(pool);

	return [self initWithTimeIntervalSince1970: tmAndTzToTime(&tm, &tz)];
	return [self initWithTimeIntervalSince1970: tmAndTzToTime(&tm, tz)];
}

- (instancetype)initWithLocalDateString: (OFString *)string
				 format: (OFString *)format
{
	void *pool = objc_autoreleasePoolPush();
	const char *UTF8String = string.UTF8String;
	struct tm tm = { .tm_isdst = -1 };
	/*
	 * of_strptime() can never set this to INT16_MAX, no matter what is
	 * of_strptime() can never set this to SHRT_MAX, no matter what is
	 * passed to it, so this is a safe way to figure out if the date
	 * contains a time zone.
	 */
	int16_t tz = INT16_MAX;
	short tz = SHRT_MAX;
	of_time_interval_t seconds;

	if (of_strptime(UTF8String, format.UTF8String, &tm, &tz) !=
	    UTF8String + string.UTF8StringLength)
		@throw [OFInvalidFormatException exception];

	if (tz == INT16_MAX) {
	if (tz == SHRT_MAX) {
#ifdef OF_WINDOWS
		if (func__mktime64 != NULL) {
			if ((seconds = func__mktime64(&tm)) == -1)
				@throw [OFInvalidFormatException exception];
		} else {
#endif
			if ((seconds = mktime(&tm)) == -1)
				@throw [OFInvalidFormatException exception];
#ifdef OF_WINDOWS
		}
#endif
	} else
		seconds = tmAndTzToTime(&tm, &tz);
		seconds = tmAndTzToTime(&tm, tz);

	objc_autoreleasePoolPop(pool);

	return [self initWithTimeIntervalSince1970: seconds];
}

- (instancetype)initWithSerialization: (OFXMLElement *)element
534
535
536
537
538
539
540
541

542
543
544
545
546
547
548
534
535
536
537
538
539
540

541
542
543
544
545
546
547
548







-
+








	if (otherDate.timeIntervalSince1970 != self.timeIntervalSince1970)
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;
	double tmp;

	OF_HASH_INIT(hash);

	tmp = OF_BSWAP_DOUBLE_IF_BE(self.timeIntervalSince1970);
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
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







-
+



-
+


-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+




-
+







	[ret retain];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}

- (uint32_t)microsecond
- (unsigned long)microsecond
{
	of_time_interval_t timeInterval = self.timeIntervalSince1970;

	return (uint32_t)((timeInterval - trunc(timeInterval)) * 1000000);
	return (unsigned long)((timeInterval - trunc(timeInterval)) * 1000000);
}

- (uint8_t)second
- (unsigned char)second
{
	GMTIME_RET(tm_sec)
}

- (uint8_t)minute
- (unsigned char)minute
{
	GMTIME_RET(tm_min)
}

- (uint8_t)localMinute
- (unsigned char)localMinute
{
	LOCALTIME_RET(tm_min)
}

- (uint8_t)hour
- (unsigned char)hour
{
	GMTIME_RET(tm_hour)
}

- (uint8_t)localHour
- (unsigned char)localHour
{
	LOCALTIME_RET(tm_hour)
}

- (uint8_t)dayOfMonth
- (unsigned char)dayOfMonth
{
	GMTIME_RET(tm_mday)
}

- (uint8_t)localDayOfMonth
- (unsigned char)localDayOfMonth
{
	LOCALTIME_RET(tm_mday)
}

- (uint8_t)monthOfYear
- (unsigned char)monthOfYear
{
	GMTIME_RET(tm_mon + 1)
}

- (uint8_t)localMonthOfYear
- (unsigned char)localMonthOfYear
{
	LOCALTIME_RET(tm_mon + 1)
}

- (uint16_t)year
- (unsigned short)year
{
	GMTIME_RET(tm_year + 1900)
}

- (uint16_t)localYear
- (unsigned short)localYear
{
	LOCALTIME_RET(tm_year + 1900)
}

- (uint8_t)dayOfWeek
- (unsigned char)dayOfWeek
{
	GMTIME_RET(tm_wday)
}

- (uint8_t)localDayOfWeek
- (unsigned char)localDayOfWeek
{
	LOCALTIME_RET(tm_wday)
}

- (uint16_t)dayOfYear
- (unsigned short)dayOfYear
{
	GMTIME_RET(tm_yday + 1)
}

- (uint16_t)localDayOfYear
- (unsigned short)localDayOfYear
{
	LOCALTIME_RET(tm_yday + 1)
}

- (OFString *)dateStringWithFormat: (OFConstantString *)format
{
	OFString *ret;
775
776
777
778
779
780
781
782
783
784
785

786
787
788
789
790
791
792
775
776
777
778
779
780
781




782
783
784
785
786
787
788
789







-
-
-
-
+







	} @finally {
		[mutex unlock];
	}
# endif
#endif

	pageSize = [OFSystemInfo pageSize];
	if ((buffer = malloc(pageSize)) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: pageSize];

	buffer = of_malloc(1, pageSize);
	@try {
#ifndef OF_WINDOWS
		if (strftime(buffer, pageSize, format.UTF8String, &tm) == 0)
			@throw [OFOutOfRangeException exception];

		ret = [OFString stringWithUTF8String: buffer];
#else
838
839
840
841
842
843
844
845
846
847
848

849
850
851
852
853
854
855
835
836
837
838
839
840
841




842
843
844
845
846
847
848
849







-
-
-
-
+







	} @finally {
		[mutex unlock];
	}
# endif
#endif

	pageSize = [OFSystemInfo pageSize];
	if ((buffer = malloc(pageSize)) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: pageSize];

	buffer = of_malloc(1, pageSize);
	@try {
#ifndef OF_WINDOWS
		if (strftime(buffer, pageSize, format.UTF8String, &tm) == 0)
			@throw [OFOutOfRangeException exception];

		ret = [OFString stringWithUTF8String: buffer];
#else

Modified src/OFDictionary.m from [9428854186] to [505aa3e10f].

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







-
+





-
+



-
-
+
+








	[new makeImmutable];

	return new;
}
#endif

- (uint32_t)hash
- (unsigned long)hash
{
	void *pool = objc_autoreleasePoolPush();
	OFEnumerator *keyEnumerator = [self keyEnumerator];
	OFEnumerator *objectEnumerator = [self objectEnumerator];
	id key, object;
	uint32_t hash = 0;
	unsigned long hash = 0;

	while ((key = [keyEnumerator nextObject]) != nil &&
	    (object = [objectEnumerator nextObject]) != nil) {
		hash += [key hash];
		hash += [object hash];
		hash ^= [key hash];
		hash ^= [object hash];
	}

	objc_autoreleasePoolPop(pool);

	return hash;
}

Modified src/OFFile.m from [14d95d3e71] to [edd10634f5].

239
240
241
242
243
244
245
246

247
248
249
250
251
252
253
254
255
256
239
240
241
242
243
244
245

246



247
248
249
250
251
252
253







-
+
-
-
-








		if (handle == -1)
			@throw [OFOpenItemFailedException
			    exceptionWithPath: path
					 mode: mode
					errNo: errno];
#else
		if ((handle = malloc(sizeof(*handle))) == NULL)
		handle = of_malloc(1, sizeof(*handle));
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: sizeof(*handle)];

		@try {
			if ((flags = parseMode(mode.UTF8String,
			    &handle->append)) == -1)
				@throw [OFInvalidArgumentException exception];

			if ((handle->handle = Open([path cStringWithEncoding:
			    [OFLocale encoding]], flags)) == 0) {

Modified src/OFFileManager.m from [f7e8bc7e28] to [22b7dac443].

629
630
631
632
633
634
635
636
637
638
639

640
641
642
643
644
645
646
629
630
631
632
633
634
635




636
637
638
639
640
641
642
643







-
-
-
-
+







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

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

		buffer = of_malloc(1, pageSize);
		@try {
			sourceStream = [[OFURLHandler handlerForURL: source]
			    openItemAtURL: source
				     mode: @"r"];
			destinationStream = [[OFURLHandler handlerForURL:
			    destination] openItemAtURL: destination
						  mode: @"w"];

Modified src/OFHTTPClient.h from [f4b177457f] to [428c441451].

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
38
39
40
41
42
43
44

45
46
47
48
49


50
51











52
53
54
55
56
57
58







-
+
+



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







 */
@protocol OFHTTPClientDelegate <OFObject>
/**
 * @brief A callback which is called when an OFHTTPClient performed a request.
 *
 * @param client The OFHTTPClient which performed the request
 * @param request The request the OFHTTPClient performed
 * @param response The response to the request performed
 * @param response The response to the request performed, or nil on error
 * @param exception An exception if the request failed, or nil on success
 */
-      (void)client: (OFHTTPClient *)client
  didPerformRequest: (OFHTTPRequest *)request
	   response: (OFHTTPResponse *)response;

	   response: (nullable OFHTTPResponse *)response
	  exception: (nullable id)exception;
/**
 * @brief A callback which is called when an OFHTTPClient encountered an
 *	  exception while performing a request.
 *
 * @param client The client which encountered an exception
 * @param exception The exception the client encountered
 * @param request The request during which the client encountered the exception
 */
-	  (void)client: (OFHTTPClient *)client
  didFailWithException: (id)exception
	       request: (OFHTTPRequest *)request;

@optional
/**
 * @brief A callback which is called when an OFHTTPClient creates a socket.
 *
 * This is useful if the connection is using HTTPS and the server requires a
 * client certificate. This callback can then be used to tell the TLS socket
97
98
99
100
101
102
103
104

105
106
107
108
109
110
111
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101







-
+







 * @param headers The headers received
 * @param statusCode The status code received
 * @param request The request for which the headers and status code have been
 *		  received
 */
-      (void)client: (OFHTTPClient *)client
  didReceiveHeaders: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headers
	 statusCode: (int)statusCode
	 statusCode: (short)statusCode
	    request: (OFHTTPRequest *)request;

/**
 * @brief A callback which is called when an OFHTTPClient wants to follow a
 *	  redirect.
 *
 * If you want to get the headers and data for each redirect, set the number of
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130







-
+







 *		  (e.g. to set the cookies for the new URL), however, keep in
 *		  mind that this will change the request you originally passed.
 * @param response The response indicating the redirect
 * @return A boolean whether the OFHTTPClient should follow the redirect
 */
-	  (bool)client: (OFHTTPClient *)client
  shouldFollowRedirect: (OFURL *)URL
	    statusCode: (int)statusCode
	    statusCode: (short)statusCode
	       request: (OFHTTPRequest *)request
	      response: (OFHTTPResponse *)response;
@end

/**
 * @class OFHTTPClient OFHTTPClient.h ObjFW/OFHTTPClient.h
 *

Modified src/OFHTTPClient.m from [561ec71175] to [72f7071464].

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







-
+







{
@public
	OFHTTPClient *_client;
	OFHTTPRequest *_request;
	unsigned int _redirects;
	bool _firstLine;
	OFString *_version;
	int _status;
	short _status;
	OFMutableDictionary OF_GENERIC(OFString *, OFString *) *_serverHeaders;
}

- (instancetype)initWithClient: (OFHTTPClient *)client
		       request: (OFHTTPRequest *)request
		     redirects: (unsigned int)redirects;
- (void)start;
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
237
238
239
240
241
242
243

244
245
246
247
248
249
250
251







-
+








		firstLetter = false;
		str++;
	}
}

static bool
defaultShouldFollow(of_http_request_method_t method, int statusCode)
defaultShouldFollow(of_http_request_method_t method, short statusCode)
{
	bool follow;

	/*
	 * 301, 302 and 307 should only redirect with user confirmation if the
	 * request method is not GET or HEAD. Asking the delegate and getting
	 * true returned is considered user confirmation.
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
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







+
+
-
+
-









+








- (void)raiseException: (id)exception
{
	[_client close];
	_client->_inProgress = false;

	[_client->_delegate client: _client
		 didPerformRequest: _request
			  response: nil
	      didFailWithException: exception
			 exception: exception];
			   request: _request];
}

- (void)createResponseWithSocketOrThrow: (OFTCPSocket *)sock
{
	OFURL *URL = _request.URL;
	OFHTTPClientResponse *response;
	OFString *connectionHeader;
	bool keepAlive;
	OFString *location;
	id exception;

	response = [[[OFHTTPClientResponse alloc] initWithSocket: sock]
	    autorelease];
	response.protocolVersionString = _version;
	response.statusCode = _status;
	response.headers = _serverHeaders;

418
419
420
421
422
423
424
425

426
427


428
429
430

431
432
433

434
435
436
437
438
439
440
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







-
+


+
+


-
+



+







			return;
		}
	}

	_client->_inProgress = false;

	if (_status / 100 != 2)
		@throw [OFHTTPRequestFailedException
		exception = [OFHTTPRequestFailedException
		    exceptionWithRequest: _request
				response: response];
	else
		exception = nil;

	[_client->_delegate performSelector: @selector(client:didPerformRequest:
						 response:)
						 response:exception:)
				 withObject: _client
				 withObject: _request
				 withObject: response
				 withObject: exception
				 afterDelay: 0];
}

- (void)createResponseWithSocket: (OFTCPSocket *)sock
{
	@try {
		[self createResponseWithSocketOrThrow: sock];
467
468
469
470
471
472
473
474

475
476
477
478
479
480
481
472
473
474
475
476
477
478

479
480
481
482
483
484
485
486







-
+







		    exceptionWithVersion: _version];

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

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

	_status = (int)status;
	_status = (short)status;

	return true;
}

- (bool)handleServerHeader: (OFString *)line
		    socket: (OFTCPSocket *)sock
{
506
507
508
509
510
511
512
513

514
515
516
517
518
519
520
521
522
523
511
512
513
514
515
516
517

518



519
520
521
522
523
524
525







-
+
-
-
-







	}

	lineC = line.UTF8String;

	if ((tmp = strchr(lineC, ':')) == NULL)
		@throw [OFInvalidServerReplyException exception];

	if ((keyC = malloc(tmp - lineC + 1)) == NULL)
	keyC = of_malloc(tmp - lineC + 1, 1);
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: tmp - lineC + 1];

	memcpy(keyC, lineC, tmp - lineC);
	keyC[tmp - lineC] = '\0';
	normalizeKey(keyC);

	@try {
		key = [OFString stringWithUTF8StringNoCopy: keyC
					      freeWhenDone: true];
996
997
998
999
1000
1001
1002
1003

1004
1005
1006
1007
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
998
999
1000
1001
1002
1003
1004

1005
1006
1007
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







-
+










-
-
-
+
+
+
-






-
+
-







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

		return length;
	} else {
		void *pool = objc_autoreleasePoolPush();
		OFString *line;
		of_range_t range;
		size_t pos;

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

		if (line == nil)
			return 0;

		range = [line rangeOfString: @";"];
		if (range.location != OF_NOT_FOUND)
			line = [line substringWithRange:
		pos = [line rangeOfString: @";"].location;
		if (pos != OF_NOT_FOUND)
			line = [line substringToIndex: pos];
			    of_range(0, range.location)];

		if (line.length < 1) {
			/*
			 * We have read the empty string because the socket is
			 * at end of stream.
			 */
			if (_socket.atEndOfStream &&
			if (_socket.atEndOfStream && pos == OF_NOT_FOUND)
			    range.location == OF_NOT_FOUND)
				@throw [OFTruncatedDataException exception];
			else
				@throw [OFInvalidServerReplyException
				    exception];
		}

		@try {
1129
1130
1131
1132
1133
1134
1135

1136











1137
1138
1139
1140
1141
1142
1143
1144

1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158

1159
1160
1161
1162
1163
1164
1165
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155

1156














1157
1158
1159
1160
1161
1162
1163
1164







+

+
+
+
+
+
+
+
+
+
+
+







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








	return _response;
}

-      (void)client: (OFHTTPClient *)client
  didPerformRequest: (OFHTTPRequest *)request
	   response: (OFHTTPResponse *)response
	  exception: (id)exception
{
	if (exception != nil) {
		/*
		 * Restore the delegate - we're giving up, but not reaching the
		 * release of the autorelease pool that contains us, so
		 * resetting it via -[dealloc] might be too late.
		 */
		_client.delegate = _delegate;

		@throw exception;
	}

	[[OFRunLoop currentRunLoop] stop];

	[_response release];
	_response = [response retain];

	[_delegate     client: client
	    didPerformRequest: request
		     response: response];
		     response: response
}

-	  (void)client: (OFHTTPClient *)client
  didFailWithException: (id)exception
	       request: (OFHTTPRequest *)request
{
	/*
	 * Restore the delegate - we're giving up, but not reaching the release
	 * of the autorelease pool that contains us, so resetting it via
	 * -[dealloc] might be too late.
	 */
	_client.delegate = _delegate;

	@throw exception;
		    exception: nil];
}

-    (void)client: (OFHTTPClient *)client
  didCreateSocket: (OFTCPSocket *)sock
	  request: (OFHTTPRequest *)request
{
	if ([_delegate respondsToSelector:
1178
1179
1180
1181
1182
1183
1184
1185

1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198

1199
1200
1201
1202
1203
1204
1205
1177
1178
1179
1180
1181
1182
1183

1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196

1197
1198
1199
1200
1201
1202
1203
1204







-
+












-
+







		[_delegate    client: client
		    wantsRequestBody: body
			     request: request];
}

-      (void)client: (OFHTTPClient *)client
  didReceiveHeaders: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headers
	 statusCode: (int)statusCode
	 statusCode: (short)statusCode
	    request: (OFHTTPRequest *)request
{
	if ([_delegate respondsToSelector:
	    @selector(client:didReceiveHeaders:statusCode:request:)])
		[_delegate     client: client
		    didReceiveHeaders: headers
			   statusCode: statusCode
			      request: request];
}

-	  (bool)client: (OFHTTPClient *)client
  shouldFollowRedirect: (OFURL *)URL
	    statusCode: (int)statusCode
	    statusCode: (short)statusCode
	       request: (OFHTTPRequest *)request
	      response: (OFHTTPResponse *)response
{
	if ([_delegate respondsToSelector: @selector(client:
	    shouldFollowRedirect:statusCode:request:response:)])
		return [_delegate client: client
		    shouldFollowRedirect: URL

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

359
360
361
362
363
364
365
366

367
368
369
370
371
372
373
359
360
361
362
363
364
365

366
367
368
369
370
371
372
373







-
+







	if (cookie->_extensions != _extensions &&
	    ![cookie->_extensions isEqual: _extensions])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);
	OF_HASH_ADD_HASH(hash, _name.hash);
	OF_HASH_ADD_HASH(hash, _value.hash);
	OF_HASH_ADD_HASH(hash, _domain.hash);

Modified src/OFHTTPCookieManager.m from [0f44cd343b] to [f3b5caf32a].

134
135
136
137
138
139
140
141
142


143
144
145
146
147
148
149
134
135
136
137
138
139
140


141
142
143
144
145
146
147
148
149







-
-
+
+








		cookieDomain = cookie.domain.lowercaseString;
		URLHost = URL.host.lowercaseString;
		if ([cookieDomain hasPrefix: @"."]) {
			if ([URLHost hasSuffix: cookieDomain])
				match = true;
			else {
				cookieDomain = [cookieDomain substringWithRange:
				    of_range(1, cookieDomain.length - 1)];
				cookieDomain =
				    [cookieDomain substringFromIndex: 1];

				match = [cookieDomain isEqual: URLHost];
			}
		} else
			match = [cookieDomain isEqual: URLHost];

		if (!match) {

Modified src/OFHTTPRequest.h from [345d23988c] to [8374acae4d].

55
56
57
58
59
60
61
62

63
64

65
66
67
68
69
70
71
55
56
57
58
59
60
61

62
63

64
65
66
67
68
69
70
71







-
+

-
+







 * @struct of_http_request_protocol_version_t \
 *	   OFHTTPRequest.h ObjFW/OFHTTPRequest.h
 *
 * @brief The HTTP version of the HTTP request.
 */
struct OF_BOXABLE of_http_request_protocol_version_t {
	/** The major of the HTTP version */
	uint8_t major;
	unsigned char major;
	/** The minor of the HTTP version */
	uint8_t minor;
	unsigned char minor;
};
typedef struct of_http_request_protocol_version_t
    of_http_request_protocol_version_t;

/**
 * @class OFHTTPRequest OFHTTPRequest.h ObjFW/OFHTTPRequest.h
 *

Modified src/OFHTTPRequest.m from [2b2b69fc08] to [517654630c].

181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
181
182
183
184
185
186
187

188
189
190
191
192
193
194
195







-
+







	if (request.remoteAddress != self.remoteAddress &&
	    !of_socket_address_equal(request.remoteAddress, self.remoteAddress))
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD(hash, _method);
	OF_HASH_ADD(hash, _protocolVersion.major);
204
205
206
207
208
209
210
211

212
213
214
215
216
217
218
204
205
206
207
208
209
210

211
212
213
214
215
216
217
218







-
+







	return hash;
}

- (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion
{
	if (protocolVersion.major != 1 || protocolVersion.minor > 1)
		@throw [OFUnsupportedVersionException exceptionWithVersion:
		    [OFString stringWithFormat: @"%u.%u",
		    [OFString stringWithFormat: @"%hhu.%hhu",
						protocolVersion.major,
						protocolVersion.minor]];

	_protocolVersion = protocolVersion;
}

- (of_http_request_protocol_version_t)protocolVersion
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
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







-
+


-
-
+
+








-
+








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

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

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

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

	self.protocolVersion = protocolVersion;

	objc_autoreleasePoolPop(pool);
}

- (OFString *)protocolVersionString
{
	return [OFString stringWithFormat: @"%u.%u",
	return [OFString stringWithFormat: @"%hhu.%hhu",
					   _protocolVersion.major,
					   _protocolVersion.minor];
}

- (OFString *)description
{
	void *pool = objc_autoreleasePoolPush();

Modified src/OFHTTPResponse.m from [b38122cc28] to [4e1a4b346b].

251
252
253
254
255
256
257
258

259
260
261
262
263
264
265
251
252
253
254
255
256
257

258
259
260
261
262
263
264
265







-
+







	[super dealloc];
}

- (void)setProtocolVersion: (of_http_request_protocol_version_t)protocolVersion
{
	if (protocolVersion.major != 1 || protocolVersion.minor > 1)
		@throw [OFUnsupportedVersionException exceptionWithVersion:
		    [OFString stringWithFormat: @"%u.%u",
		    [OFString stringWithFormat: @"%hhu.%hhu",
						protocolVersion.major,
						protocolVersion.minor]];

	_protocolVersion = protocolVersion;
}

- (of_http_request_protocol_version_t)protocolVersion
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
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







-
+


-
-
+
+








-
+








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

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

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

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

	self.protocolVersion = protocolVersion;

	objc_autoreleasePoolPop(pool);
}

- (OFString *)protocolVersionString
{
	return [OFString stringWithFormat: @"%u.%u",
	return [OFString stringWithFormat: @"%hhu.%hhu",
					   _protocolVersion.major,
					   _protocolVersion.minor];
}

- (OFString *)string
{
	return [self stringWithEncoding: OF_STRING_ENCODING_AUTODETECT];
346
347
348
349
350
351
352
353

354
355
356
357
358
359
360
361
362
346
347
348
349
350
351
352

353
354
355
356
357
358
359
360
361
362







-
+










	indentedHeaders = [_headers.description
	    stringByReplacingOccurrencesOfString: @"\n"
				      withString: @"\n\t"];

	ret = [[OFString alloc] initWithFormat:
	    @"<%@:\n"
	    @"\tStatus code = %d\n"
	    @"\tStatus code = %hd\n"
	    @"\tHeaders = %@\n"
	    @">",
	    self.class, _statusCode, indentedHeaders];

	objc_autoreleasePoolPop(pool);

	return [ret autorelease];
}
@end

Modified src/OFHTTPServer.m from [abf9a790cd] to [ac3250a22a].

143
144
145
146
147
148
149

150
151






152
153
154
155
156
157
158
143
144
145
146
147
148
149
150


151
152
153
154
155
156
157
158
159
160
161
162
163







+
-
-
+
+
+
+
+
+







		    ? of_ascii_toupper(*tmp)
		    : of_ascii_tolower(*tmp));

		firstLetter = false;
		tmp++;
	}

	@try {
	return [OFString stringWithUTF8StringNoCopy: cString
				       freeWhenDone: true];
		return [OFString stringWithUTF8StringNoCopy: cString
					       freeWhenDone: true];
	} @catch (id e) {
		free(cString);
		@throw e;
	}
}

@implementation OFHTTPServerResponse
- (instancetype)initWithSocket: (OFStreamSocket *)sock
			server: (OFHTTPServer *)server
		       request: (OFHTTPRequest *)request
{
180
181
182
183
184
185
186
187

188
189
190
191
192
193
194
185
186
187
188
189
190
191

192
193
194
195
196
197
198
199







-
+







- (void)of_sendHeaders
{
	void *pool = objc_autoreleasePoolPush();
	OFMutableDictionary OF_GENERIC(OFString *, OFString *) *headers;
	OFEnumerator *keyEnumerator, *valueEnumerator;
	OFString *key, *value;

	[_socket writeFormat: @"HTTP/%@ %d %@\r\n",
	[_socket writeFormat: @"HTTP/%@ %hd %@\r\n",
			      self.protocolVersionString, _statusCode,
			      of_http_status_code_to_string(_statusCode)];

	headers = [[_headers mutableCopy] autorelease];

	if ([headers objectForKey: @"Date"] == nil) {
		OFString *date = [[OFDate date]
372
373
374
375
376
377
378
379

380
381
382
383
384
385
386
377
378
379
380
381
382
383

384
385
386
387
388
389
390
391







-
+







		return [self sendErrorAndClose: 400];
	}

	pos = [line rangeOfString: @" "].location;
	if (pos == OF_NOT_FOUND)
		return [self sendErrorAndClose: 400];

	method = [line substringWithRange: of_range(0, pos)];
	method = [line substringToIndex: pos];
	@try {
		_method = of_http_request_method_from_string(method);
	} @catch (OFInvalidArgumentException *e) {
		return [self sendErrorAndClose: 405];
	}

	@try {
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
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







-
-
+
+
-


















-
+
-


-
-

-
+







		return false;
	}

	pos = [line rangeOfString: @":"].location;
	if (pos == OF_NOT_FOUND)
		return [self sendErrorAndClose: 400];

	key = [line substringWithRange: of_range(0, pos)];
	value = [line substringWithRange:
	key = [line substringToIndex: pos];
	value = [line substringFromIndex: pos + 1];
	    of_range(pos + 1, line.length - pos - 1)];

	key = normalizedKey(key.stringByDeletingTrailingWhitespaces);
	value = value.stringByDeletingLeadingWhitespaces;

	old = [_headers objectForKey: key];
	if (old != nil)
		value = [old stringByAppendingFormat: @",%@", value];

	[_headers setObject: value
		     forKey: key];

	if ([key isEqual: @"Host"]) {
		pos = [value
		    rangeOfString: @":"
			  options: OF_STRING_SEARCH_BACKWARDS].location;

		if (pos != OF_NOT_FOUND) {
			[_host release];
			_host = [[value substringWithRange:
			_host = [[value substringToIndex: pos] retain];
			    of_range(0, pos)] retain];

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

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

				_port = (uint16_t)portTmp;
			} @catch (OFInvalidFormatException *e) {
501
502
503
504
505
506
507
508

509
510
511
512
513
514
515
502
503
504
505
506
507
508

509
510
511
512
513
514
515
516







-
+







}

- (bool)sendErrorAndClose: (short)statusCode
{
	OFString *date = [[OFDate date]
	    dateStringWithFormat: @"%a, %d %b %Y %H:%M:%S GMT"];

	[_socket writeFormat: @"HTTP/1.1 %d %@\r\n"
	[_socket writeFormat: @"HTTP/1.1 %hd %@\r\n"
			      @"Date: %@\r\n"
			      @"Server: %@\r\n"
			      @"\r\n",
			      statusCode,
			      of_http_status_code_to_string(statusCode),
			      date, _server.name];

544
545
546
547
548
549
550
551
552


553
554
555
556
557
558
559
560
545
546
547
548
549
550
551


552
553

554
555
556
557
558
559
560







-
-
+
+
-







	URL.host = _host;
	if (_port != 80)
		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:
		path = [_path substringToIndex: pos];
		query = [_path substringFromIndex: pos + 1];
		    of_range(pos + 1, _path.length - pos - 1)];

		URL.URLEncodedPath = path;
		URL.URLEncodedQuery = query;
	} else
		URL.URLEncodedPath = _path;

	[URL makeImmutable];
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
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







-
+











-
-
-
+
+
+
-






-
+
-







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

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

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

		if (line == nil)
			return 0;

		range = [line rangeOfString: @";"];
		if (range.location != OF_NOT_FOUND)
			line = [line substringWithRange:
		pos = [line rangeOfString: @";"].location;
		if (pos != OF_NOT_FOUND)
			line = [line substringToIndex: pos];
			    of_range(0, range.location)];

		if (line.length < 1) {
			/*
			 * We have read the empty string because the socket is
			 * at end of stream.
			 */
			if (_socket.atEndOfStream &&
			if (_socket.atEndOfStream && pos == OF_NOT_FOUND)
			    range.location == OF_NOT_FOUND)
				@throw [OFTruncatedDataException exception];
			else
				@throw [OFInvalidFormatException exception];
		}

		toRead = [line unsignedLongLongValueWithBase: 16];
		if (toRead > LLONG_MAX)

Modified src/OFHostAddressResolver.m from [1663ef2651] to [9b355acb42].

275
276
277
278
279
280
281

282

283
284
285
286
287
288
289
290
275
276
277
278
279
280
281
282

283

284
285
286
287
288
289
290







+
-
+
-







		    of_socket_address_parse_ip(_host, 0);
		OFData *addresses = nil;
		id exception = nil;

		if (_addressFamily == address.family ||
		    _addressFamily == OF_SOCKET_ADDRESS_FAMILY_ANY)
			addresses = [OFData dataWithItems: &address
						    count: 1
						 itemSize: sizeof(address)
						 itemSize: sizeof(address)];
						    count: 1];
		else
			exception = [OFInvalidArgumentException exception];

		callDelegateInMode(_runLoopMode, _delegate, _resolver, _host,
		    addresses, exception);

		objc_autoreleasePoolPop(pool);

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

157
158
159
160
161
162
163
164
165

166
167
168
169



170
171
172
173
174
175
176
177
178
179
157
158
159
160
161
162
163


164




165
166
167



168
169
170
171
172
173
174







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







		    [[[OFINICategoryPair alloc] init] autorelease];
		OFString *key, *value;
		size_t pos;

		if ((pos = [line rangeOfString: @"="].location) == OF_NOT_FOUND)
			@throw [OFInvalidFormatException exception];

		key = [line substringWithRange: of_range(0, pos)];
		value = [line substringWithRange:
		key = unescapeString([line substringToIndex: pos]
		    of_range(pos + 1, line.length - pos - 1)];

		key = key.stringByDeletingEnclosingWhitespaces;
		value = value.stringByDeletingEnclosingWhitespaces;
		    .stringByDeletingEnclosingWhitespaces);
		value = unescapeString([line substringFromIndex: pos + 1]
		    .stringByDeletingEnclosingWhitespaces);

		key = unescapeString(key);
		value = unescapeString(value);

		pair->_key = [key copy];
		pair->_value = [value copy];

		[_lines addObject: pair];
	} else {
		OFINICategoryComment *comment =

Modified src/OFINIFileSettings.m from [c8fa651c4c] to [062d94ddbb].

63
64
65
66
67
68
69
70
71


72
73
74
75
76
77
78
79
63
64
65
66
67
68
69


70
71

72
73
74
75
76
77
78







-
-
+
+
-








	if (pos == OF_NOT_FOUND) {
		*category = @"";
		*key = path;
		return;
	}

	*category = [path substringWithRange: of_range(0, pos)];
	*key = [path substringWithRange:
	*category = [path substringToIndex: pos];
	*key = [path substringFromIndex: pos + 1];
	    of_range(pos + 1, path.length - pos - 1)];
}

- (void)setString: (OFString *)string
	  forPath: (OFString *)path
{
	void *pool = objc_autoreleasePoolPush();
	OFString *category, *key;

Modified src/OFIPSocketAsyncConnector.m from [6a448fb9d2] to [35ca21ecbd].

242
243
244
245
246
247
248

249

250
251
252
253
254
255
256
257
258
259
260
261
262
263
242
243
244
245
246
247
248
249

250

251
252
253
254
255
256
257
258
259
260
261
262
263







+
-
+
-













{
	@try {
		of_socket_address_t address =
		    of_socket_address_parse_ip(_host, _port);

		_socketAddresses = [[OFData alloc]
		    initWithItems: &address
			    count: 1
			 itemSize: sizeof(address)
			 itemSize: sizeof(address)];
			    count: 1];

		[self tryNextAddressWithRunLoopMode: runLoopMode];
		return;
	} @catch (OFInvalidFormatException *e) {
	}

	[[OFThread DNSResolver]
	    asyncResolveAddressesForHost: _host
			   addressFamily: OF_SOCKET_ADDRESS_FAMILY_ANY
			     runLoopMode: runLoopMode
				delegate: self];
}
@end

Modified src/OFInflateStream.m from [c1d8d6e047] to [b112db9229].

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







-
-
+













+
+
-
+
+
+



+







		_bitIndex = 8;

#ifdef OF_INFLATE64_STREAM_M
		_slidingWindowMask = 0xFFFF;
#else
		_slidingWindowMask = 0x7FFF;
#endif
		_slidingWindow = [self allocZeroedMemoryWithSize:
		    _slidingWindowMask + 1];
		_slidingWindow = of_calloc(_slidingWindowMask + 1, 1);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	if (_stream != nil)
		[self close];

	free(_slidingWindow);

	if (_state == HUFFMAN_TREE)
	if (_state == HUFFMAN_TREE) {
		free(_context.huffmanTree.lengths);

		if (_context.huffmanTree.codeLenTree != NULL)
			of_huffman_tree_release(
			    _context.huffmanTree.codeLenTree);
	}

	if (_state == HUFFMAN_TREE || _state == HUFFMAN_BLOCK) {
		if (_context.huffman.litLenTree != fixedLitLenTree)
			of_huffman_tree_release(_context.huffman.litLenTree);
		if (_context.huffman.distTree != fixedDistTree)
			of_huffman_tree_release(_context.huffman.distTree);
	}
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
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







-
+
-















-
+






-
-
+
+







				if OF_UNLIKELY (!tryReadBits(self, &bits, 4))
					return bytesWritten;

				CTX.codeLenCodesCount = bits;
			}

			if OF_LIKELY (CTX.lengths == NULL)
				CTX.lengths = [self
				CTX.lengths = of_calloc(19, 1);
				    allocZeroedMemoryWithSize: 19];

			for (uint16_t i = CTX.receivedCount;
			    i < CTX.codeLenCodesCount + 4; i++) {
				if OF_UNLIKELY (!tryReadBits(self, &bits, 3)) {
					CTX.receivedCount = i;
					return bytesWritten;
				}

				CTX.lengths[codeLengthsOrder[i]] = bits;
			}

			CTX.codeLenTree = of_huffman_tree_construct(
			    CTX.lengths, 19);
			CTX.treeIter = CTX.codeLenTree;

			[self freeMemory: CTX.lengths];
			free(CTX.lengths);
			CTX.lengths = NULL;
			CTX.receivedCount = 0;
			CTX.value = 0xFF;
		}

		if OF_LIKELY (CTX.lengths == NULL)
			CTX.lengths = [self allocMemoryWithSize:
			    CTX.litLenCodesCount + CTX.distCodesCount + 258];
			CTX.lengths = of_malloc(
			    CTX.litLenCodesCount + CTX.distCodesCount + 258, 1);

		for (uint16_t i = CTX.receivedCount;
		    i < CTX.litLenCodesCount + CTX.distCodesCount + 258;) {
			uint8_t j, count;

			if OF_LIKELY (CTX.value == 0xFF) {
				if OF_UNLIKELY (!of_huffman_tree_walk(self,
480
481
482
483
484
485
486
487

488
489
490
491
492
493
494
483
484
485
486
487
488
489

490
491
492
493
494
495
496
497







-
+








		CTX.litLenTree = of_huffman_tree_construct(CTX.lengths,
		    CTX.litLenCodesCount + 257);
		CTX.distTree = of_huffman_tree_construct(
		    CTX.lengths + CTX.litLenCodesCount + 257,
		    CTX.distCodesCount + 1);

		[self freeMemory: CTX.lengths];
		free(CTX.lengths);

		/*
		 * litLenTree and distTree are at the same location in
		 * _context.huffman and _context.huffmanTree, thus no need to
		 * set them.
		 */
		_state = HUFFMAN_BLOCK;

Modified src/OFKernelEventObserver.m from [58babda954] to [0cbb2bba17].

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







+


-
-
+
+











-
+

+
+







- (void)removeObjectForWriting: (id <OFReadyForWritingObserving>)object
{
	[_writeObjects removeObjectIdenticalTo: object];
}

- (bool)of_processReadBuffers
{
	void *pool = objc_autoreleasePoolPush();
	bool foundInReadBuffer = false;

	for (id object in _readObjects) {
		void *pool = objc_autoreleasePoolPush();
	for (id object in [[_readObjects copy] autorelease]) {
		void *pool2 = objc_autoreleasePoolPush();

		if ([object isKindOfClass: [OFStream class]] &&
		    [object hasDataInReadBuffer] &&
		    ![(OFStream *)object of_isWaitingForDelimiter]) {
			if ([_delegate respondsToSelector:
			    @selector(objectIsReadyForReading:)])
				[_delegate objectIsReadyForReading: object];

			foundInReadBuffer = true;
		}

		objc_autoreleasePoolPop(pool);
		objc_autoreleasePoolPop(pool2);
	}

	objc_autoreleasePoolPop(pool);

	/*
	 * As long as we have data in the read buffer for any stream, we don't
	 * want to block.
	 */
	return foundInReadBuffer;
}

Modified src/OFLHADecompressingStream.m from [16b7cb0b85] to [548b68c743].

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







-
-
+













+
+







+
+







		/* 0-7 address the bit, 8 means fetch next byte */
		_bitIndex = 8;

		_distanceBits = distanceBits;
		_dictionaryBits = dictionaryBits;

		_slidingWindowMask = (1u << dictionaryBits) - 1;
		_slidingWindow = [self allocMemoryWithSize:
		    _slidingWindowMask + 1];
		_slidingWindow = of_malloc(_slidingWindowMask + 1, 1);
		memset(_slidingWindow, ' ', _slidingWindowMask + 1);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	if (_stream != nil)
		[self close];

	free(_slidingWindow);

	if (_codeLenTree != NULL)
		of_huffman_tree_release(_codeLenTree);
	if (_litLenTree != NULL)
		of_huffman_tree_release(_litLenTree);
	if (_distTree != NULL)
		of_huffman_tree_release(_distTree);

	free(_codesLengths);

	[super dealloc];
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer_
			  length: (size_t)length
{
170
171
172
173
174
175
176
177

178
179
180
181
182
183
184
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187







-
+







		if OF_UNLIKELY (bits == 0) {
			_state = STATE_CODE_LEN_TREE_SINGLE;
			goto start;
		}

		_codesCount = bits;
		_codesReceived = 0;
		_codesLengths = [self allocZeroedMemoryWithSize: bits];
		_codesLengths = of_calloc(bits, 1);
		_skip = true;

		_state = STATE_CODE_LEN_TREE;
		goto start;
	case STATE_CODE_LEN_TREE:
		while (_codesReceived < _codesCount) {
			if OF_UNLIKELY (_currentIsExtendedLength) {
221
222
223
224
225
226
227
228


229
230
231
232
233
234
235
224
225
226
227
228
229
230

231
232
233
234
235
236
237
238
239







-
+
+







				continue;
			} else
				_codesReceived++;
		}

		_codeLenTree = of_huffman_tree_construct(_codesLengths,
		    _codesCount);
		[self freeMemory: _codesLengths];
		free(_codesLengths);
		_codesLengths = NULL;

		_state = STATE_LITLEN_CODES_COUNT;
		goto start;
	case STATE_CODE_LEN_TREE_SINGLE:
		if OF_UNLIKELY (!tryReadBits(self, &bits, 5))
			return bytesWritten;

250
251
252
253
254
255
256
257

258
259
260
261
262
263
264
254
255
256
257
258
259
260

261
262
263
264
265
266
267
268







-
+








			_state = STATE_LITLEN_TREE_SINGLE;
			goto start;
		}

		_codesCount = bits;
		_codesReceived = 0;
		_codesLengths = [self allocZeroedMemoryWithSize: bits];
		_codesLengths = of_calloc(bits, 1);
		_skip = false;

		_treeIter = _codeLenTree;
		_state = STATE_LITLEN_TREE;
		goto start;
	case STATE_LITLEN_TREE:
		while (_codesReceived < _codesCount) {
310
311
312
313
314
315
316
317


318
319
320
321
322
323
324
314
315
316
317
318
319
320

321
322
323
324
325
326
327
328
329







-
+
+







				_skip = true;
			} else
				_codesLengths[_codesReceived++] = value - 2;
		}

		_litLenTree = of_huffman_tree_construct(_codesLengths,
		    _codesCount);
		[self freeMemory: _codesLengths];
		free(_codesLengths);
		_codesLengths = NULL;

		of_huffman_tree_release(_codeLenTree);
		_codeLenTree = NULL;

		_state = STATE_DIST_CODES_COUNT;
		goto start;
	case STATE_LITLEN_TREE_SINGLE:
339
340
341
342
343
344
345
346

347
348
349
350
351
352
353
344
345
346
347
348
349
350

351
352
353
354
355
356
357
358







-
+







		if OF_UNLIKELY (bits == 0) {
			_state = STATE_DIST_TREE_SINGLE;
			goto start;
		}

		_codesCount = bits;
		_codesReceived = 0;
		_codesLengths = [self allocZeroedMemoryWithSize: bits];
		_codesLengths = of_calloc(bits, 1);

		_treeIter = _codeLenTree;
		_state = STATE_DIST_TREE;
		goto start;
	case STATE_DIST_TREE:
		while (_codesReceived < _codesCount) {
			if OF_UNLIKELY (_currentIsExtendedLength) {
374
375
376
377
378
379
380
381


382
383
384
385
386
387
388
379
380
381
382
383
384
385

386
387
388
389
390
391
392
393
394







-
+
+







				continue;
			} else
				_codesReceived++;
		}

		_distTree = of_huffman_tree_construct(_codesLengths,
		    _codesCount);
		[self freeMemory: _codesLengths];
		free(_codesLengths);
		_codesLengths = NULL;

		_treeIter = _litLenTree;
		_state = STATE_BLOCK_LITLEN;
		goto start;
	case STATE_DIST_TREE_SINGLE:
		if OF_UNLIKELY (!tryReadBits(self, &bits, _distanceBits))
			return bytesWritten;

Modified src/OFList.m from [58e8774a64] to [17f16f253f].

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







+
+

-
+

+
+
+








-
+







	}

	return self;
}

- (void)dealloc
{
	of_list_object_t *next;

	for (of_list_object_t *iter = _firstListObject;
	    iter != NULL; iter = iter->next)
	    iter != NULL; iter = next) {
		[iter->object release];
		next = iter->next;
		free(iter);
	}

	[super dealloc];
}

- (of_list_object_t *)appendObject: (id)object
{
	of_list_object_t *listObject;

	listObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	listObject = of_malloc(1, sizeof(of_list_object_t));
	listObject->object = [object retain];
	listObject->next = NULL;
	listObject->previous = _lastListObject;

	if (_lastListObject != NULL)
		_lastListObject->next = listObject;

111
112
113
114
115
116
117
118

119
120
121
122
123
124
125
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130







-
+







	return listObject;
}

- (of_list_object_t *)prependObject: (id)object
{
	of_list_object_t *listObject;

	listObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	listObject = of_malloc(1, sizeof(of_list_object_t));
	listObject->object = [object retain];
	listObject->next = _firstListObject;
	listObject->previous = NULL;

	if (_firstListObject != NULL)
		_firstListObject->previous = listObject;

134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
139
140
141
142
143
144
145

146
147
148
149
150
151
152
153







-
+







}

- (of_list_object_t *)insertObject: (id)object
		  beforeListObject: (of_list_object_t *)listObject
{
	of_list_object_t *newListObject;

	newListObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	newListObject = of_malloc(1, sizeof(of_list_object_t));
	newListObject->object = [object retain];
	newListObject->next = listObject;
	newListObject->previous = listObject->previous;

	if (listObject->previous != NULL)
		listObject->previous->next = newListObject;

158
159
160
161
162
163
164
165

166
167
168
169
170
171
172
163
164
165
166
167
168
169

170
171
172
173
174
175
176
177







-
+







}

- (of_list_object_t *)insertObject: (id)object
		   afterListObject: (of_list_object_t *)listObject
{
	of_list_object_t *newListObject;

	newListObject = [self allocMemoryWithSize: sizeof(of_list_object_t)];
	newListObject = of_malloc(1, sizeof(of_list_object_t));
	newListObject->object = [object retain];
	newListObject->next = listObject->next;
	newListObject->previous = listObject;

	if (listObject->next != NULL)
		listObject->next->previous = newListObject;

193
194
195
196
197
198
199
200
201

202
203
204
205
206
207
208
198
199
200
201
202
203
204


205
206
207
208
209
210
211
212







-
-
+







	if (_lastListObject == listObject)
		_lastListObject = listObject->previous;

	_count--;
	_mutations++;

	[listObject->object release];

	[self freeMemory: listObject];
	free(listObject);
}

- (id)firstObject
{
	return (_firstListObject != NULL ? _firstListObject->object : nil);
}

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







-
+



+
-
+
+

-
+
-
-
















-
-
+







			return true;

	return false;
}

- (void)removeAllObjects
{
	of_list_object_t *iter, *next;
	of_list_object_t *next;

	_mutations++;

	for (of_list_object_t *iter = _firstListObject;
	for (iter = _firstListObject; iter != NULL; iter = next) {
	    iter != NULL; iter = next) {
		[iter->object release];
		next = iter->next;

		free(iter);
		[iter->object release];
		[self freeMemory: iter];
	}

	_firstListObject = _lastListObject = NULL;
}

- (id)copy
{
	OFList *copy = [[[self class] alloc] init];
	of_list_object_t *listObject, *previous;

	listObject = NULL;
	previous = NULL;

	@try {
		for (of_list_object_t *iter = _firstListObject;
		    iter != NULL; iter = iter->next) {
			listObject = [copy allocMemoryWithSize:
			    sizeof(of_list_object_t)];
			listObject = of_malloc(1, sizeof(of_list_object_t));
			listObject->object = [iter->object retain];
			listObject->next = NULL;
			listObject->previous = previous;

			if (copy->_firstListObject == NULL)
				copy->_firstListObject = listObject;
			if (previous != NULL)
318
319
320
321
322
323
324
325

326
327
328
329
330
331
332
321
322
323
324
325
326
327

328
329
330
331
332
333
334
335







-
+







	}

	copy->_lastListObject = listObject;

	return copy;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	for (of_list_object_t *iter = _firstListObject;
	    iter != NULL; iter = iter->next)

Modified src/OFMapTable.h from [c882862b86] to [bf028bd496].

29
30
31
32
33
34
35
36

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

36
37
38
39
40
41
42
43







-
+







 */
struct of_map_table_functions_t {
	/** The function to retain keys / objects */
	void *_Nullable (*_Nullable retain)(void *_Nullable object);
	/** The function to release keys / objects */
	void (*_Nullable release)(void *_Nullable object);
	/** The function to hash keys */
	uint32_t (*_Nullable hash)(void *_Nullable object);
	unsigned long (*_Nullable hash)(void *_Nullable object);
	/** The function to compare keys / objects */
	bool (*_Nullable equal)(void *_Nullable object1,
	    void *_Nullable object2);
};
typedef struct of_map_table_functions_t of_map_table_functions_t;

#ifdef OF_HAVE_BLOCKS
72
73
74
75
76
77
78
79
80


81
82
83
84
85
86
87
72
73
74
75
76
77
78


79
80
81
82
83
84
85
86
87







-
-
+
+







 *	  and objects should be retained, released, compared and hashed.
 */
OF_SUBCLASSING_RESTRICTED
@interface OFMapTable: OFObject <OFCopying, OFFastEnumeration>
{
	of_map_table_functions_t _keyFunctions, _objectFunctions;
	struct of_map_table_bucket *_Nonnull *_Nullable _buckets;
	uint32_t _count, _capacity;
	uint8_t _rotate;
	unsigned long _count, _capacity;
	unsigned char _rotate;
	unsigned long _mutations;
}

/**
 * @brief The key functions used by the map table.
 */
@property (readonly, nonatomic) of_map_table_functions_t keyFunctions;
238
239
240
241
242
243
244
245
246
247


248
249
250
251
252
253
254
255
238
239
240
241
242
243
244



245
246

247
248
249
250
251
252
253







-
-
-
+
+
-







 * @brief A class which provides methods to enumerate through an OFMapTable's
 *	  keys or objects.
 */
@interface OFMapTableEnumerator: OFObject
{
	OFMapTable *_mapTable;
	struct of_map_table_bucket *_Nonnull *_Nullable _buckets;
	uint32_t _capacity;
	unsigned long _mutations;
	unsigned long *_Nullable _mutationsPtr;
	unsigned long _capacity, _mutations, *_Nullable _mutationsPtr;
	unsigned long _position;
	uint32_t _position;
}

- (instancetype)init OF_UNAVAILABLE;

/**
 * @brief Returns a pointer to the next object, or NULL if the enumeration
 *	  finished.

Modified src/OFMapTable.m from [ec26b7463a] to [bb1c57067e].

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







-
+














-
+


-
+












-
+






-
+







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

#define MIN_CAPACITY 16

struct of_map_table_bucket {
	void *key, *object;
	uint32_t hash;
	unsigned long hash;
};
static struct of_map_table_bucket deleted = { 0 };

static void *
defaultRetain(void *object)
{
	return object;
}

static void
defaultRelease(void *object)
{
}

static uint32_t
static unsigned long
defaultHash(void *object)
{
	return (uint32_t)(uintptr_t)object;
	return (unsigned long)(uintptr_t)object;
}

static bool
defaultEqual(void *object1, void *object2)
{
	return (object1 == object2);
}

OF_DIRECT_MEMBERS
@interface OFMapTable ()
- (void)of_setObject: (void *)object
	      forKey: (void *)key
		hash: (uint32_t)hash;
		hash: (unsigned long)hash;
@end

OF_DIRECT_MEMBERS
@interface OFMapTableEnumerator ()
- (instancetype)of_initWithMapTable: (OFMapTable *)mapTable
			    buckets: (struct of_map_table_bucket **)buckets
			   capacity: (uint32_t)capacity
			   capacity: (unsigned long)capacity
		   mutationsPointer: (unsigned long *)mutationsPtr
    OF_METHOD_FAMILY(init);
@end

@interface OFMapTableKeyEnumerator: OFMapTableEnumerator
@end

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







-
-
+
+



-
+






-
+





-
+
-













-
+



-
-
+
+
+
+
+
+







		SET_DEFAULT(_objectFunctions.retain, defaultRetain);
		SET_DEFAULT(_objectFunctions.release, defaultRelease);
		SET_DEFAULT(_objectFunctions.hash, defaultHash);
		SET_DEFAULT(_objectFunctions.equal, defaultEqual);

#undef SET_DEFAULT

		if (capacity > UINT32_MAX / sizeof(*_buckets) ||
		    capacity > UINT32_MAX / 8)
		if (capacity > ULONG_MAX / sizeof(*_buckets) ||
		    capacity > ULONG_MAX / 8)
			@throw [OFOutOfRangeException exception];

		for (_capacity = 1; _capacity < capacity;) {
			if (_capacity > UINT32_MAX / 2)
			if (_capacity > ULONG_MAX / 2)
				@throw [OFOutOfRangeException exception];

			_capacity *= 2;
		}

		if (capacity * 8 / _capacity >= 6)
			if (_capacity <= UINT32_MAX / 2)
			if (_capacity <= ULONG_MAX / 2)
				_capacity *= 2;

		if (_capacity < MIN_CAPACITY)
			_capacity = MIN_CAPACITY;

		_buckets = [self allocZeroedMemoryWithSize: sizeof(*_buckets)
		_buckets = of_calloc(_capacity, sizeof(*_buckets));
						     count: _capacity];

		if (of_hash_seed != 0)
			_rotate = of_random16() & 31;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	for (uint32_t i = 0; i < _capacity; i++) {
	for (unsigned long i = 0; i < _capacity; i++) {
		if (_buckets[i] != NULL && _buckets[i] != &deleted) {
			_keyFunctions.release(_buckets[i]->key);
			_objectFunctions.release(_buckets[i]->object);
		}
	}

			free(_buckets[i]);
		}
	}

	free(_buckets);

	[super dealloc];
}

- (bool)isEqual: (id)object
{
	OFMapTable *mapTable;
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
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







-
+













-
+

-
+

-
+

-
-
+
+














-
+




















-
+







	mapTable = object;

	if (mapTable->_count != _count ||
	    mapTable->_keyFunctions.equal != _keyFunctions.equal ||
	    mapTable->_objectFunctions.equal != _objectFunctions.equal)
		return false;

	for (uint32_t i = 0; i < _capacity; i++) {
	for (unsigned long i = 0; i < _capacity; i++) {
		if (_buckets[i] != NULL && _buckets[i] != &deleted) {
			void *objectIter =
			    [mapTable objectForKey: _buckets[i]->key];

			if (!_objectFunctions.equal(objectIter,
			    _buckets[i]->object))
				return false;
		}
	}

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash = 0;
	unsigned long hash = 0;

	for (uint32_t i = 0; i < _capacity; i++) {
	for (unsigned long i = 0; i < _capacity; i++) {
		if (_buckets[i] != NULL && _buckets[i] != &deleted) {
			hash += OF_ROR(_buckets[i]->hash, _rotate);
			hash += _objectFunctions.hash(_buckets[i]->object);
			hash ^= OF_ROR(_buckets[i]->hash, _rotate);
			hash ^= _objectFunctions.hash(_buckets[i]->object);
		}
	}

	return hash;
}

- (id)copy
{
	OFMapTable *copy = [[OFMapTable alloc]
	    initWithKeyFunctions: _keyFunctions
		 objectFunctions: _objectFunctions
			capacity: _capacity];

	@try {
		for (uint32_t i = 0; i < _capacity; i++)
		for (unsigned long i = 0; i < _capacity; i++)
			if (_buckets[i] != NULL && _buckets[i] != &deleted)
				[copy of_setObject: _buckets[i]->object
					    forKey: _buckets[i]->key
					      hash: OF_ROR(_buckets[i]->hash,
							_rotate)];
	} @catch (id e) {
		[copy release];
		@throw e;
	}

	return copy;
}

- (size_t)count
{
	return _count;
}

- (void *)objectForKey: (void *)key
{
	uint32_t i, hash, last;
	unsigned long i, hash, last;

	if (key == NULL)
		@throw [OFInvalidArgumentException exception];

	hash = OF_ROL(_keyFunctions.hash(key), _rotate);
	last = _capacity;

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







-
+

-
+


-
+





-
+















-
+
-

-
+

-
+







		if (_keyFunctions.equal(_buckets[i]->key, key))
			return _buckets[i]->object;
	}

	return NULL;
}

- (void)of_resizeForCount: (uint32_t)count OF_DIRECT
- (void)of_resizeForCount: (unsigned long)count OF_DIRECT
{
	uint32_t fullness, capacity;
	unsigned long fullness, capacity;
	struct of_map_table_bucket **buckets;

	if (count > UINT32_MAX / sizeof(*_buckets) || count > UINT32_MAX / 8)
	if (count > ULONG_MAX / sizeof(*_buckets) || count > ULONG_MAX / 8)
		@throw [OFOutOfRangeException exception];

	fullness = count * 8 / _capacity;

	if (fullness >= 6) {
		if (_capacity > UINT32_MAX / 2)
		if (_capacity > ULONG_MAX / 2)
			return;

		capacity = _capacity * 2;
	} else if (fullness <= 1)
		capacity = _capacity / 2;
	else
		return;

	/*
	 * Don't downsize if we have an initial capacity or if we would fall
	 * below the minimum capacity.
	 */
	if ((capacity < _capacity && count > _count) || capacity < MIN_CAPACITY)
		return;

	buckets = [self allocZeroedMemoryWithSize: sizeof(*buckets)
	buckets = of_calloc(capacity, sizeof(*buckets));
					    count: capacity];

	for (uint32_t i = 0; i < _capacity; i++) {
	for (unsigned long i = 0; i < _capacity; i++) {
		if (_buckets[i] != NULL && _buckets[i] != &deleted) {
			uint32_t j, last;
			unsigned long j, last;

			last = capacity;

			for (j = _buckets[i]->hash & (capacity - 1);
			    j < last && buckets[j] != NULL; j++);

			/* In case the last bucket is already used */
345
346
347
348
349
350
351
352

353
354
355
356
357
358
359

360
361

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

354
355
356
357
358
359
360

361
362

363
364
365
366
367
368
369
370







-
+






-
+

-
+







			if (j >= last)
				@throw [OFOutOfRangeException exception];

			buckets[j] = _buckets[i];
		}
	}

	[self freeMemory: _buckets];
	free(_buckets);
	_buckets = buckets;
	_capacity = capacity;
}

- (void)of_setObject: (void *)object
	      forKey: (void *)key
		hash: (uint32_t)hash
		hash: (unsigned long)hash
{
	uint32_t i, last;
	unsigned long i, last;
	void *old;

	if (key == NULL || object == NULL)
		@throw [OFInvalidArgumentException exception];

	hash = OF_ROL(hash, _rotate);
	last = _capacity;
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
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







-
+




-
+







-
+







			for (i = 0; i < last && _buckets[i] != NULL &&
			    _buckets[i] != &deleted; i++);
		}

		if (i >= last)
			@throw [OFOutOfRangeException exception];

		bucket = [self allocMemoryWithSize: sizeof(*bucket)];
		bucket = of_malloc(1, sizeof(*bucket));

		@try {
			bucket->key = _keyFunctions.retain(key);
		} @catch (id e) {
			[self freeMemory: bucket];
			free(bucket);
			@throw e;
		}

		@try {
			bucket->object = _objectFunctions.retain(object);
		} @catch (id e) {
			_keyFunctions.release(bucket->key);
			[self freeMemory: bucket];
			free(bucket);
			@throw e;
		}

		bucket->hash = hash;

		_buckets[i] = bucket;
		_count++;
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
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







-
+

















-
+







	[self of_setObject: object
		    forKey: key
		      hash: _keyFunctions.hash(key)];
}

- (void)removeObjectForKey: (void *)key
{
	uint32_t i, hash, last;
	unsigned long i, hash, last;

	if (key == NULL)
		@throw [OFInvalidArgumentException exception];

	hash = OF_ROL(_keyFunctions.hash(key), _rotate);
	last = _capacity;

	for (i = hash & (_capacity - 1); i < last && _buckets[i] != NULL; i++) {
		if (_buckets[i] == &deleted)
			continue;

		if (_keyFunctions.equal(_buckets[i]->key, key)) {
			_mutations++;

			_keyFunctions.release(_buckets[i]->key);
			_objectFunctions.release(_buckets[i]->object);

			[self freeMemory: _buckets[i]];
			free(_buckets[i]);
			_buckets[i] = &deleted;

			_count--;
			[self of_resizeForCount: _count];

			return;
		}
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
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







-
+













-
+









-
+






-
-
+
-














-
+












-
+







		if (_buckets[i] == &deleted)
			continue;

		if (_keyFunctions.equal(_buckets[i]->key, key)) {
			_keyFunctions.release(_buckets[i]->key);
			_objectFunctions.release(_buckets[i]->object);

			[self freeMemory: _buckets[i]];
			free(_buckets[i]);
			_buckets[i] = &deleted;

			_count--;
			_mutations++;
			[self of_resizeForCount: _count];

			return;
		}
	}
}

- (void)removeAllObjects
{
	for (uint32_t i = 0; i < _capacity; i++) {
	for (unsigned long i = 0; i < _capacity; i++) {
		if (_buckets[i] != NULL) {
			if (_buckets[i] == &deleted) {
				_buckets[i] = NULL;
				continue;
			}

			_keyFunctions.release(_buckets[i]->key);
			_objectFunctions.release(_buckets[i]->object);

			[self freeMemory: _buckets[i]];
			free(_buckets[i]);
			_buckets[i] = NULL;
		}
	}

	_count = 0;
	_capacity = MIN_CAPACITY;
	_buckets = [self resizeMemory: _buckets
				 size: sizeof(*_buckets)
	_buckets = of_realloc(_buckets, _capacity, sizeof(*_buckets));
				count: _capacity];

	/*
	 * Get a new random value for _rotate, so that it is not less secure
	 * than creating a new hash map.
	 */
	if (of_hash_seed != 0)
		_rotate = of_random16() & 31;
}

- (bool)containsObject: (void *)object
{
	if (object == NULL || _count == 0)
		return false;

	for (uint32_t i = 0; i < _capacity; i++)
	for (unsigned long i = 0; i < _capacity; i++)
		if (_buckets[i] != NULL && _buckets[i] != &deleted)
			if (_objectFunctions.equal(_buckets[i]->object, object))
				return true;

	return false;
}

- (bool)containsObjectIdenticalTo: (void *)object
{
	if (object == NULL || _count == 0)
		return false;

	for (uint32_t i = 0; i < _capacity; i++)
	for (unsigned long i = 0; i < _capacity; i++)
		if (_buckets[i] != NULL && _buckets[i] != &deleted)
			if (_buckets[i]->object == object)
				return true;

	return false;
}

581
582
583
584
585
586
587
588

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

588
589
590
591
592
593
594
595







-
+







	       mutationsPointer: &_mutations] autorelease];
}

- (int)countByEnumeratingWithState: (of_fast_enumeration_state_t *)state
			   objects: (id *)objects
			     count: (int)count
{
	uint32_t j = (uint32_t)state->state;
	unsigned long j = state->state;
	int i;

	for (i = 0; i < count; i++) {
		for (; j < _capacity && (_buckets[j] == NULL ||
		    _buckets[j] == &deleted); j++);

		if (j < _capacity) {
654
655
656
657
658
659
660
661

662
663
664
665
666
667
668
654
655
656
657
658
659
660

661
662
663
664
665
666
667
668







-
+







- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)of_initWithMapTable: (OFMapTable *)mapTable
			    buckets: (struct of_map_table_bucket **)buckets
			   capacity: (uint32_t)capacity
			   capacity: (unsigned long)capacity
		   mutationsPointer: (unsigned long *)mutationsPtr
{
	self = [super init];

	_mapTable = [mapTable retain];
	_buckets = buckets;
	_capacity = capacity;

Modified src/OFMapTableDictionary.m from [7eeaf3a50d] to [afa073ac3b].

45
46
47
48
49
50
51
52

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

52
53
54
55
56
57
58
59







-
+








static void
release(void *object)
{
	[(id)object release];
}

static uint32_t
static unsigned long
hash(void *object)
{
	return [(id)object hash];
}

static bool
equal(void *object1, void *object2)
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
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







-
+
-




















-
+












-
+
-




















-
+







- (OFArray *)allKeys
{
	OFArray *ret;
	id *keys;
	size_t count;

	count = _mapTable.count;
	keys = [self allocMemoryWithSize: sizeof(*keys)
	keys = of_malloc(count, sizeof(*keys));
				   count: count];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMapTableEnumerator *enumerator;
		void **keyPtr;
		size_t i;

		i = 0;
		enumerator = [_mapTable keyEnumerator];
		while ((keyPtr = [enumerator nextObject]) != NULL) {
			assert(i < count);

			keys[i++] = (id)*keyPtr;
		}

		objc_autoreleasePoolPop(pool);

		ret = [OFArray arrayWithObjects: keys
					  count: count];
	} @finally {
		[self freeMemory: keys];
		free(keys);
	}

	return ret;
}

- (OFArray *)allObjects
{
	OFArray *ret;
	id *objects;
	size_t count;

	count = _mapTable.count;
	objects = [self allocMemoryWithSize: sizeof(*objects)
	objects = of_malloc(count, sizeof(*objects));
				      count: count];

	@try {
		void *pool = objc_autoreleasePoolPush();
		OFMapTableEnumerator *enumerator;
		void **objectPtr;
		size_t i;

		i = 0;
		enumerator = [_mapTable objectEnumerator];
		while ((objectPtr = [enumerator nextObject]) != NULL) {
			assert(i < count);

			objects[i++] = (id)*objectPtr;
		}

		objc_autoreleasePoolPop(pool);

		ret = [OFArray arrayWithObjects: objects
					  count: count];
	} @finally {
		[self freeMemory: objects];
		free(objects);
	}

	return ret;
}

- (OFEnumerator *)keyEnumerator
{
442
443
444
445
446
447
448
449

450
451
452
453
440
441
442
443
444
445
446

447
448
449
450
451







-
+




	} @catch (OFEnumerationMutationException *e) {
		@throw [OFEnumerationMutationException
		    exceptionWithObject: self];
	}
}
#endif

- (uint32_t)hash
- (unsigned long)hash
{
	return _mapTable.hash;
}
@end

Modified src/OFMapTableSet.m from [9e9f04ba7b] to [6da1f132a2].

37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51







-
+








static void
release(void *object)
{
	[(id)object release];
}

static uint32_t
static unsigned long
hash(void *object)
{
	return [(id)object hash];
}

static bool
equal(void *object1, void *object2)

Modified src/OFMessagePackExtension.m from [c468d48f16] to [0041614de1].

173
174
175
176
177
178
179
180

181
182
183
184
185
186
187
173
174
175
176
177
178
179

180
181
182
183
184
185
186
187







-
+








	if (extension->_type != _type || ![extension->_data isEqual: _data])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD(hash, (uint8_t)_type);
	OF_HASH_ADD_HASH(hash, _data.hash);

Modified src/OFMethodSignature.m from [cf206c5116] to [67a687aa14].

593
594
595
596
597
598
599
600

601
602
603
604
605
606
607
593
594
595
596
597
598
599

600
601
602
603
604
605
606
607







-
+







			@throw [OFInvalidArgumentException exception];

		length = strlen(types);

		if (length == 0)
			@throw [OFInvalidFormatException exception];

		_types = [self allocMemoryWithSize: length + 1];
		_types = of_malloc(length + 1, 1);
		memcpy(_types, types, length);

		_typesPointers = [[OFMutableData alloc]
		    initWithItemSize: sizeof(char *)];
		_offsets = [[OFMutableData alloc]
		    initWithItemSize: sizeof(size_t)];

667
668
669
670
671
672
673

674
675
676
677
678
679
680
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681







+







	}

	return self;
}

- (void)dealloc
{
	free(_types);
	[_typesPointers release];
	[_offsets release];

	[super dealloc];
}

- (size_t)numberOfArguments

Modified src/OFMutableAdjacentArray.m from [1999b771ee] to [73c0aec03a].

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







-
-
+









-
+







	size_t count = _array.count;
	id *copy;

	if (range.length > SIZE_MAX - range.location ||
	    range.location >= count || range.length > count - range.location)
		@throw [OFOutOfRangeException exception];

	copy = [self allocMemoryWithSize: sizeof(*copy)
				   count: range.length];
	copy = of_malloc(range.length, sizeof(*copy));
	memcpy(copy, objects + range.location, range.length * sizeof(id));

	@try {
		[_array removeItemsInRange: range];
		_mutations++;

		for (size_t i = 0; i < range.length; i++)
			[copy[i] release];
	} @finally {
		[self freeMemory: copy];
		free(copy);
	}
}

- (void)removeLastObject
{
#ifndef __clang_analyzer__
	size_t count = _array.count;

Modified src/OFMutableData.m from [6ca92c6b7f] to [8aa04f6052].

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







+













+







}

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

	_itemSize = 1;
	_freeWhenDone = true;

	return self;
}

- (instancetype)initWithItemSize: (size_t)itemSize
{
	self = [super init];

	@try {
		if (itemSize == 0)
			@throw [OFInvalidArgumentException exception];

		_itemSize = itemSize;
		_freeWhenDone = true;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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
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







-
-
-
+


+









-

+


+
-
+
-







-

+



+
-
+
-







{
	self = [super init];

	@try {
		if (itemSize == 0)
			@throw [OFInvalidArgumentException exception];

		_items = [self allocMemoryWithSize: itemSize
					     count: capacity];

		_items = of_malloc(capacity, itemSize);
		_itemSize = itemSize;
		_capacity = capacity;
		_freeWhenDone = true;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithItems: (const void *)items
		     itemSize: (size_t)itemSize
			count: (size_t)count
		     itemSize: (size_t)itemSize
{
	self = [super initWithItems: items
			      count: count
			   itemSize: itemSize
			   itemSize: itemSize];
			      count: count];

	_capacity = _count;

	return self;
}

- (instancetype)initWithItemsNoCopy: (void *)items
			   itemSize: (size_t)itemSize
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	self = [self initWithItems: items
			     count: count
			  itemSize: itemSize
			  itemSize: itemSize];
			     count: count];

	if (freeWhenDone)
		free(items);

	return self;
}

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







+
-
+
-








-
+
-
-







- (OFData *)subdataWithRange: (of_range_t)range
{
	if (range.length > SIZE_MAX - range.location ||
	    range.location + range.length > _count)
		@throw [OFOutOfRangeException exception];

	return [OFData dataWithItems: _items + (range.location * _itemSize)
			       count: range.length
			    itemSize: _itemSize
			    itemSize: _itemSize];
			       count: range.length];
}

- (void)addItem: (const void *)item
{
	if (SIZE_MAX - _count < 1)
		@throw [OFOutOfRangeException exception];

	if (_count + 1 > _capacity) {
		_items = [self resizeMemory: _items
		_items = of_realloc(_items, _count + 1, _itemSize);
				       size: _itemSize
				      count: _count + 1];
		_capacity = _count + 1;
	}

	memcpy(_items + _count * _itemSize, item, _itemSize);

	_count++;
}
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
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







-
-
-
+















-
-
-
+
















-
-
-
+







- (void)addItems: (const void *)items
	   count: (size_t)count
{
	if (count > SIZE_MAX - _count)
		@throw [OFOutOfRangeException exception];

	if (_count + count > _capacity) {
		_items = [self resizeMemory: _items
				       size: _itemSize
				      count: _count + count];
		_items = of_realloc(_items, _count + count, _itemSize);
		_capacity = _count + count;
	}

	memcpy(_items + _count * _itemSize, items, count * _itemSize);
	_count += count;
}

- (void)insertItems: (const void *)items
	    atIndex: (size_t)idx
	      count: (size_t)count
{
	if (count > SIZE_MAX - _count || idx > _count)
		@throw [OFOutOfRangeException exception];

	if (_count + count > _capacity) {
		_items = [self resizeMemory: _items
				       size: _itemSize
				      count: _count + count];
		_items = of_realloc(_items, _count + count, _itemSize);
		_capacity = _count + count;
	}

	memmove(_items + (idx + count) * _itemSize, _items + idx * _itemSize,
	    (_count - idx) * _itemSize);
	memcpy(_items + idx * _itemSize, items, count * _itemSize);

	_count += count;
}

- (void)increaseCountBy: (size_t)count
{
	if (count > SIZE_MAX - _count)
		@throw [OFOutOfRangeException exception];

	if (_count + count > _capacity) {
		_items = [self resizeMemory: _items
				       size: _itemSize
				      count: _count + count];
		_items = of_realloc(_items, _count + count, _itemSize);
		_capacity = _count + count;
	}

	memset(_items + _count * _itemSize, '\0', count * _itemSize);
	_count += count;
}

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







-
+
-
-













-
+
-
-








-
-
+








+
-
+
-




+
+
+
+
+
+
+
+
+




	memmove(_items + range.location * _itemSize,
	    _items + (range.location + range.length) * _itemSize,
	    (_count - range.location - range.length) * _itemSize);

	_count -= range.length;
	@try {
		_items = [self resizeMemory: _items
		_items = of_realloc(_items, _count, _itemSize);
				       size: _itemSize
				      count: _count];
		_capacity = _count;
	} @catch (OFOutOfMemoryException *e) {
		/* We don't really care, as we only made it smaller */
	}
}

- (void)removeLastItem
{
	if (_count == 0)
		return;

	_count--;
	@try {
		_items = [self resizeMemory: _items
		_items = of_realloc(_items, _count, _itemSize);
				       size: _itemSize
				      count: _count];
		_capacity = _count;
	} @catch (OFOutOfMemoryException *e) {
		/* We don't care, as we only made it smaller */
	}
}

- (void)removeAllItems
{
	[self freeMemory: _items];

	free(_items);
	_items = NULL;
	_count = 0;
	_capacity = 0;
}

- (id)copy
{
	return [[OFData alloc] initWithItems: _items
				       count: _count
				    itemSize: _itemSize
				    itemSize: _itemSize];
				       count: _count];
}

- (void)makeImmutable
{
	if (_capacity != _count) {
		@try {
			_items = of_realloc(_items, _count, _itemSize);
			_capacity = _count;
		} @catch (OFOutOfMemoryException *e) {
			/* We don't care, as we only made it smaller */
		}
	}

	object_setClass(self, [OFData class]);
}
@end

Modified src/OFMutableSet.m from [460faa4705] to [247e02065c].

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







-
-
-
+













-
+








- (void)intersectSet: (OFSet *)set
{
	void *pool = objc_autoreleasePoolPush();
	size_t count = self.count;
	id *cArray;

	cArray = [self allocMemoryWithSize: sizeof(id)
				     count: count];

	cArray = of_malloc(count, sizeof(id));
	@try {
		size_t i;

		i = 0;
		for (id object in self) {
			assert(i < count);
			cArray[i++] = object;
		}

		for (i = 0; i < count; i++)
			if (![set containsObject: cArray[i]])
			      [self removeObject: cArray[i]];
	} @finally {
		[self freeMemory: cArray];
		free(cArray);
	}

	objc_autoreleasePoolPop(pool);
}

- (void)unionSet: (OFSet *)set
{

Modified src/OFMutableUTF8String.m from [cb57991be9] to [e2512a1c1d].

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







-
-
-
-
-
+
+
+
+
-








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







	if (self == [OFMutableUTF8String class])
		[self inheritMethodsFromClass: [OFUTF8String class]];
}

- (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String
			    freeWhenDone: (bool)freeWhenDone
{
	@try {
		self = [self initWithUTF8String: UTF8String];
	} @finally {
		if (freeWhenDone)
			free(UTF8String);
	self = [self initWithUTF8String: UTF8String];

	if (freeWhenDone)
		free(UTF8String);
	}

	return self;
}

- (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String
				  length: (size_t)UTF8StringLength
			    freeWhenDone: (bool)freeWhenDone
{
	@try {
		self = [self initWithUTF8String: UTF8String
					 length: UTF8StringLength];
	} @finally {
		if (freeWhenDone)
			free(UTF8String);
	self = [self initWithUTF8String: UTF8String
				 length: UTF8StringLength];

	if (freeWhenDone)
		free(UTF8String);
	}

	return self;
}

- (void)of_convertWithWordStartTable: (const of_unichar_t *const[])startTable
		     wordMiddleTable: (const of_unichar_t *const[])middleTable
		  wordStartTableSize: (size_t)startTableSize
101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
97
98
99
100
101
102
103

104

105
106
107
108
109
110
111







-
+
-







				_s->cString[i] = t;
		}

		return;
	}

	unicodeLen = self.length;
	unicodeString = [self allocMemoryWithSize: sizeof(of_unichar_t)
	unicodeString = of_malloc(unicodeLen, sizeof(of_unichar_t));
					    count: unicodeLen];

	i = j = 0;
	newCStringLength = 0;

	while (i < _s->cStringLength) {
		const of_unichar_t *const *table;
		size_t tableSize;
125
126
127
128
129
130
131
132

133
134
135
136
137
138
139
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134







-
+







			tableSize = middleTableSize;
		}

		cLen = of_string_utf8_decode(_s->cString + i,
		    _s->cStringLength - i, &c);

		if (cLen <= 0 || c > 0x10FFFF) {
			[self freeMemory: unicodeString];
			free(unicodeString);
			@throw [OFInvalidEncodingException exception];
		}

		isStart = of_ascii_isspace(c);

		if (c >> 8 < tableSize) {
			of_unichar_t tc = table[c >> 8][c & 0xFF];
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
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







-
+







-
+

-
+










-
-
+
+







-
+

-
+







		else if (c < 0x800)
			newCStringLength += 2;
		else if (c < 0x10000)
			newCStringLength += 3;
		else if (c < 0x110000)
			newCStringLength += 4;
		else {
			[self freeMemory: unicodeString];
			free(unicodeString);
			@throw [OFInvalidEncodingException exception];
		}

		i += cLen;
	}

	@try {
		newCString = [self allocMemoryWithSize: newCStringLength + 1];
		newCString = of_malloc(newCStringLength + 1, 1);
	} @catch (id e) {
		[self freeMemory: unicodeString];
		free(unicodeString);
		@throw e;
	}

	j = 0;

	for (i = 0; i < unicodeLen; i++) {
		size_t d;

		if ((d = of_string_utf8_encode(unicodeString[i],
		    newCString + j)) == 0) {
			[self freeMemory: unicodeString];
			[self freeMemory: newCString];
			free(unicodeString);
			free(newCString);
			@throw [OFInvalidEncodingException exception];
		}
		j += d;
	}

	assert(j == newCStringLength);
	newCString[j] = 0;
	[self freeMemory: unicodeString];
	free(unicodeString);

	[self freeMemory: _s->cString];
	free(_s->cString);
	_s->hashed = false;
	_s->cString = newCString;
	_s->cStringLength = newCStringLength;

	/*
	 * Even though cStringLength can change, length cannot, therefore no
	 * need to change it.
225
226
227
228
229
230
231
232
233
234


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



227
228
229
230
231
232
233
234
235







-
-
-
+
+







		@throw [OFInvalidEncodingException exception];

	_s->hashed = false;

	if (lenNew == (size_t)lenOld)
		memcpy(_s->cString + idx, buffer, lenNew);
	else if (lenNew > (size_t)lenOld) {
		_s->cString = [self resizeMemory: _s->cString
					    size: _s->cStringLength -
						  lenOld + lenNew + 1];
		_s->cString = of_realloc(_s->cString,
		    _s->cStringLength - lenOld + lenNew + 1, 1);

		memmove(_s->cString + idx + lenNew, _s->cString + idx + lenOld,
		    _s->cStringLength - idx - lenOld);
		memcpy(_s->cString + idx, buffer, lenNew);

		_s->cStringLength -= lenOld;
		_s->cStringLength += lenNew;
252
253
254
255
256
257
258
259

260
261

262
263
264
265
266
267
268
246
247
248
249
250
251
252

253


254
255
256
257
258
259
260
261







-
+
-
-
+







		_s->cStringLength += lenNew;
		_s->cString[_s->cStringLength] = '\0';

		if (character >= 0x80)
			_s->isUTF8 = true;

		@try {
			_s->cString = [self
			_s->cString = of_realloc(_s->cString,
			    resizeMemory: _s->cString
				    size: _s->cStringLength + 1];
			    _s->cStringLength + 1, 1);
		} @catch (OFOutOfMemoryException *e) {
			/* We don't really care, as we only made it smaller */
		}
	}
}

- (void)appendUTF8String: (const char *)UTF8String
281
282
283
284
285
286
287
288
289
290


291
292
293
294
295
296
297
274
275
276
277
278
279
280



281
282
283
284
285
286
287
288
289







-
-
-
+
+







		_s->isUTF8 = true;
		break;
	case -1:
		@throw [OFInvalidEncodingException exception];
	}

	_s->hashed = false;
	_s->cString = [self resizeMemory: _s->cString
				    size: _s->cStringLength +
					  UTF8StringLength + 1];
	_s->cString = of_realloc(_s->cString,
	    _s->cStringLength + UTF8StringLength + 1, 1);
	memcpy(_s->cString + _s->cStringLength, UTF8String,
	    UTF8StringLength + 1);

	_s->cStringLength += UTF8StringLength;
	_s->length += length;
}

311
312
313
314
315
316
317
318
319
320


321
322
323
324
325
326
327
303
304
305
306
307
308
309



310
311
312
313
314
315
316
317
318







-
-
-
+
+







		_s->isUTF8 = true;
		break;
	case -1:
		@throw [OFInvalidEncodingException exception];
	}

	_s->hashed = false;
	_s->cString = [self resizeMemory: _s->cString
				    size: _s->cStringLength +
					  UTF8StringLength + 1];
	_s->cString = of_realloc(_s->cString,
	    _s->cStringLength + UTF8StringLength + 1, 1);
	memcpy(_s->cString + _s->cStringLength, UTF8String, UTF8StringLength);

	_s->cStringLength += UTF8StringLength;
	_s->length += length;

	_s->cString[_s->cStringLength] = 0;
}
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
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







-
-
-
+
+



















-
+

-




















-
-
+
+








-
+








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

	UTF8StringLength = string.UTF8StringLength;

	_s->hashed = false;
	_s->cString = [self resizeMemory: _s->cString
				    size: _s->cStringLength +
					  UTF8StringLength + 1];
	_s->cString = of_realloc(_s->cString,
	    _s->cStringLength + UTF8StringLength + 1, 1);
	memcpy(_s->cString + _s->cStringLength, string.UTF8String,
	    UTF8StringLength);

	_s->cStringLength += UTF8StringLength;
	_s->length += string.length;

	_s->cString[_s->cStringLength] = 0;

	if ([string isKindOfClass: [OFUTF8String class]] ||
	    [string isKindOfClass: [OFMutableUTF8String class]]) {
		if (((OFMutableUTF8String *)string)->_s->isUTF8)
			_s->isUTF8 = true;
	} else
		_s->isUTF8 = true;
}

- (void)appendCharacters: (const of_unichar_t *)characters
		  length: (size_t)length
{
	char *tmp;
	char *tmp = of_malloc((length * 4) + 1, 1);

	tmp = [self allocMemoryWithSize: (length * 4) + 1];
	@try {
		size_t j = 0;
		bool isUTF8 = false;

		for (size_t i = 0; i < length; i++) {
			size_t len = of_string_utf8_encode(characters[i],
			    tmp + j);

			if (len == 0)
				@throw [OFInvalidEncodingException exception];

			if (len > 1)
				isUTF8 = true;

			j += len;
		}

		tmp[j] = '\0';

		_s->hashed = false;
		_s->cString = [self resizeMemory: _s->cString
					    size: _s->cStringLength + j + 1];
		_s->cString = of_realloc(_s->cString,
		    _s->cStringLength + j + 1, 1);
		memcpy(_s->cString + _s->cStringLength, tmp, j + 1);

		_s->cStringLength += j;
		_s->length += length;

		if (isUTF8)
			_s->isUTF8 = true;
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}
}

- (void)appendFormat: (OFConstantString *)format
	   arguments: (va_list)arguments
{
	char *UTF8String;
533
534
535
536
537
538
539
540
541

542
543
544
545
546
547
548
522
523
524
525
526
527
528


529
530
531
532
533
534
535
536







-
-
+








	if (_s->isUTF8)
		idx = of_string_utf8_get_position(_s->cString, idx,
		    _s->cStringLength);

	newCStringLength = _s->cStringLength + string.UTF8StringLength;
	_s->hashed = false;
	_s->cString = [self resizeMemory: _s->cString
				    size: newCStringLength + 1];
	_s->cString = of_realloc(_s->cString, newCStringLength + 1, 1);

	memmove(_s->cString + idx + string.UTF8StringLength,
	    _s->cString + idx, _s->cStringLength - idx);
	memcpy(_s->cString + idx, string.UTF8String,
	    string.UTF8StringLength);
	_s->cString[newCStringLength] = '\0';

576
577
578
579
580
581
582
583
584

585
586
587
588
589
590
591
564
565
566
567
568
569
570


571
572
573
574
575
576
577
578







-
-
+







	    _s->cStringLength - end);
	_s->hashed = false;
	_s->length -= range.length;
	_s->cStringLength -= end - start;
	_s->cString[_s->cStringLength] = 0;

	@try {
		_s->cString = [self resizeMemory: _s->cString
					    size: _s->cStringLength + 1];
		_s->cString = of_realloc(_s->cString, _s->cStringLength + 1, 1);
	} @catch (OFOutOfMemoryException *e) {
		/* We don't really care, as we only made it smaller */
	}
}

- (void)replaceCharactersInRange: (of_range_t)range
		      withString: (OFString *)replacement
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
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







-
-
+












-
-
+







	 * memmove() the rest of the string to the end.
	 *
	 * We must not resize the string if the new string is smaller, because
	 * then we can't memmove() the rest of the string forward as the rest is
	 * lost due to the resize!
	 */
	if (newCStringLength > _s->cStringLength)
		_s->cString = [self resizeMemory: _s->cString
					    size: newCStringLength + 1];
		_s->cString = of_realloc(_s->cString, newCStringLength + 1, 1);

	memmove(_s->cString + start + replacement.UTF8StringLength,
	    _s->cString + end, _s->cStringLength - end);
	memcpy(_s->cString + start, replacement.UTF8String,
	    replacement.UTF8StringLength);
	_s->cString[newCStringLength] = '\0';

	/*
	 * If the new string is smaller, we can safely resize it now as we're
	 * done with memmove().
	 */
	if (newCStringLength < _s->cStringLength)
		_s->cString = [self resizeMemory: _s->cString
					    size: newCStringLength + 1];
		_s->cString = of_realloc(_s->cString, newCStringLength + 1, 1);

	_s->cStringLength = newCStringLength;
	_s->length = newLength;

	if ([replacement isKindOfClass: [OFUTF8String class]] ||
	    [replacement isKindOfClass: [OFMutableUTF8String class]]) {
		if (((OFMutableUTF8String *)replacement)->_s->isUTF8)
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
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







-
-
+
-
-
+
+

-
+















-
-
-
+
+

-
+







-
+







	last = 0;

	for (size_t i = range.location; i <= range.length - searchLength; i++) {
		if (memcmp(_s->cString + i, searchString, searchLength) != 0)
			continue;

		@try {
			newCString = [self resizeMemory: newCString
						   size: newCStringLength +
			newCString = of_realloc(newCString,
							 i - last +
							 replacementLength + 1];
			    newCStringLength + i - last + replacementLength + 1,
			    1);
		} @catch (id e) {
			[self freeMemory: newCString];
			free(newCString);
			@throw e;
		}
		memcpy(newCString + newCStringLength, _s->cString + last,
		    i - last);
		memcpy(newCString + newCStringLength + i - last,
		    replacementString, replacementLength);

		newCStringLength += i - last + replacementLength;
		newLength = newLength - string.length + replacement.length;

		i += searchLength - 1;
		last = i + 1;
	}

	@try {
		newCString = [self resizeMemory: newCString
					   size: newCStringLength +
						 _s->cStringLength - last + 1];
		newCString = of_realloc(newCString,
		    newCStringLength + _s->cStringLength - last + 1, 1);
	} @catch (id e) {
		[self freeMemory: newCString];
		free(newCString);
		@throw e;
	}
	memcpy(newCString + newCStringLength, _s->cString + last,
	    _s->cStringLength - last);
	newCStringLength += _s->cStringLength - last;
	newCString[newCStringLength] = 0;

	[self freeMemory: _s->cString];
	free(_s->cString);
	_s->hashed = false;
	_s->cString = newCString;
	_s->cStringLength = newCStringLength;
	_s->length = newLength;

	if ([replacement isKindOfClass: [OFUTF8String class]] ||
	    [replacement isKindOfClass: [OFMutableUTF8String class]]) {
749
750
751
752
753
754
755
756
757

758
759
760
761
762
763
764
732
733
734
735
736
737
738


739
740
741
742
743
744
745
746







-
-
+







	_s->cStringLength -= i;
	_s->length -= i;

	memmove(_s->cString, _s->cString + i, _s->cStringLength);
	_s->cString[_s->cStringLength] = '\0';

	@try {
		_s->cString = [self resizeMemory: _s->cString
					    size: _s->cStringLength + 1];
		_s->cString = of_realloc(_s->cString, _s->cStringLength + 1, 1);
	} @catch (OFOutOfMemoryException *e) {
		/* We don't really care, as we only made it smaller */
	}
}

- (void)deleteTrailingWhitespaces
{
776
777
778
779
780
781
782
783
784

785
786
787
788
789
790
791
758
759
760
761
762
763
764


765
766
767
768
769
770
771
772







-
-
+







		d++;
	}

	_s->cStringLength -= d;
	_s->length -= d;

	@try {
		_s->cString = [self resizeMemory: _s->cString
					    size: _s->cStringLength + 1];
		_s->cString = of_realloc(_s->cString, _s->cStringLength + 1, 1);
	} @catch (OFOutOfMemoryException *e) {
		/* We don't really care, as we only made it smaller */
	}
}

- (void)deleteEnclosingWhitespaces
{
813
814
815
816
817
818
819
820
821

822
823
824
825
826
827
828
829
830
831
794
795
796
797
798
799
800


801
802
803
804
805
806
807
808
809
810
811







-
-
+










	_s->cStringLength -= i;
	_s->length -= i;

	memmove(_s->cString, _s->cString + i, _s->cStringLength);
	_s->cString[_s->cStringLength] = '\0';

	@try {
		_s->cString = [self resizeMemory: _s->cString
					    size: _s->cStringLength + 1];
		_s->cString = of_realloc(_s->cString, _s->cStringLength + 1, 1);
	} @catch (OFOutOfMemoryException *e) {
		/* We don't really care, as we only made it smaller */
	}
}

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

Modified src/OFNumber.m from [eeab93bc59] to [80a9f3f337].

983
984
985
986
987
988
989
990

991
992
993
994
995
996
997
983
984
985
986
987
988
989

990
991
992
993
994
995
996
997







-
+







		if (uint1 < uint2)
			return OF_ORDERED_ASCENDING;

		return OF_ORDERED_SAME;
	}
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	if (isFloat(self)) {
		double d;

Modified src/OFObject+KeyValueCoding.m from [4f60753bfd] to [060fc086b7].

46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
46
47
48
49
50
51
52

53



54
55
56
57
58
59
60







-
+
-
-
-







		char *name;

		if ((keyLength = key.UTF8StringLength) < 1) {
			objc_autoreleasePoolPop(pool);
			return [self valueForUndefinedKey: key];
		}

		if ((name = malloc(keyLength + 3)) == NULL)
		name = of_malloc(keyLength + 3, 1);
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: keyLength + 3];

		@try {
			memcpy(name, "is", 2);
			memcpy(name + 2, key.UTF8String, keyLength);
			name[keyLength + 2] = '\0';

			name[2] = of_ascii_toupper(name[2]);

161
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
158
159
160
161
162
163
164

165



166
167
168
169
170
171
172







-
+
-
-
-







	if ((keyLength = key.UTF8StringLength) < 1) {
		objc_autoreleasePoolPop(pool);
		[self	   setValue: value
		    forUndefinedKey: key];
		return;
	}

	if ((name = malloc(keyLength + 5)) == NULL)
	name = of_malloc(keyLength + 5, 1);
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: keyLength + 5];

	@try {
		memcpy(name, "set", 3);
		memcpy(name + 3, key.UTF8String, keyLength);
		memcpy(name + keyLength + 3, ":", 2);

		name[3] = of_ascii_toupper(name[3]);

Modified src/OFObject.h from [5951a63423] to [8a371736ae].

318
319
320
321
322
323
324
325

326
327
328
329
330
331
332
318
319
320
321
322
323
324

325
326
327
328
329
330
331
332







-
+







 *
 * @warning If you reimplement this, you also need to reimplement @ref isEqual:
 *	    to behave in a way compatible to your reimplementation of this
 *	    method!
 *
 * @return A 32 bit hash for the object
 */
- (uint32_t)hash;
- (unsigned long)hash;

/**
 * @brief Returns the retain count.
 *
 * @return The retain count
 */
- (unsigned int)retainCount;
541
542
543
544
545
546
547
548

549
550
551
552
553
554
555
541
542
543
544
545
546
547

548
549
550
551
552
553
554
555







-
+








# ifdef __cplusplus
@property (readonly, nonatomic) Class class;
# else
@property (readonly, nonatomic, getter=class) Class class_;
#endif
@property OF_NULLABLE_PROPERTY (readonly, nonatomic) Class superclass;
@property (readonly, nonatomic) uint32_t hash;
@property (readonly, nonatomic) unsigned long hash;
@property (readonly, nonatomic) unsigned int retainCount;
@property (readonly, nonatomic) bool isProxy;
@property (readonly, nonatomic) bool allowsWeakReference;

/**
 * @brief The name of the object's class.
 */
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
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
802
803
804
805
806
807
808



























































































809
810
811
812
813
814
815







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







 *
 * @param selector The selector for which the method signature should be
 *		   returned
 * @return The method signature for the specified selector
 */
- (nullable OFMethodSignature *)methodSignatureForSelector: (SEL)selector;

/**
 * @brief Allocates memory and stores it in the object's memory pool.
 *
 * It will be free'd automatically when the object is deallocated.
 *
 * @param size The size of the memory to allocate
 * @return A pointer to the allocated memory. May return NULL if the specified
 *	   size is 0.
 */
- (nullable void *)allocMemoryWithSize: (size_t)size OF_WARN_UNUSED_RESULT;

/**
 * @brief Allocates memory for the specified number of items and stores it in
 *	  the object's memory pool.
 *
 * It will be free'd automatically when the object is deallocated.
 *
 * @param size The size of each item to allocate
 * @param count The number of items to allocate
 * @return A pointer to the allocated memory. May return NULL if the specified
 *	   size or count is 0.
 */
- (nullable void *)allocMemoryWithSize: (size_t)size
				 count: (size_t)count OF_WARN_UNUSED_RESULT;

/**
 * @brief Allocates memory, initializes it with zeros and stores it in the
 *	  object's memory pool.
 *
 * It will be free'd automatically when the object is deallocated.
 *
 * @param size The size of the memory to allocate
 * @return A pointer to the allocated memory. May return NULL if the specified
 *	   size is 0.
 */
- (nullable void *)allocZeroedMemoryWithSize: (size_t)size
    OF_WARN_UNUSED_RESULT;

/**
 * @brief Allocates memory for the specified number of items, initializes it
 *	  with zeros and stores it in the object's memory pool.
 *
 * It will be free'd automatically when the object is deallocated.
 *
 * @param size The size of each item to allocate
 * @param count The number of items to allocate
 * @return A pointer to the allocated memory. May return NULL if the specified
 *	   size or count is 0.
 */
- (nullable void *)allocZeroedMemoryWithSize: (size_t)size
				       count: (size_t)count
    OF_WARN_UNUSED_RESULT;

/**
 * @brief Resizes memory in the object's memory pool to the specified size.
 *
 * If the pointer is NULL, this is equivalent to allocating memory.
 * If the size is 0, this is equivalent to freeing memory.
 *
 * @param pointer A pointer to the already allocated memory
 * @param size The new size for the memory chunk
 * @return A pointer to the resized memory chunk
 */
- (nullable void *)resizeMemory: (nullable void *)pointer
			   size: (size_t)size OF_WARN_UNUSED_RESULT;

/**
 * @brief Resizes memory in the object's memory pool to the specific number of
 *	  items of the specified size.
 *
 * If the pointer is NULL, this is equivalent to allocating memory.
 * If the size or number of items is 0, this is equivalent to freeing memory.
 *
 * @param pointer A pointer to the already allocated memory
 * @param size The size of each item to resize to
 * @param count The number of items to resize to
 * @return A pointer to the resized memory chunk
 */
- (nullable void *)resizeMemory: (nullable void *)pointer
			   size: (size_t)size
			  count: (size_t)count OF_WARN_UNUSED_RESULT;

/**
 * @brief Frees allocated memory and removes it from the object's memory pool.
 *
 * Does nothing if the pointer is NULL.
 *
 * @param pointer A pointer to the allocated memory
 */
- (void)freeMemory: (nullable void *)pointer;

/**
 * @brief Deallocates the object.
 *
 * It is automatically called when the retain count reaches zero.
 *
 * This also frees all memory in its memory pool.
 */
1325
1326
1327
1328
1329
1330
1331




















































1332
1333
1334
1335
1336
1337
1338
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







- (of_comparison_result_t)compare: (id <OFComparing>)object;
@end
#endif

#ifdef __cplusplus
extern "C" {
#endif
/**
 * @brief Allocates memory for the specified number of items.
 *
 * To free the allocated memory, use `free()`.
 *
 * Throws @ref OFOutOfMemoryException if allocating failed and
 * @ref OFOutOfRangeException if the requested size exceeds the address space.
 *
 * @param count The number of items to allocate
 * @param size The size of each item to allocate
 * @return A pointer to the allocated memory. May return NULL if the specified
 *	   size or count is 0.
 */
extern void *_Nullable of_malloc(size_t count, size_t size)
    OF_WARN_UNUSED_RESULT;

/**
 * @brief Allocates memory for the specified number of items and initializes it
 *	  with zeros.
 *
 * To free the allocated memory, use `free()`.
 *
 * Throws @ref OFOutOfMemoryException if allocating failed and
 * @ref OFOutOfRangeException if the requested size exceeds the address space.
 *
 * @param size The size of each item to allocate
 * @param count The number of items to allocate
 * @return A pointer to the allocated memory. May return NULL if the specified
 *	   size or count is 0.
 */
extern void *_Nullable of_calloc(size_t count, size_t size)
    OF_WARN_UNUSED_RESULT;

/**
 * @brief Resizes memory to the specific number of items of the specified size.
 *
 * To free the allocated memory, use `free()`.
 *
 * If the pointer is NULL, this is equivalent to allocating memory.
 * If the size or number of items is 0, this is equivalent to freeing memory.
 *
 * Throws @ref OFOutOfMemoryException if allocating failed and
 * @ref OFOutOfRangeException if the requested size exceeds the address space.
 *
 * @param pointer A pointer to the already allocated memory
 * @param size The size of each item to resize to
 * @param count The number of items to resize to
 * @return A pointer to the resized memory chunk
 */
extern void *_Nullable of_realloc(void *_Nullable pointer, size_t count,
    size_t size) OF_WARN_UNUSED_RESULT;

#ifdef OF_APPLE_RUNTIME
extern void *_Null_unspecified objc_autoreleasePoolPush(void);
extern void objc_autoreleasePoolPop(void *_Null_unspecified pool);
# ifndef __OBJC2__
extern id _Nullable objc_constructInstance(Class _Nullable class_,
    void *_Nullable bytes);
extern void *_Nullable objc_destructInstance(id _Nullable object);

Modified src/OFObject.m from [567d4abd47] to [4360aae9b1].

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







-
-
-
-
-
-






-
-
-
-

















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







#endif

struct pre_ivar {
	int retainCount;
#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS)
	of_spinlock_t retainCountSpinlock;
#endif
	struct pre_mem *firstMem, *lastMem;
};

struct pre_mem {
	struct pre_mem *prev, *next;
	id owner;
};

#define PRE_IVARS_ALIGN ((sizeof(struct pre_ivar) + \
    (OF_BIGGEST_ALIGNMENT - 1)) & ~(OF_BIGGEST_ALIGNMENT - 1))
#define PRE_IVARS ((struct pre_ivar *)(void *)((char *)self - PRE_IVARS_ALIGN))

#define PRE_MEM_ALIGN ((sizeof(struct pre_mem) + \
    (OF_BIGGEST_ALIGNMENT - 1)) & ~(OF_BIGGEST_ALIGNMENT - 1))
#define PRE_MEM(mem) ((struct pre_mem *)(void *)((char *)mem - PRE_MEM_ALIGN))

static struct {
	Class isa;
} allocFailedException;

#ifdef OF_AMIGAOS
# undef of_hash_seed
#endif

uint32_t of_hash_seed;

#ifdef OF_AMIGAOS
uint32_t *
of_hash_seed_ref(void)
{
	return &of_hash_seed;
}
#endif

void *
of_malloc(size_t count, size_t size)
{
	void *pointer;

	if OF_UNLIKELY (count == 0 || size == 0)
		return NULL;

	if OF_UNLIKELY (count > SIZE_MAX / size)
		@throw [OFOutOfRangeException exception];

	if OF_UNLIKELY ((pointer = malloc(count * size)) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: size];

	return pointer;
}

void *
of_calloc(size_t count, size_t size)
{
	void *pointer;

	if OF_UNLIKELY (count == 0 || size == 0)
		return NULL;

	/* Not all calloc implementations check for overflow. */
	if OF_UNLIKELY (count > SIZE_MAX / size)
		@throw [OFOutOfRangeException exception];

	if OF_UNLIKELY ((pointer = calloc(count, size)) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: size];

	return pointer;
}

void *
of_realloc(void *pointer, size_t count, size_t size)
{
	if OF_UNLIKELY (count == 0 || size == 0)
		return NULL;

	if OF_UNLIKELY (count > SIZE_MAX / size)
		@throw [OFOutOfRangeException exception];

	if OF_UNLIKELY ((pointer = realloc(pointer, count * size)) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: size];

	return pointer;
}

#if !defined(HAVE_ARC4RANDOM) && !defined(HAVE_GETRANDOM)
static void
initRandom(void)
{
	struct timeval tv;

1033
1034
1035
1036
1037
1038
1039
1040

1041
1042
1043
1044
1045
1046
1047
1076
1077
1078
1079
1080
1081
1082

1083
1084
1085
1086
1087
1088
1089
1090







-
+







}

- (bool)isEqual: (id)object
{
	return (object == self);
}

- (uint32_t)hash
- (unsigned long)hash
{
	uintptr_t ptr = (uintptr_t)self;
	uint32_t hash;

	OF_HASH_INIT(hash);

	for (size_t i = 0; i < sizeof(ptr); i++) {
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
1098
1099
1100
1101
1102
1103
1104
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
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
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
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
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1100
1101
1102
1103
1104
1105
1106





































































































































































1107
1108
1109
1110
1111
1112
1113







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







- (OFString *)description
{
	/* Classes containing data should reimplement this! */

	return [OFString stringWithFormat: @"<%@>", self.className];
}

- (void *)allocMemoryWithSize: (size_t)size
{
	void *pointer;
	struct pre_mem *preMem;

	if OF_UNLIKELY (size == 0)
		return NULL;

	if OF_UNLIKELY (size > SIZE_MAX - PRE_IVARS_ALIGN)
		@throw [OFOutOfRangeException exception];

	if OF_UNLIKELY ((pointer = malloc(PRE_MEM_ALIGN + size)) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: size];

	preMem = pointer;
	preMem->owner = self;
	preMem->prev = PRE_IVARS->lastMem;
	preMem->next = NULL;

	if OF_LIKELY (PRE_IVARS->lastMem != NULL)
		PRE_IVARS->lastMem->next = preMem;

	if OF_UNLIKELY (PRE_IVARS->firstMem == NULL)
		PRE_IVARS->firstMem = preMem;

	PRE_IVARS->lastMem = preMem;

	return (char *)pointer + PRE_MEM_ALIGN;
}

- (void *)allocMemoryWithSize: (size_t)size
			count: (size_t)count
{
	if OF_UNLIKELY (count > SIZE_MAX / size)
		@throw [OFOutOfRangeException exception];

	return [self allocMemoryWithSize: size * count];
}

- (void *)allocZeroedMemoryWithSize: (size_t)size
{
	void *pointer;
	struct pre_mem *preMem;

	if OF_UNLIKELY (size == 0)
		return NULL;

	if OF_UNLIKELY (size > SIZE_MAX - PRE_IVARS_ALIGN)
		@throw [OFOutOfRangeException exception];

	if OF_UNLIKELY ((pointer = calloc(1, PRE_MEM_ALIGN + size)) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: size];

	preMem = pointer;
	preMem->owner = self;
	preMem->prev = PRE_IVARS->lastMem;

	if OF_LIKELY (PRE_IVARS->lastMem != NULL)
		PRE_IVARS->lastMem->next = preMem;

	if OF_UNLIKELY (PRE_IVARS->firstMem == NULL)
		PRE_IVARS->firstMem = preMem;

	PRE_IVARS->lastMem = preMem;

	return (char *)pointer + PRE_MEM_ALIGN;
}

- (void *)allocZeroedMemoryWithSize: (size_t)size
			      count: (size_t)count
{
	if OF_UNLIKELY (count > SIZE_MAX / size)
		@throw [OFOutOfRangeException exception];

	return [self allocZeroedMemoryWithSize: size * count];
}

- (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
{
	void *new;
	struct pre_mem *preMem;

	if OF_UNLIKELY (pointer == NULL)
		return [self allocMemoryWithSize: size];

	if OF_UNLIKELY (size == 0) {
		[self freeMemory: pointer];
		return NULL;
	}

	if OF_UNLIKELY (PRE_MEM(pointer)->owner != self)
		@throw [OFMemoryNotPartOfObjectException
		    exceptionWithPointer: pointer
				  object: self];

	if OF_UNLIKELY ((new = realloc(PRE_MEM(pointer),
	    PRE_MEM_ALIGN + size)) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: size];
	preMem = new;

	if OF_UNLIKELY (preMem != PRE_MEM(pointer)) {
		if OF_LIKELY (preMem->prev != NULL)
			preMem->prev->next = preMem;
		if OF_LIKELY (preMem->next != NULL)
			preMem->next->prev = preMem;

		if OF_UNLIKELY (PRE_IVARS->firstMem == PRE_MEM(pointer))
			PRE_IVARS->firstMem = preMem;
		if OF_UNLIKELY (PRE_IVARS->lastMem == PRE_MEM(pointer))
			PRE_IVARS->lastMem = preMem;
	}

	return (char *)new + PRE_MEM_ALIGN;
}

- (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
		 count: (size_t)count
{
	if OF_UNLIKELY (pointer == NULL)
		return [self allocMemoryWithSize: size
					   count: count];

	if OF_UNLIKELY (size == 0 || count == 0) {
		[self freeMemory: pointer];
		return NULL;
	}

	if OF_UNLIKELY (count > SIZE_MAX / size)
		@throw [OFOutOfRangeException exception];

	return [self resizeMemory: pointer
			     size: size * count];
}

- (void)freeMemory: (void *)pointer
{
	if OF_UNLIKELY (pointer == NULL)
		return;

	if OF_UNLIKELY (PRE_MEM(pointer)->owner != self)
		@throw [OFMemoryNotPartOfObjectException
		    exceptionWithPointer: pointer
				  object: self];

	if OF_LIKELY (PRE_MEM(pointer)->prev != NULL)
		PRE_MEM(pointer)->prev->next = PRE_MEM(pointer)->next;
	if OF_LIKELY (PRE_MEM(pointer)->next != NULL)
		PRE_MEM(pointer)->next->prev = PRE_MEM(pointer)->prev;

	if OF_UNLIKELY (PRE_IVARS->firstMem == PRE_MEM(pointer))
		PRE_IVARS->firstMem = PRE_MEM(pointer)->next;
	if OF_UNLIKELY (PRE_IVARS->lastMem == PRE_MEM(pointer))
		PRE_IVARS->lastMem = PRE_MEM(pointer)->prev;

	/* To detect double-free */
	PRE_MEM(pointer)->owner = nil;

	free(PRE_MEM(pointer));
}

- (id)forwardingTargetForSelector: (SEL)selector
{
	return nil;
}

- (void)doesNotRecognizeSelector: (SEL)selector
{
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1203
1204
1205
1206
1207
1208
1209


1210
1211















1212
1213
1214
1215
1216
1217
1218







-
-


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







	[self retain];

	return true;
}

- (void)dealloc
{
	struct pre_mem *iter;

	objc_destructInstance(self);

	iter = PRE_IVARS->firstMem;
	while (iter != NULL) {
		struct pre_mem *next = iter->next;

		/*
		 * We can use owner as a sentinel to prevent exploitation in
		 * case there is a buffer underflow somewhere.
		 */
		OF_ENSURE(iter->owner == self);

		free(iter);

		iter = next;
	}

	free((char *)self - PRE_IVARS_ALIGN);
}

/* Required to use properties with the Apple runtime */
- (id)copyWithZone: (void *)zone
{
	if OF_UNLIKELY (zone != NULL) {
1369
1370
1371
1372
1373
1374
1375
1376
1377



1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1230
1231
1232
1233
1234
1235
1236


1237
1238
1239
1240




























1241
1242
1243
1244
1245
1246
1247







-
-
+
+
+

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







		abort();
	}

	return [(id)self mutableCopy];
}

/*
 * Those are needed as the root class is the superclass of the root class's
 * metaclass and thus instance methods can be sent to class objects as well.
 * The following are needed as the root class is the superclass of the root
 * class's metaclass and thus instance methods can be sent to class objects as
 * well.
 */
+ (void *)allocMemoryWithSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (void *)allocMemoryWithSize: (size_t)size
		       count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (void *)resizeMemory: (void *)pointer
		  size: (size_t)size
		 count: (size_t)count
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (void)freeMemory: (void *)pointer
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (id)retain
{
	return self;
}

+ (id)autorelease

Modified src/OFOptionsParser.m from [91dcfe7c0f] to [93ab00cf42].

20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34







-
+







#import "OFOptionsParser.h"
#import "OFApplication.h"
#import "OFArray.h"
#import "OFMapTable.h"

#import "OFInvalidArgumentException.h"

static uint32_t
static unsigned long
stringHash(void *object)
{
	return ((OFString *)object).hash;
}

static bool
stringEqual(void *object1, void *object2)
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
97
98
99
100
101
82
83
84
85
86
87
88
89
90
91
92



93
94
95
96
97
98
99







+



-
-
-







				*iter->isSpecifiedPtr = false;
			if (iter->argumentPtr)
				*iter->argumentPtr = nil;

			count++;
		}

		_options = of_malloc(count + 1, sizeof(*_options));
		_longOptions = [[OFMapTable alloc]
		    initWithKeyFunctions: keyFunctions
			 objectFunctions: objectFunctions];
		_options = [self
		    allocMemoryWithSize: sizeof(*_options)
				  count: count + 1];

		for (iter = options, iter2 = _options;
		    iter->shortOption != '\0' || iter->longOption != nil;
		    iter++, iter2++) {
			iter2->shortOption = iter->shortOption;
			iter2->longOption = nil;
			iter2->hasArgument = iter->hasArgument;
142
143
144
145
146
147
148

149
150
151
152
153
154
155
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154







+







	return self;
}

- (void)dealloc
{
	of_options_parser_option_t *iter;

	free(_options);
	[_longOptions release];

	if (_options != NULL)
		for (iter = _options;
		    iter->shortOption != '\0' || iter->longOption != nil;
		    iter++)
			[iter->longOption release];
193
194
195
196
197
198
199
200

201
202
203
204
205


206
207
208
209
210
211
212
192
193
194
195
196
197
198

199


200


201
202
203
204
205
206
207
208
209







-
+
-
-

-
-
+
+







			size_t pos;
			of_options_parser_option_t *option;

			_lastOption = '-';
			_index++;

			if ((pos = [argument rangeOfString: @"="].location) !=
			    OF_NOT_FOUND) {
			    OF_NOT_FOUND)
				of_range_t range = of_range(pos + 1,
				    argument.length - pos - 1);
				_argument = [[argument
				    substringWithRange: range] copy];
			} else
				    substringFromIndex: pos + 1] copy];
			else
				pos = argument.length;

			_lastLongOption = [[argument substringWithRange:
			    of_range(2, pos - 2)] copy];

			objc_autoreleasePoolPop(pool);

251
252
253
254
255
256
257
258

259
260
261
262
263
264
265
266
248
249
250
251
252
253
254

255

256
257
258
259
260
261
262







-
+
-







				return _lastOption;
			}

			if (_index >= _arguments.count)
				return ':';

			argument = [_arguments objectAtIndex: _index];
			argument = [argument substringWithRange:
			argument = [argument substringFromIndex: _subIndex];
			    of_range(_subIndex, argument.length - _subIndex)];

			_argument = [argument copy];

			if (iter->isSpecifiedPtr != NULL)
				*iter->isSpecifiedPtr = true;
			if (iter->argumentPtr != NULL)
				*iter->argumentPtr =

Modified src/OFPair.m from [a27e0f483b] to [6855a79df9].

81
82
83
84
85
86
87
88

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

88
89
90
91
92
93
94
95







-
+







	if (pair->_secondObject != _secondObject &&
	    ![pair->_secondObject isEqual: _secondObject])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, [_firstObject hash]);
	OF_HASH_ADD_HASH(hash, [_secondObject hash]);

Modified src/OFPollKernelEventObserver.m from [5ca69d7bfc] to [4cf3bcee3f].

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







-
-
+











+







		struct pollfd p = { _cancelFD[0], POLLIN, 0 };

		_FDs = [[OFMutableData alloc] initWithItemSize:
		    sizeof(struct pollfd)];
		[_FDs addItem: &p];

		_maxFD = _cancelFD[0];
		_FDToObject = [self allocMemoryWithSize: sizeof(id)
						  count: (size_t)_maxFD + 1];
		_FDToObject = of_malloc((size_t)_maxFD + 1, sizeof(id));
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_FDs release];
	free(_FDToObject);

	[super dealloc];
}

- (void)of_addObject: (id)object
      fileDescriptor: (int)fd
	      events: (short)events OF_DIRECT
94
95
96
97
98
99
100
101

102
103

104
105
106
107
108
109
110
94
95
96
97
98
99
100

101


102
103
104
105
106
107
108
109







-
+
-
-
+







	}

	if (!found) {
		struct pollfd p = { fd, events, 0 };

		if (fd > _maxFD) {
			_maxFD = fd;
			_FDToObject = [self resizeMemory: _FDToObject
			_FDToObject = of_realloc(_FDToObject,
						    size: sizeof(id)
						   count: (size_t)_maxFD + 1];
			    (size_t)_maxFD + 1, sizeof(id));
		}

		_FDToObject[fd] = object;
		[_FDs addItem: &p];
	}
}

Modified src/OFSandbox.m from [66d9366bf3] to [103c5612bc].

465
466
467
468
469
470
471
472

473
474
475
476
477
478
479
465
466
467
468
469
470
471

472
473
474
475
476
477
478
479







-
+







		return false;
	if (sandbox->_returnsErrors != _returnsErrors)
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD(hash, _allowsStdIO);
	OF_HASH_ADD(hash, _allowsReadingFiles);

Modified src/OFSecureData.h from [f20113d2e2] to [fe3dc9b9e1].

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







-

+




-
-
-
+
+
+




+
-
+
-




-

+







+ (instancetype)dataWithCount: (size_t)count
	allowsSwappableMemory: (bool)allowsSwappableMemory;

/**
 * @brief Creates a new, autoreleased OFSecureData with count items of the
 *	  specified item size, all set to zero.
 *
 * @param itemSize The size of a single item in the OFSecureData in bytes
 * @param count The number of zero items the OFSecureData should contain
 * @param itemSize The size of a single item in the OFSecureData in bytes
 * @param allowsSwappableMemory Whether the data may be stored in swappable
 *			       memory
 * @return A new, autoreleased OFSecureData
 */
+ (instancetype)dataWithItemSize: (size_t)itemSize
			   count: (size_t)count
	   allowsSwappableMemory: (bool)allowsSwappableMemory;
+ (instancetype)dataWithCount: (size_t)count
		     itemSize: (size_t)itemSize
	allowsSwappableMemory: (bool)allowsSwappableMemory;

+ (instancetype)dataWithItems: (const void *)items
			count: (size_t)count OF_UNAVAILABLE;
+ (instancetype)dataWithItems: (const void *)items
			count: (size_t)count
		     itemSize: (size_t)itemSize
		     itemSize: (size_t)itemSize OF_UNAVAILABLE;
			count: (size_t)count OF_UNAVAILABLE;
+ (instancetype)dataWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE;
+ (instancetype)dataWithItemsNoCopy: (void *)items
			   itemSize: (size_t)itemSize
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE;
#ifdef OF_HAVE_FILES
+ (instancetype)dataWithContentsOfFile: (OFString *)path OF_UNAVAILABLE;
#endif
+ (instancetype)dataWithContentsOfURL: (OFURL *)URL OF_UNAVAILABLE;
+ (instancetype)dataWithStringRepresentation: (OFString *)string OF_UNAVAILABLE;
+ (instancetype)dataWithBase64EncodedString: (OFString *)string OF_UNAVAILABLE;
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
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







-
-
-
+
+
+





+
-
+
-




-

+







 *
 * @param itemSize The size of a single item in the OFSecureData in bytes
 * @param count The number of zero items the OFSecureData should contain
 * @param allowsSwappableMemory Whether the data may be stored in swappable
 *				memory
 * @return An initialized OFSecureData
 */
- (instancetype)initWithItemSize: (size_t)itemSize
			   count: (size_t)count
	   allowsSwappableMemory: (bool)allowsSwappableMemory
- (instancetype)initWithCount: (size_t)count
		     itemSize: (size_t)itemSize
	allowsSwappableMemory: (bool)allowsSwappableMemory
    OF_DESIGNATED_INITIALIZER;

- (instancetype)initWithItems: (const void *)items
			count: (size_t)count OF_UNAVAILABLE;
- (instancetype)initWithItems: (const void *)items
			count: (size_t)count
		     itemSize: (size_t)itemSize
		     itemSize: (size_t)itemSize OF_UNAVAILABLE;
			count: (size_t)count OF_UNAVAILABLE;
- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE;
- (instancetype)initWithItemsNoCopy: (void *)items
			   itemSize: (size_t)itemSize
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone OF_UNAVAILABLE;
#ifdef OF_HAVE_FILES
- (instancetype)initWithContentsOfFile: (OFString *)path OF_UNAVAILABLE;
#endif
- (instancetype)initWithContentsOfURL: (OFURL *)URL OF_UNAVAILABLE;
- (instancetype)initWithStringRepresentation: (OFString *)string OF_UNAVAILABLE;
- (instancetype)initWithBase64EncodedString: (OFString *)string OF_UNAVAILABLE;

Modified src/OFSecureData.m from [98976ad696] to [8a522b1fcf].

136
137
138
139
140
141
142
143
144






145
146
147
148







149
150

151
152
153
154
155
156
157
158
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







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







# endif
			}

			return page;
		}
	}

	if ((page = malloc(sizeof(*page))) == NULL)
		@throw [OFOutOfMemoryException
	page = of_malloc(1, sizeof(*page));
	@try {
		page->map = of_calloc(1, mapSize);
	} @catch (id e) {
		free(page);
		@throw e;
		    exceptionWithRequestedSize: sizeof(*page)];

	if ((page->map = calloc(1, mapSize)) == NULL)
		@throw [OFOutOfMemoryException
	}
	@try {
		page->page = mapPages(1);
	} @catch (id e) {
		free(page->map);
		free(page);
		@throw e;
		    exceptionWithRequestedSize: mapSize];

	}
	page->page = mapPages(1);
	of_explicit_memset(page->page, 0, pageSize);

# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	lastPage = of_tlskey_get(lastPageKey);
# endif

	page->previous = lastPage;
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
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







+




-
+
-
-
-
-




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




















-
-
+
+


-
-
-
+
+
+










-

+












-

+







#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)
	size_t pageSize = [OFSystemInfo pageSize];
	size_t numPages = OF_ROUND_UP_POW2(pageSize, size) / pageSize;
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	struct page **preallocatedPages = of_tlskey_get(preallocatedPagesKey);
	size_t numPreallocatedPages;
# endif
	size_t i;

	if (preallocatedPages != NULL)
		@throw [OFInvalidArgumentException exception];

	preallocatedPages = calloc(numPages, sizeof(struct page));
	preallocatedPages = of_calloc(numPages, sizeof(struct page));
	if (preallocatedPages == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: numPages * sizeof(struct page)];

# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	of_tlskey_set(preallocatedPagesKey, preallocatedPages);
# endif

	@try {
	for (size_t i = 0; i < numPages; i++)
		preallocatedPages[i] = addPage(false);
		for (i = 0; i < numPages; i++)
			preallocatedPages[i] = addPage(false);
	} @catch (id e) {
		for (size_t j = 0; j < i; j++)
			removePageIfEmpty(preallocatedPages[j]);

		free(preallocatedPages);
		preallocatedPages = NULL;

		@throw e;
	}

	numPreallocatedPages = numPages;
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
	of_tlskey_set(numPreallocatedPagesKey,
	    (void *)(uintptr_t)numPreallocatedPages);
# endif
#else
	@throw [OFNotImplementedException exceptionWithSelector: _cmd
							 object: self];
#endif
}

+ (instancetype)dataWithCount: (size_t)count
	allowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithCount: count
		      allowsSwappableMemory: allowsSwappableMemory]
	    autorelease];
}

+ (instancetype)dataWithItemSize: (size_t)itemSize
			   count: (size_t)count
+ (instancetype)dataWithCount: (size_t)count
		     itemSize: (size_t)itemSize
	   allowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [[[self alloc] initWithItemSize: itemSize
					 count: count
			 allowsSwappableMemory: allowsSwappableMemory]
	return [[[self alloc] initWithCount: count
				   itemSize: itemSize
		      allowsSwappableMemory: allowsSwappableMemory]
	    autorelease];
}

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

+ (instancetype)dataWithItems: (const void *)items
		     itemSize: (size_t)itemSize
			count: (size_t)count
		     itemSize: (size_t)itemSize
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (instancetype)dataWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone
{
	OF_UNRECOGNIZED_SELECTOR
}

+ (instancetype)dataWithItemsNoCopy: (void *)items
			   itemSize: (size_t)itemSize
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	OF_UNRECOGNIZED_SELECTOR
}

#ifdef OF_HAVE_FILES
+ (instancetype)dataWithContentsOfFile: (OFString *)path
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
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







-
-
-
+
+
+


-
-
-
+
+
+












-
-
+
+







	OF_UNRECOGNIZED_SELECTOR
}


- (instancetype)initWithCount: (size_t)count
	allowsSwappableMemory: (bool)allowsSwappableMemory
{
	return [self initWithItemSize: 1
				count: count
		allowsSwappableMemory: allowsSwappableMemory];
	return [self initWithCount: count
			  itemSize: 1
	     allowsSwappableMemory: allowsSwappableMemory];
}

- (instancetype)initWithItemSize: (size_t)itemSize
			   count: (size_t)count
	   allowsSwappableMemory: (bool)allowsSwappableMemory
- (instancetype)initWithCount: (size_t)count
		     itemSize: (size_t)itemSize
	allowsSwappableMemory: (bool)allowsSwappableMemory
{
	self = [super init];

	@try {
#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)
		size_t pageSize = [OFSystemInfo pageSize];
#endif

		if (count > SIZE_MAX / itemSize)
			@throw [OFOutOfRangeException exception];

		if (allowsSwappableMemory) {
			_items = [self allocMemoryWithSize: itemSize
						     count: count];
			_items = of_malloc(count, itemSize);
			_freeWhenDone = true;
			memset(_items, 0, count * itemSize);
#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON)
		} else if (count * itemSize >= pageSize)
			_items = mapPages(OF_ROUND_UP_POW2(pageSize,
			    count * itemSize) / pageSize);
		else {
# if !defined(OF_HAVE_COMPILER_TLS) && defined(OF_HAVE_THREADS)
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
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







-

+
















-

+












-

+







#else
		} else
			@throw [OFNotImplementedException
			    exceptionWithSelector: _cmd
					   object: nil];
#endif

		_itemSize = itemSize;
		_count = count;
		_itemSize = itemSize;
		_allowsSwappableMemory = allowsSwappableMemory;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithItems: (const void *)items
			count: (size_t)count
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithItems: (const void *)items
		     itemSize: (size_t)itemSize
			count: (size_t)count
		     itemSize: (size_t)itemSize
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithItemsNoCopy: (void *)items
			      count: (size_t)count
		       freeWhenDone: (bool)freeWhenDone
{
	OF_INVALID_INIT_METHOD
}

- (instancetype)initWithItemsNoCopy: (void *)items
			   itemSize: (size_t)itemSize
			      count: (size_t)count
			   itemSize: (size_t)itemSize
		       freeWhenDone: (bool)freeWhenDone
{
	OF_INVALID_INIT_METHOD
}

#ifdef OF_HAVE_FILES
- (instancetype)initWithContentsOfFile: (OFString *)path
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
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







+
-
+
-










+
-
+
-







{
	of_explicit_memset(_items, 0, _count * _itemSize);
}

- (id)copy
{
	OFSecureData *copy = [[OFSecureData alloc]
		    initWithCount: _count
		 initWithItemSize: _itemSize
			 itemSize: _itemSize
			    count: _count
	    allowsSwappableMemory: _allowsSwappableMemory];

	memcpy(copy.mutableItems, _items, _count * _itemSize);

	return copy;
}

- (id)mutableCopy
{
	OFSecureData *copy = [[OFSecureData alloc]
		    initWithCount: _count
		 initWithItemSize: _itemSize
			 itemSize: _itemSize
			    count: _count
	    allowsSwappableMemory: _allowsSwappableMemory];

	memcpy(copy.mutableItems, _items, _count * _itemSize);

	return copy;
}

Modified src/OFSeekableStream.m from [57a7a2c048] to [b1692ec182].

51
52
53
54
55
56
57
58

59
60
61
62
63
64
51
52
53
54
55
56
57

58
59
60
61
62
63
64







-
+






{
	if (whence == SEEK_CUR)
		offset -= _readBufferLength;

	offset = [self lowlevelSeekToOffset: offset
				     whence: whence];

	[self freeMemory: _readBufferMemory];
	free(_readBufferMemory);
	_readBuffer = _readBufferMemory = NULL;
	_readBufferLength = 0;

	return offset;
}
@end

Modified src/OFSelectKernelEventObserver.m from [f86117a30a] to [22b01117bc].

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
163
164
165
166
167
168
169

170
171
172
173
174
175
176

177
178
179
180
181
182
183
184







-







-
+







	FD_CLR((of_socket_t)fd, &_writeFDs);

	[super removeObjectForWriting: object];
}

- (void)observeForTimeInterval: (of_time_interval_t)timeInterval
{
	id const *objects;
	fd_set readFDs;
	fd_set writeFDs;
	struct timeval timeout;
	int events;
#ifdef OF_AMIGAOS
	ULONG execSignalMask, cancelSignal;
#endif
	size_t count;
	void *pool;

	if ([self of_processReadBuffers])
		return;

#ifdef FD_COPY
	FD_COPY(&_readFDs, &readFDs);
	FD_COPY(&_writeFDs, &writeFDs);
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
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







-
-
+

-
-
-
+
+
+
+




-
+

-
+


-
-
+
+
-
-
-
-
+
+




-
+

-
+

-
+
+
+

# else
		OF_ENSURE(recvfrom(_cancelFD[0], (void *)&buffer, 1, 0, NULL,
		    NULL) == 1);
# endif
	}
#endif

	objects = _readObjects.objects;
	count = _readObjects.count;
	pool = objc_autoreleasePoolPush();

	for (size_t i = 0; i < count; i++) {
		void *pool = objc_autoreleasePoolPush();
		int fd = [objects[i] fileDescriptorForReading];
	for (id <OFReadyForReadingObserving> object in
	    [[_readObjects copy] autorelease]) {
		void *pool2 = objc_autoreleasePoolPush();
		int fd = object.fileDescriptorForReading;

		if (FD_ISSET((of_socket_t)fd, &readFDs) &&
		    [_delegate respondsToSelector:
		    @selector(objectIsReadyForReading:)])
			[_delegate objectIsReadyForReading: objects[i]];
			[_delegate objectIsReadyForReading: object];

		objc_autoreleasePoolPop(pool);
		objc_autoreleasePoolPop(pool2);
	}

	objects = _writeObjects.objects;
	count = _writeObjects.count;
	for (id <OFReadyForWritingObserving> object in
	    [[_writeObjects copy] autorelease]) {

	for (size_t i = 0; i < count; i++) {
		void *pool = objc_autoreleasePoolPush();
		int fd = [objects[i] fileDescriptorForWriting];
		void *pool2 = objc_autoreleasePoolPush();
		int fd = object.fileDescriptorForWriting;

		if (FD_ISSET((of_socket_t)fd, &writeFDs) &&
		    [_delegate respondsToSelector:
		    @selector(objectIsReadyForWriting:)])
			[_delegate objectIsReadyForWriting: objects[i]];
			[_delegate objectIsReadyForWriting: object];

		objc_autoreleasePoolPop(pool);
		objc_autoreleasePoolPop(pool2);
	}
}

	objc_autoreleasePoolPop(pool);
}
@end

Modified src/OFSet.m from [e3c9e370a2] to [fd18f62182].

294
295
296
297
298
299
300
301

302
303
304

305
306
307

308
309
310
311
312
313
314
294
295
296
297
298
299
300

301
302
303

304
305
306

307
308
309
310
311
312
313
314







-
+


-
+


-
+








	if (set.count != self.count)
		return false;

	return [set isSubsetOfSet: self];
}

- (uint32_t)hash
- (unsigned long)hash
{
	void *pool = objc_autoreleasePoolPush();
	uint32_t hash = 0;
	unsigned long hash = 0;

	for (id object in self)
		hash += [object hash];
		hash ^= [object hash];

	objc_autoreleasePoolPop(pool);

	return hash;
}

- (OFString *)description

Modified src/OFStream.m from [dd10e2b21b] to [b13d6173e0].

88
89
90
91
92
93
94








95
96
97
98
99
100
101
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109







+
+
+
+
+
+
+
+







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

	return self;
}

- (void)dealloc
{
	free(_readBufferMemory);
	free(_writeBuffer);

	[super dealloc];
}

- (bool)lowlevelIsAtEndOfStream
{
	OF_UNRECOGNIZED_SELECTOR
}

- (size_t)lowlevelReadIntoBuffer: (void *)buffer
139
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154
147
148
149
150
151
152
153


154
155
156
157
158
159
160
161







-
-
+







			bytesRead = [self
			    lowlevelReadIntoBuffer: tmp
					    length: MIN_READ_SIZE];

			if (bytesRead > length) {
				memcpy(buffer, tmp, length);

				readBuffer = [self allocMemoryWithSize:
				    bytesRead - length];
				readBuffer = of_malloc(bytesRead - length, 1);
				memcpy(readBuffer, tmp + length,
				    bytesRead - length);

				_readBuffer = _readBufferMemory = readBuffer;
				_readBufferLength = bytesRead - length;

				return length;
162
163
164
165
166
167
168
169

170
171
172
173
174
175
176
169
170
171
172
173
174
175

176
177
178
179
180
181
182
183







-
+







					     length: length];
	}

	if (length >= _readBufferLength) {
		size_t ret = _readBufferLength;
		memcpy(buffer, _readBuffer, _readBufferLength);

		[self freeMemory: _readBufferMemory];
		free(_readBufferMemory);
		_readBuffer = _readBufferMemory = NULL;
		_readBufferLength = 0;

		return ret;
	} else {
		memcpy(buffer, _readBuffer, length);

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







-
-
-
-
+





-

+













-
+











-
+

















-
+









-
+







-
-
+
+







-
+



















-
+



+
+














-
+














-
-
+
+
-












-
-
-

-
+

-
+






-
+
-

-
+







-
-
+








-
+


-
+
-




-
+










-
-
+
+





-
+




-
+







{
	OFData *ret;
	char *buffer;

	if OF_UNLIKELY (count > SIZE_MAX / itemSize)
		@throw [OFOutOfRangeException exception];

	if OF_UNLIKELY ((buffer = malloc(count * itemSize)) == NULL)
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: count * itemSize];

	buffer = of_malloc(count, itemSize);
	@try {
		[self readIntoBuffer: buffer
			 exactLength: count * itemSize];

		ret = [OFData dataWithItemsNoCopy: buffer
					 itemSize: itemSize
					    count: count
					 itemSize: itemSize
				     freeWhenDone: true];
	} @catch (id e) {
		free(buffer);
		@throw e;
	}

	return ret;
}

- (OFData *)readDataUntilEndOfStream
{
	OFMutableData *data = [OFMutableData data];
	size_t pageSize = [OFSystemInfo pageSize];
	char *buffer = [self allocMemoryWithSize: pageSize];
	char *buffer = of_malloc(1, pageSize);

	@try {
		while (!self.atEndOfStream) {
			size_t length;

			length = [self readIntoBuffer: buffer
					       length: pageSize];
			[data addItems: buffer
				 count: length];
		}
	} @finally {
		[self freeMemory: buffer];
		free(buffer);
	}

	[data makeImmutable];

	return data;
}

- (OFString *)readStringWithLength: (size_t)length
{
	return [self readStringWithLength: length
				 encoding: OF_STRING_ENCODING_UTF_8];
}

- (OFString *)readStringWithLength: (size_t)length
			  encoding: (of_string_encoding_t)encoding
{
	OFString *ret;
	char *buffer = [self allocMemoryWithSize: length + 1];
	char *buffer = of_malloc(length + 1, 1);
	buffer[length] = 0;

	@try {
		[self readIntoBuffer: buffer
			 exactLength: length];

		ret = [OFString stringWithCString: buffer
					 encoding: encoding];
	} @finally {
		[self freeMemory: buffer];
		free(buffer);
	}

	return ret;
}

- (OFString *)tryReadLineWithEncoding: (of_string_encoding_t)encoding
{
	size_t pageSize, bufferLength, retLength;
	char *retCString, *buffer, *readBuffer;
	size_t pageSize, bufferLength;
	char *buffer, *readBuffer;
	OFString *ret;

	/* Look if there's a line or \0 in our buffer */
	if (!_waitingForDelimiter && _readBuffer != NULL) {
		for (size_t i = 0; i < _readBufferLength; i++) {
			if OF_UNLIKELY (_readBuffer[i] == '\n' ||
			    _readBuffer[i] == '\0') {
				retLength = i;
				size_t retLength = i;

				if (i > 0 && _readBuffer[i - 1] == '\r')
					retLength--;

				ret = [OFString stringWithCString: _readBuffer
							 encoding: encoding
							   length: retLength];

				_readBuffer += i + 1;
				_readBufferLength -= i + 1;

				_waitingForDelimiter = false;
				return ret;
			}
		}
	}

	/* Read and see if we got a newline or \0 */
	pageSize = [OFSystemInfo pageSize];
	buffer = [self allocMemoryWithSize: pageSize];
	buffer = of_malloc(1, pageSize);

	@try {
		if ([self lowlevelIsAtEndOfStream]) {
			size_t retLength;

			if (_readBuffer == NULL) {
				_waitingForDelimiter = false;
				return nil;
			}

			retLength = _readBufferLength;

			if (retLength > 0 && _readBuffer[retLength - 1] == '\r')
				retLength--;

			ret = [OFString stringWithCString: _readBuffer
						 encoding: encoding
						   length: retLength];

			[self freeMemory: _readBufferMemory];
			free(_readBufferMemory);
			_readBuffer = _readBufferMemory = NULL;
			_readBufferLength = 0;

			_waitingForDelimiter = false;
			return ret;
		}

		bufferLength = [self lowlevelReadIntoBuffer: buffer
						     length: pageSize];

		/* Look if there's a newline or \0 */
		for (size_t i = 0; i < bufferLength; i++) {
			if OF_UNLIKELY (buffer[i] == '\n' ||
			    buffer[i] == '\0') {
				retLength = _readBufferLength + i;
				retCString = [self
				size_t retLength = _readBufferLength + i;
				char *retCString = of_malloc(retLength, 1);
				    allocMemoryWithSize: retLength];

				if (_readBuffer != NULL)
					memcpy(retCString, _readBuffer,
					    _readBufferLength);
				memcpy(retCString + _readBufferLength,
				    buffer, i);

				if (retLength > 0 &&
				    retCString[retLength - 1] == '\r')
					retLength--;

				@try {
					char *rcs = retCString;
					size_t rl = retLength;

					ret = [OFString
					    stringWithCString: rcs
					    stringWithCString: retCString
						     encoding: encoding
						       length: rl];
						       length: retLength];
				} @catch (id e) {
					if (bufferLength > 0) {
						/*
						 * Append data to _readBuffer
						 * to prevent loss of data.
						 */
						readBuffer = [self
						readBuffer = of_malloc(
						    allocMemoryWithSize:
						    _readBufferLength +
						    bufferLength];
						    bufferLength, 1);

						memcpy(readBuffer, _readBuffer,
						    _readBufferLength);
						memcpy(readBuffer +
						    _readBufferLength,
						    buffer, bufferLength);

						[self freeMemory:
						    _readBufferMemory];
						free(_readBufferMemory);
						_readBuffer = readBuffer;
						_readBufferMemory = readBuffer;
						_readBufferLength +=
						    bufferLength;
					}

					@throw e;
				} @finally {
					[self freeMemory: retCString];
					free(retCString);
				}

				readBuffer = [self
				readBuffer = of_malloc(bufferLength - i - 1, 1);
				    allocMemoryWithSize: bufferLength - i - 1];
				if (readBuffer != NULL)
					memcpy(readBuffer, buffer + i + 1,
					    bufferLength - i - 1);

				[self freeMemory: _readBufferMemory];
				free(_readBufferMemory);
				_readBuffer = _readBufferMemory = readBuffer;
				_readBufferLength = bufferLength - i - 1;

				_waitingForDelimiter = false;
				return ret;
			}
		}

		/* There was no newline or \0 */
		if (bufferLength > 0) {
			readBuffer = [self allocMemoryWithSize:
			    _readBufferLength + bufferLength];
			readBuffer = of_malloc(_readBufferLength + bufferLength,
			    1);

			memcpy(readBuffer, _readBuffer, _readBufferLength);
			memcpy(readBuffer + _readBufferLength,
			    buffer, bufferLength);

			[self freeMemory: _readBufferMemory];
			free(_readBufferMemory);
			_readBuffer = _readBufferMemory = readBuffer;
			_readBufferLength += bufferLength;
		}
	} @finally {
		[self freeMemory: buffer];
		free(buffer);
	}

	_waitingForDelimiter = true;
	return nil;
}

- (OFString *)readLine
939
940
941
942
943
944
945
946
947


948
949
950
951
952
953
954
938
939
940
941
942
943
944


945
946
947
948
949
950
951
952
953







-
-
+
+







	return [self tryReadLineWithEncoding: OF_STRING_ENCODING_UTF_8];
}

- (OFString *)tryReadTillDelimiter: (OFString *)delimiter
			  encoding: (of_string_encoding_t)encoding
{
	const char *delimiterCString;
	size_t j, delimiterLength, pageSize, bufferLength, retLength;
	char *retCString, *buffer, *readBuffer;
	size_t j, delimiterLength, pageSize, bufferLength;
	char *buffer, *readBuffer;
	OFString *ret;

	delimiterCString = [delimiter cStringWithEncoding: encoding];
	delimiterLength = [delimiter cStringLengthWithEncoding: encoding];
	j = 0;

	if (delimiterLength == 0)
976
977
978
979
980
981
982
983

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

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

1100
1101
1102
1103
1104
1105
1106
975
976
977
978
979
980
981

982
983
984
985
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
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
1098
1099
1100
1101







-
+












-
+
















+
+
+





-
+
-













-
-
-

-
+

-
+






-
+
-

-
+







-
-
+








-
+


-
-
+




-
+










-
-
+
+





-
+




-
+







				return ret;
			}
		}
	}

	/* Read and see if we got a delimiter or \0 */
	pageSize = [OFSystemInfo pageSize];
	buffer = [self allocMemoryWithSize: pageSize];
	buffer = of_malloc(1, pageSize);

	@try {
		if ([self lowlevelIsAtEndOfStream]) {
			if (_readBuffer == NULL) {
				_waitingForDelimiter = false;
				return nil;
			}

			ret = [OFString stringWithCString: _readBuffer
						 encoding: encoding
						   length: _readBufferLength];

			[self freeMemory: _readBufferMemory];
			free(_readBufferMemory);
			_readBuffer = _readBufferMemory = NULL;
			_readBufferLength = 0;

			_waitingForDelimiter = false;
			return ret;
		}

		bufferLength = [self lowlevelReadIntoBuffer: buffer
						     length: pageSize];

		/* Look if there's a delimiter or \0 */
		for (size_t i = 0; i < bufferLength; i++) {
			if (buffer[i] != delimiterCString[j++])
				j = 0;

			if (j == delimiterLength || buffer[i] == '\0') {
				size_t retLength;
				char *retCString;

				if (buffer[i] == '\0')
					delimiterLength = 1;

				retLength = _readBufferLength + i + 1 -
				    delimiterLength;
				retCString = [self
				retCString = of_malloc(retLength, 1);
				    allocMemoryWithSize: retLength];

				if (_readBuffer != NULL &&
				    _readBufferLength <= retLength)
					memcpy(retCString, _readBuffer,
					    _readBufferLength);
				else if (_readBuffer != NULL)
					memcpy(retCString, _readBuffer,
					    retLength);
				if (i >= delimiterLength)
					memcpy(retCString + _readBufferLength,
					    buffer, i + 1 - delimiterLength);

				@try {
					char *rcs = retCString;
					size_t rl = retLength;

					ret = [OFString
					    stringWithCString: rcs
					    stringWithCString: retCString
						     encoding: encoding
						       length: rl];
						       length: retLength];
				} @catch (id e) {
					if (bufferLength > 0) {
						/*
						 * Append data to _readBuffer
						 * to prevent loss of data.
						 */
						readBuffer = [self
						readBuffer = of_malloc(
						    allocMemoryWithSize:
						    _readBufferLength +
						    bufferLength];
						    bufferLength, 1);

						memcpy(readBuffer, _readBuffer,
						    _readBufferLength);
						memcpy(readBuffer +
						    _readBufferLength,
						    buffer, bufferLength);

						[self freeMemory:
						    _readBufferMemory];
						free(_readBufferMemory);
						_readBuffer = readBuffer;
						_readBufferMemory = readBuffer;
						_readBufferLength +=
						    bufferLength;
					}

					@throw e;
				} @finally {
					[self freeMemory: retCString];
					free(retCString);
				}

				readBuffer = [self allocMemoryWithSize:
				    bufferLength - i - 1];
				readBuffer = of_malloc(bufferLength - i - 1, 1);
				if (readBuffer != NULL)
					memcpy(readBuffer, buffer + i + 1,
					    bufferLength - i - 1);

				[self freeMemory: _readBufferMemory];
				free(_readBufferMemory);
				_readBuffer = _readBufferMemory = readBuffer;
				_readBufferLength = bufferLength - i - 1;

				_waitingForDelimiter = false;
				return ret;
			}
		}

		/* Neither the delimiter nor \0 was found */
		if (bufferLength > 0) {
			readBuffer = [self allocMemoryWithSize:
			    _readBufferLength + bufferLength];
			readBuffer = of_malloc(_readBufferLength + bufferLength,
			    1);

			memcpy(readBuffer, _readBuffer, _readBufferLength);
			memcpy(readBuffer + _readBufferLength,
			    buffer, bufferLength);

			[self freeMemory: _readBufferMemory];
			free(_readBufferMemory);
			_readBuffer = _readBufferMemory = readBuffer;
			_readBufferLength += bufferLength;
		}
	} @finally {
		[self freeMemory: buffer];
		free(buffer);
	}

	_waitingForDelimiter = true;
	return nil;
}


1133
1134
1135
1136
1137
1138
1139
1140

1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162


1163
1164
1165
1166
1167
1168
1169
1128
1129
1130
1131
1132
1133
1134

1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155


1156
1157
1158
1159
1160
1161
1162
1163
1164







-
+




















-
-
+
+







{
	if (_writeBuffer == NULL)
		return;

	[self lowlevelWriteBuffer: _writeBuffer
			   length: _writeBufferLength];

	[self freeMemory: _writeBuffer];
	free(_writeBuffer);
	_writeBuffer = NULL;
	_writeBufferLength = 0;
}

- (size_t)writeBuffer: (const void *)buffer
	       length: (size_t)length
{
	if (!_buffersWrites) {
		size_t bytesWritten = [self lowlevelWriteBuffer: buffer
							 length: length];

		if (_canBlock && bytesWritten < length)
			@throw [OFWriteFailedException
			    exceptionWithObject: self
				requestedLength: length
				   bytesWritten: bytesWritten
					  errNo: 0];

		return bytesWritten;
	} else {
		_writeBuffer = [self resizeMemory: _writeBuffer
					     size: _writeBufferLength + length];
		_writeBuffer = of_realloc(_writeBuffer,
		    _writeBufferLength + length, 1);
		memcpy(_writeBuffer + _writeBufferLength, buffer, length);
		_writeBufferLength += length;

		return length;
	}
}

1337
1338
1339
1340
1341
1342
1343
1344

1345
1346
1347
1348
1349
1350
1351
1352
1353
1354

1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375

1376
1377
1378
1379
1380
1381
1382
1383
1384
1385

1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406

1407
1408
1409
1410
1411
1412
1413
1414
1415
1416

1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437

1438
1439
1440
1441
1442
1443
1444
1445
1446
1447

1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468

1469
1470
1471
1472
1473
1474
1475
1476
1477
1478

1479
1480
1481
1482
1483
1484
1485
1332
1333
1334
1335
1336
1337
1338

1339

1340
1341
1342
1343
1344
1345
1346
1347

1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368

1369

1370
1371
1372
1373
1374
1375
1376
1377

1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398

1399

1400
1401
1402
1403
1404
1405
1406
1407

1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428

1429

1430
1431
1432
1433
1434
1435
1436
1437

1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458

1459

1460
1461
1462
1463
1464
1465
1466
1467

1468
1469
1470
1471
1472
1473
1474
1475







-
+
-








-
+




















-
+
-








-
+




















-
+
-








-
+




















-
+
-








-
+




















-
+
-








-
+








	size = count * sizeof(uint16_t);

#ifdef OF_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
#else
	uint16_t *tmp = [self allocMemoryWithSize: sizeof(uint16_t)
	uint16_t *tmp = of_malloc(count, sizeof(uint16_t));
					    count: count];

	@try {
		for (size_t i = 0; i < count; i++)
			tmp[i] = OF_BSWAP16(buffer[i]);

		[self writeBuffer: tmp
			   length: size];
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}
#endif

	return size;
}

- (size_t)writeBigEndianInt32s: (const uint32_t *)buffer
			 count: (size_t)count
{
	size_t size;

	if OF_UNLIKELY (count > SIZE_MAX / sizeof(uint32_t))
		@throw [OFOutOfRangeException exception];

	size = count * sizeof(uint32_t);

#ifdef OF_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
#else
	uint32_t *tmp = [self allocMemoryWithSize: sizeof(uint32_t)
	uint32_t *tmp = of_malloc(count, sizeof(uint32_t));
					    count: count];

	@try {
		for (size_t i = 0; i < count; i++)
			tmp[i] = OF_BSWAP32(buffer[i]);

		[self writeBuffer: tmp
			   length: size];
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}
#endif

	return size;
}

- (size_t)writeBigEndianInt64s: (const uint64_t *)buffer
			 count: (size_t)count
{
	size_t size;

	if OF_UNLIKELY (count > SIZE_MAX / sizeof(uint64_t))
		@throw [OFOutOfRangeException exception];

	size = count * sizeof(uint64_t);

#ifdef OF_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
#else
	uint64_t *tmp = [self allocMemoryWithSize: sizeof(uint64_t)
	uint64_t *tmp = of_malloc(count, sizeof(uint64_t));
					    count: count];

	@try {
		for (size_t i = 0; i < count; i++)
			tmp[i] = OF_BSWAP64(buffer[i]);

		[self writeBuffer: tmp
			   length: size];
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}
#endif

	return size;
}

- (size_t)writeBigEndianFloats: (const float *)buffer
			 count: (size_t)count
{
	size_t size;

	if OF_UNLIKELY (count > SIZE_MAX / sizeof(float))
		@throw [OFOutOfRangeException exception];

	size = count * sizeof(float);

#ifdef OF_FLOAT_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
#else
	float *tmp = [self allocMemoryWithSize: sizeof(float)
	float *tmp = of_malloc(count, sizeof(float));
					 count: count];

	@try {
		for (size_t i = 0; i < count; i++)
			tmp[i] = OF_BSWAP_FLOAT(buffer[i]);

		[self writeBuffer: tmp
			   length: size];
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}
#endif

	return size;
}

- (size_t)writeBigEndianDoubles: (const double *)buffer
			  count: (size_t)count
{
	size_t size;

	if OF_UNLIKELY (count > SIZE_MAX / sizeof(double))
		@throw [OFOutOfRangeException exception];

	size = count * sizeof(double);

#ifdef OF_FLOAT_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
#else
	double *tmp = [self allocMemoryWithSize: sizeof(double)
	double *tmp = of_malloc(count, sizeof(double));
					  count: count];

	@try {
		for (size_t i = 0; i < count; i++)
			tmp[i] = OF_BSWAP_DOUBLE(buffer[i]);

		[self writeBuffer: tmp
			   length: size];
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}
#endif

	return size;
}

- (void)writeLittleEndianInt16: (uint16_t)int16
1532
1533
1534
1535
1536
1537
1538
1539

1540
1541
1542
1543
1544
1545
1546
1547
1548
1549

1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570

1571
1572
1573
1574
1575
1576
1577
1578
1579
1580

1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601

1602
1603
1604
1605
1606
1607
1608
1609
1610
1611

1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632

1633
1634
1635
1636
1637
1638
1639
1640
1641
1642

1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663

1664
1665
1666
1667
1668
1669
1670
1671
1672
1673

1674
1675
1676
1677
1678
1679
1680
1522
1523
1524
1525
1526
1527
1528

1529

1530
1531
1532
1533
1534
1535
1536
1537

1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558

1559

1560
1561
1562
1563
1564
1565
1566
1567

1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588

1589

1590
1591
1592
1593
1594
1595
1596
1597

1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618

1619

1620
1621
1622
1623
1624
1625
1626
1627

1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648

1649

1650
1651
1652
1653
1654
1655
1656
1657

1658
1659
1660
1661
1662
1663
1664
1665







-
+
-








-
+




















-
+
-








-
+




















-
+
-








-
+




















-
+
-








-
+




















-
+
-








-
+








	size = count * sizeof(uint16_t);

#ifndef OF_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
#else
	uint16_t *tmp = [self allocMemoryWithSize: sizeof(uint16_t)
	uint16_t *tmp = of_malloc(count, sizeof(uint16_t));
					    count: count];

	@try {
		for (size_t i = 0; i < count; i++)
			tmp[i] = OF_BSWAP16(buffer[i]);

		[self writeBuffer: tmp
			   length: size];
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}
#endif

	return size;
}

- (size_t)writeLittleEndianInt32s: (const uint32_t *)buffer
			    count: (size_t)count
{
	size_t size;

	if OF_UNLIKELY (count > SIZE_MAX / sizeof(uint32_t))
		@throw [OFOutOfRangeException exception];

	size = count * sizeof(uint32_t);

#ifndef OF_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
#else
	uint32_t *tmp = [self allocMemoryWithSize: sizeof(uint32_t)
	uint32_t *tmp = of_malloc(count, sizeof(uint32_t));
					    count: count];

	@try {
		for (size_t i = 0; i < count; i++)
			tmp[i] = OF_BSWAP32(buffer[i]);

		[self writeBuffer: tmp
			   length: size];
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}
#endif

	return size;
}

- (size_t)writeLittleEndianInt64s: (const uint64_t *)buffer
			    count: (size_t)count
{
	size_t size;

	if OF_UNLIKELY (count > SIZE_MAX / sizeof(uint64_t))
		@throw [OFOutOfRangeException exception];

	size = count * sizeof(uint64_t);

#ifndef OF_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
#else
	uint64_t *tmp = [self allocMemoryWithSize: sizeof(uint64_t)
	uint64_t *tmp = of_malloc(count, sizeof(uint64_t));
					    count: count];

	@try {
		for (size_t i = 0; i < count; i++)
			tmp[i] = OF_BSWAP64(buffer[i]);

		[self writeBuffer: tmp
			   length: size];
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}
#endif

	return size;
}

- (size_t)writeLittleEndianFloats: (const float *)buffer
			    count: (size_t)count
{
	size_t size;

	if OF_UNLIKELY (count > SIZE_MAX / sizeof(float))
		@throw [OFOutOfRangeException exception];

	size = count * sizeof(float);

#ifndef OF_FLOAT_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
#else
	float *tmp = [self allocMemoryWithSize: sizeof(float)
	float *tmp = of_malloc(count, sizeof(float));
					 count: count];

	@try {
		for (size_t i = 0; i < count; i++)
			tmp[i] = OF_BSWAP_FLOAT(buffer[i]);

		[self writeBuffer: tmp
			   length: size];
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}
#endif

	return size;
}

- (size_t)writeLittleEndianDoubles: (const double *)buffer
			     count: (size_t)count
{
	size_t size;

	if OF_UNLIKELY (count > SIZE_MAX / sizeof(double))
		@throw [OFOutOfRangeException exception];

	size = count * sizeof(double);

#ifndef OF_FLOAT_BIG_ENDIAN
	[self writeBuffer: buffer
		   length: size];
#else
	double *tmp = [self allocMemoryWithSize: sizeof(double)
	double *tmp = of_malloc(count, sizeof(double));
					  count: count];

	@try {
		for (size_t i = 0; i < count; i++)
			tmp[i] = OF_BSWAP_DOUBLE(buffer[i]);

		[self writeBuffer: tmp
			   length: size];
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}
#endif

	return size;
}

- (size_t)writeData: (OFData *)data
1730
1731
1732
1733
1734
1735
1736
1737

1738
1739
1740
1741
1742
1743
1744
1745
1746
1747

1748
1749
1750
1751
1752
1753
1754
1715
1716
1717
1718
1719
1720
1721

1722
1723
1724
1725
1726
1727
1728
1729
1730
1731

1732
1733
1734
1735
1736
1737
1738
1739







-
+









-
+








- (size_t)writeLine: (OFString *)string
	   encoding: (of_string_encoding_t)encoding
{
	size_t stringLength = [string cStringLengthWithEncoding: encoding];
	char *buffer;

	buffer = [self allocMemoryWithSize: stringLength + 1];
	buffer = of_malloc(stringLength + 1, 1);

	@try {
		memcpy(buffer, [string cStringWithEncoding: encoding],
		    stringLength);
		buffer[stringLength] = '\n';

		[self writeBuffer: buffer
			   length: stringLength + 1];
	} @finally {
		[self freeMemory: buffer];
		free(buffer);
	}

	return stringLength + 1;
}

- (size_t)writeFormat: (OFConstantString *)format, ...
{
1885
1886
1887
1888
1889
1890
1891
1892

1893
1894
1895
1896

1897
1898
1899
1900
1901
1902
1903

1904
1905
1906
1907

1908
1909
1910
1911
1912
1913
1914
1870
1871
1872
1873
1874
1875
1876

1877
1878
1879
1880

1881
1882
1883
1884
1885
1886
1887

1888
1889
1890
1891

1892
1893
1894
1895
1896
1897
1898
1899







-
+



-
+






-
+



-
+







		  length: (size_t)length
{
	char *readBuffer;

	if (length > SIZE_MAX - _readBufferLength)
		@throw [OFOutOfRangeException exception];

	readBuffer = [self allocMemoryWithSize: _readBufferLength + length];
	readBuffer = of_malloc(_readBufferLength + length, 1);
	memcpy(readBuffer, buffer, length);
	memcpy(readBuffer + length, _readBuffer, _readBufferLength);

	[self freeMemory: _readBufferMemory];
	free(_readBufferMemory);
	_readBuffer = _readBufferMemory = readBuffer;
	_readBufferLength += length;
}

- (void)close
{
	[self freeMemory: _readBufferMemory];
	free(_readBufferMemory);
	_readBuffer = _readBufferMemory = NULL;
	_readBufferLength = 0;

	[self freeMemory: _writeBuffer];
	free(_writeBuffer);
	_writeBuffer = NULL;
	_writeBufferLength = 0;
	_buffersWrites = false;

	_waitingForDelimiter = false;
}
@end

Modified src/OFString+JSONParsing.m from [706b49d04b] to [c0346b7fe9].

144
145
146
147
148
149
150
151

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

151

152
153
154
155
156
157
158







-
+
-







	char *buffer;
	size_t i = 0;
	char delimiter = **pointer;

	if (++(*pointer) + 1 >= stop)
		return nil;

	if ((buffer = malloc(stop - *pointer)) == NULL)
	buffer = of_malloc(stop - *pointer, 1);
		return nil;

	while (*pointer < stop) {
		/* Parse escape codes */
		if (**pointer == '\\') {
			if (++(*pointer) >= stop) {
				free(buffer);
				return nil;
291
292
293
294
295
296
297
298

299
300
301
302
303
304
305
306
290
291
292
293
294
295
296

297

298
299
300
301
302
303
304







-
+
-








static inline OFString *
parseIdentifier(const char **pointer, const char *stop)
{
	char *buffer;
	size_t i = 0;

	if ((buffer = malloc(stop - *pointer)) == NULL)
	buffer = of_malloc(stop - *pointer, 1);
		return nil;

	while (*pointer < stop) {
		if ((**pointer >= 'a' && **pointer <= 'z') ||
		    (**pointer >= 'A' && **pointer <= 'Z') ||
		    (**pointer >= '0' && **pointer <= '9') ||
		    **pointer == '_' || **pointer == '$' ||
		    (**pointer & 0x80)) {
382
383
384
385
386
387
388

389
390
391
392
393
394
395
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394







+







		}
	}

	/*
	 * It is never possible to end with an identifier, thus we should never
	 * reach stop.
	 */
	free(buffer);
	return nil;
}

static inline OFMutableArray *
parseArray(const char **pointer, const char *stop, size_t *line,
    size_t depthLimit)
{

Modified src/OFString+URLEncoding.m from [4455805b29] to [329955234f].

80
81
82
83
84
85
86
87

88
89
90
91
92

93
94
95
96
97
98
99
100
101
80
81
82
83
84
85
86

87
88
89
90
91

92


93
94
95
96
97
98
99







-
+




-
+
-
-







}

- (OFString *)stringByURLDecoding
{
	void *pool = objc_autoreleasePoolPush();
	const char *string = self.UTF8String;
	size_t length = self.UTF8StringLength;
	char *retCString, *retCString2;
	char *retCString;
	char byte = 0;
	int state = 0;
	size_t i = 0;

	if ((retCString = malloc(length + 1)) == NULL)
	retCString = of_malloc(length + 1, 1);
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: length + 1];

	while (length--) {
		char c = *string++;

		switch (state) {
		case 0:
			if (c == '%')
132
133
134
135
136
137
138



139

140
141
142
143
144
145
146











147
130
131
132
133
134
135
136
137
138
139

140







141
142
143
144
145
146
147
148
149
150
151
152







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

	objc_autoreleasePoolPop(pool);

	if (state != 0) {
		free(retCString);
		@throw [OFInvalidFormatException exception];
	}

	@try {
		retCString = of_realloc(retCString, 1, i + 1);
	} @catch (OFOutOfMemoryException *e) {
	/* We don't care if it fails, as we only made it smaller. */
		/* We don't care if it fails, as we only made it smaller. */
	if ((retCString2 = realloc(retCString, i + 1)) == NULL)
		retCString2 = retCString;

	return [OFString stringWithUTF8StringNoCopy: retCString2
					     length: i
				       freeWhenDone: true];
}
	}

	@try {
		return [OFString stringWithUTF8StringNoCopy: retCString
						     length: i
					       freeWhenDone: true];
	} @catch (id e) {
		free(retCString);
		@throw e;
	}
}
@end

Modified src/OFString+XMLEscaping.m from [896b2f634c] to [e1df224af8].

38
39
40
41
42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
57
58
38
39
40
41
42
43
44





45


46
47
48
49
50
51
52







-
-
-
-
-
+
-
-







	OFString *ret;

	string = self.UTF8String;
	length = self.UTF8StringLength;

	j = 0;
	retLength = length;

	/*
	 * We can't use allocMemoryWithSize: here as it might be a @"" literal
	 */
	if ((retCString = malloc(retLength)) == NULL)
	retCString = of_malloc(retLength, 1);
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: retLength];

	for (size_t i = 0; i < length; i++) {
		switch (string[i]) {
		case '<':
			append = "&lt;";
			appendLen = 4;
			break;
78
79
80
81
82
83
84
85
86
87
88




89
90

91
92
93
94
95
96
97
98
99
100
101
72
73
74
75
76
77
78




79
80
81
82
83

84


85

86
87
88
89
90
91
92







-
-
-
-
+
+
+
+

-
+
-
-

-







			break;
		default:
			append = NULL;
			appendLen = 0;
		}

		if (append != NULL) {
			char *newRetCString;

			if ((newRetCString = realloc(retCString,
			    retLength + appendLen)) == NULL) {
			@try {
				retCString = of_realloc(retCString, 1,
				    retLength + appendLen);
			} @catch (id e) {
				free(retCString);
				@throw [OFOutOfMemoryException
				@throw e;
				     exceptionWithRequestedSize: retLength +
								 appendLen];
			}
			retCString = newRetCString;
			retLength += appendLen - 1;

			memcpy(retCString + j, append, appendLen);
			j += appendLen;
		} else
			retCString[j++] = string[i];
	}

Modified src/OFString.h from [670340b7ed] to [b31ea8640a].

1000
1001
1002
1003
1004
1005
1006
















1007
1008
1009
1010
1011
1012
1013
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







 * @brief Returns whether the string contains the specified string.
 *
 * @param string The string to search
 * @return Whether the string contains the specified string
 */
- (bool)containsString: (OFString *)string;

/**
 * @brief Creates a substring from the specified index to the end.
 *
 * @param idx The index from where the substring should start, inclusive
 * @return The substring from the specified index to the end
 */
- (OFString *)substringFromIndex: (size_t)idx;

/**
 * @brief Creates a substring from the beginning to the specified index.
 *
 * @param idx The index at which the substring should end, exclusive
 * @return The subtring from the beginning to the specified index
 */
- (OFString *)substringToIndex: (size_t)idx;

/**
 * @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;

Modified src/OFString.m from [a28b46c55c] to [3f36b9543e].

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
867
868
869
870
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







-
+

-
-
-
-
-
+
+
-








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







			    encoding: OF_STRING_ENCODING_UTF_8
			      length: UTF8StringLength];
}

- (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String
			    freeWhenDone: (bool)freeWhenDone
{
	id ret;
	id ret = [self initWithUTF8String: UTF8String];

	@try {
		ret = [self initWithUTF8String: UTF8String];
	} @finally {
		if (freeWhenDone)
			free(UTF8String);
	if (freeWhenDone)
		free(UTF8String);
	}

	return ret;
}

- (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String
				  length: (size_t)UTF8StringLength
			    freeWhenDone: (bool)freeWhenDone
{
	id ret;

	@try {
		ret = [self initWithUTF8String: UTF8String
					length: UTF8StringLength];
	} @finally {
		if (freeWhenDone)
			free(UTF8String);
	id ret = [self initWithUTF8String: UTF8String
				   length: UTF8StringLength];

	if (freeWhenDone)
		free(UTF8String);
	}

	return ret;
}

- (instancetype)initWithCString: (const char *)cString
		       encoding: (of_string_encoding_t)encoding
{
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
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







-
+
-
-
-



















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







		/*
		 * We need one extra byte for the terminating zero if we want
		 * to use -[initWithUTF8StringNoCopy:length:freeWhenDone:].
		 */
		if (SIZE_MAX - (size_t)fileSize < 1)
			@throw [OFOutOfRangeException exception];

		if ((tmp = malloc((size_t)fileSize + 1)) == NULL)
		tmp = of_malloc((size_t)fileSize + 1, 1);
			@throw [OFOutOfMemoryException
			    exceptionWithRequestedSize: (size_t)fileSize];

		@try {
			file = [[OFFile alloc] initWithPath: path
						       mode: @"r"];

			[file readIntoBuffer: tmp
				 exactLength: (size_t)fileSize];
		} @catch (id e) {
			free(tmp);
			@throw e;
		} @finally {
			[file release];
		}

		tmp[(size_t)fileSize] = '\0';
	} @catch (id e) {
		[self release];
		@throw e;
	}

	if (encoding == OF_STRING_ENCODING_UTF_8)
		self = [self initWithUTF8StringNoCopy: tmp
					       length: (size_t)fileSize
					 freeWhenDone: true];
	else {
	if (encoding == OF_STRING_ENCODING_UTF_8) {
		@try {
			self = [self initWithUTF8StringNoCopy: tmp
						       length: (size_t)fileSize
						 freeWhenDone: true];
		} @catch (id e) {
			free(tmp);
			@throw e;
		}
	} else {
		@try {
			self = [self initWithCString: tmp
					    encoding: encoding
					      length: (size_t)fileSize];
		} @finally {
			free(tmp);
		}
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387

1388
1389
1390
1391


1392
1393
1394
1395
1396
1397
1398
1399











1400
1401
1402

1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421

1422

1423
1424
1425
1426








1427
1428
1429
1430
1431
1432





1433



1434
1435
1436
1437
1438
1439
1440
1372
1373
1374
1375
1376
1377
1378

1379
1380
1381
1382
1383


1384
1385
1386







1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398


1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417

1418
1419
1420




1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439

1440
1441
1442
1443
1444
1445
1446
1447
1448
1449







-


+


-
-
+
+

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

-
-
+


















-
+

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






+
+
+
+
+
-
+
+
+







			  encoding: encoding
			     lossy: true];
}

- (const char *)of_cStringWithEncoding: (of_string_encoding_t)encoding
				 lossy: (bool)lossy
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	size_t length = self.length;
	char *cString;
	size_t cStringLength;

	switch (encoding) {
	case OF_STRING_ENCODING_UTF_8:;
		size_t cStringLength;
	case OF_STRING_ENCODING_UTF_8:
		cString = of_malloc((length * 4) + 1, 1);

		cString = [object allocMemoryWithSize: (length * 4) + 1];

		cStringLength = [self of_getCString: cString
					  maxLength: (length * 4) + 1
					   encoding: OF_STRING_ENCODING_UTF_8
					      lossy: lossy];

		@try {
			cStringLength = [self
			    of_getCString: cString
				maxLength: (length * 4) + 1
				 encoding: OF_STRING_ENCODING_UTF_8
				    lossy: lossy];
		} @catch (id e) {
			free(cString);
			@throw e;
		}

		@try {
			cString = [object resizeMemory: cString
						  size: cStringLength + 1];
			cString = of_realloc(cString, cStringLength + 1, 1);
		} @catch (OFOutOfMemoryException *e) {
			/* We don't care, as we only tried to make it smaller */
		}

		break;
	case OF_STRING_ENCODING_ASCII:
	case OF_STRING_ENCODING_ISO_8859_1:
	case OF_STRING_ENCODING_ISO_8859_2:
	case OF_STRING_ENCODING_ISO_8859_3:
	case OF_STRING_ENCODING_ISO_8859_15:
	case OF_STRING_ENCODING_WINDOWS_1251:
	case OF_STRING_ENCODING_WINDOWS_1252:
	case OF_STRING_ENCODING_CODEPAGE_437:
	case OF_STRING_ENCODING_CODEPAGE_850:
	case OF_STRING_ENCODING_CODEPAGE_858:
	case OF_STRING_ENCODING_MAC_ROMAN:
	case OF_STRING_ENCODING_KOI8_R:
	case OF_STRING_ENCODING_KOI8_U:
		cString = [object allocMemoryWithSize: length + 1];
		cString = of_malloc(length + 1, 1);

		@try {
		[self of_getCString: cString
			  maxLength: length + 1
			   encoding: encoding
			      lossy: lossy];
			cStringLength = [self of_getCString: cString
						  maxLength: length + 1
						   encoding: encoding
						      lossy: lossy];
		} @catch (id e) {
			free(cString);
			@throw e;
		}

		break;
	default:
		@throw [OFInvalidEncodingException exception];
	}

	@try {
		return [[OFData dataWithItemsNoCopy: cString
					      count: cStringLength + 1
				       freeWhenDone: true] items];
	} @catch (id e) {
	return cString;
		free(cString);
		@throw e;
	}
}

- (const char *)cStringWithEncoding: (of_string_encoding_t)encoding
{
	return [self of_cStringWithEncoding: encoding
				      lossy: false];
}
1658
1659
1660
1661
1662
1663
1664
1665

1666
1667
1668
1669
1670
1671
1672
1667
1668
1669
1670
1671
1672
1673

1674
1675
1676
1677
1678
1679
1680
1681







-
+







		return OF_ORDERED_DESCENDING;
	if (length < otherLength)
		return OF_ORDERED_ASCENDING;

	return OF_ORDERED_SAME;
}

- (uint32_t)hash
- (unsigned long)hash
{
	const of_unichar_t *characters = self.characters;
	size_t length = self.length;
	uint32_t hash;

	OF_HASH_INIT(hash);

1856
1857
1858
1859
1860
1861
1862
1863
1864
1865

1866
1867
1868
1869
1870
1871
1872
1873
1865
1866
1867
1868
1869
1870
1871



1872

1873
1874
1875
1876
1877
1878
1879







-
-
-
+
-







	if (range.length > SIZE_MAX / sizeof(of_unichar_t))
		@throw [OFOutOfRangeException exception];

	pool = objc_autoreleasePoolPush();

	searchCharacters = string.characters;

	if ((characters = malloc(range.length * sizeof(of_unichar_t))) == NULL)
		@throw [OFOutOfMemoryException exceptionWithRequestedSize:
		    range.length * sizeof(of_unichar_t)];
	characters = of_malloc(range.length, sizeof(of_unichar_t));

	@try {
		[self getCharacters: characters
			    inRange: range];

		if (options & OF_STRING_SEARCH_BACKWARDS) {
			for (size_t i = range.length - searchLength;; i--) {
				if (memcmp(characters + i, searchCharacters,
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936

1937
1938
1939
1940
1941
1942
1943
1944
1933
1934
1935
1936
1937
1938
1939



1940

1941
1942
1943
1944
1945
1946
1947







-
-
-
+
-








	if (range.length == 0)
		return OF_NOT_FOUND;

	if (range.length > SIZE_MAX / sizeof(of_unichar_t))
		@throw [OFOutOfRangeException exception];

	if ((characters = malloc(range.length * sizeof(of_unichar_t))) == NULL)
		@throw [OFOutOfMemoryException exceptionWithRequestedSize:
		    range.length * sizeof(of_unichar_t)];
	characters = of_malloc(range.length, sizeof(of_unichar_t));

	@try {
		[self getCharacters: characters
			    inRange: range];

		if (options & OF_STRING_SEARCH_BACKWARDS) {
			for (size_t i = range.length - 1;; i--) {
				if (characterIsMember(characterSet,
1989
1990
1991
1992
1993
1994
1995










1996
1997
1998
1999
2000
2001
2002
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015







+
+
+
+
+
+
+
+
+
+







		}
	}

	objc_autoreleasePoolPop(pool);

	return false;
}

- (OFString *)substringFromIndex: (size_t)idx
{
	return [self substringWithRange: of_range(idx, self.length - idx)];
}

- (OFString *)substringToIndex: (size_t)idx
{
	return [self substringWithRange: of_range(0, idx)];
}

- (OFString *)substringWithRange: (of_range_t)range
{
	void *pool;
	OFString *ret;

	if (range.length > SIZE_MAX - range.location ||
2163
2164
2165
2166
2167
2168
2169
2170

2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183

2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201

2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216

2217
2218
2219
2220
2221
2222
2223
2176
2177
2178
2179
2180
2181
2182

2183

2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194

2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212

2213

2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226

2227
2228
2229
2230
2231
2232
2233
2234







-
+
-











-
+

















-
+
-













-
+







	of_unichar_t *tmp;
	size_t prefixLength;
	bool hasPrefix;

	if ((prefixLength = prefix.length) > self.length)
		return false;

	tmp = [self allocMemoryWithSize: sizeof(of_unichar_t)
	tmp = of_malloc(prefixLength, sizeof(of_unichar_t));
				  count: prefixLength];
	@try {
		void *pool = objc_autoreleasePoolPush();

		[self getCharacters: tmp
			    inRange: of_range(0, prefixLength)];

		hasPrefix = (memcmp(tmp, prefix.characters,
		    prefixLength * sizeof(of_unichar_t)) == 0);

		objc_autoreleasePoolPop(pool);
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}

	return hasPrefix;
}

- (bool)hasSuffix: (OFString *)suffix
{
	of_unichar_t *tmp;
	const of_unichar_t *suffixCharacters;
	size_t length, suffixLength;
	bool hasSuffix;

	if ((suffixLength = suffix.length) > self.length)
		return false;

	length = self.length;

	tmp = [self allocMemoryWithSize: sizeof(of_unichar_t)
	tmp = of_malloc(suffixLength, sizeof(of_unichar_t));
				  count: suffixLength];
	@try {
		void *pool = objc_autoreleasePoolPush();

		[self getCharacters: tmp
			    inRange: of_range(length - suffixLength,
					 suffixLength)];

		suffixCharacters = suffix.characters;
		hasSuffix = (memcmp(tmp, suffixCharacters,
		    suffixLength * sizeof(of_unichar_t)) == 0);

		objc_autoreleasePoolPop(pool);
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}

	return hasSuffix;
}

- (OFArray *)componentsSeparatedByString: (OFString *)delimiter
{
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
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
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588







-

-
+

-
-
-
-
+
+
+
+

-
+
+
+
+
+
+
+
+









-



-
+




-
-
+





-
+
+

+




-
-
+
+

-
+



-
-
+
+

-
+


-
+


-
-
+
-






+
-
+
+
+
+
+
+
+
+







	objc_autoreleasePoolPop(pool);

	return value;
}

- (const of_unichar_t *)characters
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	size_t length = self.length;
	of_unichar_t *ret;
	of_unichar_t *buffer;

	ret = [object allocMemoryWithSize: sizeof(of_unichar_t)
				    count: length];
	[self getCharacters: ret
		    inRange: of_range(0, length)];
	buffer = of_malloc(length, sizeof(of_unichar_t));
	@try {
		[self getCharacters: buffer
			    inRange: of_range(0, length)];

	return ret;
		return [[OFData dataWithItemsNoCopy: buffer
					      count: length
					   itemSize: sizeof(of_unichar_t)
				       freeWhenDone: true] items];
	} @catch (id e) {
		free(buffer);
		@throw e;
	}
}

- (const of_char16_t *)UTF16String
{
	return [self UTF16StringWithByteOrder: OF_BYTE_ORDER_NATIVE];
}

- (const of_char16_t *)UTF16StringWithByteOrder: (of_byte_order_t)byteOrder
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	void *pool = objc_autoreleasePoolPush();
	const of_unichar_t *characters = self.characters;
	size_t length = self.length;
	of_char16_t *ret;
	of_char16_t *buffer;
	size_t j;
	bool swap = (byteOrder != OF_BYTE_ORDER_NATIVE);

	/* Allocate memory for the worst case */
	ret = [object allocMemoryWithSize: sizeof(of_char16_t)
				    count: (length + 1) * 2];
	buffer = of_malloc((length + 1) * 2, sizeof(of_char16_t));

	j = 0;
	for (size_t i = 0; i < length; i++) {
		of_unichar_t c = characters[i];

		if (c > 0x10FFFF)
		if (c > 0x10FFFF) {
			free(buffer);
			@throw [OFInvalidEncodingException exception];
		}

		if (swap) {
			if (c > 0xFFFF) {
				c -= 0x10000;
				ret[j++] = OF_BSWAP16(0xD800 | (c >> 10));
				ret[j++] = OF_BSWAP16(0xDC00 | (c & 0x3FF));
				buffer[j++] = OF_BSWAP16(0xD800 | (c >> 10));
				buffer[j++] = OF_BSWAP16(0xDC00 | (c & 0x3FF));
			} else
				ret[j++] = OF_BSWAP16(c);
				buffer[j++] = OF_BSWAP16(c);
		} else {
			if (c > 0xFFFF) {
				c -= 0x10000;
				ret[j++] = 0xD800 | (c >> 10);
				ret[j++] = 0xDC00 | (c & 0x3FF);
				buffer[j++] = 0xD800 | (c >> 10);
				buffer[j++] = 0xDC00 | (c & 0x3FF);
			} else
				ret[j++] = c;
				buffer[j++] = c;
		}
	}
	ret[j] = 0;
	buffer[j] = 0;

	@try {
		ret = [object resizeMemory: ret
				      size: sizeof(of_char16_t)
		buffer = of_realloc(buffer, j + 1, sizeof(of_char16_t));
				     count: j + 1];
	} @catch (OFOutOfMemoryException *e) {
		/* We don't care, as we only tried to make it smaller */
	}

	objc_autoreleasePoolPop(pool);

	@try {
	return ret;
		return [[OFData dataWithItemsNoCopy: buffer
					      count: j + 1
					   itemSize: sizeof(of_char16_t)
				       freeWhenDone: true] items];
	} @catch (id e) {
		free(buffer);
		@throw e;
	}
}

- (size_t)UTF16StringLength
{
	const of_unichar_t *characters = self.characters;
	size_t length, UTF16StringLength;

2575
2576
2577
2578
2579
2580
2581
2582
2583
2584

2585
2586

2587
2588
2589
2590




2591
2592
2593
2594



2595
2596








2597
2598
2599
2600
2601
2602
2603
2598
2599
2600
2601
2602
2603
2604

2605

2606
2607

2608




2609
2610
2611
2612
2613



2614
2615
2616
2617

2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632







-

-
+

-
+
-
-
-
-
+
+
+
+

-
-
-
+
+
+

-
+
+
+
+
+
+
+
+







- (const of_char32_t *)UTF32String
{
	return [self UTF32StringWithByteOrder: OF_BYTE_ORDER_NATIVE];
}

- (const of_char32_t *)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	size_t length = self.length;
	of_char32_t *ret;
	of_char32_t *buffer;

	ret = [object allocMemoryWithSize: sizeof(of_char32_t)
	buffer = of_malloc(length + 1, sizeof(of_char32_t));
				    count: length + 1];
	[self getCharacters: ret
		    inRange: of_range(0, length)];
	ret[length] = 0;
	@try {
		[self getCharacters: buffer
			    inRange: of_range(0, length)];
		buffer[length] = 0;

	if (byteOrder != OF_BYTE_ORDER_NATIVE)
		for (size_t i = 0; i < length; i++)
			ret[i] = OF_BSWAP32(ret[i]);
		if (byteOrder != OF_BYTE_ORDER_NATIVE)
			for (size_t i = 0; i < length; i++)
				buffer[i] = OF_BSWAP32(buffer[i]);

	return ret;
		return [[OFData dataWithItemsNoCopy: buffer
					      count: length + 1
					   itemSize: sizeof(of_char32_t)
				       freeWhenDone: true] items];
	} @catch (id e) {
		free(buffer);
		@throw e;
	}
}

- (OFData *)dataWithEncoding: (of_string_encoding_t)encoding
{
	void *pool = objc_autoreleasePoolPush();
	OFData *data =
	    [OFData dataWithItems: [self cStringWithEncoding: encoding]

Modified src/OFSystemInfo.m from [3f56016e9e] to [97e07274dd].

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







-
+




-
-
-
+
+
+

-
+









-
-
-
+
+
+

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







}
#endif

+ (OFString *)CPUVendor
{
#if defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
	struct x86_regs regs = x86_cpuid(0, 0);
	char buffer[12];
	uint32_t buffer[3];

	if (regs.eax == 0)
		return nil;

	memcpy(buffer, &regs.ebx, 4);
	memcpy(buffer + 4, &regs.edx, 4);
	memcpy(buffer + 8, &regs.ecx, 4);
	buffer[0] = regs.ebx;
	buffer[1] = regs.edx;
	buffer[2] = regs.ecx;

	return [OFString stringWithCString: buffer
	return [OFString stringWithCString: (char *)buffer
				  encoding: OF_STRING_ENCODING_ASCII
				    length: 12];
#else
	return nil;
#endif
}

+ (OFString *)CPUModel
{
#if defined(OF_MACOS) || defined(OF_NETBSD)
	char value[256];
	size_t length = sizeof(value);
#if defined(OF_X86_64_ASM) || defined(OF_X86_ASM)
	uint32_t buffer[12];
	size_t i;

# if defined(OF_MACOS)
	if (sysctlbyname("machdep.cpu.brand_string",
# elif defined(OF_NETBSD)
	if (sysctlbyname("machdep.cpu_brand",
# endif
	    &value, &length, NULL, 0) != 0)
		return nil;

	return [OFString stringWithCString: value
	i = 0;
	for (uint32_t eax = 0x80000002; eax <= 0x80000004; eax++) {
		struct x86_regs regs = x86_cpuid(eax, 0);

		buffer[i++] = regs.eax;
		buffer[i++] = regs.ebx;
		buffer[i++] = regs.ecx;
		buffer[i++] = regs.edx;
	}

	return [OFString stringWithCString: (char *)buffer
				  encoding: OF_STRING_ENCODING_ASCII];
#elif defined(OF_AMIGAOS4)
	CONST_STRPTR model, version;

	GetCPUInfoTags(GCIT_ModelString, &model,
	    GCIT_VersionString, &version, TAG_END);

Modified src/OFTimer.h from [e04cb8b583] to [e351b12ba6].

46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
46
47
48
49
50
51
52

53
54
55
56
57
58
59
60







-
+







@interface OFTimer: OFObject <OFComparing>
{
	OFDate *_fireDate;
	of_time_interval_t _interval;
	id _target;
	id _Nullable _object1, _object2, _object3, _object4;
	SEL _selector;
	uint8_t _arguments;
	unsigned char _arguments;
	bool _repeats;
#ifdef OF_HAVE_BLOCKS
	of_timer_block_t _block;
#endif
	bool _valid;
#ifdef OF_HAVE_THREADS
	OFCondition *_condition;

Modified src/OFTimer.m from [ced46435b5] to [b1d045935e].

324
325
326
327
328
329
330
331

332
333
334
335
336
337
338
324
325
326
327
328
329
330

331
332
333
334
335
336
337
338







-
+







			   interval: (of_time_interval_t)interval
			     target: (id)target
			   selector: (SEL)selector
			     object: (id)object1
			     object: (id)object2
			     object: (id)object3
			     object: (id)object4
			  arguments: (uint8_t)arguments
			  arguments: (unsigned char)arguments
			    repeats: (bool)repeats
    OF_METHOD_FAMILY(init) OF_DIRECT
{
	self = [super init];

	@try {
		_fireDate = [fireDate retain];

Modified src/OFTriple.m from [132f7da5da] to [9a522e8d33].

95
96
97
98
99
100
101
102

103
104
105
106
107
108
109
95
96
97
98
99
100
101

102
103
104
105
106
107
108
109







-
+







	if (triple->_thirdObject != _thirdObject &&
	    ![triple->_thirdObject isEqual: _thirdObject])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, [_firstObject hash]);
	OF_HASH_ADD_HASH(hash, [_secondObject hash]);

Modified src/OFURL.m from [00f085f9ce] to [a1fb3bc27c].

846
847
848
849
850
851
852
853

854
855
856
857
858
859
860
846
847
848
849
850
851
852

853
854
855
856
857
858
859
860







-
+







	if (URL->_URLEncodedFragment != _URLEncodedFragment &&
	    ![URL->_URLEncodedFragment isEqual: _URLEncodedFragment])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, _URLEncodedScheme.hash);
	OF_HASH_ADD_HASH(hash, _URLEncodedHost.hash);
1001
1002
1003
1004
1005
1006
1007
1008

1009
1010
1011
1012
1013
1014
1015
1001
1002
1003
1004
1005
1006
1007

1008
1009
1010
1011
1012
1013
1014
1015







-
+








	if ([path isEqual: @"/"]) {
		objc_autoreleasePoolPop(pool);
		return @"/";
	}

	if ([path hasSuffix: @"/"])
		path = [path substringWithRange: of_range(0, path.length - 1)];
		path = [path substringToIndex: path.length - 1];

	UTF8String = lastComponent = path.UTF8String;
	length = path.UTF8StringLength;

	for (size_t i = 1; i <= length; i++) {
		if (UTF8String[length - i] == '/') {
			lastComponent = UTF8String + (length - i) + 1;

Modified src/OFUTF8String.h from [3d372b3717] to [3093d4730f].

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







39
40
41
42
43
44
45
25
26
27
28
29
30
31







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







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







	 * A pointer to the actual data.
	 *
	 * Since constant strings don't have `_storage`, they have to allocate
	 * it on the first access. Strings created at runtime just set the
	 * pointer to `&_storage`.
	 */
	struct of_string_utf8_ivars {
		char	 *cString;
		size_t	 cStringLength;
		bool	 isUTF8;
		size_t	 length;
		bool	 hashed;
		uint32_t hash;
		char	 *_Nullable freeWhenDone;
		char          *cString;
		size_t        cStringLength;
		bool          isUTF8;
		size_t        length;
		bool          hashed;
		unsigned long hash;
		bool          freeWhenDone;
	} *restrict _s;
	struct of_string_utf8_ivars _storage;
}
@end

#ifdef __cplusplus
extern "C" {

Modified src/OFUTF8String.m from [03dadccc61] to [4cdd46e0d2].

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







+







#ifdef OF_HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif

#import "OFUTF8String.h"
#import "OFUTF8String+Private.h"
#import "OFArray.h"
#import "OFData.h"
#import "OFMutableUTF8String.h"

#import "OFInitializationFailedException.h"
#import "OFInvalidArgumentException.h"
#import "OFInvalidEncodingException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfMemoryException.h"
176
177
178
179
180
181
182
183
184


185
186
187
188
189
190
191
177
178
179
180
181
182
183


184
185
186
187
188
189
190
191
192







-
-
+
+







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

	@try {
		_s = &_storage;

		_s->cString = [self allocMemoryWithSize: 1];
		_s->cString[0] = '\0';
		_s->cString = of_calloc(1, 1);
		_s->freeWhenDone = true;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
242
243
244
245
246
247
248
249

250

251
252
253
254
255
256
257
243
244
245
246
247
248
249

250
251
252
253
254
255
256
257
258
259







-
+

+







		    memcmp(cString, "\xEF\xBB\xBF", 3) == 0) {
			cString += 3;
			cStringLength -= 3;
		}

		_s = &_storage;

		_s->cString = [self allocMemoryWithSize: cStringLength + 1];
		_s->cString = of_malloc(cStringLength + 1, 1);
		_s->cStringLength = cStringLength;
		_s->freeWhenDone = true;

		if (encoding == OF_STRING_ENCODING_UTF_8 ||
		    encoding == OF_STRING_ENCODING_ASCII) {
			switch (of_string_utf8_check(cString, cStringLength,
			    &_s->length)) {
			case 1:
				if (encoding == OF_STRING_ENCODING_ASCII)
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
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







-
+
-
-
+











-
-
-
-
-
+
+
+
+
+







				    (uint8_t)cString[i], buffer);

				if (bytes == 0)
					@throw [OFInvalidEncodingException
					    exception];

				_s->cStringLength += bytes - 1;
				_s->cString = [self
				_s->cString = of_realloc(_s->cString,
				    resizeMemory: _s->cString
					    size: _s->cStringLength + 1];
				    _s->cStringLength + 1, 1);

				memcpy(_s->cString + j, buffer, bytes);
				j += bytes;
			}

			_s->cString[_s->cStringLength] = 0;

			return self;
		}

		switch (encoding) {
#define CASE(encoding, var)			\
	case encoding:				\
		table = var;			\
		tableOffset = var##_offset;	\
		break;
#define CASE(encoding, var)				\
		case encoding:				\
			table = var;			\
			tableOffset = var##_offset;	\
			break;
#ifdef HAVE_ISO_8859_2
		CASE(OF_STRING_ENCODING_ISO_8859_2, of_iso_8859_2_table)
#endif
#ifdef HAVE_ISO_8859_3
		CASE(OF_STRING_ENCODING_ISO_8859_3, of_iso_8859_3_table)
#endif
#ifdef HAVE_ISO_8859_15
370
371
372
373
374
375
376
377

378
379

380
381
382
383
384
385
386
371
372
373
374
375
376
377

378


379
380
381
382
383
384
385
386







-
+
-
-
+







			_s->isUTF8 = true;
			byteLength = of_string_utf8_encode(unichar, buffer);

			if (byteLength == 0)
				@throw [OFInvalidEncodingException exception];

			_s->cStringLength += byteLength - 1;
			_s->cString = [self
			_s->cString = of_realloc(_s->cString,
			    resizeMemory: _s->cString
				    size: _s->cStringLength + 1];
			    _s->cStringLength + 1, 1);

			memcpy(_s->cString + j, buffer, byteLength);
			j += byteLength;
		}

		_s->cString[_s->cStringLength] = 0;
	} @catch (id e) {
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
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







-
-
+
-
-
-
-
-




-
-
-






-
-
-








+
+
+
+








}

- (instancetype)initWithUTF8StringNoCopy: (char *)UTF8String
				  length: (size_t)UTF8StringLength
			    freeWhenDone: (bool)freeWhenDone
{
	@try {
		self = [super init];
	self = [super init];
	} @catch (id e) {
		if (freeWhenDone)
			free(UTF8String);
		@throw e;
	}

	@try {
		_s = &_storage;

		if (freeWhenDone)
			_s->freeWhenDone = UTF8String;

		if (UTF8StringLength >= 3 &&
		    memcmp(UTF8String, "\xEF\xBB\xBF", 3) == 0) {
			UTF8String += 3;
			UTF8StringLength -= 3;
		}

		_s->cString = (char *)UTF8String;
		_s->cStringLength = UTF8StringLength;

		switch (of_string_utf8_check(UTF8String, UTF8StringLength,
		    &_s->length)) {
		case 1:
			_s->isUTF8 = true;
			break;
		case -1:
			@throw [OFInvalidEncodingException exception];
		}

		_s->cString = (char *)UTF8String;
		_s->cStringLength = UTF8StringLength;
		_s->freeWhenDone = freeWhenDone;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}
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
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







-
+

+


















-
+

+



















-
+
-







		    [string isKindOfClass: [OFMutableUTF8String class]])
			_s->isUTF8 = ((OFUTF8String *)string)->_s->isUTF8;
		else
			_s->isUTF8 = true;

		_s->length = string.length;

		_s->cString = [self allocMemoryWithSize: _s->cStringLength + 1];
		_s->cString = of_malloc(_s->cStringLength + 1, 1);
		memcpy(_s->cString, string.UTF8String, _s->cStringLength + 1);
		_s->freeWhenDone = true;
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (instancetype)initWithCharacters: (const of_unichar_t *)characters
			    length: (size_t)length
{
	self = [super init];

	@try {
		size_t j;

		_s = &_storage;

		_s->cString = [self allocMemoryWithSize: (length * 4) + 1];
		_s->cString = of_malloc((length * 4) + 1, 1);
		_s->length = length;
		_s->freeWhenDone = true;

		j = 0;
		for (size_t i = 0; i < length; i++) {
			size_t len = of_string_utf8_encode(characters[i],
			    _s->cString + j);

			if (len == 0)
				@throw [OFInvalidEncodingException exception];

			if (len > 1)
				_s->isUTF8 = true;

			j += len;
		}

		_s->cString[j] = '\0';
		_s->cStringLength = j;

		@try {
			_s->cString = [self resizeMemory: _s->cString
			_s->cString = of_realloc(_s->cString, j + 1, 1);
						    size: j + 1];
		} @catch (OFOutOfMemoryException *e) {
			/* We don't care, as we only tried to make it smaller */
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}
532
533
534
535
536
537
538
539

540

541
542
543
544
545
546
547
525
526
527
528
529
530
531

532
533
534
535
536
537
538
539
540
541







-
+

+







			string++;
			length--;
		} else if (byteOrder != OF_BYTE_ORDER_NATIVE)
			swap = true;

		_s = &_storage;

		_s->cString = [self allocMemoryWithSize: (length * 4) + 1];
		_s->cString = of_malloc((length * 4) + 1, 1);
		_s->length = length;
		_s->freeWhenDone = true;

		j = 0;
		for (size_t i = 0; i < length; i++) {
			of_unichar_t character =
			    (swap ? OF_BSWAP16(string[i]) : string[i]);
			size_t len;

582
583
584
585
586
587
588
589

590
591
592
593
594
595
596
597
576
577
578
579
580
581
582

583

584
585
586
587
588
589
590







-
+
-







			j += len;
		}

		_s->cString[j] = '\0';
		_s->cStringLength = j;

		@try {
			_s->cString = [self resizeMemory: _s->cString
			_s->cString = of_realloc(_s->cString, j + 1, 1);
						    size: j + 1];
		} @catch (OFOutOfMemoryException *e) {
			/* We don't care, as we only tried to make it smaller */
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}
617
618
619
620
621
622
623
624

625

626
627
628
629
630
631
632
610
611
612
613
614
615
616

617
618
619
620
621
622
623
624
625
626







-
+

+







			characters++;
			length--;
		} else if (byteOrder != OF_BYTE_ORDER_NATIVE)
			swap = true;

		_s = &_storage;

		_s->cString = [self allocMemoryWithSize: (length * 4) + 1];
		_s->cString = of_malloc((length * 4) + 1, 1);
		_s->length = length;
		_s->freeWhenDone = true;

		j = 0;
		for (size_t i = 0; i < length; i++) {
			char buffer[4];
			size_t len = of_string_utf8_encode(
			    (swap ? OF_BSWAP32(characters[i]) : characters[i]),
			    buffer);
649
650
651
652
653
654
655
656

657
658
659
660
661
662
663
664
643
644
645
646
647
648
649

650

651
652
653
654
655
656
657







-
+
-







			}
		}

		_s->cString[j] = '\0';
		_s->cStringLength = j;

		@try {
			_s->cString = [self resizeMemory: _s->cString
			_s->cString = of_realloc(_s->cString, j + 1, 1);
						    size: j + 1];
		} @catch (OFOutOfMemoryException *e) {
			/* We don't care, as we only tried to make it smaller */
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}
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
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







-
+
-

+













-
-
+
+







			case 1:
				_s->isUTF8 = true;
				break;
			case -1:
				@throw [OFInvalidEncodingException exception];
			}

			_s->cString = [self
			_s->cString = of_malloc(cStringLength + 1, 1);
			    allocMemoryWithSize: cStringLength + 1];
			memcpy(_s->cString, tmp, cStringLength + 1);
			_s->freeWhenDone = true;
		} @finally {
			free(tmp);
		}
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	if (_s != NULL && _s->freeWhenDone != NULL)
		free(_s->freeWhenDone);
	if (_s != NULL && _s->freeWhenDone)
		free(_s->cString);

	[super dealloc];
}

- (size_t)getCString: (char *)cString
	   maxLength: (size_t)maxLength
	    encoding: (of_string_encoding_t)encoding
925
926
927
928
929
930
931
932

933
934
935
936
937
938
939
918
919
920
921
922
923
924

925
926
927
928
929
930
931
932







-
+







	else if (_s->cStringLength - i < otherCStringLength - j)
		return OF_ORDERED_ASCENDING;
#endif

	return OF_ORDERED_SAME;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	if (_s->hashed)
		return _s->hash;

	OF_HASH_INIT(hash);
1158
1159
1160
1161
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
1187
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
1217
1218
1219

1220
1221




1222
1223
1224
1225
1226
1227
1228
1151
1152
1153
1154
1155
1156
1157



1158
1159





1160
1161
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
1187





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
1217
1218
1219







-
-
-
+
+
-
-
-
-
-








-
+
+

-
-
+
+
+



-
+
+
+
+




-
-
-
+
+

-
-
-
-
-

-
+





-
+
+

-
+
+

-
+

-
+



-
+

-
+
+
+
+







	objc_autoreleasePoolPop(pool);

	return array;
}

- (const of_unichar_t *)characters
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	of_unichar_t *ret;
	size_t i, j;
	of_unichar_t *buffer = of_malloc(_s->length, sizeof(of_unichar_t));
	size_t i = 0, j = 0;

	ret = [object allocMemoryWithSize: sizeof(of_unichar_t)
				    count: _s->length];

	i = j = 0;

	while (i < _s->cStringLength) {
		of_unichar_t c;
		ssize_t cLen;

		cLen = of_string_utf8_decode(_s->cString + i,
		    _s->cStringLength - i, &c);

		if (cLen <= 0 || c > 0x10FFFF)
		if (cLen <= 0 || c > 0x10FFFF) {
			free(buffer);
			@throw [OFInvalidEncodingException exception];

		ret[j++] = c;
		}

		buffer[j++] = c;
		i += cLen;
	}

	return ret;
	return [[OFData dataWithItemsNoCopy: buffer
				      count: _s->length
				   itemSize: sizeof(of_unichar_t)
			       freeWhenDone: true] items];
}

- (const of_char32_t *)UTF32StringWithByteOrder: (of_byte_order_t)byteOrder
{
	OFObject *object = [[[OFObject alloc] init] autorelease];
	of_char32_t *ret;
	size_t i, j;
	of_char32_t *buffer = of_malloc(_s->length + 1, sizeof(of_char32_t));
	size_t i = 0, j = 0;

	ret = [object allocMemoryWithSize: sizeof(of_unichar_t)
				    count: _s->length + 1];

	i = j = 0;

	while (i < _s->cStringLength) {
		of_unichar_t c;
		of_char32_t c;
		ssize_t cLen;

		cLen = of_string_utf8_decode(_s->cString + i,
		    _s->cStringLength - i, &c);

		if (cLen <= 0 || c > 0x10FFFF)
		if (cLen <= 0 || c > 0x10FFFF) {
			free(buffer);
			@throw [OFInvalidEncodingException exception];

		}

		if (byteOrder != OF_BYTE_ORDER_NATIVE)
			ret[j++] = OF_BSWAP32(c);
			buffer[j++] = OF_BSWAP32(c);
		else
			ret[j++] = c;
			buffer[j++] = c;

		i += cLen;
	}
	ret[j] = 0;
	buffer[j] = 0;

	return ret;
	return [[OFData dataWithItemsNoCopy: buffer
				      count: _s->length + 1
				   itemSize: sizeof(of_char32_t)
			       freeWhenDone: true] items];
}

#ifdef OF_HAVE_BLOCKS
- (void)enumerateLinesUsingBlock: (of_string_line_enumeration_block_t)block
{
	void *pool;
	const char *cString = _s->cString;

Modified src/OFValue.m from [a224fd5a05] to [3be7f2e37d].

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







-
+
-
-
-
-
+
+
+

-
+
-

















-
+





-
-
-
-
+







	objCType = self.objCType;

	if (strcmp([object objCType], objCType) != 0)
		return false;

	size = of_sizeof_type_encoding(objCType);

	if ((value = malloc(size)) == NULL)
	value = of_malloc(1, size);
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: size];

	if ((otherValue = malloc(size)) == NULL) {
	@try {
		otherValue = of_malloc(1, size);
	} @catch (id e) {
		free(value);
		@throw [OFOutOfMemoryException
		@throw e;
		    exceptionWithRequestedSize: size];
	}

	@try {
		[self getValue: value
			  size: size];
		[object getValue: otherValue
			    size: size];

		ret = (memcmp(value, otherValue, size) == 0);
	} @finally {
		free(value);
		free(otherValue);
	}

	return ret;
}

- (uint32_t)hash
- (unsigned long)hash
{
	size_t size = of_sizeof_type_encoding(self.objCType);
	unsigned char *value;
	uint32_t hash;

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

	value = of_malloc(1, size);
	@try {
		[self getValue: value
			  size: size];

		OF_HASH_INIT(hash);

		for (size_t i = 0; i < size; i++)
314
315
316
317
318
319
320
321
322
323
324

325
326
327
328
329
330
331
309
310
311
312
313
314
315




316
317
318
319
320
321
322
323







-
-
-
-
+







- (OFString *)description
{
	OFMutableString *ret =
	    [OFMutableString stringWithString: @"<OFValue: "];
	size_t size = of_sizeof_type_encoding(self.objCType);
	unsigned char *value;

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

	value = of_malloc(1, size);
	@try {
		[self getValue: value
			  size: size];

		for (size_t i = 0; i < size; i++) {
			if (i > 0)
				[ret appendString: @" "];

Modified src/OFWin32ConsoleStdIOStream.m from [959c780c29] to [7dd85d6178].

133
134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
133
134
135
136
137
138
139

140

141
142
143
144
145
146
147







-
+
-







	char *buffer = buffer_;
	of_char16_t *UTF16;
	size_t j = 0;

	if (length > UINT32_MAX)
		@throw [OFOutOfRangeException exception];

	UTF16 = [self allocMemoryWithSize: sizeof(of_char16_t)
	UTF16 = of_malloc(length, sizeof(of_char16_t));
				    count: length];
	@try {
		DWORD UTF16Len;
		OFMutableData *rest = nil;
		size_t i = 0;

		if ([OFSystemInfo isWindowsNT]) {
			if (!ReadConsoleW(_handle, UTF16, (DWORD)length,
256
257
258
259
260
261
262
263

264
265
266
267
268
269
270
255
256
257
258
259
260
261

262
263
264
265
266
267
268
269







-
+







			}
		}

		if (rest != nil)
			[self unreadFromBuffer: rest.items
					length: rest.count];
	} @finally {
		[self freeMemory: UTF16];
		free(UTF16);
	}

	objc_autoreleasePoolPop(pool);

	return j;
}

361
362
363
364
365
366
367
368

369
370
371
372
373
374
375
376
360
361
362
363
364
365
366

367

368
369
370
371
372
373
374







-
+
-







				   bytesWritten: bytesWritten * 2
					  errNo: 0];

		_incompleteUTF8SurrogateLen = 0;
		i += toCopy;
	}

	tmp = [self allocMemoryWithSize: sizeof(of_char16_t)
	tmp = of_malloc(length * 2, sizeof(of_char16_t));
				  count: length * 2];
	@try {
		DWORD bytesWritten;

		while (i < length) {
			of_unichar_t c;
			ssize_t UTF8Len;

441
442
443
444
445
446
447
448

449
450
451
452
453
454
455
439
440
441
442
443
444
445

446
447
448
449
450
451
452
453







-
+







		if (bytesWritten != j)
			@throw [OFWriteFailedException
			    exceptionWithObject: self
				requestedLength: j * 2
				   bytesWritten: bytesWritten * 2
					  errNo: 0];
	} @finally {
		[self freeMemory: tmp];
		free(tmp);
	}

	/*
	 * We do not count in bytes when writing to the Win32 console. But
	 * since any incomplete write is an exception here anyway, we can just
	 * return length.
	 */

Modified src/OFXMLAttribute.m from [e9a34efaab] to [182fa6d94f].

136
137
138
139
140
141
142
143

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

143
144
145
146
147
148
149
150







-
+







		return false;
	if (![attribute->_stringValue isEqual: _stringValue])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, _name.hash);
	OF_HASH_ADD_HASH(hash, _namespace.hash);

Modified src/OFXMLCDATA.m from [f85cf9a41b] to [bc1aa40b4f].

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







-
+







		return false;

	CDATA = object;

	return ([CDATA->_CDATA isEqual: _CDATA]);
}

- (uint32_t)hash
- (unsigned long)hash
{
	return _CDATA.hash;
}

- (OFString *)stringValue
{
	return [[_CDATA copy] autorelease];

Modified src/OFXMLCharacters.m from [d05a22ddc3] to [a2bb78c19c].

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







-
+







		return false;

	characters = object;

	return ([characters->_characters isEqual: _characters]);
}

- (uint32_t)hash
- (unsigned long)hash
{
	return _characters.hash;
}

- (OFString *)stringValue
{
	return [[_characters copy] autorelease];

Modified src/OFXMLComment.m from [69c4d2c798] to [2577a47d50].

86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
86
87
88
89
90
91
92

93
94
95
96
97
98
99
100







-
+







		return false;

	comment = object;

	return ([comment->_comment isEqual: _comment]);
}

- (uint32_t)hash
- (unsigned long)hash
{
	return _comment.hash;
}

- (OFString *)stringValue
{
	return @"";
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
112
113
114
115
116
117
118


119
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135







-
-
+








-
+








- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
				 level: (unsigned int)level
{
	OFString *ret;

	if (indentation > 0 && level > 0) {
		char *whitespaces = [self allocMemoryWithSize:
		    (level * indentation) + 1];
		char *whitespaces = of_malloc((level * indentation) + 1, 1);
		memset(whitespaces, ' ', level * indentation);
		whitespaces[level * indentation] = 0;

		@try {
			ret = [OFString stringWithFormat: @"%s<!--%@-->",
							  whitespaces,
							  _comment];
		} @finally {
			[self freeMemory: whitespaces];
			free(whitespaces);
		}
	} else
		ret = [OFString stringWithFormat: @"<!--%@-->", _comment];

	return ret;
}

Modified src/OFXMLElement.m from [a8d9602939] to [d12879cd95].

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







-
-
-







/* References for static linking */
void
_references_to_categories_of_OFXMLElement(void)
{
	_OFXMLElement_Serialization_reference = 1;
}

static Class charactersClass = Nil;
static Class CDATAClass = Nil;

@interface OFXMLElementElementBuilderDelegate: OFObject
    <OFXMLElementBuilderDelegate>
{
@public
	OFXMLElement *_element;
}
@end
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
72
73
74
75
76
77
78








79
80
81
82
83
84
85







-
-
-
-
-
-
-
-







}
@end

@implementation OFXMLElement
@synthesize name = _name, namespace = _namespace;
@synthesize defaultNamespace = _defaultNamespace;

+ (void)initialize
{
	if (self == [OFXMLElement class]) {
		charactersClass = [OFXMLCharacters class];
		CDATAClass = [OFXMLCDATA class];
	}
}

+ (instancetype)elementWithName: (OFString *)name
{
	return [[[self alloc] initWithName: name] autorelease];
}

+ (instancetype)elementWithName: (OFString *)name
		    stringValue: (OFString *)stringValue
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
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







-
+












-
+




-
+





-
+






-
+

-
+

-
+











-
+

+
-
-
+
+

-
-
+
+

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






+


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

-
-
+
+

-
+

-



-
+








	[ret makeImmutable];

	return ret;
}

- (OFString *)of_XMLStringWithParent: (OFXMLElement *)parent
			  namespaces: (OFDictionary *)allNamespaces
			  namespaces: (OFDictionary *)allNS
			 indentation: (unsigned int)indentation
			       level: (unsigned int)level OF_DIRECT
{
	void *pool;
	char *cString;
	size_t length, i;
	OFString *prefix, *parentPrefix;
	OFString *ret;
	OFString *defaultNS;

	pool = objc_autoreleasePoolPush();

	parentPrefix = [allNamespaces objectForKey:
	parentPrefix = [allNS objectForKey:
	    (parent != nil && parent->_namespace != nil
	    ? parent->_namespace : (OFString *)@"")];

	/* Add the namespaces of the current element */
	if (allNamespaces != nil) {
	if (allNS != nil) {
		OFEnumerator *keyEnumerator = [_namespaces keyEnumerator];
		OFEnumerator *objectEnumerator = [_namespaces objectEnumerator];
		OFMutableDictionary *tmp;
		OFString *key, *object;

		tmp = [[allNamespaces mutableCopy] autorelease];
		tmp = [[allNS mutableCopy] autorelease];

		while ((key = [keyEnumerator nextObject]) != nil &&
		    (object = [objectEnumerator nextObject]) != nil)
			[tmp setObject: object
				forKey: key];

		allNamespaces = tmp;
		allNS = tmp;
	} else
		allNamespaces = _namespaces;
		allNS = _namespaces;

	prefix = [allNamespaces objectForKey:
	prefix = [allNS objectForKey:
	    (_namespace != nil ? _namespace : (OFString *)@"")];

	if (parent != nil && parent->_namespace != nil && parentPrefix == nil)
		defaultNS = parent->_namespace;
	else if (parent != nil && parent->_defaultNamespace != nil)
		defaultNS = parent->_defaultNamespace;
	else
		defaultNS = _defaultNamespace;

	i = 0;
	length = _name.UTF8StringLength + 3 + (level * indentation);
	cString = [self allocMemoryWithSize: length];
	cString = of_malloc(length, 1);

	@try {
	memset(cString + i, ' ', level * indentation);
	i += level * indentation;
		memset(cString + i, ' ', level * indentation);
		i += level * indentation;

	/* Start of tag */
	cString[i++] = '<';
		/* Start of tag */
		cString[i++] = '<';

	if (prefix != nil && ![_namespace isEqual: defaultNS]) {
		length += prefix.UTF8StringLength + 1;
		if (prefix != nil && ![_namespace isEqual: defaultNS]) {
			length += prefix.UTF8StringLength + 1;
		@try {
			cString = [self resizeMemory: cString
						size: length];
		} @catch (id e) {
			[self freeMemory: cString];
			@throw e;
		}

			cString = of_realloc(cString, length, 1);
		memcpy(cString + i, prefix.UTF8String, prefix.UTF8StringLength);
		i += prefix.UTF8StringLength;
		cString[i++] = ':';
	}

	memcpy(cString + i, _name.UTF8String, _name.UTF8StringLength);
	i += _name.UTF8StringLength;

	/* xmlns if necessary */
	if (prefix == nil && ((_namespace != nil &&
	    ![_namespace isEqual: defaultNS]) ||
	    (_namespace == nil && defaultNS != nil))) {
		length += _namespace.UTF8StringLength + 9;
		@try {
			cString = [self resizeMemory: cString
						size: length];
		} @catch (id e) {
			[self freeMemory: cString];
			@throw e;
		}

		memcpy(cString + i, " xmlns='", 8);
		i += 8;
		memcpy(cString + i, _namespace.UTF8String,
		    _namespace.UTF8StringLength);
		i += _namespace.UTF8StringLength;
		cString[i++] = '\'';
	}

	/* Attributes */
	for (OFXMLAttribute *attribute in _attributes) {
		void *pool2 = objc_autoreleasePoolPush();
		const char *attributeNameCString = attribute->_name.UTF8String;
		size_t attributeNameLength = attribute->_name.UTF8StringLength;
		OFString *attributePrefix = nil;
		OFString *tmp = attribute.stringValue.stringByXMLEscaping;
		char delimiter = (attribute->_useDoubleQuotes ? '"' : '\'');

		if (attribute->_namespace != nil &&
		    (attributePrefix = [allNamespaces objectForKey:
		    attribute->_namespace]) == nil)
			@throw [OFUnboundNamespaceException
			    exceptionWithNamespace: [attribute namespace]
					   element: self];

		length += attributeNameLength + (attributePrefix != nil
		    ? attributePrefix.UTF8StringLength + 1 : 0) +
		    tmp.UTF8StringLength + 4;

		@try {
			cString = [self resizeMemory: cString
						size: length];
		} @catch (id e) {
			[self freeMemory: cString];
			@throw e;
		}

		cString[i++] = ' ';
		if (attributePrefix != nil) {
			memcpy(cString + i, attributePrefix.UTF8String,
			    attributePrefix.UTF8StringLength);
			i += attributePrefix.UTF8StringLength;
			cString[i++] = ':';
		}
		memcpy(cString + i, attributeNameCString, attributeNameLength);
		i += attributeNameLength;
		cString[i++] = '=';
		cString[i++] = delimiter;
		memcpy(cString + i, tmp.UTF8String, tmp.UTF8StringLength);
		i += tmp.UTF8StringLength;
		cString[i++] = delimiter;

		objc_autoreleasePoolPop(pool2);
	}

	/* Children */
	if (_children != nil) {
		OFMutableData *tmp = [OFMutableData data];
		bool indent;

		if (indentation > 0) {
			indent = true;

			for (OFXMLNode *child in _children) {
				if ([child isKindOfClass: charactersClass] ||
				    [child isKindOfClass: CDATAClass]) {
					indent = false;
					break;
				}
			}
		} else
			indent = false;

		for (OFXMLNode *child in _children) {
			OFString *childString;
			unsigned int ind = (indent ? indentation : 0);

			if (ind)
				[tmp addItem: "\n"];

			if ([child isKindOfClass: [OFXMLElement class]])
				childString = [(OFXMLElement *)child
				    of_XMLStringWithParent: self
						namespaces: allNamespaces
					       indentation: ind
						     level: level + 1];
			else
				childString = [child
				    XMLStringWithIndentation: ind
						       level: level + 1];

			[tmp addItems: childString.UTF8String
				count: childString.UTF8StringLength];
		}

		if (indent)
			[tmp addItem: "\n"];

		length += tmp.count + _name.UTF8StringLength + 2 +
		    (indent ? level * indentation : 0);
		@try {
			cString = [self resizeMemory: cString
						size: length];
		} @catch (id e) {
			[self freeMemory: cString];
			@throw e;
		}

		cString[i++] = '>';

		memcpy(cString + i, tmp.items, tmp.count);
		i += tmp.count;

		if (indent) {
			memset(cString + i, ' ', level * indentation);
			i += level * indentation;
		}

		cString[i++] = '<';
		cString[i++] = '/';
		if (prefix != nil) {
			length += prefix.UTF8StringLength + 1;
			@try {
				cString = [self resizeMemory: cString
							size: length];
			} @catch (id e) {
				[self freeMemory: cString];
				@throw e;
			}

			memcpy(cString + i, prefix.UTF8String,
			    prefix.UTF8StringLength);
			i += prefix.UTF8StringLength;
			cString[i++] = ':';
		}

		memcpy(cString + i, _name.UTF8String, _name.UTF8StringLength);
		i += _name.UTF8StringLength;

		/* xmlns if necessary */
		if (prefix == nil && ((_namespace != nil &&
		    ![_namespace isEqual: defaultNS]) ||
		    (_namespace == nil && defaultNS != nil))) {
			length += _namespace.UTF8StringLength + 9;
			cString = of_realloc(cString, length, 1);

			memcpy(cString + i, " xmlns='", 8);
			i += 8;
			memcpy(cString + i, _namespace.UTF8String,
			    _namespace.UTF8StringLength);
			i += _namespace.UTF8StringLength;
			cString[i++] = '\'';
		}

		/* Attributes */
		for (OFXMLAttribute *attribute in _attributes) {
			void *pool2 = objc_autoreleasePoolPush();
			const char *attributeNameCString =
			    attribute->_name.UTF8String;
			size_t attributeNameLength =
			    attribute->_name.UTF8StringLength;
			OFString *attributePrefix = nil;
			OFString *tmp =
			    attribute.stringValue.stringByXMLEscaping;
			char delimiter = (attribute->_useDoubleQuotes
			    ? '"' : '\'');

			if (attribute->_namespace != nil &&
			    (attributePrefix = [allNS objectForKey:
			    attribute->_namespace]) == nil)
				@throw [OFUnboundNamespaceException
				    exceptionWithNamespace: attribute.namespace
						   element: self];

			length += attributeNameLength + (attributePrefix != nil
			    ? attributePrefix.UTF8StringLength + 1 : 0) +
			    tmp.UTF8StringLength + 4;
			cString = of_realloc(cString, length, 1);

			cString[i++] = ' ';
			if (attributePrefix != nil) {
				memcpy(cString + i, attributePrefix.UTF8String,
				    attributePrefix.UTF8StringLength);
				i += attributePrefix.UTF8StringLength;
				cString[i++] = ':';
			}
			memcpy(cString + i, attributeNameCString,
			    attributeNameLength);
			i += attributeNameLength;
			cString[i++] = '=';
			cString[i++] = delimiter;
			memcpy(cString + i, tmp.UTF8String,
			    tmp.UTF8StringLength);
			i += tmp.UTF8StringLength;
			cString[i++] = delimiter;

			objc_autoreleasePoolPop(pool2);
		}

		/* Children */
		if (_children != nil) {
			OFMutableData *tmp = [OFMutableData data];
			bool indent;

			if (indentation > 0) {
				indent = true;

				for (OFXMLNode *child in _children) {
					if ([child isKindOfClass:
					    [OFXMLCharacters class]] ||
					    [child isKindOfClass:
					    [OFXMLCDATA class]]) {
						indent = false;
						break;
					}
				}
			} else
				indent = false;

			for (OFXMLNode *child in _children) {
				OFString *childString;
				unsigned int ind = (indent ? indentation : 0);

				if (ind)
					[tmp addItem: "\n"];

				if ([child isKindOfClass: [OFXMLElement class]])
					childString = [(OFXMLElement *)child
					    of_XMLStringWithParent: self
							namespaces: allNS
						       indentation: ind
							     level: level + 1];
				else
					childString = [child
					    XMLStringWithIndentation: ind
							       level: level +
								      1];

				[tmp addItems: childString.UTF8String
					count: childString.UTF8StringLength];
			}

			if (indent)
				[tmp addItem: "\n"];

			length += tmp.count + _name.UTF8StringLength + 2 +
			    (indent ? level * indentation : 0);
			cString = of_realloc(cString, length, 1);

			cString[i++] = '>';

			memcpy(cString + i, tmp.items, tmp.count);
			i += tmp.count;

			if (indent) {
				memset(cString + i, ' ', level * indentation);
				i += level * indentation;
			}

			cString[i++] = '<';
			cString[i++] = '/';
			if (prefix != nil) {
				length += prefix.UTF8StringLength + 1;
				cString = of_realloc(cString, length, 1);

				memcpy(cString + i, prefix.UTF8String,
				    prefix.UTF8StringLength);
				i += prefix.UTF8StringLength;
				cString[i++] = ':';
			}
			memcpy(cString + i, _name.UTF8String,
			    _name.UTF8StringLength);
			i += _name.UTF8StringLength;
	} else
		cString[i++] = '/';
		} else
			cString[i++] = '/';

	cString[i++] = '>';
	assert(i == length);
		cString[i++] = '>';
		assert(i == length);

	objc_autoreleasePoolPop(pool);
		objc_autoreleasePoolPop(pool);

	@try {
		ret = [OFString stringWithUTF8String: cString
					      length: length];
	} @finally {
		[self freeMemory: cString];
		free(cString);
	}
	return ret;
}

- (OFString *)XMLString
{
	return [self of_XMLStringWithParent: nil
1062
1063
1064
1065
1066
1067
1068
1069

1070
1071
1072
1073
1074
1075
1076
1031
1032
1033
1034
1035
1036
1037

1038
1039
1040
1041
1042
1043
1044
1045







-
+







	if (element->_children != _children &&
	    ![element->_children isEqual: _children])
		return false;

	return true;
}

- (uint32_t)hash
- (unsigned long)hash
{
	uint32_t hash;

	OF_HASH_INIT(hash);

	OF_HASH_ADD_HASH(hash, _name.hash);
	OF_HASH_ADD_HASH(hash, _namespace.hash);

Modified src/OFXMLParser.m from [51abbe68ac] to [8b036ac867].

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







-
+










-
+







	[self parseBuffer: string.UTF8String
		   length: string.UTF8StringLength];
}

- (void)parseStream: (OFStream *)stream
{
	size_t pageSize = [OFSystemInfo pageSize];
	char *buffer = [self allocMemoryWithSize: pageSize];
	char *buffer = of_malloc(1, pageSize);

	@try {
		while (!stream.atEndOfStream) {
			size_t length = [stream readIntoBuffer: buffer
							length: pageSize];

			[self parseBuffer: buffer
				   length: length];
		}
	} @finally {
		[self freeMemory: buffer];
		free(buffer);
	}
}

#ifdef OF_HAVE_FILES
- (void)parseFile: (OFString *)path
{
	OFFile *file = [[OFFile alloc] initWithPath: path
412
413
414
415
416
417
418
419

420
421
422
423
424
425
426
412
413
414
415
416
417
418

419
420
421
422
423
424
425
426







-
+







	bool hasVersion = false;

	if (!self->_acceptProlog)
		return false;

	self->_acceptProlog = false;

	pi = [pi substringWithRange: of_range(3, pi.length - 3)];
	pi = [pi substringFromIndex: 3];
	pi = pi.stringByDeletingEnclosingWhitespaces;

	cString = pi.UTF8String;
	length = pi.UTF8StringLength;

	last = 0;
	for (size_t i = 0; i < length; i++) {

Modified src/OFXMLProcessingInstructions.m from [c927bb8870] to [5705c589f5].

87
88
89
90
91
92
93
94

95
96
97
98
99
100
101
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101







-
+








	processingInstructions = object;

	return [processingInstructions->_processingInstructions
	    isEqual: _processingInstructions];
}

- (uint32_t)hash
- (unsigned long)hash
{
	return _processingInstructions.hash;
}

- (OFString *)stringValue
{
	return @"";
113
114
115
116
117
118
119
120
121

122
123
124
125
126
127
128
129

130
131
132
133
134
135
136
113
114
115
116
117
118
119


120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
135







-
-
+







-
+








- (OFString *)XMLStringWithIndentation: (unsigned int)indentation
				 level: (unsigned int)level
{
	OFString *ret;

	if (indentation > 0 && level > 0) {
		char *whitespaces = [self allocMemoryWithSize:
		    (level * indentation) + 1];
		char *whitespaces = of_malloc((level * indentation) + 1, 1);
		memset(whitespaces, ' ', level * indentation);
		whitespaces[level * indentation] = 0;

		@try {
			ret = [OFString stringWithFormat:
			    @"%s<?%@?>", whitespaces, _processingInstructions];
		} @finally {
			[self freeMemory: whitespaces];
			free(whitespaces);
		}
	} else
		ret = [OFString stringWithFormat: @"<?%@?>",
						  _processingInstructions];

	return ret;
}

Modified src/condition.h from [1ae822cd57] to [ed39b78cbd].

39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53







-
+







	volatile int count;
} of_condition_t;
#elif defined(OF_AMIGAOS)
# include <exec/tasks.h>
typedef struct {
	struct of_condition_waiting_task {
		struct Task *task;
		uint8_t sigBit;
		unsigned char sigBit;
		struct of_condition_waiting_task *next;
	} *waitingTasks;
} of_condition_t;
#endif

#ifdef __cplusplus
extern "C" {

Modified src/exceptions/OFAllocFailedException.m from [54ff75e246] to [0eedb0ddc1].

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
32
33
34
35
36
37
38





























39
40
41
42
43
44
45







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







}

- (instancetype)init
{
	OF_INVALID_INIT_METHOD
}

- (void *)allocMemoryWithSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)allocMemoryForNItems: (size_t)nitems
		      withSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)resizeMemory: (void *)ptr
		toSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void *)resizeMemory: (void *)ptr
	      toNItems: (size_t)nitems
	      withSize: (size_t)size
{
	OF_UNRECOGNIZED_SELECTOR
}

- (void)freeMemory: (void *)ptr
{
	OF_UNRECOGNIZED_SELECTOR
}

- (instancetype)retain
{
	return self;
}

- (instancetype)autorelease
{

Modified src/exceptions/OFHTTPRequestFailedException.m from [802233b235] to [ef8de3042e].

62
63
64
65
66
67
68
69

70
71
72
62
63
64
65
66
67
68

69
70
71
72







-
+



}

- (OFString *)description
{
	const char *method = of_http_request_method_to_string(_request.method);

	return [OFString stringWithFormat:
	    @"An HTTP %s request with URL %@ failed with code %d!", method,
	    @"An HTTP %s request with URL %@ failed with code %hd!", method,
	    _request.URL, _response.statusCode];
}
@end

Modified src/huffman_tree.m from [784bf1ffb2] to [f65a681bbc].

26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
41
42
43
26
27
28
29
30
31
32

33



34
35
36
37
38
39
40







-
+
-
-
-







#import "OFOutOfMemoryException.h"

static struct of_huffman_tree *
newTree(void)
{
	struct of_huffman_tree *tree;

	if ((tree = malloc(sizeof(*tree))) == NULL)
	tree = of_malloc(1, sizeof(*tree));
		@throw [OFOutOfMemoryException
		    exceptionWithRequestedSize: sizeof(*tree)];

	tree->leaves[0] = tree->leaves[1] = NULL;
	tree->value = 0xFFFF;

	return tree;
}

static void
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
65
66
67
68
69
70
71










72
73
74



75

76
77
78
79
80
81
82







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







	uint_fast8_t maxBit = 0;

	@try {
		for (uint16_t i = 0; i < count; i++) {
			uint_fast8_t length = lengths[i];

			if OF_UNLIKELY (length > maxBit) {
				size_t size = (length + 1) * sizeof(uint16_t);
				uint16_t *new;

				if ((new = realloc(lengthCount, size)) == NULL)
					@throw [OFOutOfMemoryException
					    exceptionWithRequestedSize: size];

				lengthCount = new;

				if ((new = realloc(nextCode, size)) == NULL)
				lengthCount = of_realloc(lengthCount,
				    length + 1, sizeof(uint16_t));
				nextCode = of_realloc(nextCode,
					@throw [OFOutOfMemoryException
					    exceptionWithRequestedSize: size];

				    length + 1, sizeof(uint16_t));
				nextCode = new;

				for (uint_fast8_t j = maxBit + 1; j <= length;
				    j++) {
					lengthCount[j] = 0;
					nextCode[j] = 0;
				}

Modified src/macros.h from [76df5e8f5b] to [43e7dc4d8f].

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







-
+







	{				\
		hash += (hash << 3);	\
		hash ^= (hash >> 11);	\
		hash += (hash << 15);	\
	}
#define OF_HASH_ADD_HASH(hash, other)				\
	{							\
		uint32_t otherCopy = other;			\
		uint32_t otherCopy = (uint32_t)other;		\
		OF_HASH_ADD(hash, (otherCopy >> 24) & 0xFF);	\
		OF_HASH_ADD(hash, (otherCopy >> 16) & 0xFF);	\
		OF_HASH_ADD(hash, (otherCopy >>  8) & 0xFF);	\
		OF_HASH_ADD(hash, otherCopy & 0xFF);		\
	}

static OF_INLINE bool

Modified src/of_strptime.h from [be5859fecb] to [e5c0a8d157].

28
29
30
31
32
33
34
35

36
37
38
39
40
28
29
30
31
32
33
34

35
36
37
38
39
40







-
+






OF_ASSUME_NONNULL_BEGIN

#ifdef __cplusplus
extern "C" {
#endif
extern const char *_Nullable of_strptime(const char *buf, const char *fmt,
    struct tm *tm, int16_t *_Nullable tz);
    struct tm *tm, short *_Nullable tz);
#ifdef __cplusplus
}
#endif

OF_ASSUME_NONNULL_END

Modified src/of_strptime.m from [0542c09e57] to [ef61304e79].

20
21
22
23
24
25
26
27

28
29
30
31
32
33
34
20
21
22
23
24
25
26

27
28
29
30
31
32
33
34







-
+







#include <string.h>

#include <time.h>

#import "macros.h"

const char *
of_strptime(const char *buffer, const char *format, struct tm *tm, int16_t *tz)
of_strptime(const char *buffer, const char *format, struct tm *tm, short *tz)
{
	enum {
		SEARCH_CONVERSION_SPECIFIER,
		IN_CONVERSION_SPECIFIER
	} state = SEARCH_CONVERSION_SPECIFIER;
	size_t j, bufferLen, formatLen;

177
178
179
180
181
182
183
184
185
186
187




188
189
190
191
192
193
194
177
178
179
180
181
182
183




184
185
186
187
188
189
190
191
192
193
194







-
-
-
-
+
+
+
+








					if (bufferLen < j + 5)
						return NULL;

					if (tz == NULL)
						break;

					*tz = (((int16_t)b[1] - '0') * 600 +
					    ((int16_t)b[2] - '0') * 60 +
					    ((int16_t)b[3] - '0') * 10 +
					    ((int16_t)b[4] - '0')) *
					*tz = (((short)b[1] - '0') * 600 +
					    ((short)b[2] - '0') * 60 +
					    ((short)b[3] - '0') * 10 +
					    ((short)b[4] - '0')) *
					    (b[0] == '-' ? -1 : 1);

					j += 5;
				} else if (buffer[j] == 'Z') {
					if (tz != NULL)
						*tz = 0;

Modified src/pbkdf2.h from [b190fa060c] to [906ee7a0eb].

31
32
33
34
35
36
37
38

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

38
39
40
41
42
43
44
45







-
+







@class OFHMAC;

/**
 * @brief The parameters for @ref of_pbkdf2.
 */
typedef struct of_pbkdf2_parameters_t {
	/** @brief The HMAC to use to derive a key. */
	OFHMAC *HMAC;
	__unsafe_unretained OFHMAC *HMAC;
	/** @brief The number of iterations to perform. */
	size_t iterations;
	/** @brief The salt to derive a key with. */
	const unsigned char *salt;
	/** @brief The length of the salt. */
	size_t saltLength;
	/** @brief The password to derive a key from. */

Modified src/platform/amiga/OFString+PathAdditions.m from [1ed97b2697] to [6f79ae7bc0].

123
124
125
126
127
128
129
130

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

130

131
132
133
134
135
136
137







-
+
-







	pos = [fileName rangeOfString: @"."
			      options: OF_STRING_SEARCH_BACKWARDS].location;
	if (pos == OF_NOT_FOUND || pos == 0) {
		objc_autoreleasePoolPop(pool);
		return @"";
	}

	ret = [fileName substringWithRange:
	ret = [fileName substringFromIndex: pos + 1];
	    of_range(pos + 1, fileName.length - pos - 1)];

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

- (OFString *)stringByDeletingLastPathComponent
183
184
185
186
187
188
189
190

191
192
193
194
195
196
197
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196







-
+







	pos = [fileName rangeOfString: @"."
			      options: OF_STRING_SEARCH_BACKWARDS].location;
	if (pos == OF_NOT_FOUND || pos == 0) {
		objc_autoreleasePoolPop(pool);
		return [[self copy] autorelease];
	}

	fileName = [fileName substringWithRange: of_range(0, pos)];
	fileName = [fileName substringToIndex: pos];
	[components replaceObjectAtIndex: components.count - 1
			      withObject: fileName];

	ret = [OFString pathWithComponents: components];

	[ret retain];
	objc_autoreleasePoolPop(pool);
301
302
303
304
305
306
307
308

309
310
311
312
313

314
315
316
317
318
319
320
300
301
302
303
304
305
306

307
308
309
310
311

312
313
314
315
316
317
318
319







-
+




-
+







}

- (OFString *)of_URLPathToPathWithURLEncodedHost: (OFString *)URLEncodedHost
{
	OFString *path = self;

	if (path.length > 1 && [path hasSuffix: @"/"])
		path = [path substringWithRange: of_range(0, path.length - 1)];
		path = [path substringToIndex: path.length - 1];

	OFMutableArray OF_GENERIC(OFString *) *components;
	size_t count;

	path = [path substringWithRange: of_range(1, path.length - 1)];
	path = [path substringFromIndex: 1];
	components = [[[path
	    componentsSeparatedByString: @"/"] mutableCopy] autorelease];
	count = components.count;

	for (size_t i = 0; i < count; i++) {
		OFString *component = [components objectAtIndex: i];

Modified src/platform/libfat/OFString+PathAdditions.m from [b5e9ff2888] to [67bd48bd8c].

157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
157
158
159
160
161
162
163

164

165
166
167
168
169
170
171







-
+
-







	pos = [fileName rangeOfString: @"."
			      options: OF_STRING_SEARCH_BACKWARDS].location;
	if (pos == OF_NOT_FOUND || pos == 0) {
		objc_autoreleasePoolPop(pool);
		return @"";
	}

	ret = [fileName substringWithRange:
	ret = [fileName substringFromIndex: pos + 1];
	    of_range(pos + 1, fileName.length - pos - 1)];

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

- (OFString *)stringByDeletingLastPathComponent
228
229
230
231
232
233
234
235

236
237
238
239
240
241
242
227
228
229
230
231
232
233

234
235
236
237
238
239
240
241







-
+







	pos = [fileName rangeOfString: @"."
			      options: OF_STRING_SEARCH_BACKWARDS].location;
	if (pos == OF_NOT_FOUND || pos == 0) {
		objc_autoreleasePoolPop(pool);
		return [[self copy] autorelease];
	}

	fileName = [fileName substringWithRange: of_range(0, pos)];
	fileName = [fileName substringToIndex: pos];
	[components replaceObjectAtIndex: components.count - 1
			      withObject: fileName];

	ret = [OFString pathWithComponents: components];

	[ret retain];
	objc_autoreleasePoolPop(pool);
330
331
332
333
334
335
336
337

338
339

340
341
342
343
344
345
346
329
330
331
332
333
334
335

336
337

338
339
340
341
342
343
344
345







-
+

-
+







}

- (OFString *)of_URLPathToPathWithURLEncodedHost: (OFString *)URLEncodedHost
{
	OFString *path = self;

	if (path.length > 1 && [path hasSuffix: @"/"])
		path = [path substringWithRange: of_range(0, path.length - 1)];
		path = [path substringToIndex: path.length - 1];

	return [path substringWithRange: of_range(1, path.length - 1)];
	return [path substringFromIndex: 1];
}

- (OFString *)of_pathComponentToURLPathComponent
{
	return self;
}
@end

Modified src/platform/posix/OFProcess.m from [a1d2451059] to [39ae31952e].

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







-
+














-
-
+







		    environment: (OFDictionary *)environment
{
	self = [super init];

	@try {
		void *pool = objc_autoreleasePoolPush();
		const char *path;
		char **argv;
		char **argv, **env = NULL;

		_pid = -1;
		_readPipe[0] = _writePipe[1] = -1;

		if (pipe(_readPipe) != 0 || pipe(_writePipe) != 0)
			@throw [OFInitializationFailedException
			    exceptionWithClass: self.class];

		path = [program cStringWithEncoding: [OFLocale encoding]];
		[self of_getArgv: &argv
		  forProgramName: programName
		    andArguments: arguments];

		@try {
			char **env = [self
			    of_environmentForDictionary: environment];
			env = [self of_environmentForDictionary: environment];
#ifdef HAVE_POSIX_SPAWNP
			posix_spawn_file_actions_t actions;
			posix_spawnattr_t attr;

			if (posix_spawn_file_actions_init(&actions) != 0)
				@throw [OFInitializationFailedException
				    exceptionWithClass: self.class];
202
203
204
205
206
207
208


209
210

211





212
213
214
215
216
217
218
201
202
203
204
205
206
207
208
209
210
211
212

213
214
215
216
217
218
219
220
221
222
223
224







+
+


+
-
+
+
+
+
+







			}

			if (_pid == -1)
				@throw [OFInitializationFailedException
				    exceptionWithClass: self.class];
#endif
		} @finally {
			char **iter;

			close(_readPipe[1]);
			close(_writePipe[0]);
			free(argv);
			[self freeMemory: argv];

			for (iter = env; *iter != NULL; iter++)
				free(*iter);

			free(env);
		}

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}
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
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







-
+
-














-

-
+








-
+
-

+
-
-
+
+

-
-
-
-
+
+
+
+

-
-
+
+

-
-
+
+
+

-
+

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

+
-
+
+
+







    forProgramName: (OFString *)programName
      andArguments: (OFArray *)arguments
{
	OFString *const *objects = arguments.objects;
	size_t i, count = arguments.count;
	of_string_encoding_t encoding;

	*argv = [self allocMemoryWithSize: sizeof(char *)
	*argv = of_malloc(count + 2, sizeof(char *));
				    count: count + 2];

	encoding = [OFLocale encoding];

	(*argv)[0] = (char *)[programName cStringWithEncoding: encoding];

	for (i = 0; i < count; i++)
		(*argv)[i + 1] =
		    (char *)[objects[i] cStringWithEncoding: encoding];

	(*argv)[i + 1] = NULL;
}

- (char **)of_environmentForDictionary: (OFDictionary *)environment
{
	OFEnumerator *keyEnumerator, *objectEnumerator;
	char **envp;
	size_t i, count;
	size_t count;
	of_string_encoding_t encoding;

	if (environment == nil)
		return NULL;

	encoding = [OFLocale encoding];

	count = environment.count;
	envp = [self allocMemoryWithSize: sizeof(char *)
	envp = of_calloc(count + 1, sizeof(char *));
				   count: count + 1];

	@try {
	keyEnumerator = [environment keyEnumerator];
	objectEnumerator = [environment objectEnumerator];
		OFEnumerator *keyEnumerator = [environment keyEnumerator];
		OFEnumerator *objectEnumerator = [environment objectEnumerator];

	for (i = 0; i < count; i++) {
		OFString *key;
		OFString *object;
		size_t keyLen, objectLen;
		for (size_t i = 0; i < count; i++) {
			OFString *key;
			OFString *object;
			size_t keyLen, objectLen;

		key = [keyEnumerator nextObject];
		object = [objectEnumerator nextObject];
			key = [keyEnumerator nextObject];
			object = [objectEnumerator nextObject];

		keyLen = [key cStringLengthWithEncoding: encoding];
		objectLen = [object cStringLengthWithEncoding: encoding];
			keyLen = [key cStringLengthWithEncoding: encoding];
			objectLen = [object
			    cStringLengthWithEncoding: encoding];

		envp[i] = [self allocMemoryWithSize: keyLen + objectLen + 2];
			envp[i] = of_malloc(keyLen + objectLen + 2, 1);

			memcpy(envp[i],
		memcpy(envp[i], [key cStringWithEncoding: encoding], keyLen);
		envp[i][keyLen] = '=';
		memcpy(envp[i] + keyLen + 1,
		    [object cStringWithEncoding: encoding], objectLen);
		envp[i][keyLen + objectLen + 1] = '\0';
	}
			    [key cStringWithEncoding: encoding], keyLen);
			envp[i][keyLen] = '=';
			memcpy(envp[i] + keyLen + 1,
			    [object cStringWithEncoding: encoding], objectLen);
			envp[i][keyLen + objectLen + 1] = '\0';
		}
	} @catch (id e) {
		for (size_t i = 0; i < count; i++)
			free(envp[i]);

		free(envp);
	envp[i] = NULL;

		@throw e;
	}

	return envp;
}

- (bool)lowlevelIsAtEndOfStream
{
	if (_readPipe[0] == -1)

Modified src/platform/posix/OFString+PathAdditions.m from [e173df7149] to [b28e56e3b6].

150
151
152
153
154
155
156
157

158
159
160
161
162
163
164
165
150
151
152
153
154
155
156

157

158
159
160
161
162
163
164







-
+
-







	pos = [fileName rangeOfString: @"."
			      options: OF_STRING_SEARCH_BACKWARDS].location;
	if (pos == OF_NOT_FOUND || pos == 0) {
		objc_autoreleasePoolPop(pool);
		return @"";
	}

	ret = [fileName substringWithRange:
	ret = [fileName substringFromIndex: pos + 1];
	    of_range(pos + 1, fileName.length - pos - 1)];

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

- (OFString *)stringByDeletingLastPathComponent
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
219
220
221
222
223
224
225

226
227
228
229
230
231
232
233







-
+







	pos = [fileName rangeOfString: @"."
			      options: OF_STRING_SEARCH_BACKWARDS].location;
	if (pos == OF_NOT_FOUND || pos == 0) {
		objc_autoreleasePoolPop(pool);
		return [[self copy] autorelease];
	}

	fileName = [fileName substringWithRange: of_range(0, pos)];
	fileName = [fileName substringToIndex: pos];
	[components replaceObjectAtIndex: [components count] - 1
			      withObject: fileName];

	ret = [OFString pathWithComponents: components];

	[ret retain];
	objc_autoreleasePoolPop(pool);
330
331
332
333
334
335
336
337

338
339
340
341
342
343
344
345
346
329
330
331
332
333
334
335

336
337
338
339
340
341
342
343
344
345







-
+









}

- (OFString *)of_URLPathToPathWithURLEncodedHost: (OFString *)URLEncodedHost
{
	OFString *path = self;

	if (path.length > 1 && [path hasSuffix: @"/"])
		path = [path substringWithRange: of_range(0, path.length - 1)];
		path = [path substringToIndex: path.length - 1];

	return path;
}

- (OFString *)of_pathComponentToURLPathComponent
{
	return self;
}
@end

Modified src/platform/windows/OFProcess.m from [816ee6b0db] to [1de0e5d870].

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







-
+
-
-











-
+







			si.cb = sizeof(si);
			si.hStdInput = _writePipe[0];
			si.hStdOutput = _readPipe[1];
			si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
			si.dwFlags |= STARTF_USESTDHANDLES;

			length = argumentsString.UTF16StringLength;
			argumentsCopy = [self
			argumentsCopy = of_malloc(length + 1, sizeof(of_char16_t));
			    allocMemoryWithSize: sizeof(of_char16_t)
					  count: length + 1];
			memcpy(argumentsCopy, argumentsString.UTF16String,
			    (length + 1) * 2);
			@try {
				if (!CreateProcessW(program.UTF16String,
				    argumentsCopy, NULL, NULL, TRUE,
				    CREATE_UNICODE_ENVIRONMENT,
				    [self of_wideEnvironmentForDictionary:
				    environment], NULL, &si, &pi))
					@throw [OFInitializationFailedException
					    exceptionWithClass: self.class];
			} @finally {
				[self freeMemory: argumentsCopy];
				free(argumentsCopy);
			}
		} else {
			of_string_encoding_t encoding = [OFLocale encoding];
			STARTUPINFO si;

			memset(&si, 0, sizeof(si));
			si.cb = sizeof(si);

Modified src/platform/windows/OFString+PathAdditions.m from [c654a7d368] to [3c2f48d580].

161
162
163
164
165
166
167
168

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

168

169
170
171
172
173
174
175







-
+
-







	pos = [fileName rangeOfString: @"."
			      options: OF_STRING_SEARCH_BACKWARDS].location;
	if (pos == OF_NOT_FOUND || pos == 0) {
		objc_autoreleasePoolPop(pool);
		return @"";
	}

	ret = [fileName substringWithRange:
	ret = [fileName substringFromIndex: pos + 1];
	    of_range(pos + 1, fileName.length - pos - 1)];

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

- (OFString *)stringByDeletingLastPathComponent
231
232
233
234
235
236
237
238

239
240
241
242
243
244
245
230
231
232
233
234
235
236

237
238
239
240
241
242
243
244







-
+







	pos = [fileName rangeOfString: @"."
			      options: OF_STRING_SEARCH_BACKWARDS].location;
	if (pos == OF_NOT_FOUND || pos == 0) {
		objc_autoreleasePoolPop(pool);
		return [[self copy] autorelease];
	}

	fileName = [fileName substringWithRange: of_range(0, pos)];
	fileName = [fileName substringToIndex: pos];
	[components replaceObjectAtIndex: components.count - 1
			      withObject: fileName];

	ret = [OFString pathWithComponents: components];

	[ret retain];
	objc_autoreleasePoolPop(pool);
354
355
356
357
358
359
360
361

362
363

364
365
366
367
368
369
370
353
354
355
356
357
358
359

360
361

362
363
364
365
366
367
368
369







-
+

-
+








- (OFString *)of_URLPathToPathWithURLEncodedHost: (OFString *)URLEncodedHost
{
	OFString *path = self;

	if (path.length > 1 && [path hasSuffix: @"/"] &&
	    ![path hasSuffix: @":/"])
		path = [path substringWithRange: of_range(0, path.length - 1)];
		path = [path substringToIndex: path.length - 1];

	path = [path substringWithRange: of_range(1, path.length - 1)];
	path = [path substringFromIndex: 1];
	path = [path stringByReplacingOccurrencesOfString: @"/"
					       withString: @"\\"];

	if (URLEncodedHost != nil) {
		OFString *host = [URLEncodedHost stringByURLDecoding];

		if (path.length == 0)

Modified src/scrypt.m from [163ddcc8f1] to [b6bce8773e].

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







-
-
+
+







-
-
+
+







		uint32_t *tmpItems, *bufferItems;

		if (param.costFactor > SIZE_MAX - 1 ||
		    (param.costFactor + 1) > SIZE_MAX / 128)
			@throw [OFOutOfRangeException exception];

		tmp = [[OFSecureData alloc]
			 initWithItemSize: param.blockSize
				    count: (param.costFactor + 1) * 128
			    initWithCount: (param.costFactor + 1) * 128
				 itemSize: param.blockSize
		    allowsSwappableMemory: param.allowsSwappableMemory];
		tmpItems = tmp.mutableItems;

		if (param.parallelization > SIZE_MAX / 128)
			@throw [OFOutOfRangeException exception];

		buffer = [[OFSecureData alloc]
			 initWithItemSize: param.blockSize
				    count: param.parallelization * 128
			    initWithCount: param.parallelization * 128
				 itemSize: param.blockSize
		    allowsSwappableMemory: param.allowsSwappableMemory];
		bufferItems = buffer.mutableItems;

		HMAC = [[OFHMAC alloc]
			initWithHashClass: [OFSHA256Hash class]
		    allowsSwappableMemory: param.allowsSwappableMemory];

Modified src/socket.h from [5c636947ff] to [750c66c5d1].

215
216
217
218
219
220
221
222

223
224
225
226
227
228
229
215
216
217
218
219
220
221

222
223
224
225
226
227
228
229







-
+








/**
 * @brief Returns the hash for the specified of_socket_address_t.
 *
 * @param address The address to hash
 * @return The hash for the specified of_socket_address_t
 */
extern uint32_t of_socket_address_hash(
extern unsigned long of_socket_address_hash(
    const of_socket_address_t *_Nonnull address);

/**
 * @brief Converts the specified of_socket_address_t to an IP string and port.
 *
 * @param address The address to convert to a string
 * @param port A pointer to an uint16_t which should be set to the port of the

Modified src/socket.m from [e490baa3be] to [2544d0730b].

435
436
437
438
439
440
441
442

443
444

445
446
447
448
449
450
451
452
435
436
437
438
439
440
441

442


443

444
445
446
447
448
449
450







-
+
-
-
+
-







	addrIn6->sin6_family = AF_UNSPEC;
#endif
	addrIn6->sin6_port = OF_BSWAP16_IF_LE(port);

	doubleColon = [IPv6 rangeOfString: @"::"].location;

	if (doubleColon != OF_NOT_FOUND) {
		OFString *left = [IPv6 substringWithRange:
		OFString *left = [IPv6 substringToIndex: doubleColon];
		    of_range(0, doubleColon)];
		OFString *right = [IPv6 substringWithRange:
		OFString *right = [IPv6 substringFromIndex: doubleColon + 2];
		    of_range(doubleColon + 2, IPv6.length - doubleColon - 2)];
		OFArray OF_GENERIC(OFString *) *leftComponents;
		OFArray OF_GENERIC(OFString *) *rightComponents;
		size_t i;

		if ([right hasPrefix: @":"] || [right containsString: @"::"])
			@throw [OFInvalidFormatException exception];

604
605
606
607
608
609
610
611

612
613
614
615
616
617
618
602
603
604
605
606
607
608

609
610
611
612
613
614
615
616







-
+







	default:
		@throw [OFInvalidArgumentException exception];
	}

	return true;
}

uint32_t
unsigned long
of_socket_address_hash(const of_socket_address_t *address)
{
	uint32_t hash;

	OF_HASH_INIT(hash);
	OF_HASH_ADD(hash, address->family);

Modified src/thread.h from [b01274c03d] to [bf84b7cea6].

37
38
39
40
41
42
43
44

45
46
47
48
49
50
51
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51







-
+







# include <exec/semaphores.h>
typedef struct {
	struct Task *task;
	void (*function)(id);
	id object;
	struct SignalSemaphore semaphore;
	struct Task *joinTask;
	uint8_t joinSigBit;
	unsigned char joinSigBit;
	bool detached, done;
} *of_thread_t;
#endif

typedef struct of_thread_attr_t {
	float priority;
	size_t stackSize;

Modified tests/Makefile from [c9cc3c5c36] to [6a6c363390].

34
35
36
37
38
39
40

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







+







       OFURLTests.m			\
       OFValueTests.m			\
       OFXMLElementBuilderTests.m	\
       OFXMLNodeTests.m			\
       OFXMLParserTests.m		\
       PBKDF2Tests.m			\
       RuntimeTests.m			\
       ${RUNTIME_ARC_TESTS_M}		\
       ScryptTests.m			\
       TestsAppDelegate.m		\
       ${USE_SRCS_FILES}		\
       ${USE_SRCS_PLUGINS}		\
       ${USE_SRCS_SOCKETS}		\
       ${USE_SRCS_THREADS}		\
       ${USE_SRCS_WINDOWS}
199
200
201
202
203
204
205

206
207
208
200
201
202
203
204
205
206
207
208
209
210







+



	ndstool -c $@ -9 $< -d nds-data
	rm -fr nds-data

${PROG_NOINST}.3dsx: ${PROG_NOINST}
	3dsxtool $< $@

CPPFLAGS += -I../src -I../src/exceptions -I../src/runtime -I.. -DSTDOUT
OBJCFLAGS_RuntimeARCTests.m = -fobjc-arc -fobjc-arc-exceptions
LIBS := ${TESTS_LIBS} ${LIBS}
LDFLAGS += ${MAP_LDFLAGS}
LD = ${OBJC}

Modified tests/OFDataTests.m from [ec82a4e0aa] to [b5f79a4b6c].

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







-
-
-
+
+
















+
-
+
-







	OFData *immutable;
	void *raw[2];
	of_range_t range;

	TEST(@"+[dataWithItemSize:]",
	    (mutable = [OFMutableData dataWithItemSize: 4096]))

	OFObject *tmp = [[[OFObject alloc] init] autorelease];
	raw[0] = [tmp allocMemoryWithSize: 4096];
	raw[1] = [tmp allocMemoryWithSize: 4096];
	raw[0] = of_malloc(1, 4096);
	raw[1] = of_malloc(1, 4096);
	memset(raw[0], 0xFF, 4096);
	memset(raw[1], 0x42, 4096);

	TEST(@"-[addItem:]", R([mutable addItem: raw[0]]) &&
	    R([mutable addItem: raw[1]]))

	TEST(@"-[itemAtIndex:]",
	    memcmp([mutable itemAtIndex: 0], raw[0], 4096) == 0 &&
	    memcmp([mutable itemAtIndex: 1], raw[1], 4096) == 0)

	TEST(@"-[lastItem]", memcmp(mutable.lastItem, raw[1], 4096) == 0)

	TEST(@"-[count]", mutable.count == 2)

	TEST(@"-[isEqual:]",
	    (immutable = [OFData dataWithItems: mutable.items
					 count: mutable.count
				      itemSize: mutable.itemSize
				      itemSize: mutable.itemSize]) &&
					 count: mutable.count]) &&
	    [immutable isEqual: mutable] &&
	    R([mutable removeLastItem]) && ![mutable isEqual: immutable])

	TEST(@"-[mutableCopy]",
	    (mutable = [[immutable mutableCopy] autorelease]) &&
	    [mutable isEqual: immutable])

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







+
-
+
-


-
-
+
+




-
-
+
+




-
-
+
+




-
-
+
+




-
-
+
+




-
-
+
+








-
-
+
+







-
-
+
+






+
-
+
-







	TEST(@"-[insertItems:atIndex:count:]",
	    R([mutable insertItems: "bc"
			   atIndex: 1
			     count: 2]) && mutable.count == 5 &&
	    memcmp(mutable.items, "abcde", 5) == 0)

	immutable = [OFData dataWithItems: "aaabaccdacaabb"
				    count: 7
				 itemSize: 2
				 itemSize: 2];
				    count: 7];
	TEST(@"-[rangeOfString:options:range:]",
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aa"
							   itemSize: 2
							      count: 1]
							      count: 1
							   itemSize: 2]
				     options: 0
				       range: of_range(0, 7)]) &&
	    range.location == 0 && range.length == 1 &&
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aa"
							   itemSize: 2
							      count: 1]
							      count: 1
							   itemSize: 2]
				     options: OF_DATA_SEARCH_BACKWARDS
				       range: of_range(0, 7)]) &&
	    range.location == 5 && range.length == 1 &&
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "ac"
							   itemSize: 2
							      count: 1]
							      count: 1
							   itemSize: 2]
				     options: 0
				       range: of_range(0, 7)]) &&
	    range.location == 2 && range.length == 1 &&
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aabb"
							   itemSize: 2
							      count: 2]
							      count: 2
							   itemSize: 2]
				     options: 0
				       range: of_range(0, 7)]) &&
	    range.location == 5 && range.length == 2 &&
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aa"
							   itemSize: 2
							      count: 1]
							      count: 1
							   itemSize: 2]
				     options: 0
				       range: of_range(1, 6)]) &&
	    range.location == 5 && range.length == 1 &&
	    R(range = [immutable rangeOfData: [OFData dataWithItems: "aa"
							   itemSize: 2
							      count: 1]
							      count: 1
							   itemSize: 2]
				     options: OF_DATA_SEARCH_BACKWARDS
				       range: of_range(0, 5)]) &&
	    range.location == 0 && range.length == 1)

	EXPECT_EXCEPTION(
	    @"-[rangeOfString:options:range:] failing on different itemSize",
	    OFInvalidArgumentException,
	    [immutable rangeOfData: [OFData dataWithItems: "aaa"
						 itemSize: 3
						    count: 1]
						    count: 1
						 itemSize: 3]
			   options: 0
			     range: of_range(0, 1)])

	EXPECT_EXCEPTION(
	    @"-[rangeOfData:options:range:] failing on out of range",
	    OFOutOfRangeException,
	    [immutable rangeOfData: [OFData dataWithItems: ""
						 itemSize: 2
						    count: 0]
						    count: 0
						 itemSize: 2]
			   options: 0
			     range: of_range(8, 1)])

	TEST(@"-[subdataWithRange:]",
	    [[immutable subdataWithRange: of_range(2, 4)]
	    isEqual: [OFData dataWithItems: "accdacaa"
				     count: 4
				  itemSize: 2
				  itemSize: 2]] &&
				     count: 4]] &&
	    [[mutable subdataWithRange: of_range(2, 3)]
	    isEqual: [OFData dataWithItems: "cde"
				     count: 3]])

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

203
204
205
206
207
208
209



210
211
212
213
202
203
204
205
206
207
208
209
210
211
212
213
214
215







+
+
+




	EXPECT_EXCEPTION(@"Detect out of range in -[addItems:count:]",
	    OFOutOfRangeException, [mutable addItems: raw[0]
					       count: SIZE_MAX])

	EXPECT_EXCEPTION(@"Detect out of range in -[removeItemsInRange:]",
	    OFOutOfRangeException,
	    [mutable removeItemsInRange: of_range(mutable.count, 1)])

	free(raw[0]);
	free(raw[1]);

	objc_autoreleasePoolPop(pool);
}
@end

Modified tests/OFHTTPClientTests.m from [a109d65c25] to [086ef33868].

97
98
99
100
101
102
103

104


105
106
107
108
109
110
111
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114







+

+
+







{
	[body writeString: @"Hello"];
}

-      (void)client: (OFHTTPClient *)client
  didPerformRequest: (OFHTTPRequest *)request
	   response: (OFHTTPResponse *)response_
	  exception: (id)exception
{
	OF_ENSURE(exception == nil);

	response = [response_ retain];

	[[OFRunLoop mainRunLoop] stop];
}

- (void)HTTPClientTests
{

Modified tests/OFObjectTests.m from [5ded62534c] to [7fc519cbf2].

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
83
84
85
86
87
88
89


90
91







































92
93
94
95
96
97
98







-
-


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







}
@end

@implementation TestsAppDelegate (OFObjectTests)
- (void)objectTests
{
	void *pool = objc_autoreleasePoolPush();
	OFObject *obj = [[[OFObject alloc] init] autorelease];
	void *p, *q, *r;
	OFObject *o;
	MyObj *m;
	char *tmp;

	TEST(@"Allocating 4096 bytes",
	    (p = [obj allocMemoryWithSize: 4096]) != NULL)

	TEST(@"Freeing memory", R([obj freeMemory: p]))

	TEST(@"Allocating and freeing 4096 bytes 3 times",
	    (p = [obj allocMemoryWithSize: 4096]) != NULL &&
	    (q = [obj allocMemoryWithSize: 4096]) != NULL &&
	    (r = [obj allocMemoryWithSize: 4096]) != NULL &&
	    R([obj freeMemory: p]) && R([obj freeMemory: q]) &&
	    R([obj freeMemory: r]))

	tmp = [self allocMemoryWithSize: 1024];
	EXPECT_EXCEPTION(@"Detect freeing of memory not allocated by object",
	    OFMemoryNotPartOfObjectException, [obj freeMemory: tmp])

	EXPECT_EXCEPTION(@"Detect out of memory on alloc",
	    OFOutOfMemoryException, tmp = [obj allocMemoryWithSize: TOO_BIG])

	EXPECT_EXCEPTION(@"Detect out of memory on resize",
	    OFOutOfMemoryException,
	    {
		p = [obj allocMemoryWithSize: 1];
		p = [obj resizeMemory: p
				 size: TOO_BIG];
	    })
	[obj freeMemory: p];

	TEST(@"Allocate when trying to resize NULL",
	    (p = [obj resizeMemory: NULL
			      size: 1024]) != NULL)
	[obj freeMemory: p];

	EXPECT_EXCEPTION(@"Detect resizing of memory not allocated by object",
	    OFMemoryNotPartOfObjectException, tmp = [obj resizeMemory: tmp
								 size: 2048])
	[self freeMemory: tmp];

	TEST(@"+[description]",
	    [[OFObject description] isEqual: @"OFObject"] &&
	    [[MyObj description] isEqual: @"MyObj"])

	o = [[[OFObject alloc] init] autorelease];
	m = [[[MyObj alloc] init] autorelease];

Modified tests/OFStreamTests.m from [3c0c93a949] to [5c572f840c].

67
68
69
70
71
72
73
74

75
76
77
78
79
80


81
82
83
84
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83
84
85
86







-
+






+
+




{
	void *pool = objc_autoreleasePoolPush();
	size_t pageSize = [OFSystemInfo pageSize];
	StreamTester *t = [[[StreamTester alloc] init] autorelease];
	OFString *str;
	char *cstr;

	cstr = [t allocMemoryWithSize: pageSize - 2];
	cstr = of_malloc(pageSize - 2, 1);
	memset(cstr, 'X', pageSize - 3);
	cstr[pageSize - 3] = '\0';

	TEST(@"-[readLine]", [[t readLine] isEqual: @"foo"] &&
	    [(str = [t readLine]) length] == pageSize - 3 &&
	    !strcmp(str.UTF8String, cstr))

	free(cstr);

	objc_autoreleasePoolPop(pool);
}
@end

Added tests/RuntimeARCTests.m version [0ff145ce55].























































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017,
 *               2018, 2019, 2020
 *   Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "TestsAppDelegate.h"

static OFString *module = @"Runtime (ARC)";

@interface RuntimeARCTest: OFObject
@end

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

	@throw [OFException exception];

	return self;
}
@end

@implementation TestsAppDelegate (RuntimeARCTests)
- (void)runtimeARCTests
{
	id object;
	__weak id weak;

	EXPECT_EXCEPTION(@"Exceptions in init", OFException,
	    object = [[RuntimeARCTest alloc] init])

	object = [[OFObject alloc] init];
	weak = object;
	TEST(@"weakly referencing an object", weak == object)

	object = nil;
	TEST(@"weak references becoming nil", weak == nil)
}
@end

Modified tests/TestsAppDelegate.h from [0e4b40ac71] to [474ebe8ce9].

173
174
175
176
177
178
179




180
181
182
183
184
185
186
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190







+
+
+
+







@interface TestsAppDelegate (OFPluginTests)
- (void)pluginTests;
@end

@interface TestsAppDelegate (RuntimeTests)
- (void)runtimeTests;
@end

@interface TestsAppDelegate (RuntimeARCTests)
- (void)runtimeARCTests;
@end

@interface TestsAppDelegate (OFRIPEMD160HashTests)
- (void)RIPEMD160HashTests;
@end

@interface TestsAppDelegate (ScryptTests)
- (void)scryptTests;

Modified tests/TestsAppDelegate.m from [b1233ca24e] to [7de17ddfab].

310
311
312
313
314
315
316



317
318
319
320
321
322
323
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326







+
+
+







#endif
#if defined(OF_WII) && defined(OF_HAVE_FILES)
	[[OFFileManager defaultManager]
	    changeCurrentDirectoryPath: @"/apps/objfw-tests"];
#endif

	[self runtimeTests];
#ifdef COMPILER_SUPPORTS_ARC
	[self runtimeARCTests];
#endif
	[self objectTests];
	[self methodSignatureTests];
	[self invocationTests];
	[self forwardingTests];
#ifdef OF_HAVE_BLOCKS
	[self blockTests];
#endif

Modified utils/ofhttp/OFHTTP.m from [cd147444d1] to [121d87bdd5].

61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
61
62
63
64
65
66
67

68
69
70
71
72
73
74
75







-
+







    OFStreamDelegate>
{
	OFArray OF_GENERIC(OFString *) *_URLs;
	size_t _URLIndex;
	int _errorCode;
	OFString *_outputPath, *_currentFileName;
	bool _continue, _force, _detectFileName, _detectFileNameRequest;
	bool _detectedFileName, _quiet, _verbose, _insecure;
	bool _detectedFileName, _quiet, _verbose, _insecure, _ignoreStatus;
	OFStream *_body;
	of_http_request_method_t _method;
	OFMutableDictionary *_clientHeaders;
	OFHTTPClient *_HTTPClient;
	char *_buffer;
	OFStream *_output;
	unsigned long long _received, _length, _resumedFrom;
114
115
116
117
118
119
120
121



122
123
124
125
126
127
128
114
115
116
117
118
119
120

121
122
123
124
125
126
127
128
129
130







-
+
+
+







		    @"-P  --proxy          "
		    @"  Specify SOCKS5 proxy\n    "
		    @"-q  --quiet          "
		    @"  Quiet mode (no output, except errors)\n    "
		    @"-v  --verbose        "
		    @"  Verbose mode (print headers)\n    "
		    @"    --insecure       "
		    @"  Ignore TLS errors and allow insecure redirects")];
		    @"  Ignore TLS errors and allow insecure redirects\n    "
		    @"    --ignore-status  "
		    @"  Ignore HTTP status code")];
	}

	[OFApplication terminateWithStatus: status];
}

static OFString *
fileNameFromContentDisposition(OFString *contentDisposition)
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
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







-
+




















-
-
+
+

-
+
-
-
+







		_clientHeaders = [[OFMutableDictionary alloc]
		    initWithObject: @"OFHTTP"
			    forKey: @"User-Agent"];

		_HTTPClient = [[OFHTTPClient alloc] init];
		_HTTPClient.delegate = self;

		_buffer = [self allocMemoryWithSize: [OFSystemInfo pageSize]];
		_buffer = of_malloc(1, [OFSystemInfo pageSize]);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)addHeader: (OFString *)header
{
	size_t pos = [header rangeOfString: @":"].location;
	OFString *name, *value;

	if (pos == OF_NOT_FOUND) {
		[of_stderr writeLine: OF_LOCALIZED(@"invalid_input_header",
		    @"%[prog]: Headers must to be in format name:value!",
		    @"prog", [OFApplication programName])];
		[OFApplication terminateWithStatus: 1];
	}

	name = [header substringWithRange: of_range(0, pos)];
	name = name.stringByDeletingEnclosingWhitespaces;
	name = [header substringToIndex: pos]
	    .stringByDeletingEnclosingWhitespaces;

	value = [header substringWithRange:
	value = [header substringFromIndex: pos + 1]
	    of_range(pos + 1, header.length - pos - 1)];
	value = value.stringByDeletingEnclosingWhitespaces;
	    .stringByDeletingEnclosingWhitespaces;

	[_clientHeaders setObject: value
			   forKey: name];
}

- (void)setBody: (OFString *)path
{
392
393
394
395
396
397
398
399
400
401



402
403
404
405
406
407
408
393
394
395
396
397
398
399



400
401
402
403
404
405
406
407
408
409







-
-
-
+
+
+







			  options: OF_STRING_SEARCH_BACKWARDS].location;
		OFString *host;
		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)].unsignedLongLongValue;
		host = [proxy substringToIndex: pos];
		port = [proxy substringFromIndex: pos + 1]
		    .unsignedLongLongValue;

		if (port > UINT16_MAX)
			@throw [OFOutOfRangeException exception];

		[OFTCPSocket setSOCKS5Host: host];
		[OFTCPSocket setSOCKS5Port: (uint16_t)port];
	} @catch (OFInvalidFormatException *e) {
425
426
427
428
429
430
431

432
433
434
435
436
437
438
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440







+







		{ 'm', @"method", 1, NULL, NULL },
		{ 'o', @"output", 1, NULL, &outputPath },
		{ 'O', @"detect-filename", 0, &_detectFileName, NULL },
		{ 'P', @"socks5-proxy", 1, NULL, NULL },
		{ 'q', @"quiet", 0, &_quiet, NULL },
		{ 'v', @"verbose", 0, &_verbose, NULL },
		{ '\0', @"insecure", 0, &_insecure, NULL },
		{ '\0', @"ignore-status", 0, &_ignoreStatus, NULL },
		{ '\0', nil, 0, NULL, NULL }
	};
	OFOptionsParser *optionsParser;
	of_unichar_t option;

#ifdef OF_HAVE_SANDBOX
	OFSandbox *sandbox = [OFSandbox sandbox];
602
603
604
605
606
607
608
609

610
611
612
613
614
615
616
604
605
606
607
608
609
610

611
612
613
614
615
616
617
618







-
+







		[body writeBuffer: buffer
			   length: length];
	}
}

-	  (bool)client: (OFHTTPClient *)client
  shouldFollowRedirect: (OFURL *)URL
	    statusCode: (int)statusCode
	    statusCode: (short)statusCode
	       request: (OFHTTPRequest *)request
	      response: (OFHTTPResponse *)response
{
	if (_verbose) {
		void *pool = objc_autoreleasePoolPush();
		OFDictionary OF_GENERIC(OFString *, OFString *) *headers =
		    response.headers;
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
632
633
634
635
636
637
638

























































































639
640
641
642
643
644
645







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







		[of_stdout writeFormat: @"☇ %@", URL.string];

	_length = 0;

	return true;
}

-	  (void)client: (OFHTTPClient *)client
  didFailWithException: (id)e
	       request: (OFHTTPRequest *)request
{
	if ([e isKindOfClass: [OFResolveHostFailedException class]]) {
		if (!_quiet)
			[of_stdout writeString: @"\n"];

		[of_stderr writeLine:
		    OF_LOCALIZED(@"download_resolve_host_failed",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  Failed to resolve host: %[exception]",
		    @"prog", [OFApplication programName],
		    @"url", request.URL.string,
		    @"exception", e)];
	} else if ([e isKindOfClass: [OFConnectionFailedException class]]) {
		if (!_quiet)
			[of_stdout writeString: @"\n"];

		[of_stderr writeLine:
		    OF_LOCALIZED(@"download_failed_connection_failed",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  Connection failed: %[exception]",
		    @"prog", [OFApplication programName],
		    @"url", request.URL.string,
		    @"exception", e)];
	} else if ([e isKindOfClass: [OFInvalidServerReplyException class]]) {
		if (!_quiet)
			[of_stdout writeString: @"\n"];

		[of_stderr writeLine:
		    OF_LOCALIZED(@"download_failed_invalid_server_reply",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  Invalid server reply!",
		    @"prog", [OFApplication programName],
		    @"url", request.URL.string)];
	} else if ([e isKindOfClass: [OFUnsupportedProtocolException class]]) {
		if (!_quiet)
			[of_stdout writeString: @"\n"];

		[of_stderr writeLine: OF_LOCALIZED(@"no_ssl_library",
		    @"%[prog]: No TLS library loaded!\n"
		    @"  In order to download via https, you need to preload an "
		    @"TLS library for ObjFW\n"
		    @"  such as ObjOpenSSL!",
		    @"prog", [OFApplication programName])];
	} else if ([e isKindOfClass: [OFReadOrWriteFailedException class]]) {
		OFString *error = OF_LOCALIZED(
		    @"download_failed_read_or_write_failed_any",
		    @"Read or write failed");

		if (!_quiet)
			[of_stdout writeString: @"\n"];

		if ([e isKindOfClass: [OFReadFailedException class]])
			error = OF_LOCALIZED(
			    @"download_failed_read_or_write_failed_read",
			    @"Read failed");
		else if ([e isKindOfClass: [OFWriteFailedException class]])
			error = OF_LOCALIZED(
			    @"download_failed_read_or_write_failed_write",
			    @"Write failed");

		[of_stderr writeLine:
		    OF_LOCALIZED(@"download_failed_read_or_write_failed",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  %[error]: %[exception]",
		    @"prog", [OFApplication programName],
		    @"url", request.URL.string,
		    @"error", error,
		    @"exception", e)];
	} else if ([e isKindOfClass: [OFHTTPRequestFailedException class]]) {
		short statusCode = [[e response] statusCode];
		OFString *codeString = [OFString stringWithFormat: @"%d %@",
		    statusCode, of_http_status_code_to_string(statusCode)];
		[of_stderr writeLine: OF_LOCALIZED(@"download_failed",
		    @"%[prog]: Failed to download <%[url]>!\n"
		    @"  HTTP status code: %[code]",
		    @"prog", [OFApplication programName],
		    @"url", request.URL.string,
		    @"code", codeString)];
	} else
		@throw e;

	_errorCode = 1;
	[self performSelector: @selector(downloadNextURL)
		   afterDelay: 0];
}

-      (bool)stream: (OFStream *)response
  didReadIntoBuffer: (void *)buffer
	     length: (size_t)length
	  exception: (id)exception
{
	if (exception != nil) {
		OFString *URL;
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
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







-
+










-
+







	}

	return true;
}

-      (void)client: (OFHTTPClient *)client
  didReceiveHeaders: (OFDictionary OF_GENERIC(OFString *, OFString *) *)headers
	 statusCode: (int)statusCode
	 statusCode: (short)statusCode
	    request: (OFHTTPRequest *)request
{
	if (statusCode != 206)
		_resumedFrom = 0;

	if (!_quiet) {
		OFString *lengthString =
		    [headers objectForKey: @"Content-Length"];
		OFString *type = [headers objectForKey: @"Content-Type"];

		[of_stdout writeFormat: @" ➜ %d\n", statusCode];
		[of_stdout writeFormat: @" ➜ %hd\n", statusCode];

		if (type == nil)
			type = OF_LOCALIZED(@"type_unknown", @"unknown");

		if (lengthString != nil) {
			_length = lengthString.unsignedLongLongValue;

880
881
882
883
884
885
886

887











































































































888
889
890
891
892
893
894
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
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915







+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







		}
	}
}

-      (void)client: (OFHTTPClient *)client
  didPerformRequest: (OFHTTPRequest *)request
	   response: (OFHTTPResponse *)response
	  exception: (id)exception
{
	if (exception != nil) {
		if ([exception isKindOfClass:
		    [OFResolveHostFailedException class]]) {
			if (!_quiet)
				[of_stdout writeString: @"\n"];

			[of_stderr writeLine:
			    OF_LOCALIZED(@"download_resolve_host_failed",
			    @"%[prog]: Failed to download <%[url]>!\n"
			    @"  Failed to resolve host: %[exception]",
			    @"prog", [OFApplication programName],
			    @"url", request.URL.string,
			    @"exception", exception)];
		} else if ([exception isKindOfClass:
		    [OFConnectionFailedException class]]) {
			if (!_quiet)
				[of_stdout writeString: @"\n"];

			[of_stderr writeLine:
			    OF_LOCALIZED(@"download_failed_connection_failed",
			    @"%[prog]: Failed to download <%[url]>!\n"
			    @"  Connection failed: %[exception]",
			    @"prog", [OFApplication programName],
			    @"url", request.URL.string,
			    @"exception", exception)];
		} else if ([exception isKindOfClass:
		    [OFInvalidServerReplyException class]]) {
			if (!_quiet)
				[of_stdout writeString: @"\n"];

			[of_stderr writeLine: OF_LOCALIZED(
			    @"download_failed_invalid_server_reply",
			    @"%[prog]: Failed to download <%[url]>!\n"
			    @"  Invalid server reply!",
			    @"prog", [OFApplication programName],
			    @"url", request.URL.string)];
		} else if ([exception isKindOfClass:
		    [OFUnsupportedProtocolException class]]) {
			if (!_quiet)
				[of_stdout writeString: @"\n"];

			[of_stderr writeLine: OF_LOCALIZED(@"no_ssl_library",
			    @"%[prog]: No TLS library loaded!\n"
			    @"  In order to download via https, you need to "
			    @"preload an TLS library for ObjFW\n"
			    @"  such as ObjOpenSSL!",
			    @"prog", [OFApplication programName])];
		} else if ([exception isKindOfClass:
		    [OFReadOrWriteFailedException class]]) {
			OFString *error = OF_LOCALIZED(
			    @"download_failed_read_or_write_failed_any",
			    @"Read or write failed");

			if (!_quiet)
				[of_stdout writeString: @"\n"];

			if ([exception isKindOfClass:
			    [OFReadFailedException class]])
				error = OF_LOCALIZED(
				    @"download_failed_read_or_write_failed_"
				    @"read",
				    @"Read failed");
			else if ([exception isKindOfClass:
			    [OFWriteFailedException class]])
				error = OF_LOCALIZED(
				    @"download_failed_read_or_write_failed_"
				    @"write",
				    @"Write failed");

			[of_stderr writeLine: OF_LOCALIZED(
			    @"download_failed_read_or_write_failed",
			    @"%[prog]: Failed to download <%[url]>!\n"
			    @"  %[error]: %[exception]",
			    @"prog", [OFApplication programName],
			    @"url", request.URL.string,
			    @"error", error,
			    @"exception", exception)];
		} else if ([exception isKindOfClass:
		    [OFHTTPRequestFailedException class]]) {
			short statusCode;
			OFString *codeString;

			if (_ignoreStatus) {
				exception = nil;
				goto after_exception_handling;
			}

			statusCode = response.statusCode;
			codeString = [OFString stringWithFormat: @"%hd %@",
			    statusCode,
			    of_http_status_code_to_string(statusCode)];
			[of_stderr writeLine: OF_LOCALIZED(@"download_failed",
			    @"%[prog]: Failed to download <%[url]>!\n"
			    @"  HTTP status code: %[code]",
			    @"prog", [OFApplication programName],
			    @"url", request.URL.string,
			    @"code", codeString)];
		} else
			@throw exception;

		_errorCode = 1;
		[self performSelector: @selector(downloadNextURL)
			   afterDelay: 0];
		return;
	}

after_exception_handling:
	if (_method == OF_HTTP_REQUEST_METHOD_HEAD)
		goto next;

	if (_detectFileNameRequest) {
		_currentFileName = [fileNameFromContentDisposition(
		    [response.headers objectForKey: @"Content-Disposition"])
		    copy];

Modified utils/ofhttp/lang/de.json from [ccf7a0ea89] to [ad71562e8d].

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
28







-
+
+







        "    -o  --output           Ausgabe-Dateiname angeben\n",
        "    -O  --detect-filename  Dateiname mittels HEAD-Request ermitteln\n",
        "    -P  --proxy            SOCKS5-Proxy angeben\n",
        "    -q  --quiet            Ruhiger Modus (keine Ausgabe außer Fehler)",
        "\n",
        "    -v  --verbose          Ausführlicher Modus (gibt Header aus)\n",
        "        --insecure         TLS-Fehler ignorieren und unsichere\n",
        "                           Weiterleitungen erlauben"
        "                           Weiterleitungen erlauben\n",
        "        --ignore-status    HTTP Status-Code ignorieren"
    ],
    "invalid_input_header": "%[prog]: Header müssen im Format Name:Wert sein!",
    "invalid_input_method": "%[prog]: Ungültige Request-Methode %[method]!",
    "invalid_input_proxy": "%[prog]: Proxy muss im Format Host:Port sein!",
    "long_argument_missing": "%[prog]: Argument für Option --%[opt] fehlt",
    "argument_missing": "%[prog]: Argument für option -%[opt] fehlt",
    "option_takes_no_argument": "%[prog]: Option --%[opt] nimmt kein Argument",