Files
allwpilib/upstream_utils/protobuf_patches/0001-Fix-sign-compare-warnings.patch
Thad House a9ac5b8e24 Don't read protobuf static data across shared library lines directly (#6979)
Reading exported data from shared objects on windows is broken. It requires __declspec(dllimport). However, this is problematic, as we use the same static libraries both from a shared and static context. So we can't just blindly apply dllimport.

The linker should have caught this, as data members are exported in a different way. However, due to a bug in native-utils, data member symbols were exposed directly. However, interacting with those data member was completely broken.

The only way we can really solve this is to just not use static data members. We're pretty good about this in WPILib itself. However, protobuf is absolutely terrible at this. There are a ton of inline functions that access global data. For the protobuf library itself, we can solve this easily enough.

However, for the generated protobuf code, this is much more problematic. The member needed to bypass the global data is private. This means using just the stock protobuf code, this problem is not solvable. But, protobuf generated code has insertion points. Those insertion points let us add our own code into the generated code via a protoc plugin. And it just so happens that an insertion point exists to add extra public methodsto the generated protobuf header. There is also an insertion point to let us add to the cpp file.

The methods we need are the getters, for unpacking protobufs. For any protobuf that has a message as a member, we generate a new wpi_x() getter (the existing one is just x(), where x is the field name). We then implement this in the cpp file. A trick we can use is in the cpp file, we can safely call the x() function, as the cpp file is in the same library as the global. Thus we can call that inline method, and not actually need to directly access any internal private state of the protobuf object.

TL;DR, all protobuf classes that have messages as fields now have a wpi_x() accessor that must be used instead of x() if you want the code to work on windows. After wpilibsuite/native-utils#212, the bad code will fail to link, rather then just fail at runtime.
2024-08-21 07:53:20 -07:00

