This is an automated email from the ASF dual-hosted git repository.

jdanek pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git

commit 077ea99536c82f918cb90f662001a15efa1208c8
Author: Jiri DanÄ›k <[email protected]>
AuthorDate: Wed Apr 19 18:37:21 2023 +0200

    PROTON-2772: add parameter safety annotations for printf format strings
---
 c/include/proton/annotations.h            | 93 +++++++++++++++++++++++++++++++
 c/include/proton/condition.h              |  4 +-
 c/include/proton/connection_driver.h      |  7 ++-
 c/include/proton/cproton.i                |  1 +
 c/include/proton/error.h                  |  4 +-
 c/include/proton/logger.h                 |  4 +-
 c/include/proton/sasl_plugin.h            |  4 +-
 c/include/proton/transport.h              |  4 +-
 c/src/core/engine-internal.h              |  4 +-
 c/src/core/fixed_string.h                 |  5 +-
 c/src/core/log_private.h                  |  4 +-
 c/src/core/logger_private.h               |  7 ++-
 c/src/core/object_private.h               | 15 ++---
 c/src/platform/platform.c                 |  5 +-
 c/src/proactor/win_iocp.cpp               |  7 ++-
 c/src/reactor/io/windows/io.c             |  4 +-
 c/src/reactor/io/windows/iocp.c           |  4 +-
 c/src/reactor/io/windows/write_pipeline.c |  4 +-
 c/src/ssl/openssl.c                       |  7 ++-
 c/src/ssl/schannel.cpp                    |  7 ++-
 c/src/tls/openssl.c                       |  7 ++-
 c/tests/threaderciser.c                   |  4 +-
 c/tools/msgr-common.h                     |  3 +-
 23 files changed, 171 insertions(+), 37 deletions(-)

diff --git a/c/include/proton/annotations.h b/c/include/proton/annotations.h
new file mode 100644
index 000000000..82e3df310
--- /dev/null
+++ b/c/include/proton/annotations.h
@@ -0,0 +1,93 @@
+#ifndef PROTON_ANNOTATIONS_H
+#define PROTON_ANNOTATIONS_H 1
+
+/*
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
+ *
+ * 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.
+ */
+
+/**
+ * @cond INTERNAL
+ *
+ * Compiler specific mechanisms for annotating functions and function 
parameters.
+ *
+ * SAL (MSVC) documentation:
+ *  
https://learn.microsoft.com/en-us/cpp/c-runtime-library/sal-annotations?view=msvc-170
+ *  
https://learn.microsoft.com/en-us/cpp/code-quality/understanding-sal?view=msvc-170&viewFallbackFrom=vs-2019
+ *  
https://learn.microsoft.com/en-us/cpp/code-quality/annotating-function-parameters-and-return-values?view=msvc-170
+ * GCC documentation: 
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
+ * Clang documentation: https://clang.llvm.org/docs/AttributeReference.html
+ * Clang Analyzer documentation: 
https://clang-analyzer.llvm.org/annotations.html
+ *
+ * Example usage for the implemented annotation macros:
+ *
+ * std::string stringPrintf(PN_PRINTF_FORMAT const char* format, ...)
+ *   PN_PRINTF_FORMAT_ATTR(1, 2);
+ *
+ * PN_NODISCARD std::unique_lock<Mutex> make_unique_lock(
+ *   Mutex& mutex, Args&&... args) { ... }
+ *
+ */
+
+// compiler specific attribute translation
+// msvc should come first, so if clang is in msvc mode it gets the right 
defines
+
+// warn format placeholders
+
+// NOTE: this will only do checking in msvc with versions that support /analyze
+#ifdef _MSC_VER
+
+    #include <stddef.h>
+
+    #ifdef _USE_ATTRIBUTES_FOR_SAL
+        #undef _USE_ATTRIBUTES_FOR_SAL
+    #endif
+
+    #define _USE_ATTRIBUTES_FOR_SAL 1
+    #include <sal.h>
+
+    #define PN_PRINTF_FORMAT _Printf_format_string_
+    #define PN_PRINTF_FORMAT_ATTR(format_param, dots_param) /**/
+
+#elif defined(__GNUC__)
+
+    #define PN_PRINTF_FORMAT /**/
+    #define PN_PRINTF_FORMAT_ATTR(format_param, dots_param) \
+      __attribute__((__format__(__printf__, format_param, dots_param)))
+
+#else
+
+    #define PN_PRINTF_FORMAT /**/
+    #define PN_PRINTF_FORMAT_ATTR(format_param, dots_param) /**/
+
+#endif
+
+
+// warn unused result
+#if defined(__has_cpp_attribute)
+    #if __has_cpp_attribute(nodiscard)
+        #define PN_NODISCARD [[nodiscard]]
+    #endif
+#endif
+#if !defined PN_NODISCARD
+    #if defined(_MSC_VER) && (_MSC_VER >= 1700)
+        #define PN_NODISCARD _Check_return_
+    #elif defined(__GNUC__)
+        #define PN_NODISCARD __attribute__((__warn_unused_result__))
+    #else
+        #define PN_NODISCARD
+    #endif
+#endif
+
+#endif /* annotations.h */
diff --git a/c/include/proton/condition.h b/c/include/proton/condition.h
index 8c5cfe31c..d4a62a5fa 100644
--- a/c/include/proton/condition.h
+++ b/c/include/proton/condition.h
@@ -22,6 +22,7 @@
  *
  */
 
