• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// -*- c++ -*-
2// Protocol Buffers - Google's data interchange format
3// Copyright 2008 Google Inc.  All rights reserved.
4//
5// Use of this source code is governed by a BSD-style
6// license that can be found in the LICENSE file or at
7// https://developers.google.com/open-source/licenses/bsd
8
9// Author: kenton@google.com (Kenton Varda)
10//  Based on original Protocol Buffers design by
11//  Sanjay Ghemawat, Jeff Dean, and others.
12//
13// This file needs to be included as .inc as it depends on certain macros being
14// defined prior to its inclusion.
15
16#include <fcntl.h>
17#include <sys/stat.h>
18#include <sys/types.h>
19
20#include <cmath>
21#include <functional>
22#include <limits>
23#include <vector>
24
25#ifndef _MSC_VER
26#include <unistd.h>
27#endif
28#include <fstream>
29#include <sstream>
30
31#include "google/protobuf/descriptor.pb.h"
32#include <gmock/gmock.h>
33#include "google/protobuf/testing/googletest.h"
34#include <gtest/gtest.h>
35#include "absl/log/absl_check.h"
36#include "absl/log/scoped_mock_log.h"
37#include "absl/strings/cord.h"
38#include "absl/strings/substitute.h"
39#include "google/protobuf/arena.h"
40#include "google/protobuf/descriptor.h"
41#include "google/protobuf/dynamic_message.h"
42#include "google/protobuf/generated_message_reflection.h"
43#include "google/protobuf/generated_message_tctable_impl.h"
44#include "google/protobuf/io/coded_stream.h"
45#include "google/protobuf/io/io_win32.h"
46#include "google/protobuf/io/zero_copy_stream.h"
47#include "google/protobuf/io/zero_copy_stream_impl.h"
48#include "google/protobuf/message.h"
49#include "google/protobuf/reflection_ops.h"
50#include "google/protobuf/test_util2.h"
51
52// Must be included last.
53#include "google/protobuf/port_def.inc"
54
55namespace google {
56namespace protobuf {
57
58TEST(MESSAGE_TEST_NAME, AllSetMethodsOnStringField) {
59  UNITTEST::TestAllTypes msg;
60
61  msg.set_optional_string(absl::string_view("Abcdef"));
62  EXPECT_EQ(msg.optional_string(), "Abcdef");
63
64  msg.set_optional_string("Asciiz");
65  EXPECT_EQ(msg.optional_string(), "Asciiz");
66
67  msg.set_optional_string("Length delimited", 6);
68  EXPECT_EQ(msg.optional_string(), "Length");
69
70  std::string value = "std::string value 1";
71  msg.set_optional_string(value);
72  EXPECT_EQ(msg.optional_string(), "std::string value 1");
73
74  value = "std::string value 2";
75  msg.set_optional_string(std::cref(value));
76  EXPECT_EQ(msg.optional_string(), "std::string value 2");
77
78  value = "std::string value 3";
79  msg.set_optional_string(std::move(value));
80  EXPECT_EQ(msg.optional_string(), "std::string value 3");
81}
82
83
84TEST(MESSAGE_TEST_NAME, AllAddMethodsOnRepeatedStringField) {
85  UNITTEST::TestAllTypes msg;
86
87  msg.add_repeated_string(absl::string_view("Abcdef"));
88  EXPECT_EQ(msg.repeated_string(0), "Abcdef");
89  msg.clear_repeated_string();
90
91  msg.add_repeated_string("Asciiz");
92  EXPECT_EQ(msg.repeated_string(0), "Asciiz");
93  msg.clear_repeated_string();
94
95  msg.add_repeated_string("Length delimited", 6);
96  EXPECT_EQ(msg.repeated_string(0), "Length");
97  msg.clear_repeated_string();
98
99  std::string value = "std::string value 1";
100  msg.add_repeated_string(value);
101  EXPECT_EQ(msg.repeated_string(0), "std::string value 1");
102  msg.clear_repeated_string();
103
104  value = "std::string value 2";
105  msg.add_repeated_string(std::cref(value));
106  EXPECT_EQ(msg.repeated_string(0), "std::string value 2");
107  msg.clear_repeated_string();
108
109  value = "std::string value 3";
110  msg.add_repeated_string(std::move(value));
111  EXPECT_EQ(msg.repeated_string(0), "std::string value 3");
112  msg.clear_repeated_string();
113}
114
115
116namespace {
117template <typename T>
118static const internal::TcParseTableBase* GetTableIfAvailable(...) {
119  return nullptr;
120}
121
122template <typename T>
123static const internal::TcParseTableBase* GetTableIfAvailable(
124    decltype(internal::TcParser::GetTable<T>())) {
125  return internal::TcParser::GetTable<T>();
126}
127}  // namespace
128
129TEST(MESSAGE_TEST_NAME, TestRegressionInlinedStringAuxIdxMismatchOnFastParser) {
130  using Proto = UNITTEST::InlinedStringIdxRegressionProto;
131
132  auto* table = GetTableIfAvailable<Proto>(nullptr);
133  // Only test when TDP is on, and we have these fields inlined.
134  if (table != nullptr &&
135      table->fast_entry(1)->target() == internal::TcParser::FastSiS1) {
136    // optional string str1 = 1;
137    // The aux_idx points to the inlined_string_idx and not the actual aux_idx.
138    EXPECT_EQ(table->fast_entry(1)->bits.aux_idx(), 1);
139    // optional InlinedStringIdxRegressionProto sub = 2;
140    EXPECT_EQ(table->fast_entry(2)->bits.aux_idx(), 1);
141    // optional string str2 = 3;
142    // The aux_idx points to the inlined_string_idx and not the actual aux_idx.
143    EXPECT_EQ(table->fast_entry(3)->bits.aux_idx(), 2);
144    // optional string str3 = 4;
145    // The aux_idx points to the inlined_string_idx and not the actual aux_idx.
146    EXPECT_EQ(table->fast_entry(0)->bits.aux_idx(), 3);
147  }
148
149  std::string encoded;
150  {
151    Proto proto;
152    // We use strings longer than SSO.
153    proto.set_str1(std::string(100, 'a'));
154    proto.set_str2(std::string(100, 'a'));
155    proto.set_str3(std::string(100, 'a'));
156    encoded = proto.SerializeAsString();
157  }
158  Arena arena;
159  auto* proto = Arena::Create<Proto>(&arena);
160  // We don't alter donation here, so it works even if the idx are bad.
161  ASSERT_TRUE(proto->ParseFromString(encoded));
162  // Now we alter donation bits. str2's bit (#2) will be off, but its aux_idx
163  // (#3) will point to a donated string.
164  proto = Arena::Create<Proto>(&arena);
165  proto->mutable_str1();
166  proto->mutable_str2();
167  proto->mutable_str3();
168  // With the bug, this breaks the cleanup list, causing UB on arena
169  // destruction.
170  ASSERT_TRUE(proto->ParseFromString(encoded));
171}
172
173}  // namespace protobuf
174}  // namespace google
175
176#include "google/protobuf/port_undef.inc"
177