Index: .travis.yml ================================================================== --- .travis.yml +++ .travis.yml @@ -239,10 +239,12 @@ - os: linux 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"; @@ -266,28 +268,16 @@ 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" - -o "$config" = "wii" ]; then - deb=devkitpro-pacman.amd64.deb; - wget https://github.com/devkitPro/pacman/releases/download/v1.0.2/$deb; - sudo apt install gdebi; - sudo gdebi -n $deb; - fi - - - if [ "$config" = "nintendo_3ds" ]; then - sudo dkp-pacman --noconfirm -Syu 3ds-dev; - fi - - - if [ "$config" = "nintendo_ds" ]; then - sudo dkp-pacman --noconfirm -Syu nds-dev; + - if [ "$config" = "nintendo_3ds" -o "$config" = "nintendo_ds" ]; then + docker pull devkitpro/devkitarm; fi - if [ "$config" = "wii" ]; then - sudo dkp-pacman --noconfirm -Syu wii-dev; + docker pull devkitpro/devkitppc; fi - if [ "$config" = "amigaos" ]; then wget -q https://franke.ms/download/amiga-gcc.tgz; tar -C / -xzf amiga-gcc.tgz; @@ -297,26 +287,12 @@ - build() { if ! git clean -fxd >/tmp/clean_log 2>&1; then cat /tmp/clean_log; exit 1; fi; - echo ">> Configuring with $@"; ./autogen.sh; - if ! ./configure ac_cv_path_TPUT= "$@"; then - cat config.log; - exit 1; - fi; - echo ">> Building (configured with $@)"; - if ! make -j4 >/tmp/make_log 2>&1; then - cat /tmp/make_log; - exit 1; - fi; - echo ">> Installing (configured with $@)"; - if ! sudo PATH="$PATH" make install >/tmp/install_log 2>&1; then - cat /tmp/install_log; - exit 1; - fi; + .travis/build.sh "$@"; } - if [ "$TRAVIS_OS_NAME" = "linux" -a -z "$config" ]; then build_32_64() { build OBJC="$CC" $@; @@ -423,24 +399,28 @@ build --host=m68k-amigaos --disable-amiga-lib; build --host=m68k-amigaos --enable-static; fi - if [ "$config" = "nintendo_3ds" ]; then - export DEVKITPRO="/opt/devkitpro"; - export PATH="$DEVKITPRO/devkitARM/bin:$PATH"; - - build --host=arm-none-eabi --with-3ds; + ./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 - export DEVKITPRO="/opt/devkitpro"; - export PATH="$DEVKITPRO/devkitARM/bin:$PATH"; - - build --host=arm-none-eabi --with-nds; + ./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 - export DEVKITPRO="/opt/devkitpro"; - export PATH="$DEVKITPRO/devkitPPC/bin:$PATH"; - - build ac_cv_prog_wiiload= --host=powerpc-eabi --with-wii; + ./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/build.sh Index: .travis/build.sh ================================================================== --- .travis/build.sh +++ .travis/build.sh @@ -0,0 +1,20 @@ +#!/bin/sh +cd $(dirname $0)/.. + +echo ">> Configuring with $@" +if ! ./configure ac_cv_path_TPUT= "$@"; then + cat config.log + exit 1 +fi + +echo ">> Building (configured with $@)" +if ! make -j4 >/tmp/make_log 2>&1; then + cat /tmp/make_log + exit 1 +fi + +echo ">> Installing (configured with $@)" +if ! sudo PATH="$PATH" make install >/tmp/install_log 2>&1; then + cat /tmp/install_log + exit 1 +fi Index: Makefile ================================================================== --- Makefile +++ Makefile @@ -23,11 +23,11 @@ tarball: docs echo "Generating tarball for version ${PACKAGE_VERSION}..." rm -fr objfw-${PACKAGE_VERSION} objfw-${PACKAGE_VERSION}.tar \ objfw-${PACKAGE_VERSION}.tar.gz fossil tarball --name objfw-${PACKAGE_VERSION} current - \ - --exclude '.fossil-settings/*,.gitignore,.travis.yml' | \ + --exclude '.cirrus*,.fossil-settings/*,.gitignore,.travis*' | \ ofarc -ttgz -xq - cp configure config.h.in objfw-${PACKAGE_VERSION}/ ofarc -cq objfw-${PACKAGE_VERSION}.tar \ $$(find objfw-${PACKAGE_VERSION} | sort) rm -fr objfw-${PACKAGE_VERSION} Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -818,11 +818,11 @@ AC_MSG_CHECKING(for VFP2 or above) AC_TRY_COMPILE([], [ #if !defined(__arm64__) && !defined(__aarch64__) && \ !defined(__ARM64_ARCH_8__) __asm__ __volatile__ ( - "fstmfdd sp!, {d0-d7}" + "vstmdb sp!, {d0-d7}" ); #endif ], [ AC_DEFINE(HAVE_VFP2, 1, [Whether we have VFP2 or above]) AC_MSG_RESULT(yes) @@ -899,17 +899,11 @@ AC_SUBST(ENCODINGS_A, "encodings.a") AC_SUBST(ENCODINGS_ENCODINGS_A, "encodings/encodings.a") ]) ]) -AC_CHECK_FUNC(arc4random, [ - AC_DEFINE(OF_HAVE_ARC4RANDOM, 1, [Whether we have arc4random()]) -], [ - AC_CHECK_FUNC(random, [ - AC_DEFINE(OF_HAVE_RANDOM, 1, [Whether we have random()]) - ]) -]) +AC_CHECK_FUNCS(arc4random getrandom random, break) AS_IF([test x"$host_os" != x"morphos"], [ AC_CHECK_LIB(dl, dlopen, LIBS="$LIBS -ldl") ]) AC_CHECK_HEADERS_ONCE(dlfcn.h) Index: src/OFDNSResolver.m ================================================================== --- src/OFDNSResolver.m +++ src/OFDNSResolver.m @@ -812,11 +812,11 @@ OFNumber *ID; OFDNSResolverContext *context; /* Random, unused ID */ do { - ID = [OFNumber numberWithUInt16: (uint16_t)of_random()]; + ID = [OFNumber numberWithUInt16: of_random16()]; } while ([_queries objectForKey: ID] != nil); if (query.domainName.UTF8StringLength > 253) @throw [OFOutOfRangeException exception]; Index: src/OFMapTable.m ================================================================== --- src/OFMapTable.m +++ src/OFMapTable.m @@ -165,11 +165,11 @@ _buckets = [self allocZeroedMemoryWithSize: sizeof(*_buckets) count: _capacity]; if (of_hash_seed != 0) - _rotate = of_random() & 31; + _rotate = of_random16() & 31; } @catch (id e) { [self release]; @throw e; } @@ -532,11 +532,11 @@ /* * 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_random() & 31; + _rotate = of_random16() & 31; } - (bool)containsObject: (void *)object { if (object == NULL || _count == 0) Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -30,12 +30,13 @@ #include #include #include #include -#include "macros.h" #include "block.h" +#include "macros.h" +#include "once.h" /* * Some versions of MinGW require to be included before * . Do this here to make sure this is always done in the correct * order, even if another header includes just . @@ -1315,10 +1316,14 @@ #endif extern id of_alloc_object(Class class_, size_t extraSize, size_t extraAlignment, void *_Nullable *_Nullable extra); extern void OF_NO_RETURN_FUNC of_method_not_found(id self, SEL _cmd); extern uint32_t of_hash_seed; +/* These do *NOT* provide cryptographically secure randomness! */ +extern uint16_t of_random16(void); +extern uint32_t of_random32(void); +extern uint64_t of_random64(void); #ifdef __cplusplus } #endif OF_ASSUME_NONNULL_END Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -101,10 +101,85 @@ static struct { Class isa; } allocFailedException; uint32_t of_hash_seed; + +#ifndef HAVE_ARC4RANDOM +static void +initRandom(void) +{ + struct timeval tv; + +# ifdef HAVE_RANDOM + gettimeofday(&tv, NULL); + srandom((unsigned)(tv.tv_sec ^ tv.tv_usec)); +# else + gettimeofday(&tv, NULL); + srand((unsigned)(tv.tv_sec ^ tv.tv_usec)); +# endif +} +#endif + +uint16_t +of_random16(void) +{ +#if defined(HAVE_ARC4RANDOM) + return arc4random(); +#elif defined(HAVE_GETRANDOM) + uint16_t buffer; + + OF_ENSURE(getrandom(&buffer, sizeof(buffer), 0) == sizeof(buffer)); + + return buffer; +#else + static of_once_t onceControl = OF_ONCE_INIT; + + of_once(&onceControl, initRandom); +# ifdef HAVE_RANDOM + return random() & 0xFFFF; +# else + return rand() & 0xFFFF; +# endif +#endif +} + +uint32_t +of_random32(void) +{ +#if defined(HAVE_ARC4RANDOM) + return arc4random(); +#elif defined(HAVE_GETRANDOM) + uint32_t buffer; + + OF_ENSURE(getrandom(&buffer, sizeof(buffer), 0) == sizeof(buffer)); + + return buffer; +#else + return ((uint32_t)of_random16() << 16) | of_random16(); +#endif +} + +uint64_t +of_random64(void) +{ +#if defined(HAVE_ARC4RANDOM) + uint64_t buffer; + + arc4random_buf(&buffer, sizeof(buffer)); + + return buffer; +#elif defined(HAVE_GETRANDOM) + uint64_t buffer; + + OF_ENSURE(getrandom(&buffer, sizeof(buffer), 0) == sizeof(buffer)); + + return buffer; +#else + return ((uint64_t)of_random32() << 32) | of_random32(); +#endif +} static const char * typeEncodingForSelector(Class class, SEL selector) { Method method; @@ -250,11 +325,11 @@ #endif objc_setEnumerationMutationHandler(enumerationMutationHandler); do { - of_hash_seed = of_random(); + of_hash_seed = of_random32(); } while (of_hash_seed == 0); } + (void)unload { Index: src/macros.h ================================================================== --- src/macros.h +++ src/macros.h @@ -896,27 +896,6 @@ static OF_INLINE char of_ascii_tolower(char c) { return (c >= 'A' && c <= 'Z' ? 'a' + (c - 'A') : c); } - -/* This does *NOT* provide cryptographically secure randomness! */ -static OF_INLINE uint32_t -of_random(void) { -#if defined(OF_HAVE_ARC4RANDOM) - return arc4random(); -#elif defined(OF_HAVE_RANDOM) - struct timeval tv; - - gettimeofday(&tv, NULL); - srandom((unsigned)(tv.tv_sec ^ tv.tv_usec)); - return (((uint32_t)(random()) << 16) | ((uint32_t)(random()) & 0xFFFF)); -#else - struct timeval tv; - - gettimeofday(&tv, NULL); - srand((unsigned)(tv.tv_sec ^ tv.tv_usec)); - return (((uint32_t)(rand()) << 16) | ((uint32_t)(rand()) & 0xFFFF)); -#endif -} - #endif Index: src/objfw-defs.h.in ================================================================== --- src/objfw-defs.h.in +++ src/objfw-defs.h.in @@ -2,11 +2,10 @@ #undef LLONG_MAX #undef LLONG_MIN #undef OF_APPLE_RUNTIME #undef OF_BIG_ENDIAN #undef OF_FLOAT_BIG_ENDIAN -#undef OF_HAVE_ARC4RANDOM #undef OF_HAVE_ATOMIC_BUILTINS #undef OF_HAVE_ATOMIC_OPS #undef OF_HAVE_BUILTIN_BSWAP16 #undef OF_HAVE_BUILTIN_BSWAP32 #undef OF_HAVE_BUILTIN_BSWAP64 @@ -29,11 +28,10 @@ #undef OF_HAVE_PLEDGE #undef OF_HAVE_PLUGINS #undef OF_HAVE_PROCESSES #undef OF_HAVE_PTHREADS #undef OF_HAVE_PTHREAD_SPINLOCKS -#undef OF_HAVE_RANDOM #undef OF_HAVE_RECURSIVE_PTHREAD_MUTEXES #undef OF_HAVE_SCHED_YIELD #undef OF_HAVE_SOCKETS #undef OF_HAVE_STDNORETURN #undef OF_HAVE_SYMLINK