From b90184e8713a60a5d9fe52a3d8829cbe23eaf2f1 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Mon, 7 Jun 2021 21:17:03 +0300 Subject: [PATCH] check errno in JSC long number parser Signed-off-by: Ivailo Monev --- src/3rdparty/javascriptcore/wtf/DateMath.cpp | 6 ++-- src/core/io/qfilesystemwatcher_unix.cpp | 2 +- src/core/io/qfsfileengine.cpp | 4 +-- src/core/kernel/qcore_unix_p.h | 32 ++++++++++++------- src/core/kernel/qsharedmemory_unix.cpp | 6 ++-- src/core/kernel/qsystemsemaphore_unix.cpp | 4 +-- src/core/tools/qlocale.cpp | 17 +++------- .../socket/qnativesocketengine_unix.cpp | 4 +-- src/network/socket/qnet_unix_p.h | 4 +-- 9 files changed, 41 insertions(+), 38 deletions(-) diff --git a/src/3rdparty/javascriptcore/wtf/DateMath.cpp b/src/3rdparty/javascriptcore/wtf/DateMath.cpp index 40cd66e08..45b88756b 100644 --- a/src/3rdparty/javascriptcore/wtf/DateMath.cpp +++ b/src/3rdparty/javascriptcore/wtf/DateMath.cpp @@ -76,6 +76,8 @@ #include "CurrentTime.h" #include "CallFrame.h" +#include "qcore_unix_p.h" + #include #include #include @@ -522,9 +524,9 @@ static int findMonth(const char* monthStr) static bool parseLong(const char* string, char** stopPosition, int base, long* result) { + Q_RESET_ERRNO *result = strtol(string, stopPosition, base); - // Avoid the use of errno as it is not available on Windows CE - if (string == *stopPosition || *result == LONG_MIN || *result == LONG_MAX) + if (string == *stopPosition || ((*result == LONG_MIN || *result == LONG_MAX) && (errno == ERANGE || errno == EINVAL))) return false; return true; } diff --git a/src/core/io/qfilesystemwatcher_unix.cpp b/src/core/io/qfilesystemwatcher_unix.cpp index f5127c282..16f963a04 100644 --- a/src/core/io/qfilesystemwatcher_unix.cpp +++ b/src/core/io/qfilesystemwatcher_unix.cpp @@ -295,7 +295,7 @@ void QFileSystemWatcherEngineUnix::readFromFd() int r; struct kevent kev; struct timespec ts = { 0, 0 }; // 0 ts, because we want to poll - EINTR_LOOP(r, kevent(sockfd, 0, 0, &kev, 1, &ts)); + Q_EINTR_LOOP(r, kevent(sockfd, 0, 0, &kev, 1, &ts)); if (r < 0) { perror("QFileSystemWatcherEngineUnix: error during kevent wait"); return; diff --git a/src/core/io/qfsfileengine.cpp b/src/core/io/qfsfileengine.cpp index 466e27952..c6c25a4f2 100644 --- a/src/core/io/qfsfileengine.cpp +++ b/src/core/io/qfsfileengine.cpp @@ -181,7 +181,7 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode) // Seek to the end when in Append mode. if (d->openMode & QFile::Append) { int ret; - EINTR_LOOP(ret, QT_LSEEK(d->fd, 0, SEEK_END)); + Q_EINTR_LOOP(ret, QT_LSEEK(d->fd, 0, SEEK_END)); if (ret == -1) { setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno)); @@ -252,7 +252,7 @@ bool QFSFileEngine::open(QIODevice::OpenMode openMode, int fd, QFile::FileHandle // Seek to the end when in Append mode. if (d->openMode & QFile::Append) { int ret; - EINTR_LOOP(ret, QT_LSEEK(d->fd, 0, SEEK_END)); + Q_EINTR_LOOP(ret, QT_LSEEK(d->fd, 0, SEEK_END)); if (ret == -1) { setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno)); diff --git a/src/core/kernel/qcore_unix_p.h b/src/core/kernel/qcore_unix_p.h index b76247a71..4c54b9ca3 100644 --- a/src/core/kernel/qcore_unix_p.h +++ b/src/core/kernel/qcore_unix_p.h @@ -40,11 +40,21 @@ #include #include -#define EINTR_LOOP(var, cmd) \ +#define Q_EINTR_LOOP(var, cmd) \ do { \ var = cmd; \ } while (var == -1 && errno == EINTR) +// BSD and musl libc implementations do not reset errno and there is no +// reliable way to check if some functions (e.g. strtoll()) errored or returned +// a valid value if they do not reset errno +#ifdef __GLIBC__ +# define Q_RESET_ERRNO +#else +# define Q_RESET_ERRNO errno = 0; +#endif + + QT_BEGIN_NAMESPACE // Internal operator functions for timevals @@ -115,7 +125,7 @@ static inline int qt_safe_open(const char *pathname, int flags, mode_t mode = 07 flags |= O_CLOEXEC; #endif int fd; - EINTR_LOOP(fd, QT_OPEN(pathname, flags, mode)); + Q_EINTR_LOOP(fd, QT_OPEN(pathname, flags, mode)); #ifndef O_CLOEXEC // unknown flags are ignored, so we have no way of verifying if @@ -174,7 +184,7 @@ static inline int qt_safe_dup(int oldfd) static inline int qt_safe_dup2(int oldfd, int newfd) { int ret; - EINTR_LOOP(ret, ::dup2(oldfd, newfd)); + Q_EINTR_LOOP(ret, ::dup2(oldfd, newfd)); return ret; } @@ -182,7 +192,7 @@ static inline int qt_safe_dup2(int oldfd, int newfd) static inline qint64 qt_safe_read(int fd, void *data, qint64 maxlen) { qint64 ret = 0; - EINTR_LOOP(ret, QT_READ(fd, data, maxlen)); + Q_EINTR_LOOP(ret, QT_READ(fd, data, maxlen)); return ret; } @@ -190,7 +200,7 @@ static inline qint64 qt_safe_read(int fd, void *data, qint64 maxlen) static inline qint64 qt_safe_write(int fd, const void *data, qint64 len) { qint64 ret = 0; - EINTR_LOOP(ret, QT_WRITE(fd, data, len)); + Q_EINTR_LOOP(ret, QT_WRITE(fd, data, len)); return ret; } @@ -204,7 +214,7 @@ static inline qint64 qt_safe_write_nosignal(int fd, const void *data, qint64 len static inline int qt_safe_creat(const char* path, mode_t flags) { int ret; - EINTR_LOOP(ret, QT_CREAT(path, flags)); + Q_EINTR_LOOP(ret, QT_CREAT(path, flags)); return ret; } @@ -212,7 +222,7 @@ static inline int qt_safe_creat(const char* path, mode_t flags) static inline int qt_safe_close(int fd) { int ret; - EINTR_LOOP(ret, QT_CLOSE(fd)); + Q_EINTR_LOOP(ret, QT_CLOSE(fd)); return ret; } @@ -221,7 +231,7 @@ static inline int qt_safe_execve(const char *filename, char *const argv[], char *const envp[]) { int ret; - EINTR_LOOP(ret, ::execve(filename, argv, envp)); + Q_EINTR_LOOP(ret, ::execve(filename, argv, envp)); return ret; } @@ -229,7 +239,7 @@ static inline int qt_safe_execve(const char *filename, char *const argv[], static inline int qt_safe_execv(const char *path, char *const argv[]) { int ret; - EINTR_LOOP(ret, ::execv(path, argv)); + Q_EINTR_LOOP(ret, ::execv(path, argv)); return ret; } @@ -237,7 +247,7 @@ static inline int qt_safe_execv(const char *path, char *const argv[]) static inline int qt_safe_execvp(const char *file, char *const argv[]) { int ret; - EINTR_LOOP(ret, ::execvp(file, argv)); + Q_EINTR_LOOP(ret, ::execvp(file, argv)); return ret; } @@ -245,7 +255,7 @@ static inline int qt_safe_execvp(const char *file, char *const argv[]) static inline pid_t qt_safe_waitpid(pid_t pid, int *status, int options) { pid_t ret; - EINTR_LOOP(ret, ::waitpid(pid, status, options)); + Q_EINTR_LOOP(ret, ::waitpid(pid, status, options)); return ret; } diff --git a/src/core/kernel/qsharedmemory_unix.cpp b/src/core/kernel/qsharedmemory_unix.cpp index f498f7705..f2a3ea0c7 100644 --- a/src/core/kernel/qsharedmemory_unix.cpp +++ b/src/core/kernel/qsharedmemory_unix.cpp @@ -125,7 +125,7 @@ bool QSharedMemoryPrivate::create(int size) QByteArray shmName = QFile::encodeName(makePlatformSafeKey(key)); int fd; - EINTR_LOOP(fd, ::shm_open(shmName.constData(), O_RDWR | O_CREAT | O_EXCL, 0666)); + Q_EINTR_LOOP(fd, ::shm_open(shmName.constData(), O_RDWR | O_CREAT | O_EXCL, 0666)); if (fd == -1) { QString function = QLatin1String("QSharedMemory::create"); switch (errno) { @@ -142,7 +142,7 @@ bool QSharedMemoryPrivate::create(int size) // the size may only be set once; ignore errors int ret; - EINTR_LOOP(ret, QT_FTRUNCATE(fd, size)); + Q_EINTR_LOOP(ret, QT_FTRUNCATE(fd, size)); if (ret == -1) { setErrorString(QLatin1String("QSharedMemory::create (ftruncate)")); qt_safe_close(fd); @@ -161,7 +161,7 @@ bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode) int oflag = (mode == QSharedMemory::ReadOnly ? O_RDONLY : O_RDWR); mode_t omode = (mode == QSharedMemory::ReadOnly ? 0444 : 0660); - EINTR_LOOP(hand, ::shm_open(shmName.constData(), oflag, omode)); + Q_EINTR_LOOP(hand, ::shm_open(shmName.constData(), oflag, omode)); if (hand == -1) { QString function = QLatin1String("QSharedMemory::attach (shm_open)"); switch (errno) { diff --git a/src/core/kernel/qsystemsemaphore_unix.cpp b/src/core/kernel/qsystemsemaphore_unix.cpp index f30db0a84..475845fa7 100644 --- a/src/core/kernel/qsystemsemaphore_unix.cpp +++ b/src/core/kernel/qsystemsemaphore_unix.cpp @@ -198,7 +198,7 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count) // rollback changes to preserve the SysV semaphore behavior for ( ; cnt < count; ++cnt) { int res; - EINTR_LOOP(res, ::sem_wait(semaphore)); + Q_EINTR_LOOP(res, ::sem_wait(semaphore)); } return false; } @@ -206,7 +206,7 @@ bool QSystemSemaphorePrivate::modifySemaphore(int count) } while (cnt > 0); } else { int res; - EINTR_LOOP(res, ::sem_wait(semaphore)); + Q_EINTR_LOOP(res, ::sem_wait(semaphore)); if (res == -1) { // If the semaphore was removed be nice and create it and then modifySemaphore again if (errno == EINVAL || errno == EIDRM) { diff --git a/src/core/tools/qlocale.cpp b/src/core/tools/qlocale.cpp index a2d2298dd..ea4a07dfb 100644 --- a/src/core/tools/qlocale.cpp +++ b/src/core/tools/qlocale.cpp @@ -34,8 +34,8 @@ #include "qlocale_data_p.h" #include "qdebug.h" #include "qcorecommon_p.h" +#include "qcore_unix_p.h" -#include #include // #define QLOCALE_DEBUG @@ -45,15 +45,6 @@ # define QLOCALEDEBUG if (false) qDebug() #endif -// BSD and musl libc implementations do not reset errno and there is no -// reliable way to check if some functions (e.g. strtoll()) errored or returned -// a valid value if they do not reset errno -#ifdef __GLIBC__ -# define QLOCALE_RESET_ERRNO -#else -# define QLOCALE_RESET_ERRNO errno = 0; -#endif - QT_BEGIN_NAMESPACE static const qint16 systemLocaleIndex = localeTblSize + 1; @@ -2738,7 +2729,7 @@ double QLocalePrivate::bytearrayToDouble(const char *num, bool *ok) } char *endptr; - QLOCALE_RESET_ERRNO + Q_RESET_ERRNO double ret = std::strtod(num, &endptr); if ((ret == 0.0l && errno == ERANGE) || ret == HUGE_VAL || ret == -HUGE_VAL) { if (ok != Q_NULLPTR) @@ -2767,7 +2758,7 @@ qlonglong QLocalePrivate::bytearrayToLongLong(const char *num, int base, bool *o } char *endptr; - QLOCALE_RESET_ERRNO + Q_RESET_ERRNO qlonglong ret = std::strtoll(num, &endptr, base); if ((ret == LLONG_MIN || ret == LLONG_MAX) && (errno == ERANGE || errno == EINVAL)) { if (ok != Q_NULLPTR) @@ -2796,7 +2787,7 @@ qulonglong QLocalePrivate::bytearrayToUnsLongLong(const char *num, int base, boo } char *endptr; - QLOCALE_RESET_ERRNO + Q_RESET_ERRNO qulonglong ret = std::strtoull(num, &endptr, base); if (ret == ULLONG_MAX && (errno == ERANGE || errno == EINVAL)) { if (ok != Q_NULLPTR) diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 282391029..2354247fa 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -735,7 +735,7 @@ bool QNativeSocketEnginePrivate::nativeHasPendingDatagrams() const // well be 0, so we can't check recvfrom's return value. ssize_t readBytes; char c; - EINTR_LOOP(readBytes, ::recvfrom(socketDescriptor, &c, 1, MSG_PEEK, &storage.a, &storageSize)); + Q_EINTR_LOOP(readBytes, ::recvfrom(socketDescriptor, &c, 1, MSG_PEEK, &storage.a, &storageSize)); // If there's no error, or if our buffer was too small, there must be a // pending datagram. @@ -785,7 +785,7 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxS ssize_t recvFromResult = 0; char c; - EINTR_LOOP(recvFromResult, ::recvfrom(socketDescriptor, maxSize ? data : &c, maxSize ? maxSize : 1, + Q_EINTR_LOOP(recvFromResult, ::recvfrom(socketDescriptor, maxSize ? data : &c, maxSize ? maxSize : 1, 0, &aa.a, &sz)); if (recvFromResult == -1) { diff --git a/src/network/socket/qnet_unix_p.h b/src/network/socket/qnet_unix_p.h index c44912a78..949eecb80 100644 --- a/src/network/socket/qnet_unix_p.h +++ b/src/network/socket/qnet_unix_p.h @@ -76,7 +76,7 @@ static inline int qt_safe_connect(int sockfd, const struct sockaddr *addr, QT_SO { int ret; // Solaris e.g. expects a non-const 2nd parameter - EINTR_LOOP(ret, QT_SOCKET_CONNECT(sockfd, const_cast(addr), addrlen)); + Q_EINTR_LOOP(ret, QT_SOCKET_CONNECT(sockfd, const_cast(addr), addrlen)); return ret; } @@ -97,7 +97,7 @@ static inline int qt_safe_sendto(int sockfd, const void *buf, size_t len, int fl #endif int ret; - EINTR_LOOP(ret, ::sendto(sockfd, buf, len, flags, to, tolen)); + Q_EINTR_LOOP(ret, ::sendto(sockfd, buf, len, flags, to, tolen)); return ret; }