Fix the packed length prefix and over-encoded zero in binary_wireformat.

Packed() prefixed its payload with the element count instead of the byte
length, which only matches the wire format when every element is a
single byte.  LongVarint(0, n) returned a plain zero byte, ignoring the
requested over-encoding, and the bounds check guarding its stack buffer
compiled out in optimized builds.  The unit tests that enshrined the
wrong bytes are corrected and new cases pin the length-vs-count
distinction.

PiperOrigin-RevId: 1002052455
diff --git a/conformance/BUILD b/conformance/BUILD
index c209321..efcaa34 100644
--- a/conformance/BUILD
+++ b/conformance/BUILD
@@ -314,6 +314,7 @@
     deps = [
         "//src/google/protobuf:endian",
         "//src/google/protobuf:protobuf_lite",
+        "@abseil-cpp//absl/log:absl_check",
         "@abseil-cpp//absl/strings",
     ],
 )
diff --git a/conformance/binary_wireformat.cc b/conformance/binary_wireformat.cc
index 3ed5f4a..3921f94 100644
--- a/conformance/binary_wireformat.cc
+++ b/conformance/binary_wireformat.cc
@@ -1,10 +1,10 @@
 #include "conformance/binary_wireformat.h"
 
-#include <cassert>
 #include <cstdint>
 #include <cstring>
 #include <string>
 
+#include "absl/log/absl_check.h"
 #include "absl/strings/string_view.h"
 #include "google/protobuf/endian.h"
 #include "google/protobuf/wire_format_lite.h"
@@ -18,19 +18,16 @@
 #define VARINT_MAX_LEN 10
 
 size_t vencode64(uint64_t val, int over_encoded_bytes, char* buf) {
-  if (val == 0) {
-    buf[0] = 0;
-    return 1;
-  }
+  ABSL_CHECK_GE(over_encoded_bytes, 0);
   size_t i = 0;
-  while (val) {
+  do {
     uint8_t byte = val & 0x7fU;
     val >>= 7;
     if (val || over_encoded_bytes) byte |= 0x80U;
     buf[i++] = byte;
-  }
+  } while (val);
   while (over_encoded_bytes--) {
-    assert(i < 10);
+    ABSL_CHECK_LT(i, VARINT_MAX_LEN);
     uint8_t byte = over_encoded_bytes ? 0x80 : 0;
     buf[i++] = byte;
   }
diff --git a/conformance/binary_wireformat.h b/conformance/binary_wireformat.h
index 63c5f7b..86f01eb 100644
--- a/conformance/binary_wireformat.h
+++ b/conformance/binary_wireformat.h
@@ -169,11 +169,11 @@
 namespace internal {
 template <typename Func, typename Container>
 Wire PackedImpl(Func func, const Container& container) {
-  std::string buf = Varint(container.size()).str();
+  std::string elements;
   for (auto x : container) {
-    absl::StrAppend(&buf, func(x).str());
+    absl::StrAppend(&elements, func(x).str());
   }
-  return Wire(buf);
+  return LengthPrefixed(elements);
 }
 }  // namespace internal
 
diff --git a/conformance/binary_wireformat_test.cc b/conformance/binary_wireformat_test.cc
index 5e5d322..f285d96 100644
--- a/conformance/binary_wireformat_test.cc
+++ b/conformance/binary_wireformat_test.cc
@@ -148,7 +148,8 @@
 INSTANTIATE_TEST_SUITE_P(
     LongVarintTest, LongVarintTest,
     testing::ValuesIn(std::vector<LongVarintTestCase>{
-        {0, 1, std::string("\000", 1)},
+        {0, 1, std::string("\200\000", 2)},
+        {0, 2, std::string("\200\200\000", 3)},
         {1, 1, std::string("\201\000", 2)},
         {1, 4, std::string("\201\200\200\200\000", 5)},
         {127, 1, std::string("\377\000", 2)},
@@ -347,7 +348,16 @@
 
 TEST(PackedTest, OneFixed32) {
   EXPECT_EQ(Packed(Fixed32<int>, {9}),
-            Wire(absl::string_view("\001\011\000\000\000", 5)));
+            Wire(absl::string_view("\004\011\000\000\000", 5)));
+}
+
+TEST(PackedTest, TwoFixed32s) {
+  EXPECT_EQ(Packed(Fixed32<int>, {9, 8}),
+            Wire(absl::string_view("\010\011\000\000\000\010\000\000\000", 9)));
+}
+
+TEST(PackedTest, MultiByteVarints) {
+  EXPECT_EQ(Packed(Varint<int>, {128, 1}), Wire("\003\200\001\001"));
 }
 
 TEST(PackedTest, Varints) {