Skip to content

Commit b6749bf

Browse files
ThisIsFineTMkelson42
authored andcommitted
Fix #954. safe_memcmp in tinystring.
UBSan was complaining about std::memcmp being called with nullptr arguments even when the count == 0. This adds a "safe" wrapper that will just return 0 if the count is 0 or if either of the pointers are nullptr.
1 parent 1ca271c commit b6749bf

File tree

2 files changed

+17
-3
lines changed

2 files changed

+17
-3
lines changed

src/tools.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#ifndef OPENZIM_LIBZIM_TOOLS_H
2323
#define OPENZIM_LIBZIM_TOOLS_H
2424

25+
#include <cstddef> // size_t
26+
#include <cstring> // memcmp
2527
#include <string>
2628
#include <tuple>
2729
#include <map>
@@ -71,6 +73,17 @@ namespace zim {
7173
return count;
7274
}
7375

76+
// Work around for errors reported by too picky UB sanitizer tools on std::memcmp()
77+
// being called with a nullptr pointer argument even though count==0. Explicit
78+
// nullptr checks to satisfy other picky compilers.
79+
template <typename T>
80+
int safe_memcmp(T const *const lhs, T const *const rhs, std::size_t count) noexcept {
81+
if(count == 0UL || lhs == nullptr || rhs == nullptr) {
82+
return 0;
83+
}
84+
return std::memcmp(lhs, rhs, count);
85+
}
86+
7487
namespace writer {
7588
class Dirent;
7689
bool isFrontArticle(const Dirent* dirent, const Hints& hints);

src/writer/tinyString.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#ifndef ZIM_WRITER_TINYSTRING_H
2121
#define ZIM_WRITER_TINYSTRING_H
2222

23+
#include "../tools.h"
2324
#include "../zim_types.h"
2425
#include <cstring>
2526

@@ -66,11 +67,11 @@ namespace zim
6667
size_t size() const { return m_size; }
6768
const char* const data() const { return m_data; }
6869
bool operator==(const TinyString& other) const {
69-
return (m_size == other.m_size) && (std::memcmp(m_data, other.m_data, m_size) == 0);
70+
return (m_size == other.m_size) && (safe_memcmp(m_data, other.m_data, m_size) == 0);
7071
}
7172
bool operator<(const TinyString& other) const {
72-
auto min_size = std::min(m_size, other.m_size);
73-
auto ret = std::memcmp(m_data, other.m_data, min_size);
73+
const auto min_size = std::min(m_size, other.m_size);
74+
const auto ret = safe_memcmp(m_data, other.m_data, min_size);
7475
if (ret == 0) {
7576
return m_size < other.m_size;
7677
} else {

0 commit comments

Comments
 (0)