+#include <proton/annotations.h>
 #include <proton/import_export.h>
 #include <proton/codec.h>
 #include <proton/type_compat.h>
@@ -139,7 +140,8 @@ PN_EXTERN int pn_condition_vformat(pn_condition_t *, const 
char *name, const cha
 /**
  * Set the name and printf-style formatted description.
  */
-PN_EXTERN int pn_condition_format(pn_condition_t *, const char *name, const 
char *fmt, ...);
+PN_EXTERN int pn_condition_format(pn_condition_t *, const char *name, 
PN_PRINTF_FORMAT const char *fmt, ...)
+        PN_PRINTF_FORMAT_ATTR(3, 4);
 
 /**
  * Returns true if the condition is a redirect.
diff --git a/c/include/proton/connection_driver.h 
b/c/include/proton/connection_driver.h
index bc478bdb8..2a964fc9f 100644
--- a/c/include/proton/connection_driver.h
+++ b/c/include/proton/connection_driver.h
@@ -74,6 +74,7 @@
  * different threads.
  */
 
+#include <proton/annotations.h>
 #include <proton/import_export.h>
 #include <proton/event.h>
 #include <proton/types.h>
@@ -238,7 +239,8 @@ PN_EXTERN bool 
pn_connection_driver_finished(pn_connection_driver_t *);
  * You must call this *before* pn_connection_driver_read_close() or
  * pn_connection_driver_write_close() to ensure the error is processed.
  */
-PN_EXTERN void pn_connection_driver_errorf(pn_connection_driver_t *d, const 
char *name, const char *fmt, ...);
+PN_EXTERN void pn_connection_driver_errorf(pn_connection_driver_t *d, const 
char *name, PN_PRINTF_FORMAT const char *fmt, ...)
+        PN_PRINTF_FORMAT_ATTR(3, 4);
 
 /**
  * Set transport error via a va_list, see pn_connection_driver_errorf()
@@ -265,7 +267,8 @@ PN_EXTERN void 
pn_connection_driver_log(pn_connection_driver_t *d, const char *m
 /**
  * **Deprecated** - Use pn_transport_logf().
  */
-PN_EXTERN void pn_connection_driver_logf(pn_connection_driver_t *d, const char 
*fmt, ...);
+PN_EXTERN void pn_connection_driver_logf(pn_connection_driver_t *d, 
PN_PRINTF_FORMAT const char *fmt, ...)
+        PN_PRINTF_FORMAT_ATTR(2, 3);
 
 /**
  * **Deprecated** - Use pn_transport_vlogf().
diff --git a/c/include/proton/cproton.i b/c/include/proton/cproton.i
index e0cfc0bb0..af109ae66 100644
--- a/c/include/proton/cproton.i
+++ b/c/include/proton/cproton.i
@@ -34,6 +34,7 @@ typedef unsigned long int uintptr_t;
 
 /* Parse these interface header files to generate APIs for script languages */
 
+%include "proton/annotations.h"
 %include "proton/import_export.h"
 
 %ignore _PROTON_VERSION_H;
diff --git a/c/include/proton/error.h b/c/include/proton/error.h
index 5bb603a56..dfebd09fd 100644
--- a/c/include/proton/error.h
+++ b/c/include/proton/error.h
@@ -22,6 +22,7 @@
  *
  */
 
+#include <proton/annotations.h>
 #include <proton/import_export.h>
 #include <stdarg.h>
 
@@ -92,7 +93,8 @@ PN_EXTERN int pn_error_vformat(pn_error_t *error, int code, 
const char *fmt, va_
  * Set the code and set the text using a printf-style formatted
  * string.
  */
-PN_EXTERN int pn_error_format(pn_error_t *error, int code, const char *fmt, 
...);
+PN_EXTERN int pn_error_format(pn_error_t *error, int code, PN_PRINTF_FORMAT 
const char *fmt, ...)
+        PN_PRINTF_FORMAT_ATTR(3, 4);
 
 /**
  * Get the the error code.
diff --git a/c/include/proton/logger.h b/c/include/proton/logger.h
index f5ce9147c..3633723c3 100644
--- a/c/include/proton/logger.h
+++ b/c/include/proton/logger.h
@@ -28,6 +28,7 @@
  * @ingroup core
  */
 
+#include <proton/annotations.h>
 #include <proton/import_export.h>
 
 #include <stdarg.h>
@@ -231,7 +232,8 @@ PN_EXTERN intptr_t 
pn_logger_get_log_sink_context(pn_logger_t *logger);
  * @param[in] level the log level of the log message
  * @param[in] fmt the printf formatted message to be logged
  */
-PN_EXTERN void pn_logger_logf(pn_logger_t *logger, pn_log_subsystem_t 
subsystem, pn_log_level_t level, const char *fmt, ...);
+PN_EXTERN void pn_logger_logf(pn_logger_t *logger, pn_log_subsystem_t 
subsystem, pn_log_level_t level, PN_PRINTF_FORMAT const char *fmt, ...)
+        PN_PRINTF_FORMAT_ATTR(4, 5);
 
 #ifdef __cplusplus
 }
diff --git a/c/include/proton/sasl_plugin.h b/c/include/proton/sasl_plugin.h
index c6b6015cc..5f8f6f045 100644
--- a/c/include/proton/sasl_plugin.h
+++ b/c/include/proton/sasl_plugin.h
@@ -22,6 +22,7 @@
  *
  */
 
+#include <proton/annotations.h>
 #include <proton/import_export.h>
 #include <proton/logger.h>
 #include <proton/type_compat.h>
@@ -108,7 +109,8 @@ enum pnx_sasl_state {
 };
 
 /* APIs used by sasl implementations */
-PN_EXTERN void  pnx_sasl_logf(pn_transport_t *transport, pn_log_level_t level, 
const char *format, ...);
+PN_EXTERN void  pnx_sasl_logf(pn_transport_t *transport, pn_log_level_t level, 
PN_PRINTF_FORMAT const char *format, ...)
+        PN_PRINTF_FORMAT_ATTR(3, 4);
 PN_EXTERN void  pnx_sasl_error(pn_transport_t *transport, const char* err, 
const char* condition_name);
 
 PN_EXTERN void *pnx_sasl_get_context(pn_transport_t *transport);
diff --git a/c/include/proton/transport.h b/c/include/proton/transport.h
index d7693e074..8b8b66403 100644
--- a/c/include/proton/transport.h
+++ b/c/include/proton/transport.h
@@ -22,6 +22,7 @@
  *
  */
 
+#include <proton/annotations.h>
 #include <proton/import_export.h>
 #include <proton/type_compat.h>
 #include <proton/condition.h>
@@ -370,7 +371,8 @@ PN_EXTERN void pn_transport_vlogf(pn_transport_t 
*transport, const char *fmt, va
  *
  * @internal XXX Deprecate when logging is made independent
  */
-PN_EXTERN void pn_transport_logf(pn_transport_t *transport, const char *fmt, 
...);
+PN_EXTERN void pn_transport_logf(pn_transport_t *transport, PN_PRINTF_FORMAT 
const char *fmt, ...)
+        PN_PRINTF_FORMAT_ATTR(2, 3);
 
 /**
  * Get the maximum allowed channel for a transport.
diff --git a/c/src/core/engine-internal.h b/c/src/core/engine-internal.h
index 69f8a8293..9f43036b6 100644
--- a/c/src/core/engine-internal.h
+++ b/c/src/core/engine-internal.h
@@ -22,6 +22,7 @@
  *
  */
 
+#include <proton/annotations.h>
 #include <proton/object.h>
 #include <proton/engine.h>
 #include <proton/types.h>
@@ -370,7 +371,8 @@ void pn_work_update(pn_connection_t *connection, 
pn_delivery_t *delivery);
 void pn_clear_modified(pn_connection_t *connection, pn_endpoint_t *endpoint);
 void pn_connection_bound(pn_connection_t *conn);
 void pn_connection_unbound(pn_connection_t *conn);
-int pn_do_error(pn_transport_t *transport, const char *condition, const char 
*fmt, ...);
+int pn_do_error(pn_transport_t *transport, const char *condition, 
PN_PRINTF_FORMAT const char *fmt, ...)
+        PN_PRINTF_FORMAT_ATTR(3, 4);
 void pn_set_error_layer(pn_transport_t *transport);
 void pn_session_unbound(pn_session_t* ssn);
 void pn_link_unbound(pn_link_t* link);
diff --git a/c/src/core/fixed_string.h b/c/src/core/fixed_string.h
index e60c3102a..27d23c7e8 100644
--- a/c/src/core/fixed_string.h
+++ b/c/src/core/fixed_string.h
@@ -24,6 +24,8 @@
 
 #include "util.h"
 
+#include <proton/annotations.h>
+
 #include <stdarg.h>
 #include <stdio.h>
 #include <string.h>
@@ -68,7 +70,8 @@ static inline void pn_fixed_string_vaddf(pn_fixed_string_t 
*str, const char *for
   str->position += pn_min((uint32_t)out_size, bytes_left);
 }
 
-static inline void pn_fixed_string_addf(pn_fixed_string_t *str, const char 
*format, ...) {
+PN_PRINTF_FORMAT_ATTR(2, 3)
+static inline void pn_fixed_string_addf(pn_fixed_string_t *str, 
PN_PRINTF_FORMAT const char *format, ...) {
   va_list ap;
   va_start(ap, format);
   pn_fixed_string_vaddf(str, format, ap);
diff --git a/c/src/core/log_private.h b/c/src/core/log_private.h
index 80f30028d..a673a6941 100644
--- a/c/src/core/log_private.h
+++ b/c/src/core/log_private.h
@@ -24,6 +24,7 @@
  * Log messages that are not associated with a transport.
  */
 
+#include <proton/annotations.h>
 #include <proton/log.h>
 #include <stdarg.h>
 
@@ -45,7 +46,8 @@
 PN_EXTERN bool pni_log_enabled(void);
 
 /**@internal*/
-PN_EXTERN void pni_logf_impl(const char* fmt, ...);
+PN_EXTERN void pni_logf_impl(PN_PRINTF_FORMAT const char* fmt, ...)
+        PN_PRINTF_FORMAT_ATTR(1, 2);
 /**@internal*/
 PN_EXTERN void pni_vlogf_impl(const char *fmt, va_list ap);
 
diff --git a/c/src/core/logger_private.h b/c/src/core/logger_private.h
index 98a9b1e8a..d1974073e 100644
--- a/c/src/core/logger_private.h
+++ b/c/src/core/logger_private.h
@@ -21,6 +21,7 @@
 
 #include "buffer.h"
 
+#include <proton/annotations.h>
 #include "proton/logger.h"
 
 #if __cplusplus
@@ -44,8 +45,10 @@ void pni_logger_log(pn_logger_t *logger, pn_log_subsystem_t 
subsystem, pn_log_le
 void pni_logger_vlogf(pn_logger_t *logger, pn_log_subsystem_t subsystem, 
pn_log_level_t severity, const char *fmt, va_list ap);
 void pni_logger_log_data(pn_logger_t *logger, pn_log_subsystem_t subsystem, 
pn_log_level_t severity, const char *msg, const char *bytes, size_t size);
 void pni_logger_log_raw(pn_logger_t *logger, pn_log_subsystem_t subsystem, 
pn_log_level_t severity, pn_bytes_t bytes, size_t size, const char* msg);
-void pni_logger_log_msg_inspect(pn_logger_t *logger, pn_log_subsystem_t 
subsystem, pn_log_level_t severity, void *object, const char *fmt, ...);
-void pni_logger_log_msg_frame(pn_logger_t *logger, pn_log_subsystem_t 
subsystem, pn_log_level_t severity, pn_bytes_t frame, const char *fmt, ...);
+void pni_logger_log_msg_inspect(pn_logger_t *logger, pn_log_subsystem_t 
subsystem, pn_log_level_t severity, void *object, PN_PRINTF_FORMAT const char 
*fmt, ...)
+        PN_PRINTF_FORMAT_ATTR(5, 6);
+void pni_logger_log_msg_frame(pn_logger_t *logger, pn_log_subsystem_t 
subsystem, pn_log_level_t severity, pn_bytes_t frame, PN_PRINTF_FORMAT const 
char *fmt, ...)
+        PN_PRINTF_FORMAT_ATTR(5, 6);
 
 #define PN_SHOULD_LOG(logger, subsys, sev) \
     (((sev) & PN_LEVEL_CRITICAL) || (((logger)->sub_mask & (subsys)) && 
((logger)->sev_mask & (sev))))
diff --git a/c/src/core/object_private.h b/c/src/core/object_private.h
index c6864625e..cdf883f46 100644
--- a/c/src/core/object_private.h
+++ b/c/src/core/object_private.h
@@ -24,6 +24,7 @@
 
 #include "proton/object.h"
 
+#include <proton/annotations.h>
 #include <proton/types.h>
 #include <stdarg.h>
 #include <proton/type_compat.h>
@@ -184,17 +185,11 @@ PN_EXTERN int pn_string_set(pn_string_t *string, const 
char *bytes);
 PN_EXTERN int pn_string_setn(pn_string_t *string, const char *bytes, size_t n);
 ssize_t pn_string_put(pn_string_t *string, char *dst);
 void pn_string_clear(pn_string_t *string);
-PN_EXTERN int pn_string_format(pn_string_t *string, const char *format, ...)
-#ifdef __GNUC__
-  __attribute__ ((format (printf, 2, 3)))
-#endif
-    ;
+PN_EXTERN int pn_string_format(pn_string_t *string, PN_PRINTF_FORMAT const 
char *format, ...)
+        PN_PRINTF_FORMAT_ATTR(2, 3);
 int pn_string_vformat(pn_string_t *string, const char *format, va_list ap);
-PN_EXTERN int pn_string_addf(pn_string_t *string, const char *format, ...)
-#ifdef __GNUC__
-__attribute__ ((format (printf, 2, 3)))
-#endif
-;
+PN_EXTERN int pn_string_addf(pn_string_t *string, PN_PRINTF_FORMAT const char 
*format, ...)
+        PN_PRINTF_FORMAT_ATTR(2, 3);
 int pn_string_vaddf(pn_string_t *string, const char *format, va_list ap);
 int pn_string_grow(pn_string_t *string, size_t capacity);
 char *pn_string_buffer(pn_string_t *string);
diff --git a/c/src/platform/platform.c b/c/src/platform/platform.c
index 105fdc081..deba7d64e 100644
--- a/c/src/platform/platform.c
+++ b/c/src/platform/platform.c
@@ -21,6 +21,8 @@
 
 #include "platform.h"
 
+#include <proton/annotations.h>
+
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -43,7 +45,8 @@ void pni_vfatal(const char *fmt, va_list ap)
   abort();
 }
 
-void pni_fatal(const char *fmt, ...)
+PN_PRINTF_FORMAT_ATTR(1, 2)
+void pni_fatal(PN_PRINTF_FORMAT const char *fmt, ...)
 {
   va_list ap;
   va_start(ap, fmt);
diff --git a/c/src/proactor/win_iocp.cpp b/c/src/proactor/win_iocp.cpp
index 1c245e1e4..c71cd76d0 100644
--- a/c/src/proactor/win_iocp.cpp
+++ b/c/src/proactor/win_iocp.cpp
@@ -19,6 +19,7 @@
  *
  */
 
+#include <proton/annotations.h>
 #include <proton/condition.h>
 #include <proton/connection_driver.h>
 #include <proton/engine.h>
@@ -243,7 +244,8 @@ namespace pn_experimental {
 // Write buffer size
 #define IOCP_WBUFSIZE 16384
 
-static void pipeline_log(const char *fmt, ...)
+PN_PRINTF_FORMAT_ATTR(1, 2)
+static void pipeline_log(PN_PRINTF_FORMAT const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
@@ -532,7 +534,8 @@ size_t pni_write_pipeline_size(write_pipeline_t *pl)
 
 namespace pn_experimental {
 
-static void iocp_log(const char *fmt, ...)
+PN_PRINTF_FORMAT_ATTR(1, 2)
+static void iocp_log(PN_PRINTF_FORMAT const char *fmt, ...)
 {
   va_list ap;
   va_start(ap, fmt);
diff --git a/c/src/reactor/io/windows/io.c b/c/src/reactor/io/windows/io.c
index d7d6f291e..79b4ed749 100644
--- a/c/src/reactor/io/windows/io.c
+++ b/c/src/reactor/io/windows/io.c
@@ -37,6 +37,7 @@
 #include "iocp.h"
 #include "core/util.h"
 
+#include <proton/annotations.h>
 #include <proton/object.h>
 
 #include <ctype.h>
@@ -53,7 +54,8 @@ int pni_win32_error(pn_error_t *error, const char *msg, 
HRESULT code)
   return pn_error_format(error, PN_ERR, "%s: %s", msg, err);
 }
 
-static void io_log(const char *fmt, ...)
+PN_PRINTF_FORMAT_ATTR(1, 2)
+static void io_log(PN_PRINTF_FORMAT const char *fmt, ...)
 {
   va_list ap;
   va_start(ap, fmt);
diff --git a/c/src/reactor/io/windows/iocp.c b/c/src/reactor/io/windows/iocp.c
index d247e2983..ff7f70ff3 100644
--- a/c/src/reactor/io/windows/iocp.c
+++ b/c/src/reactor/io/windows/iocp.c
@@ -36,6 +36,7 @@
 #include "platform/platform.h"
 #include "core/util.h"
 
+#include <proton/annotations.h>
 #include <proton/error.h>
 #include <proton/transport.h>
 
@@ -68,7 +69,8 @@
 #define IOCP_SOCKADDRMAXLEN (sizeof(struct sockaddr_in6) + 16)
 #define IOCP_SOCKADDRBUFLEN (2 * IOCP_SOCKADDRMAXLEN)
 
-static void iocp_log(const char *fmt, ...)
+PN_PRINTF_FORMAT_ATTR(1, 2)
+static void iocp_log(PN_PRINTF_FORMAT const char *fmt, ...)
 {
   va_list ap;
   va_start(ap, fmt);
diff --git a/c/src/reactor/io/windows/write_pipeline.c 
b/c/src/reactor/io/windows/write_pipeline.c
index ffe5c20bf..2a7ecf88c 100644
--- a/c/src/reactor/io/windows/write_pipeline.c
+++ b/c/src/reactor/io/windows/write_pipeline.c
@@ -43,6 +43,7 @@
 #include "iocp.h"
 #include "core/util.h"
 
+#include <proton/annotations.h>
 #include <proton/error.h>
 #include <proton/object.h>
 
@@ -53,7 +54,8 @@
 // Write buffer size
 #define IOCP_WBUFSIZE 16384
 
-static void pipeline_log(const char *fmt, ...)
+PN_PRINTF_FORMAT_ATTR(1, 2)
+static void pipeline_log(PN_PRINTF_FORMAT const char *fmt, ...)
 {
     va_list ap;
     va_start(ap, fmt);
diff --git a/c/src/ssl/openssl.c b/c/src/ssl/openssl.c
index 41965dcd6..8e1b15a81 100644
--- a/c/src/ssl/openssl.c
+++ b/c/src/ssl/openssl.c
@@ -26,6 +26,7 @@
 #include "core/util.h"
 #include "core/util_str.h"
 
+#include <proton/annotations.h>
 #include <proton/ssl.h>
 #include <proton/engine.h>
 
@@ -159,7 +160,8 @@ static void ssl_vlog(pn_transport_t *transport, 
pn_log_level_t sev, const char *
   }
 }
 
-static void ssl_log(pn_transport_t *transport, pn_log_level_t sev, const char 
*fmt, ...)
+PN_PRINTF_FORMAT_ATTR(3, 4)
+static void ssl_log(pn_transport_t *transport, pn_log_level_t sev, 
PN_PRINTF_FORMAT const char *fmt, ...)
 {
   va_list ap;
   va_start(ap, fmt);
@@ -179,7 +181,8 @@ static void ssl_log_flush(pn_transport_t* transport, 
pn_log_level_t sev)
 }
 
 // log an error and dump the SSL error stack
-static void ssl_log_error(const char *fmt, ...)
+PN_PRINTF_FORMAT_ATTR(1, 2)
+static void ssl_log_error(PN_PRINTF_FORMAT const char *fmt, ...)
 {
   if (fmt) {
     va_list ap;
diff --git a/c/src/ssl/schannel.cpp b/c/src/ssl/schannel.cpp
index de1a182fb..4793775eb 100644
--- a/c/src/ssl/schannel.cpp
+++ b/c/src/ssl/schannel.cpp
@@ -39,6 +39,7 @@
 
 #include "platform/platform.h"
 
+#include <proton/annotations.h>
 #include <proton/ssl.h>
 #include <proton/engine.h>
 
@@ -61,9 +62,9 @@ extern "C" {
  * This file contains an SChannel-based implemention of the SSL/TLS API for 
Windows platforms.
  */
 
-static void ssl_log(pn_transport_t *transport, pn_log_level_t sev, const char 
*fmt, ...);
-static void ssl_log_error(const char *fmt, ...);
-static void ssl_log_error_status(HRESULT status, const char *fmt, ...);
+static void ssl_log(pn_transport_t *transport, pn_log_level_t sev, 
PN_PRINTF_FORMAT const char *fmt, ...) PN_PRINTF_FORMAT_ATTR(3, 4);
+static void ssl_log_error(PN_PRINTF_FORMAT const char *fmt, ...) 
PN_PRINTF_FORMAT_ATTR(1, 2);
+static void ssl_log_error_status(HRESULT status, PN_PRINTF_FORMAT const char 
*fmt, ...) PN_PRINTF_FORMAT_ATTR(2, 3);
 static HCERTSTORE open_cert_db(const char *store_name, const char *passwd, int 
*error);
 
 // Thread support.  Some SChannel objects are shared or ref-counted.
diff --git a/c/src/tls/openssl.c b/c/src/tls/openssl.c
index 0c3b6bd66..4ba457d13 100644
--- a/c/src/tls/openssl.c
+++ b/c/src/tls/openssl.c
@@ -30,6 +30,7 @@
 #include "platform/platform.h"
 #include "platform/platform_fmt.h"
 #include "core/util.h"
+#include <proton/annotations.h>
 #include <proton/error.h>
 #include <proton/tls.h>
 
@@ -500,7 +501,8 @@ static X509 *get_peer_certificate(pn_tls_t *ssl);
 #define     PN_LEVEL_RAW       128
 #define     PN_LEVEL_ALL       65535
 
-static void ssl_log(void *v, int sev, const char *fmt, ...)
+PN_PRINTF_FORMAT_ATTR(3, 4)
+static void ssl_log(void *v, int sev, PN_PRINTF_FORMAT const char *fmt, ...)
 {
 #ifdef at_least_some_logging
   va_list ap;
@@ -521,7 +523,8 @@ static void ssl_log_flush(void *v, int sev)
   }
 }
 // log an error and dump the SSL error stack
-static void ssl_log_error(const char *fmt, ...)
+PN_PRINTF_FORMAT_ATTR(1, 2)
+static void ssl_log_error(PN_PRINTF_FORMAT const char *fmt, ...)
 {
 }
 
diff --git a/c/tests/threaderciser.c b/c/tests/threaderciser.c
index f787bda6c..f51e01934 100644
--- a/c/tests/threaderciser.c
+++ b/c/tests/threaderciser.c
@@ -51,6 +51,7 @@
 
 #include "thread.h"
 
+#include <proton/annotations.h>
 #include <proton/connection.h>
 #include <proton/event.h>
 #include <proton/listener.h>
@@ -90,7 +91,8 @@ static bool debug_enable = false;
 */
 #define debug(...) if (debug_enable) debug_impl(__VA_ARGS__)
 
-static void debug_impl(const char *fmt, ...) {
+PN_PRINTF_FORMAT_ATTR(1, 2)
+static void debug_impl(PN_PRINTF_FORMAT const char *fmt, ...) {
   /* Collect thread-id and message in a single buffer to minimize mixed 
messages */
   char msg[256];
   char *i = msg;
diff --git a/c/tools/msgr-common.h b/c/tools/msgr-common.h
index 6fefce7ae..aecade41b 100644
--- a/c/tools/msgr-common.h
+++ b/c/tools/msgr-common.h
@@ -22,6 +22,7 @@
 
 #include <inttypes.h>
 
+#include "proton/annotations.h"
 #include "proton/types.h"
 #include "proton/message.h"
 
@@ -66,5 +67,5 @@ void statistics_msg_received( Statistics_t *s, pn_message_t 
*message );
 void statistics_report( Statistics_t *s, uint64_t sent, uint64_t received );
 
 void enable_logging(void);
-void LOG( const char *fmt, ... );
+void LOG( PN_PRINTF_FORMAT const char *fmt, ... ) PN_PRINTF_FORMAT_ATTR(1, 2);
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to