326 lines
16 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Johnson <johnson.peter@gmail.com>
Date: Sat, 10 Jun 2023 14:13:07 -0700
Subject: [PATCH 01/13] Fix sign-compare warnings
---
src/google/protobuf/compiler/importer.cc | 2 +-
src/google/protobuf/compiler/parser.cc | 4 ++--
src/google/protobuf/io/io_win32.cc | 2 +-
src/google/protobuf/stubs/stringprintf.cc | 4 ++--
src/google/protobuf/stubs/strutil.cc | 2 +-
src/google/protobuf/stubs/substitute.cc | 2 +-
src/google/protobuf/util/field_mask_util.cc | 2 +-
src/google/protobuf/util/internal/datapiece.cc | 7 +++++++
.../protobuf/util/internal/default_value_objectwriter.cc | 4 ++--
.../protobuf/util/internal/default_value_objectwriter.h | 2 +-
src/google/protobuf/util/internal/json_escaping.cc | 6 +++---
src/google/protobuf/util/internal/json_objectwriter.h | 2 +-
src/google/protobuf/util/internal/json_stream_parser.cc | 8 ++++----
src/google/protobuf/util/internal/proto_writer.cc | 2 +-
.../protobuf/util/internal/protostream_objectwriter.cc | 2 +-
src/google/protobuf/util/internal/utility.cc | 2 +-
src/google/protobuf/util/json_util.cc | 2 +-
17 files changed, 31 insertions(+), 24 deletions(-)
diff --git a/src/google/protobuf/compiler/importer.cc b/src/google/protobuf/compiler/importer.cc
index f1e26f8bdd1d3619acd8827f9a2a0e6b2acdd124..678e87eb03cc3959a1890327cd1e918cb1896fa3 100644
--- a/src/google/protobuf/compiler/importer.cc
+++ b/src/google/protobuf/compiler/importer.cc
@@ -398,7 +398,7 @@ DiskSourceTree::DiskFileToVirtualFile(const std::string& disk_file,
int mapping_index = -1;
std::string canonical_disk_file = CanonicalizePath(disk_file);
- for (int i = 0; i < mappings_.size(); i++) {
+ for (size_t i = 0; i < mappings_.size(); i++) {
// Apply the mapping in reverse.
if (ApplyMapping(canonical_disk_file, mappings_[i].disk_path,
mappings_[i].virtual_path, virtual_file)) {
diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc
index 5bd37d147bc449444f875f89367a208a32a9146e..e36a4a74359fcace20c017f241d58930660b9381 100644
--- a/src/google/protobuf/compiler/parser.cc
+++ b/src/google/protobuf/compiler/parser.cc
@@ -159,7 +159,7 @@ bool IsLowerUnderscore(const std::string& name) {
}
bool IsNumberFollowUnderscore(const std::string& name) {
- for (int i = 1; i < name.length(); i++) {
+ for (size_t i = 1; i < name.length(); i++) {
const char c = name[i];
if (IsNumber(c) && name[i - 1] == '_') {
return true;
@@ -500,7 +500,7 @@ void Parser::LocationRecorder::AttachComments(
if (!trailing->empty()) {
location_->mutable_trailing_comments()->swap(*trailing);
}
- for (int i = 0; i < detached_comments->size(); ++i) {
+ for (size_t i = 0; i < detached_comments->size(); ++i) {
location_->add_leading_detached_comments()->swap((*detached_comments)[i]);
}
detached_comments->clear();
diff --git a/src/google/protobuf/io/io_win32.cc b/src/google/protobuf/io/io_win32.cc
index 4e8190880918f1ba155d75db76d6c1ee0b003247..78c07d0d771b9c227c6cd930fc91d272fd67500f 100644
--- a/src/google/protobuf/io/io_win32.cc
+++ b/src/google/protobuf/io/io_win32.cc
@@ -198,7 +198,7 @@ wstring normalize(wstring path) {
// Join all segments.
bool first = true;
std::wstringstream result;
- for (int i = 0; i < segments.size(); ++i) {
+ for (size_t i = 0; i < segments.size(); ++i) {
if (!first) {
result << L'\\';
}
diff --git a/src/google/protobuf/stubs/stringprintf.cc b/src/google/protobuf/stubs/stringprintf.cc
index a6ad4c0da4080f5241c26176046a3add5247e25c..8b890f47c386f0d6b0ab9fd9928fae03edd076eb 100644
--- a/src/google/protobuf/stubs/stringprintf.cc
+++ b/src/google/protobuf/stubs/stringprintf.cc
@@ -149,10 +149,10 @@ std::string StringPrintfVector(const char* format,
// or displaying random chunks of memory to users.
const char* cstr[kStringPrintfVectorMaxArgs];
- for (int i = 0; i < v.size(); ++i) {
+ for (size_t i = 0; i < v.size(); ++i) {
cstr[i] = v[i].c_str();
}
- for (int i = v.size(); i < GOOGLE_ARRAYSIZE(cstr); ++i) {
+ for (size_t i = v.size(); i < GOOGLE_ARRAYSIZE(cstr); ++i) {
cstr[i] = &string_printf_empty_block[0];
}
diff --git a/src/google/protobuf/stubs/strutil.cc b/src/google/protobuf/stubs/strutil.cc
index 594c8eac6a6ebff6d8bc8cc8518e3fd521f24da1..3462e91ff273dc071628f06b91698a0f166514fc 100644
--- a/src/google/protobuf/stubs/strutil.cc
+++ b/src/google/protobuf/stubs/strutil.cc
@@ -697,7 +697,7 @@ bool safe_parse_positive_int(std::string text, IntType *value_p) {
IntType value = 0;
const IntType vmax = std::numeric_limits<IntType>::max();
assert(vmax > 0);
- assert(vmax >= base);
+ assert(static_cast<int>(vmax) >= base);
const IntType vmax_over_base = vmax / base;
const char* start = text.data();
const char* end = start + text.size();
diff --git a/src/google/protobuf/stubs/substitute.cc b/src/google/protobuf/stubs/substitute.cc
index d301682ee3377760430839bc5d6530621333e48d..8c75b2562e43d9d4ade3ef187d38e2e81b43e2c7 100644
--- a/src/google/protobuf/stubs/substitute.cc
+++ b/src/google/protobuf/stubs/substitute.cc
@@ -128,7 +128,7 @@ void SubstituteAndAppend(std::string* output, const char* format,
}
}
- GOOGLE_DCHECK_EQ(target - output->data(), output->size());
+ GOOGLE_DCHECK_EQ(target - output->data(), static_cast<int>(output->size()));
}
} // namespace strings
diff --git a/src/google/protobuf/util/field_mask_util.cc b/src/google/protobuf/util/field_mask_util.cc
index 700e59004a083c731477bcc0bb4d5c36d06f306c..9a40b851a9e51d30b286ff5d89707bf9f279d0c0 100644
--- a/src/google/protobuf/util/field_mask_util.cc
+++ b/src/google/protobuf/util/field_mask_util.cc
@@ -366,7 +366,7 @@ void FieldMaskTree::RemovePath(const std::string& path,
Node* node = &root_;
const Descriptor* current_descriptor = descriptor;
Node* new_branch_node = nullptr;
- for (int i = 0; i < parts.size(); ++i) {
+ for (size_t i = 0; i < parts.size(); ++i) {
nodes[i] = node;
const FieldDescriptor* field_descriptor =
current_descriptor->FindFieldByName(parts[i]);
diff --git a/src/google/protobuf/util/internal/datapiece.cc b/src/google/protobuf/util/internal/datapiece.cc
index 3e7aa84da7181e2ab270e181b9f63deb1905542f..56f4a18fa4afc64708938fa5352937cdd17b5747 100644
--- a/src/google/protobuf/util/internal/datapiece.cc
+++ b/src/google/protobuf/util/internal/datapiece.cc
@@ -53,6 +53,10 @@ namespace {
template <typename To, typename From>
util::StatusOr<To> ValidateNumberConversion(To after, From before) {
+#ifdef __GNUC__
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-compare"
+#endif
if (after == before &&
MathUtil::Sign<From>(before) == MathUtil::Sign<To>(after)) {
return after;
@@ -62,6 +66,9 @@ util::StatusOr<To> ValidateNumberConversion(To after, From before) {
: std::is_same<From, double>::value ? DoubleAsString(before)
: FloatAsString(before));
}
+#ifdef __GNUC__
+#pragma GCC diagnostic pop
+#endif
}
// For general conversion between
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc
index 7f61cdafa7c771a69364c5e9c49667535b16d957..a7d4ce78bd47e0250def474df8937927be9ef116 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.cc
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc
@@ -312,7 +312,7 @@ void DefaultValueObjectWriter::Node::PopulateChildren(
std::unordered_map<std::string, int> orig_children_map;
// Creates a map of child nodes to speed up lookup.
- for (int i = 0; i < children_.size(); ++i) {
+ for (size_t i = 0; i < children_.size(); ++i) {
InsertIfNotPresent(&orig_children_map, children_[i]->name_, i);
}
@@ -389,7 +389,7 @@ void DefaultValueObjectWriter::Node::PopulateChildren(
new_children.push_back(child.release());
}
// Adds all leftover nodes in children_ to the beginning of new_child.
- for (int i = 0; i < children_.size(); ++i) {
+ for (size_t i = 0; i < children_.size(); ++i) {
if (children_[i] == nullptr) {
continue;
}
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h
index a9e1673fa1e4ed35ab6890a44eed1d362265d914..1a151ab25951f8b0e1c9c724253b16524b88530a 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.h
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.h
@@ -154,7 +154,7 @@ class PROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
bool preserve_proto_field_names, bool use_ints_for_enums,
FieldScrubCallBack field_scrub_callback);
virtual ~Node() {
- for (int i = 0; i < children_.size(); ++i) {
+ for (size_t i = 0; i < children_.size(); ++i) {
delete children_[i];
}
}
diff --git a/src/google/protobuf/util/internal/json_escaping.cc b/src/google/protobuf/util/internal/json_escaping.cc
index e4fa8cf788642e4a9d9c0460c287b1c24891b9fa..c192ddca7aff3984ffcbf82e13585bdf34ad8aae 100644
--- a/src/google/protobuf/util/internal/json_escaping.cc
+++ b/src/google/protobuf/util/internal/json_escaping.cc
@@ -179,7 +179,7 @@ bool ReadCodePoint(StringPiece str, int index, uint32_t* cp,
// the last unicode code point.
*num_read = 0;
}
- while (*num_left > 0 && index < str.size()) {
+ while (*num_left > 0 && index < static_cast<int>(str.size())) {
uint32_t ch = static_cast<uint8_t>(str[index++]);
--(*num_left);
++(*num_read);
@@ -309,7 +309,7 @@ void JsonEscaping::Escape(strings::ByteSource* input,
while (input->Available() > 0) {
StringPiece str = input->Peek();
StringPiece escaped;
- int i = 0;
+ size_t i = 0;
int num_read;
bool ok;
bool cp_was_split = num_left > 0;
@@ -349,7 +349,7 @@ void JsonEscaping::Escape(StringPiece input, strings::ByteSink* output) {
const char* p = input.data();
bool can_skip_escaping = true;
- for (int i = 0; i < len; i++) {
+ for (size_t i = 0; i < len; i++) {
char c = p[i];
if (c < 0x20 || c >= 0x7F || c == '"' || c == '<' || c == '>' ||
c == '\\') {
diff --git a/src/google/protobuf/util/internal/json_objectwriter.h b/src/google/protobuf/util/internal/json_objectwriter.h
index cb7dff6e9fe79858a73b2c7501106fe8d05ccac5..92348da3b5c3f07e6146136352f976c94fe54340 100644
--- a/src/google/protobuf/util/internal/json_objectwriter.h
+++ b/src/google/protobuf/util/internal/json_objectwriter.h
@@ -102,7 +102,7 @@ class PROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter {
if (!indent_string.empty()) {
indent_char_ = indent_string[0];
indent_count_ = indent_string.length();
- for (int i = 1; i < indent_string.length(); i++) {
+ for (size_t i = 1; i < indent_string.length(); i++) {
if (indent_char_ != indent_string_[i]) {
indent_char_ = '\0';
indent_count_ = 0;
diff --git a/src/google/protobuf/util/internal/json_stream_parser.cc b/src/google/protobuf/util/internal/json_stream_parser.cc
index 5c34dbccafb9f40249ba3c0b7318b2e897f203dc..e786781f6de23c8a7ea282d061df6032111f6d21 100644
--- a/src/google/protobuf/util/internal/json_stream_parser.cc
+++ b/src/google/protobuf/util/internal/json_stream_parser.cc
@@ -80,7 +80,7 @@ inline void ReplaceInvalidCodePoints(StringPiece str,
const std::string& replacement,
std::string* dst) {
while (!str.empty()) {
- int n_valid_bytes = internal::UTF8SpnStructurallyValid(str);
+ size_t n_valid_bytes = internal::UTF8SpnStructurallyValid(str);
StringPiece valid_part = str.substr(0, n_valid_bytes);
StrAppend(dst, valid_part);
@@ -98,7 +98,7 @@ inline void ReplaceInvalidCodePoints(StringPiece str,
static bool ConsumeKey(StringPiece* input, StringPiece* key) {
if (input->empty() || !IsLetter((*input)[0])) return false;
- int len = 1;
+ size_t len = 1;
for (; len < input->size(); ++len) {
if (!IsAlphanumeric((*input)[len])) {
break;
@@ -113,7 +113,7 @@ static bool ConsumeKey(StringPiece* input, StringPiece* key) {
static bool ConsumeKeyPermissive(StringPiece* input,
StringPiece* key) {
if (input->empty() || !IsLetter((*input)[0])) return false;
- int len = 1;
+ size_t len = 1;
for (; len < input->size(); ++len) {
if (IsKeySeparator((*input)[len])) {
break;
@@ -946,7 +946,7 @@ util::Status JsonStreamParser::ParseKey() {
JsonStreamParser::TokenType JsonStreamParser::GetNextTokenType() {
SkipWhitespace();
- int size = p_.size();
+ size_t size = p_.size();
if (size == 0) {
// If we ran out of data, report unknown and we'll place the previous parse
// type onto the stack and try again when we have more data.
diff --git a/src/google/protobuf/util/internal/proto_writer.cc b/src/google/protobuf/util/internal/proto_writer.cc
index afa5e2e474b6960b8826a40b73615d5dffd971de..11b6df13d8f4f9506e828c39d6e74bc8acceb23d 100644
--- a/src/google/protobuf/util/internal/proto_writer.cc
+++ b/src/google/protobuf/util/internal/proto_writer.cc
@@ -408,7 +408,7 @@ std::string ProtoWriter::ProtoElement::ToString() const {
if (!ow_->IsRepeated(*(now->parent_field_)) ||
now->parent()->parent_field_ != now->parent_field_) {
std::string name = now->parent_field_->name();
- int i = 0;
+ size_t i = 0;
while (i < name.size() &&
(ascii_isalnum(name[i]) || name[i] == '_'))
++i;
diff --git a/src/google/protobuf/util/internal/protostream_objectwriter.cc b/src/google/protobuf/util/internal/protostream_objectwriter.cc
index ecb219e06e514b1a6ba0e3e343126a75852d0a1d..ce94cfcefb417203f80142c54003efea283f6a1c 100644
--- a/src/google/protobuf/util/internal/protostream_objectwriter.cc
+++ b/src/google/protobuf/util/internal/protostream_objectwriter.cc
@@ -378,7 +378,7 @@ void ProtoStreamObjectWriter::AnyWriter::StartAny(const DataPiece& value) {
// Now we know the proto type and can interpret all data fields we gathered
// before the "@type" field.
- for (int i = 0; i < uninterpreted_events_.size(); ++i) {
+ for (size_t i = 0; i < uninterpreted_events_.size(); ++i) {
uninterpreted_events_[i].Replay(this);
}
}
diff --git a/src/google/protobuf/util/internal/utility.cc b/src/google/protobuf/util/internal/utility.cc
index 918ee17d9b040ae1bf9d98e3f46f75770c471393..3c4ac086d594d67b334cbc1dc046c281cd59a374 100644
--- a/src/google/protobuf/util/internal/utility.cc
+++ b/src/google/protobuf/util/internal/utility.cc
@@ -345,7 +345,7 @@ void DeleteWellKnownTypes() { delete well_known_types_; }
void InitWellKnownTypes() {
well_known_types_ = new std::set<std::string>;
- for (int i = 0; i < GOOGLE_ARRAYSIZE(well_known_types_name_array_); ++i) {
+ for (size_t i = 0; i < GOOGLE_ARRAYSIZE(well_known_types_name_array_); ++i) {
well_known_types_->insert(well_known_types_name_array_[i]);
}
google::protobuf::internal::OnShutdown(&DeleteWellKnownTypes);
diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc
index c39c10d87b7d8bf6fc18cae1ce459257c45945d6..a9b1c52a73c86d3e3655ba0748f2a82c68bd40ce 100644
--- a/src/google/protobuf/util/json_util.cc
+++ b/src/google/protobuf/util/json_util.cc
@@ -64,7 +64,7 @@ ZeroCopyStreamByteSink::~ZeroCopyStreamByteSink() {
void ZeroCopyStreamByteSink::Append(const char* bytes, size_t len) {
while (true) {
- if (len <= buffer_size_) { // NOLINT
+ if (static_cast<int>(len) <= buffer_size_) { // NOLINT
memcpy(buffer_, bytes, len);
buffer_ = static_cast<char*>(buffer_) + len;
buffer_size_ -= len;