Adding -Wformat-nonliteral check (#12763)
* Turn on -Wformat-security and -Wformat-nonliteral.
The ENFORCE_FORMAT annotations help make it clear to the compiler
which seemingly-nonliteral values are actually checked to be literals
further up the callstack, because we disallow passing a non-literal as
the format arg indicated by ENFORCE_FORMAT.
* Address review comments
Co-authored-by: Boris Zbarsky <bzbarsky@apple.com>
diff --git a/.github/workflows/examples-esp32.yaml b/.github/workflows/examples-esp32.yaml
index 023d1b2..54298cf 100644
--- a/.github/workflows/examples-esp32.yaml
+++ b/.github/workflows/examples-esp32.yaml
@@ -26,7 +26,7 @@
# TODO ESP32 https://github.com/project-chip/connectedhomeip/issues/1510
esp32:
name: ESP32
- timeout-minutes: 85
+ timeout-minutes: 95
runs-on: ubuntu-latest
if: github.actor != 'restyled-io[bot]'
@@ -60,7 +60,7 @@
.environment/gn_out/.ninja_log
.environment/pigweed-venv/*.log
- name: Build some M5Stack variations
- timeout-minutes: 20
+ timeout-minutes: 30
run: |
./scripts/run_in_build_env.sh \
"./scripts/build/build_examples.py \
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 81fb08c..9df167b 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -202,6 +202,9 @@
"-Wshadow",
"-Wunreachable-code",
"-Wvla",
+ "-Wformat",
+ "-Wformat-nonliteral",
+ "-Wformat-security",
]
cflags_cc = [ "-Wnon-virtual-dtor" ]
diff --git a/config/ameba/chip.cmake b/config/ameba/chip.cmake
index 9d39d92..b7986d5 100644
--- a/config/ameba/chip.cmake
+++ b/config/ameba/chip.cmake
@@ -42,6 +42,8 @@
-Wno-unused-parameter
-Wno-format
-Wno-stringop-truncation
+ -Wno-format-nonliteral
+ -Wno-format-security
-std=c++17
)
diff --git a/examples/all-clusters-app/esp32/CMakeLists.txt b/examples/all-clusters-app/esp32/CMakeLists.txt
index 9685eac..3753bdd 100644
--- a/examples/all-clusters-app/esp32/CMakeLists.txt
+++ b/examples/all-clusters-app/esp32/CMakeLists.txt
@@ -34,6 +34,9 @@
project(chip-all-clusters-app)
idf_build_set_property(CXX_COMPILE_OPTIONS "-std=gnu++17;-Os;-DLWIP_IPV6_SCOPES=0;-DCHIP_HAVE_CONFIG_H" APPEND)
idf_build_set_property(C_COMPILE_OPTIONS "-Os;-DLWIP_IPV6_SCOPES=0" APPEND)
+# For the C3, project_include.cmake sets -Wno-format, but does not clear various
+# flags that depend on -Wformat
+idf_build_set_property(COMPILE_OPTIONS "-Wno-format-nonliteral;-Wno-format-security" APPEND)
flashing_script()
diff --git a/examples/platform/telink/util/src/ThreadUtil.cpp b/examples/platform/telink/util/src/ThreadUtil.cpp
index c501cd9..bbe95d8 100644
--- a/examples/platform/telink/util/src/ThreadUtil.cpp
+++ b/examples/platform/telink/util/src/ThreadUtil.cpp
@@ -51,7 +51,7 @@
chip::DeviceLayer::ThreadStackMgr().SetThreadEnabled(true);
}
-void tlOtPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char * aFormat, ...)
+void ENFORCE_FORMAT(3, 4) tlOtPlatLog(otLogLevel aLogLevel, otLogRegion aLogRegion, const char * aFormat, ...)
{
va_list args;
diff --git a/src/app/MessageDef/MessageDefHelper.cpp b/src/app/MessageDef/MessageDefHelper.cpp
index a8f6c33..f57feed 100644
--- a/src/app/MessageDef/MessageDefHelper.cpp
+++ b/src/app/MessageDef/MessageDefHelper.cpp
@@ -41,7 +41,7 @@
size_t gCurLineBufferSize = 0;
} // namespace
-void PrettyPrintIM(bool aIsNewLine, const char * aFmt, ...)
+void ENFORCE_FORMAT(2, 3) PrettyPrintIM(bool aIsNewLine, const char * aFmt, ...)
{
va_list args;
size_t ret;
diff --git a/src/app/tests/TestEventLogging.cpp b/src/app/tests/TestEventLogging.cpp
index 016df16..97f152e 100644
--- a/src/app/tests/TestEventLogging.cpp
+++ b/src/app/tests/TestEventLogging.cpp
@@ -32,8 +32,10 @@
#include <lib/core/CHIPTLV.h>
#include <lib/core/CHIPTLVDebug.hpp>
#include <lib/core/CHIPTLVUtilities.hpp>
+#include <lib/support/EnforceFormat.h>
#include <lib/support/ErrorStr.h>
#include <lib/support/UnitTestRegistration.h>
+#include <lib/support/logging/Constants.h>
#include <messaging/ExchangeContext.h>
#include <messaging/Flags.h>
#include <platform/CHIPDeviceLayer.h>
@@ -89,7 +91,7 @@
}
};
-void SimpleDumpWriter(const char * aFormat, ...)
+void ENFORCE_FORMAT(1, 2) SimpleDumpWriter(const char * aFormat, ...)
{
va_list args;
diff --git a/src/app/tests/TestMessageDef.cpp b/src/app/tests/TestMessageDef.cpp
index 9451e20..95c3cd5 100644
--- a/src/app/tests/TestMessageDef.cpp
+++ b/src/app/tests/TestMessageDef.cpp
@@ -37,7 +37,9 @@
#include <lib/core/CHIPError.h>
#include <lib/core/CHIPTLVDebug.hpp>
#include <lib/support/CHIPMem.h>
+#include <lib/support/EnforceFormat.h>
#include <lib/support/UnitTestRegistration.h>
+#include <lib/support/logging/Constants.h>
#include <system/TLVPacketBufferBackingStore.h>
#include <nlunit-test.h>
@@ -46,7 +48,7 @@
using namespace chip::app;
-void TLVPrettyPrinter(const char * aFormat, ...)
+void ENFORCE_FORMAT(1, 2) TLVPrettyPrinter(const char * aFormat, ...)
{
va_list args;
diff --git a/src/app/tests/integration/common.cpp b/src/app/tests/integration/common.cpp
index d0ad7da..d898928 100644
--- a/src/app/tests/integration/common.cpp
+++ b/src/app/tests/integration/common.cpp
@@ -27,7 +27,9 @@
#include <app/tests/integration/common.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/CHIPTLVDebug.hpp>
+#include <lib/support/EnforceFormat.h>
#include <lib/support/ErrorStr.h>
+#include <lib/support/logging/Constants.h>
#include <platform/CHIPDeviceLayer.h>
chip::Messaging::ExchangeManager gExchangeManager;
@@ -65,7 +67,7 @@
chip::DeviceLayer::PlatformMgr().Shutdown();
}
-void TLVPrettyPrinter(const char * aFormat, ...)
+void ENFORCE_FORMAT(1, 2) TLVPrettyPrinter(const char * aFormat, ...)
{
va_list args;
diff --git a/src/app/util/ember-print.cpp b/src/app/util/ember-print.cpp
index 3f21c53..51326ca 100644
--- a/src/app/util/ember-print.cpp
+++ b/src/app/util/ember-print.cpp
@@ -76,7 +76,14 @@
const uint32_t outStringEnd = segmentLength * perByteCharCount;
for (uint32_t dst_idx = 0; dst_idx < outStringEnd && index < segmentEnd; dst_idx += perByteCharCount, index++)
{
+ // The perByteFormatStr is in fact a literal (one of two), but
+ // the compiler does not realize that. We could branch on
+ // perByteFormatStr and have separate snprintf calls, but this
+ // seems like it might lead to smaller code.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
snprintf(result + dst_idx, outStringEnd - dst_idx + 1, perByteFormatStr, buffer[index]);
+#pragma GCC diagnostic pop
}
result[outStringEnd] = 0;
emberAfPrint(category, "%s", result);
diff --git a/src/controller/python/chip/logging/LoggingRedirect.cpp b/src/controller/python/chip/logging/LoggingRedirect.cpp
index e66f663..c290fa3 100644
--- a/src/controller/python/chip/logging/LoggingRedirect.cpp
+++ b/src/controller/python/chip/logging/LoggingRedirect.cpp
@@ -26,7 +26,7 @@
PythonLogCallback sPythonLogCallback;
-void NativeLoggingCallback(const char * module, uint8_t category, const char * msg, va_list args)
+void ENFORCE_FORMAT(3, 0) NativeLoggingCallback(const char * module, uint8_t category, const char * msg, va_list args)
{
if (sPythonLogCallback == nullptr)
{
diff --git a/src/darwin/Framework/CHIP.xcodeproj/project.pbxproj b/src/darwin/Framework/CHIP.xcodeproj/project.pbxproj
index 312dd83..00dd58d 100644
--- a/src/darwin/Framework/CHIP.xcodeproj/project.pbxproj
+++ b/src/darwin/Framework/CHIP.xcodeproj/project.pbxproj
@@ -663,6 +663,11 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
LIBRARY_SEARCH_PATHS = "$(TEMP_DIR)/out/lib";
+ OTHER_CFLAGS = (
+ "-Wformat",
+ "-Wformat-nonliteral",
+ "-Wformat-security",
+ );
OTHER_LDFLAGS = "";
"OTHER_LDFLAGS[sdk=*]" = (
"-framework",
@@ -800,6 +805,11 @@
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
LIBRARY_SEARCH_PATHS = "$(TEMP_DIR)/out/lib";
+ OTHER_CFLAGS = (
+ "-Wformat",
+ "-Wformat-nonliteral",
+ "-Wformat-security",
+ );
OTHER_LDFLAGS = "";
"OTHER_LDFLAGS[arch=*]" = (
"-lnetwork",
diff --git a/src/lib/core/CHIPTLV.h b/src/lib/core/CHIPTLV.h
index 1410493..9f3947c 100644
--- a/src/lib/core/CHIPTLV.h
+++ b/src/lib/core/CHIPTLV.h
@@ -33,9 +33,11 @@
#include <lib/support/BitFlags.h>
#include <lib/support/DLLUtil.h>
+#include <lib/support/EnforceFormat.h>
#include <lib/support/ScopedBuffer.h>
#include <lib/support/Span.h>
#include <lib/support/TypeTraits.h>
+#include <lib/support/logging/Constants.h>
#include <stdarg.h>
#include <stdlib.h>
@@ -1614,7 +1616,9 @@
* `WriteElementHead` or `GetNewBuffer` -- failed, their
* error is immediately forwarded up the call stack.
*/
- CHIP_ERROR PutStringF(Tag tag, const char * fmt, ...);
+ // The ENFORCE_FORMAT args are "off by one" because this is a class method,
+ // with an implicit "this" as first arg.
+ CHIP_ERROR PutStringF(Tag tag, const char * fmt, ...) ENFORCE_FORMAT(3, 4);
/**
* @brief
@@ -1660,7 +1664,9 @@
* `WriteElementHead` or `GetNewBuffer` -- failed, their
* error is immediately forwarded up the call stack.
*/
- CHIP_ERROR VPutStringF(Tag tag, const char * fmt, va_list ap);
+ // The ENFORCE_FORMAT args are "off by one" because this is a class method,
+ // with an implicit "this" as first arg.
+ CHIP_ERROR VPutStringF(Tag tag, const char * fmt, va_list ap) ENFORCE_FORMAT(3, 0);
/**
* Encodes a TLV null value.
diff --git a/src/lib/core/tests/TestCHIPTLV.cpp b/src/lib/core/tests/TestCHIPTLV.cpp
index 112a721..3cc0800 100644
--- a/src/lib/core/tests/TestCHIPTLV.cpp
+++ b/src/lib/core/tests/TestCHIPTLV.cpp
@@ -38,6 +38,7 @@
#include <lib/support/ScopedBuffer.h>
#include <lib/support/UnitTestRegistration.h>
#include <lib/support/UnitTestUtils.h>
+#include <lib/support/logging/Constants.h>
#include <system/TLVPacketBufferBackingStore.h>
@@ -1632,7 +1633,7 @@
* to the format specifiers in @a aFormat.
*
*/
-void SimpleDumpWriter(const char * aFormat, ...)
+void ENFORCE_FORMAT(1, 2) SimpleDumpWriter(const char * aFormat, ...)
{
va_list args;
diff --git a/src/lib/dnssd/Discovery_ImplPlatform.cpp b/src/lib/dnssd/Discovery_ImplPlatform.cpp
index ca32481..916bf27 100644
--- a/src/lib/dnssd/Discovery_ImplPlatform.cpp
+++ b/src/lib/dnssd/Discovery_ImplPlatform.cpp
@@ -174,7 +174,8 @@
return AddPtrRecord(type, entries, entriesCount, buffer, bufferLen, value.Value());
}
-CHIP_ERROR CopyTextRecordValue(char * buffer, size_t bufferLen, int minCharactersWritten, const char * format, ...)
+CHIP_ERROR ENFORCE_FORMAT(4, 5)
+ CopyTextRecordValue(char * buffer, size_t bufferLen, int minCharactersWritten, const char * format, ...)
{
va_list args;
va_start(args, format);
diff --git a/src/lib/shell/streamer.cpp b/src/lib/shell/streamer.cpp
index 4bb11eb..852688e 100644
--- a/src/lib/shell/streamer.cpp
+++ b/src/lib/shell/streamer.cpp
@@ -23,6 +23,8 @@
#include "streamer.h"
+#include <lib/support/EnforceFormat.h>
+#include <lib/support/logging/Constants.h>
#include <limits.h>
#include <stdio.h>
@@ -48,7 +50,7 @@
return self->write_cb(self, buf, len);
}
-ssize_t streamer_vprintf(streamer_t * self, const char * fmt, va_list ap)
+ssize_t ENFORCE_FORMAT(2, 0) streamer_vprintf(streamer_t * self, const char * fmt, va_list ap)
{
char buf[CONSOLE_DEFAULT_MAX_LINE];
unsigned len;
@@ -64,7 +66,7 @@
return streamer_write(self, buf, len);
}
-ssize_t streamer_printf(streamer_t * self, const char * fmt, ...)
+ssize_t ENFORCE_FORMAT(2, 3) streamer_printf(streamer_t * self, const char * fmt, ...)
{
va_list ap;
ssize_t rc;
diff --git a/src/lib/support/BUILD.gn b/src/lib/support/BUILD.gn
index fe8c92d..39b83c3 100644
--- a/src/lib/support/BUILD.gn
+++ b/src/lib/support/BUILD.gn
@@ -40,6 +40,10 @@
sources = [ "logging/Constants.h" ]
}
+source_set("enforce_format") {
+ sources = [ "EnforceFormat.h" ]
+}
+
source_set("chip_version_header") {
sources = get_target_outputs(":gen_chip_version")
@@ -131,6 +135,7 @@
public_deps = [
":chip_version_header",
+ ":enforce_format",
":logging_constants",
"${chip_root}/src/lib/core:chip_config_header",
"${chip_root}/src/platform:platform_buildconfig",
diff --git a/src/lib/support/CHIPArgParser.cpp b/src/lib/support/CHIPArgParser.cpp
index a4384ba..6fd0858 100644
--- a/src/lib/support/CHIPArgParser.cpp
+++ b/src/lib/support/CHIPArgParser.cpp
@@ -48,6 +48,8 @@
#include <lib/support/CHIPMem.h>
#include <lib/support/CHIPMemString.h>
+#include <lib/support/EnforceFormat.h>
+#include <lib/support/logging/Constants.h>
/*
* TODO: Revisit these if and when fabric ID and node ID support has
@@ -622,7 +624,7 @@
* Applications should call through the PrintArgError function pointer, rather
* than calling this function directly.
*/
-void DefaultPrintArgError(const char * msg, ...)
+void ENFORCE_FORMAT(1, 2) DefaultPrintArgError(const char * msg, ...)
{
va_list ap;
diff --git a/src/lib/support/DefaultStorageKeyAllocator.h b/src/lib/support/DefaultStorageKeyAllocator.h
index 4a8ada7..c469f04 100644
--- a/src/lib/support/DefaultStorageKeyAllocator.h
+++ b/src/lib/support/DefaultStorageKeyAllocator.h
@@ -17,6 +17,8 @@
#pragma once
#include <app/util/basic-types.h>
+#include <lib/support/EnforceFormat.h>
+#include <lib/support/logging/Constants.h>
#include <string.h>
namespace chip {
@@ -48,7 +50,9 @@
private:
static const size_t kKeyLengthMax = 32;
- const char * Format(const char * format...)
+ // The ENFORCE_FORMAT args are "off by one" because this is a class method,
+ // with an implicit "this" as first arg.
+ const char * ENFORCE_FORMAT(2, 3) Format(const char * format, ...)
{
va_list args;
va_start(args, format);
diff --git a/src/lib/support/EnforceFormat.h b/src/lib/support/EnforceFormat.h
new file mode 100644
index 0000000..7d8f681
--- /dev/null
+++ b/src/lib/support/EnforceFormat.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022 Project CHIP Authors
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+/**
+ * gcc and clang provide a way to warn for a custom formatter when formats don't
+ * match arguments. Use that so we catch mistakes. The "format"
+ * attribute takes the type of format, which arg is the format string, and which
+ * arg is the first variadic arg, with both arg numbers 1-based.
+ *
+ * The second arg should be set to 0 if the function takes a va_list instead of
+ * varargs.
+ */
+
+#if defined(__GNUC__)
+#define ENFORCE_FORMAT(n, m) __attribute__((format(printf, n, m)))
+#else // __GNUC__
+#define ENFORCE_FORMAT(n, m) /* How to do with MSVC? */
+#endif // __GNUC__
diff --git a/src/lib/support/logging/CHIPLogging.h b/src/lib/support/logging/CHIPLogging.h
index 8dfffd2..fa48aa4 100644
--- a/src/lib/support/logging/CHIPLogging.h
+++ b/src/lib/support/logging/CHIPLogging.h
@@ -39,6 +39,7 @@
#include <platform/logging/LogV.h>
+#include <lib/support/EnforceFormat.h>
#include <lib/support/logging/Constants.h>
#include <inttypes.h>
@@ -79,20 +80,7 @@
void SetLogRedirectCallback(LogRedirectCallback_t callback);
-/**
- * gcc and clang provide a way to warn for a custom formatter when formats don't
- * match arguments. Use that for Log() so we catch mistakes. The "format"
- * attribute takes the type of format, which arg is the format string, and which
- * arg is the first variadic arg, with both arg numbers 1-based.
- */
-
-#if defined(__GNUC__)
-#define ENFORCE_FORMAT(n, m) __attribute__((format(printf, n, m)))
-#else // __GNUC__
-#define ENFORCE_FORMAT(n, m) /* How to do with MSVC? */
-#endif // __GNUC__
-
-void LogV(uint8_t module, uint8_t category, const char * msg, va_list args);
+void LogV(uint8_t module, uint8_t category, const char * msg, va_list args) ENFORCE_FORMAT(3, 0);
void Log(uint8_t module, uint8_t category, const char * msg, ...) ENFORCE_FORMAT(3, 4);
void LogByteSpan(uint8_t module, uint8_t category, const ByteSpan & span);
diff --git a/src/lib/support/tests/TestCHIPArgParser.cpp b/src/lib/support/tests/TestCHIPArgParser.cpp
index 128b5d7..4ba1f9f 100644
--- a/src/lib/support/tests/TestCHIPArgParser.cpp
+++ b/src/lib/support/tests/TestCHIPArgParser.cpp
@@ -26,8 +26,10 @@
#include <lib/support/CHIPArgParser.hpp>
#include <lib/support/CHIPMem.h>
#include <lib/support/CHIPMemString.h>
+#include <lib/support/EnforceFormat.h>
#include <lib/support/ScopedBuffer.h>
#include <lib/support/UnitTestRegistration.h>
+#include <lib/support/logging/Constants.h>
#if CHIP_CONFIG_ENABLE_ARG_PARSER
@@ -730,7 +732,7 @@
return true;
}
-static void HandleArgError(const char * msg, ...)
+static void ENFORCE_FORMAT(1, 2) HandleArgError(const char * msg, ...)
{
size_t msgLen;
int status;
diff --git a/src/platform/Darwin/Logging.cpp b/src/platform/Darwin/Logging.cpp
index 180ec87..8e25d6a 100644
--- a/src/platform/Darwin/Logging.cpp
+++ b/src/platform/Darwin/Logging.cpp
@@ -1,10 +1,10 @@
/* See Project chip LICENSE file for licensing information. */
+#include <lib/support/EnforceFormat.h>
#include <lib/support/logging/Constants.h>
#include <platform/logging/LogV.h>
#include <lib/core/CHIPConfig.h>
-#include <lib/support/logging/Constants.h>
#include <os/log.h>
@@ -19,7 +19,7 @@
namespace Logging {
namespace Platform {
-void LogV(const char * module, uint8_t category, const char * msg, va_list v)
+void ENFORCE_FORMAT(3, 0) LogV(const char * module, uint8_t category, const char * msg, va_list v)
{
timeval time;
gettimeofday(&time, NULL);
diff --git a/src/platform/ESP32/Logging.cpp b/src/platform/ESP32/Logging.cpp
index a6f7aca..ee22dc4 100644
--- a/src/platform/ESP32/Logging.cpp
+++ b/src/platform/ESP32/Logging.cpp
@@ -3,6 +3,7 @@
#include <platform/logging/LogV.h>
#include <lib/core/CHIPConfig.h>
+#include <lib/support/EnforceFormat.h>
#include <lib/support/logging/Constants.h>
#include <stdio.h>
@@ -18,7 +19,7 @@
namespace Logging {
namespace Platform {
-void LogV(const char * module, uint8_t category, const char * msg, va_list v)
+void ENFORCE_FORMAT(3, 0) LogV(const char * module, uint8_t category, const char * msg, va_list v)
{
char tag[11];
diff --git a/src/platform/Linux/Logging.cpp b/src/platform/Linux/Logging.cpp
index b5a15f5..5f8aeb5 100644
--- a/src/platform/Linux/Logging.cpp
+++ b/src/platform/Linux/Logging.cpp
@@ -1,5 +1,7 @@
/* See Project CHIP LICENSE file for licensing information. */
+#include <lib/support/EnforceFormat.h>
+#include <lib/support/logging/Constants.h>
#include <platform/logging/LogV.h>
#include <cinttypes>
@@ -27,7 +29,7 @@
/**
* CHIP log output functions.
*/
-void LogV(const char * module, uint8_t category, const char * msg, va_list v)
+void ENFORCE_FORMAT(3, 0) LogV(const char * module, uint8_t category, const char * msg, va_list v)
{
struct timeval tv;
diff --git a/src/platform/Tizen/Logging.cpp b/src/platform/Tizen/Logging.cpp
index 7c8865f..4c5c8b8 100644
--- a/src/platform/Tizen/Logging.cpp
+++ b/src/platform/Tizen/Logging.cpp
@@ -18,6 +18,7 @@
#include <platform/logging/LogV.h>
#include <lib/core/CHIPConfig.h>
+#include <lib/support/EnforceFormat.h>
#include <lib/support/logging/Constants.h>
#include <dlog.h>
@@ -30,7 +31,7 @@
/**
* CHIP log output functions.
*/
-void LogV(const char * module, uint8_t category, const char * msg, va_list v)
+void ENFORCE_FORMAT(3, 0) LogV(const char * module, uint8_t category, const char * msg, va_list v)
{
constexpr const char * kLogTag = "CHIP";
char msgBuf[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE] = {
diff --git a/src/platform/Zephyr/Logging.cpp b/src/platform/Zephyr/Logging.cpp
index 017ed0f..5fb3b98 100644
--- a/src/platform/Zephyr/Logging.cpp
+++ b/src/platform/Zephyr/Logging.cpp
@@ -3,6 +3,7 @@
#include <platform/logging/LogV.h>
#include <lib/core/CHIPConfig.h>
+#include <lib/support/EnforceFormat.h>
#include <lib/support/logging/Constants.h>
#include <kernel.h>
@@ -40,7 +41,7 @@
* CHIP log output function.
*/
-void LogV(const char * module, uint8_t category, const char * msg, va_list v)
+void ENFORCE_FORMAT(3, 0) LogV(const char * module, uint8_t category, const char * msg, va_list v)
{
char formattedMsg[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE];
snprintfcb(formattedMsg, sizeof(formattedMsg), "[%s]", module);
diff --git a/src/platform/logging/BUILD.gn b/src/platform/logging/BUILD.gn
index bfece14..038f942 100644
--- a/src/platform/logging/BUILD.gn
+++ b/src/platform/logging/BUILD.gn
@@ -16,6 +16,7 @@
deps = [
":headers",
"${chip_root}/src/lib/core:chip_config_header",
+ "${chip_root}/src/lib/support:enforce_format",
"${chip_root}/src/lib/support:logging_constants",
"${chip_root}/src/platform:platform_buildconfig",
]
@@ -30,6 +31,7 @@
deps = [
":headers",
"${chip_root}/src/lib/core:chip_config_header",
+ "${chip_root}/src/lib/support:enforce_format",
"${chip_root}/src/lib/support:logging_constants",
"${chip_root}/src/platform:platform_buildconfig",
]
diff --git a/src/platform/logging/LogV.h b/src/platform/logging/LogV.h
index 5b961b7..5bff38f 100644
--- a/src/platform/logging/LogV.h
+++ b/src/platform/logging/LogV.h
@@ -2,6 +2,7 @@
#pragma once
+#include <lib/support/EnforceFormat.h>
#include <stdarg.h>
#include <stdint.h>
@@ -27,7 +28,7 @@
* correspond to the format specifiers in @a msg.
*
*/
-void LogV(const char * module, uint8_t category, const char * msg, va_list v);
+void ENFORCE_FORMAT(3, 0) LogV(const char * module, uint8_t category, const char * msg, va_list v);
} // namespace Platform
} // namespace Logging
diff --git a/src/platform/logging/impl/android/Logging.cpp b/src/platform/logging/impl/android/Logging.cpp
index fcfc397..fc64331 100644
--- a/src/platform/logging/impl/android/Logging.cpp
+++ b/src/platform/logging/impl/android/Logging.cpp
@@ -1,5 +1,6 @@
/* See Project chip LICENSE file for licensing information. */
+#include <lib/support/EnforceFormat.h>
#include <lib/support/logging/Constants.h>
#include <platform/logging/LogV.h>
@@ -9,7 +10,7 @@
namespace Logging {
namespace Platform {
-void LogV(const char * module, uint8_t category, const char * msg, va_list v)
+void ENFORCE_FORMAT(3, 0) LogV(const char * module, uint8_t category, const char * msg, va_list v)
{
int priority = (category == kLogCategory_Error) ? ANDROID_LOG_ERROR : ANDROID_LOG_DEBUG;
__android_log_vprint(priority, module, msg, v);
diff --git a/src/platform/logging/impl/stdio/Logging.cpp b/src/platform/logging/impl/stdio/Logging.cpp
index 95d2093..6eceebb 100644
--- a/src/platform/logging/impl/stdio/Logging.cpp
+++ b/src/platform/logging/impl/stdio/Logging.cpp
@@ -1,5 +1,7 @@
/* See Project CHIP LICENSE file for licensing information. */
+#include <lib/support/EnforceFormat.h>
+#include <lib/support/logging/Constants.h>
#include <platform/logging/LogV.h>
#include <stdio.h>
@@ -8,7 +10,7 @@
namespace Logging {
namespace Platform {
-void LogV(const char * module, uint8_t category, const char * msg, va_list v)
+void ENFORCE_FORMAT(3, 0) LogV(const char * module, uint8_t category, const char * msg, va_list v)
{
printf("CHIP:%s: ", module);
vprintf(msg, v);
diff --git a/src/platform/mbed/Logging.cpp b/src/platform/mbed/Logging.cpp
index 0da70e4..3061585 100644
--- a/src/platform/mbed/Logging.cpp
+++ b/src/platform/mbed/Logging.cpp
@@ -22,6 +22,7 @@
*/
#include <lib/core/CHIPConfig.h>
+#include <lib/support/EnforceFormat.h>
#include <lib/support/logging/CHIPLogging.h>
#include <lib/support/logging/Constants.h>
#include <platform/logging/LogV.h>
@@ -65,7 +66,7 @@
/**
* CHIP log output functions.
*/
-void LogV(const char * module, uint8_t category, const char * msg, va_list v)
+void ENFORCE_FORMAT(3, 0) LogV(const char * module, uint8_t category, const char * msg, va_list v)
{
size_t prefixLen = 0;
snprintf(logMsgBuffer, sizeof(logMsgBuffer), "[%s]", module);
diff --git a/src/platform/nxp/k32w/k32w0/Logging.cpp b/src/platform/nxp/k32w/k32w0/Logging.cpp
index bf5bc98..69db581 100644
--- a/src/platform/nxp/k32w/k32w0/Logging.cpp
+++ b/src/platform/nxp/k32w/k32w0/Logging.cpp
@@ -3,6 +3,7 @@
#include <platform/logging/LogV.h>
#include <lib/core/CHIPConfig.h>
+#include <lib/support/EnforceFormat.h>
#include <lib/support/logging/Constants.h>
#include <platform/CHIPDeviceConfig.h>
#include <src/lib/support/CodeUtils.h>
@@ -96,7 +97,7 @@
} // namespace DeviceLayer
} // namespace chip
-void GenericLog(const char * format, va_list arg, const char * module, uint8_t category)
+void ENFORCE_FORMAT(1, 0) GenericLog(const char * format, va_list arg, const char * module, uint8_t category)
{
#if K32W_LOG_ENABLED
@@ -135,7 +136,7 @@
/**
* CHIP log output function.
*/
-void LogV(const char * module, uint8_t category, const char * msg, va_list v)
+void ENFORCE_FORMAT(3, 0) LogV(const char * module, uint8_t category, const char * msg, va_list v)
{
(void) module;
(void) category;
diff --git a/src/platform/qpg/Logging.cpp b/src/platform/qpg/Logging.cpp
index f5f346e..b9fb6b4 100644
--- a/src/platform/qpg/Logging.cpp
+++ b/src/platform/qpg/Logging.cpp
@@ -5,6 +5,7 @@
#include <lib/core/CHIPConfig.h>
#include <lib/support/CHIPPlatformMemory.h>
+#include <lib/support/EnforceFormat.h>
#include <lib/support/logging/Constants.h>
#include <platform/CHIPDeviceConfig.h>
@@ -42,7 +43,7 @@
* CHIP log output function.
*/
-void LogV(const char * module, uint8_t category, const char * msg, va_list v)
+void ENFORCE_FORMAT(3, 0) LogV(const char * module, uint8_t category, const char * msg, va_list v)
{
char formattedMsg[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE];
size_t prefixLen;
diff --git a/third_party/mbedtls/mbedtls.gni b/third_party/mbedtls/mbedtls.gni
index bea9519..9bde362 100644
--- a/third_party/mbedtls/mbedtls.gni
+++ b/third_party/mbedtls/mbedtls.gni
@@ -24,6 +24,7 @@
"-Wno-maybe-uninitialized",
"-Wno-string-concatenation",
"-Wno-unused-but-set-parameter",
+ "-Wno-format-nonliteral", # Because of mbedtls_debug_print_msg
]
}