Cleanup: log a fatal error instead of dereferencing a null
pointer after a first/next cursor initialization failure.
Fedor Vorobev. File: util/dict_db.c.
+
+20260507
+
+ Fix for 'uninitialized value' error. Viktor Dukhovni. File:
+ auxiliary/collate/collate.pl.
+
+20260508
+
+ Claude AI finding: signed integer overshift (util/vstring.h).
+ Brought to our attention by Robert Sayre.
+
+20260513
+
+ Bitrot: builds with musl libc were using the obsolete
+ NO_SNPRINTF code path in vbuf_print.c. File: util/sys_defs.h.
+
+20260514
+
+ Bitrot: the obsolete NO_SNPRINTF code path in vbuf_print.c
+ wasn't updated for Claude Code findings. File: util/vbuf_print.c.
+
+20250515
+
+ Portability: The __MAXINT__(T) macro, to determine the
+ maximal signed value for objects of type T, was using
+ implementation-defined behavior (shift one bit into the
+ sign position). This works today but may break later.
+ Reported by Kamil Frankowicz. File: util/sys_defs.h.
if (defined($transaction{$qid})) {
$transaction{$qid} .= $_;
}
- $transaction{$newid} =
- $_ . $transaction{$newid};
+ $transaction{$newid} = $_ . ($transaction{$newid} // "");
$seqno{$newid} = ++$i if (! exists $seqno{$newid});
}
next;
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20260501"
-#define MAIL_VERSION_NUMBER "3.10.9"
+#define MAIL_RELEASE_DATE "20260515"
+#define MAIL_VERSION_NUMBER "3.10.10"
#ifdef SNAPSHOT
#define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE
#if HAVE_GLIBC_API_VERSION_SUPPORT(2, 1)
#define SOCKADDR_SIZE socklen_t
#define SOCKOPT_SIZE socklen_t
-#else
-#define NO_SNPRINTF
#endif
#ifndef NO_IPV6
#define HAS_IPV6
/*
* Bit banging!! There is no official constant that defines the INT_MAX
- * equivalent for off_t, ssize_t, etc. Wietse came up with the following
- * macro that works as long as off_t, ssize_t, etc. use one's or two's
- * complement logic (that is, the maximum value is binary 01...1). Don't use
- * right-shift for signed types: the result is implementation-defined.
+ * equivalent for off_t, ssize_t, etc. Decades ago, Wietse came up with a
+ * macro that worked on one's or two's complement logic (that is, the
+ * maximum value is binary 01...1). As Kamil Frankowicz pointed out, that
+ * code relied on shifting into the sign bit, which is not defined in the
+ * language standard. The current version still works on one's and two's
+ * complement logic, but avoids the undefined behavior.
*/
#include <limits.h>
-#define __MAXINT__(T) ((T) ~(((T) 1) << ((sizeof(T) * CHAR_BIT) - 1)))
+#define __MAXINT__(T) ((((T) 1 << (sizeof(T) * CHAR_BIT - 2)) - 1) * 2 + 1)
#ifndef OFF_T_MAX
#define OFF_T_MAX __MAXINT__(off_t)
#endif
VBUF_SKIP(bp); \
} while (0)
#else
-#define VBUF_SNPRINTF(bp, sz, fmt, arg) do { \
- if (VBUF_SPACE((bp), (sz)) != 0) \
+#define VBUF_SNPRINTF(bp, width_or_prec, type_space, fmt, arg) do { \
+ if ((width_or_prec) > INT_MAX - (type_space)) \
+ msg_panic("vbuf_print: field width (%d + %lu) > INT_MAX", \
+ (width_or_prec), (unsigned long) (type_space)); \
+ if (VBUF_SPACE((bp), (width_or_prec) + (type_space)) != 0) \
return (bp); \
sprintf((char *) (bp)->ptr, (fmt), (arg)); \
VBUF_SKIP(bp); \
/* Flags 24..31 are reserved for VSTRING. */
#define VSTRING_FLAG_EXACT (1<<24) /* exact allocation for tests */
-#define VSTRING_FLAG_MASK (255 << 24)
+#define VSTRING_FLAG_MASK (255U << 24)
/*
* Macros. Unsafe macros have UPPERCASE names.