Revision control

++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
++ // Qt-Security score:critical reason:data-parser
++
++ #include "qplatformdefs.h"
++
++ #include "qbytearray.h"
++ #include "qstring.h"
++
++ #include <cerrno>
++ #include <QtCore/q26numeric.h>
++
++ #include "string.h"
++
++ QT_BEGIN_NAMESPACE
++
++ /*!
++ \macro QT_NO_QSNPRINTF
++ \since 6.8
++ \relates QByteArray
++
++ Defining this macro removes the availability of the qsnprintf() and
++ qvsnprintf() functions. See the functions' documentation for why you may
++ want to disable them.
++
++ \sa qsnprintf(), qvsnprintf().
++ */
++
++ #if QT_DEPRECATED_SINCE(6, 9)
++
++ #if !defined(QT_VSNPRINTF) || defined(Q_QDOC)
++
++ /*!
++ \fn int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap)
++ \relates QByteArray
++
++ \deprecated [6.9] Use C++11's \c{std::vsnprintf()} from \c{<cstdio>} instead.
++
++ A portable \c vsnprintf() function. Will call \c ::vsnprintf(), \c
++ ::_vsnprintf(), or \c ::vsnprintf_s depending on the system, or
++ fall back to an internal version.
++
++ \a fmt is the \c printf() format string. The result is put into
++ \a str, which is a buffer of at least \a n bytes.
++
++ The caller is responsible to call \c va_end() on \a ap.
++
++ \warning Since vsnprintf() shows different behavior on certain
++ platforms, you should not rely on the return value or on the fact
++ that you will always get a 0 terminated string back. There are also
++ differences in how \c{%a} (hex floats) and \c{%ls} (wide strings) are
++ handled on WebAssembly and Android.
++
++ Ideally, you should never call this function but use QString::asprintf()
++ instead.
++
++ \sa qsnprintf(), QString::asprintf()
++ */
++
++ Q_CORE_EXPORT // QT_NO_QSNPRINTF is in effect
++ int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap)
++ {
++ if (!str || !fmt)
++ return -1;
++
++ const QByteArray ba = QString::vasprintf(fmt, ap).toLocal8Bit();
++
++ const auto realSize = ba.size();
++ int result;
++ if constexpr (sizeof(int) != sizeof(realSize)) {
++ result = q26::saturating_cast<int>(realSize);
++ if (result != realSize) {
++ errno = EOVERFLOW;
++ return -1;
++ }
++ } else {
++ result = realSize;
++ }
++
++ if (n > 0) {
++ size_t blen = (std::min)(size_t(realSize), n - 1);
++ memcpy(str, ba.constData(), blen);
++ str[blen] = '\0'; // make sure str is always 0 terminated
++ }
++
++ return result;
++ }
++
++ #else
++
++ QT_BEGIN_INCLUDE_NAMESPACE
++ #include <stdio.h>
++ QT_END_INCLUDE_NAMESPACE
++
++ Q_CORE_EXPORT // QT_NO_QSNPRINTF is in effect
++ int qvsnprintf(char *str, size_t n, const char *fmt, va_list ap)
++ {
++ return QT_VSNPRINTF(str, n, fmt, ap);
++ }
++
++ #endif
++
++ /*!
++ \fn int qsnprintf(char *str, size_t n, const char *fmt, ...)
++ \target bytearray-qsnprintf
++ \relates QByteArray
++
++ \deprecated [6.9] Use C++11's \c{std::snprintf()} from \c{<cstdio>} instead.
++
++ A portable snprintf() function, calls qvsnprintf.
++
++ \a fmt is the \c printf() format string. The result is put into
++ \a str, which is a buffer of at least \a n bytes.
++
++ \warning Call this function only when you know what you are doing
++ since it shows different behavior on certain platforms.
++ Use QString::asprintf() to format a string instead.
++
++ \sa qvsnprintf(), QString::asprintf()
++ */
++
++ Q_CORE_EXPORT // QT_NO_QSNPRINTF is in effect
++ int qsnprintf(char *str, size_t n, const char *fmt, ...)
++ {
++ va_list ap;
++ va_start(ap, fmt);
++
++ QT_IGNORE_DEPRECATIONS(
++ int ret = qvsnprintf(str, n, fmt, ap);
++ )
++ va_end(ap);
++
++ return ret;
++ }
++
++ #endif // QT_DEPRECATED_SINCE(6, 9)
++
++ QT_END_NAMESPACE