[Git][debian-gis-team/protozero][upstream] New upstream version 1.8.1

Bas Couwenberg (@sebastic) gitlab at salsa.debian.org
Wed Jul 16 11:47:47 BST 2025



Bas Couwenberg pushed to branch upstream at Debian GIS Project / protozero


Commits:
a01158b4 by Bas Couwenberg at 2025-07-16T12:32:09+02:00
New upstream version 1.8.1
- - - - -


12 changed files:

- .github/actions/install-ubuntu/action.yml
- .github/workflows/ci.yml
- CHANGELOG.md
- CMakeLists.txt
- FUZZING.md
- doc/CMakeLists.txt
- include/protozero/pbf_reader.hpp
- include/protozero/version.hpp
- test/t/bool/reader_test_cases.cpp
- test/unit/test_data_view.cpp
- tools/pbf-decoder.cpp
- + tools/pbf-fuzzer.cpp


Changes:

=====================================
.github/actions/install-ubuntu/action.yml
=====================================
@@ -7,6 +7,8 @@ runs:
       run: |
         sudo apt-get update -qq
         sudo apt-get install -yq \
+            doxygen \
+            graphviz \
             libprotobuf-dev \
             protobuf-compiler
       shell: bash


=====================================
.github/workflows/ci.yml
=====================================
@@ -51,6 +51,7 @@ jobs:
           - image: "debian:bookworm"
             c_compiler: clang
             cpp_compiler: clang++
+            cpp_version: 17
             data_view: std::string_view
           - image: "debian:testing"
             c_compiler: clang
@@ -136,7 +137,7 @@ jobs:
       CXX: clang++
       BUILD_TYPE: ${{ matrix.build_type }}
     steps:
-      - run: brew install protobuf
+      - run: brew install doxygen graphviz protobuf
       - uses: actions/checkout at v4
       - uses: ./.github/actions/cmake
       - uses: ./.github/actions/build
@@ -149,8 +150,8 @@ jobs:
       fail-fast: false
       matrix:
         os:
-          - windows-2019
           - windows-2022
+          - windows-2025
     steps:
       - run: |
           vcpkg install \


=====================================
CHANGELOG.md
=====================================
@@ -14,7 +14,15 @@ This project adheres to [Semantic Versioning](https://semver.org/).
 ### Fixed
 
 
-## [1.8.0] - 2024-01-13
+## [1.8.1] - 2025-07-15
+
+### Fixed
+
+- Fix buffer overrun in `get_bool()`
+- Fix test that checks that protozero also works with `std::string_view`
+
+
+## [1.8.0] - 2025-01-13
 
 ### Changed
 


=====================================
CMakeLists.txt
=====================================
@@ -10,7 +10,7 @@ cmake_minimum_required(VERSION 3.10.0 FATAL_ERROR)
 
 #-----------------------------------------------------------------------------
 
-project(protozero VERSION 1.8.0 LANGUAGES CXX C)
+project(protozero VERSION 1.8.1 LANGUAGES CXX C)
 
 set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
 
@@ -40,9 +40,13 @@ endif()
 
 include_directories("${CMAKE_SOURCE_DIR}/include")
 
+# Used for testing
 set(PROTOZERO_DATA_VIEW "" CACHE STRING "Type used for protozero::data_view")
 if(NOT PROTOZERO_DATA_VIEW STREQUAL "")
-    add_definitions(-DPROTOZERO_DATA_VIEW=${PROTOZERO_DATA_VIEW})
+    message(STATUS "Using ${PROTOZERO_DATA_VIEW} as data_view")
+    add_definitions(-DPROTOZERO_USE_VIEW=${PROTOZERO_DATA_VIEW})
+else()
+    message(STATUS "Using built-in data_view")
 endif()
 
 


=====================================
FUZZING.md
=====================================
@@ -18,5 +18,16 @@ Then do the actual fuzzing:
 
 See the AFL documentation for more information.
 
+For increased speed, you can also use the dedicated pbf-fuzzer tool, which skips reading
+data from files or stdin:
+
+    clang++ -O2 -std=c++17 -g -DNDEBUG -Iinclude -fsanitize=address,fuzzer tools/pbf-fuzzer.cpp -o tools/pbf-fuzzer
+    ./tools/pbf-fuzzer
+
+or using AFL++
+
+    afl-clang-fast++ -O2 -std=c++17 -g -DNDEBUG -Iinclude -fsanitize=address,fuzzer tools/pbf-fuzzer.cpp -o tools/pbf-fuzzer
+    afl-fuzz -i testcase_dir -o findings_dir -- tools/pbf-fuzzer
+
 This only checkes the reading side of Protozero!
 


=====================================
doc/CMakeLists.txt
=====================================
@@ -11,7 +11,7 @@ message(STATUS "Configuring documentation")
 message(STATUS "Looking for doxygen")
 find_package(Doxygen)
 
-if(DOXYGEN_FOUND)
+if(DOXYGEN_FOUND AND DOXYGEN_DOT_FOUND)
     message(STATUS "Looking for doxygen - found")
     configure_file(Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
 


=====================================
include/protozero/pbf_reader.hpp
=====================================
@@ -494,9 +494,9 @@ public:
     bool get_bool() {
         protozero_assert(tag() != 0 && "call next() before accessing field value");
         protozero_assert(has_wire_type(pbf_wire_type::varint) && "not a varint");
-        const bool result = m_data[0] != 0;
+        const char* value = m_data;
         skip_varint(&m_data, m_end);
-        return result;
+        return *value != 0;
     }
 
     /**


=====================================
include/protozero/version.hpp
=====================================
@@ -23,12 +23,12 @@ documentation.
 #define PROTOZERO_VERSION_MINOR 8
 
 /// The patch number
-#define PROTOZERO_VERSION_PATCH 0
+#define PROTOZERO_VERSION_PATCH 1
 
 /// The complete version number
 #define PROTOZERO_VERSION_CODE (PROTOZERO_VERSION_MAJOR * 10000 + PROTOZERO_VERSION_MINOR * 100 + PROTOZERO_VERSION_PATCH)
 
 /// Version number as string
-#define PROTOZERO_VERSION_STRING "1.8.0"
+#define PROTOZERO_VERSION_STRING "1.8.1"
 
 #endif // PROTOZERO_VERSION_HPP


=====================================
test/t/bool/reader_test_cases.cpp
=====================================
@@ -139,3 +139,11 @@ TEST_CASE("write bool field using moved pbf_builder") {
     }
 }
 
+TEST_CASE("read bool from using pbf_reader: truncated message") {
+    std::vector<char> buffer = { 0x08 };
+
+    protozero::pbf_reader item{buffer.data(), buffer.size()};
+
+    REQUIRE(item.next());
+    REQUIRE_THROWS_AS(item.get_bool(), protozero::end_of_buffer_exception);
+}


=====================================
test/unit/test_data_view.cpp
=====================================
@@ -53,7 +53,9 @@ TEST_CASE("convert data_view to std::string") {
     const std::string s = std::string(view);
     REQUIRE(s == "foobar");
     REQUIRE(std::string(view) == "foobar");
+#ifndef PROTOZERO_USE_VIEW
     REQUIRE(view.to_string() == "foobar");
+#endif
 }
 
 #ifndef PROTOZERO_USE_VIEW
@@ -69,14 +71,14 @@ TEST_CASE("swapping data_view") {
     protozero::data_view view1{"foo"};
     protozero::data_view view2{"bar"};
 
-    REQUIRE(view1.to_string() == "foo");
-    REQUIRE(view2.to_string() == "bar");
+    REQUIRE(std::string(view1) == "foo");
+    REQUIRE(std::string(view2) == "bar");
 
     using std::swap;
     swap(view1, view2);
 
-    REQUIRE(view2.to_string() == "foo");
-    REQUIRE(view1.to_string() == "bar");
+    REQUIRE(std::string(view2) == "foo");
+    REQUIRE(std::string(view1) == "bar");
 }
 
 TEST_CASE("comparing data_views") {


=====================================
tools/pbf-decoder.cpp
=====================================
@@ -32,6 +32,7 @@ Call with --help/-h to see more options.
 #include <sstream>
 #include <stdexcept>
 #include <string>
+#include <vector>
 
 namespace {
 
@@ -194,15 +195,15 @@ void print_help() {
               << "  -o, --offset=OFFSET  Start reading from OFFSET bytes\n";
 }
 
-std::string read_from_file(const char* filename) {
+std::vector<char> read_from_file(const char* filename) {
     const std::ifstream file{filename, std::ios::binary};
-    return std::string{std::istreambuf_iterator<char>(file.rdbuf()),
-                       std::istreambuf_iterator<char>()};
+    return std::vector<char>{std::istreambuf_iterator<char>(file.rdbuf()),
+                             std::istreambuf_iterator<char>()};
 }
 
-std::string read_from_stdin() {
-    return std::string{std::istreambuf_iterator<char>(std::cin.rdbuf()),
-                       std::istreambuf_iterator<char>()};
+std::vector<char> read_from_stdin() {
+    return std::vector<char>{std::istreambuf_iterator<char>(std::cin.rdbuf()),
+                             std::istreambuf_iterator<char>()};
 }
 
 } // anonymous namespace
@@ -251,15 +252,15 @@ int main(int argc, char* argv[]) {
     const std::string filename{argv[optind]};
 
     try {
-        std::string buffer{filename == "-" ? read_from_stdin() :
-                                             read_from_file(argv[optind])};
+        std::vector<char> buffer{filename == "-" ? read_from_stdin() :
+                                                   read_from_file(argv[optind])};
 
         if (offset > buffer.size()) {
             throw std::runtime_error{"offset is larger than file size"};
         }
 
         if (offset > 0) {
-            buffer.erase(0, offset);
+            buffer.erase(buffer.begin(), buffer.begin() + offset);
         }
 
         if (length < buffer.size()) {


=====================================
tools/pbf-fuzzer.cpp
=====================================
@@ -0,0 +1,85 @@
+#include <protozero/pbf_reader.hpp>
+
+// From Google Benchmark library.
+// See https://github.com/google/benchmark/blob/main/LICENSE
+template <class Tp>
+inline __attribute__((always_inline)) void DoNotOptimize(Tp const& value) {
+    asm volatile("" : : "r,m"(value) : "memory");
+}
+
+template <typename T>
+int read_packed(protozero::iterator_range<T> range) {
+    try {
+        for (const auto& item : range) {
+            DoNotOptimize(item);
+        }
+    } catch (const protozero::exception&) {
+        // no-op. This is probably not a packed field of that type.
+    }
+    return 0;
+}
+
+template <typename Fn>
+void try_field(const protozero::pbf_reader& reader, Fn&& fn) {
+    try {
+        DoNotOptimize(fn(reader));
+    } catch (const protozero::exception&) {
+        // no-op. This is probably not a field of that type.
+    }
+}
+
+int try_message(protozero::pbf_reader reader) {
+    try {
+        while (reader.next()) {
+            if (reader.has_wire_type(protozero::pbf_wire_type::varint)) {
+                // Try to decode this field as any of the types that can be encoded as varint.
+                try_field(reader, [](protozero::pbf_reader r) { return r.get_bool(); });
+                try_field(reader, [](protozero::pbf_reader r) { return r.get_enum(); });
+                try_field(reader, [](protozero::pbf_reader r) { return r.get_int32(); });
+                try_field(reader, [](protozero::pbf_reader r) { return r.get_sint32(); });
+                try_field(reader, [](protozero::pbf_reader r) { return r.get_uint32(); });
+                try_field(reader, [](protozero::pbf_reader r) { return r.get_int64(); });
+                try_field(reader, [](protozero::pbf_reader r) { return r.get_sint64(); });
+                try_field(reader, [](protozero::pbf_reader r) { return r.get_uint64(); });
+            } else if (reader.has_wire_type(protozero::pbf_wire_type::length_delimited)) {
+                // Try to decode this field as any of the types that can be encoded as length-delimited.
+                try_field(reader, [](protozero::pbf_reader r) { return try_message(r.get_message()); });
+                try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_bool()); });
+                try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_double()); });
+                try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_enum()); });
+                try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_fixed32()); });
+                try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_fixed64()); });
+                try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_float()); });
+                try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_int32()); });
+                try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_int64()); });
+                try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_sfixed32()); });
+                try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_sfixed64()); });
+                try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_sint32()); });
+                try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_sint64()); });
+                try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_uint32()); });
+                try_field(reader, [](protozero::pbf_reader r) { return read_packed(r.get_packed_uint64()); });
+            } else if (reader.has_wire_type(protozero::pbf_wire_type::fixed64)) {
+                // Try to decode this field as any of the types that can be encoded as fixed64.
+                try_field(reader, [](protozero::pbf_reader r) { return r.get_double(); });
+                try_field(reader, [](protozero::pbf_reader r) { return r.get_fixed64(); });
+                try_field(reader, [](protozero::pbf_reader r) { return r.get_sfixed64(); });
+            } else if (reader.has_wire_type(protozero::pbf_wire_type::fixed32)) {
+                // Try to decode this field as any of the types that can be encoded as fixed32.
+                try_field(reader, [](protozero::pbf_reader r) { return r.get_float(); });
+                try_field(reader, [](protozero::pbf_reader r) { return r.get_fixed32(); });
+                try_field(reader, [](protozero::pbf_reader r) { return r.get_sfixed32(); });
+            }
+
+            reader.skip();
+        }
+    } catch (const protozero::exception&) {
+        // no-op. This is probably not a valid message.
+    }
+
+    return 0;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+    try_message(protozero::pbf_reader{reinterpret_cast<const char*>(data), size});
+    return 0;
+}



View it on GitLab: https://salsa.debian.org/debian-gis-team/protozero/-/commit/a01158b4228e392765ffdedaf96c8afdff95b56a

-- 
View it on GitLab: https://salsa.debian.org/debian-gis-team/protozero/-/commit/a01158b4228e392765ffdedaf96c8afdff95b56a
You're receiving this email because of your account on salsa.debian.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20250716/9361ce67/attachment-0001.htm>


More information about the Pkg-grass-devel mailing list