1 // Copyright 2014 The Crashpad Authors. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef CRASHPAD_MINIDUMP_MINIDUMP_STRING_WRITER_H_
16 #define CRASHPAD_MINIDUMP_MINIDUMP_STRING_WRITER_H_
17 
18 #include <windows.h>
19 #include <dbghelp.h>
20 #include <sys/types.h>
21 
22 #include <memory>
23 #include <string>
24 #include <vector>
25 
26 #include "base/macros.h"
27 #include "base/strings/string16.h"
28 #include "minidump/minidump_extensions.h"
29 #include "minidump/minidump_rva_list_writer.h"
30 #include "minidump/minidump_writable.h"
31 
32 namespace crashpad {
33 namespace internal {
34 
35 //! \cond
36 
37 struct MinidumpStringWriterUTF16Traits {
38   using StringType = base::string16;
39   using MinidumpStringType = MINIDUMP_STRING;
40 };
41 
42 struct MinidumpStringWriterUTF8Traits {
43   using StringType = std::string;
44   using MinidumpStringType = MinidumpUTF8String;
45 };
46 
47 //! \endcond
48 
49 //! \brief Writes a variable-length string to a minidump file in accordance with
50 //!     the string type’s characteristics.
51 //!
52 //! MinidumpStringWriter objects should not be instantiated directly. To write
53 //! strings to minidump file, use the MinidumpUTF16StringWriter and
54 //! MinidumpUTF8StringWriter subclasses instead.
55 template <typename Traits>
56 class MinidumpStringWriter : public MinidumpWritable {
57  public:
58   MinidumpStringWriter();
59   ~MinidumpStringWriter() override;
60 
61  protected:
62   using MinidumpStringType = typename Traits::MinidumpStringType;
63   using StringType = typename Traits::StringType;
64 
65   bool Freeze() override;
66   size_t SizeOfObject() override;
67   bool WriteObject(FileWriterInterface* file_writer) override;
68 
69   //! \brief Sets the string to be written.
70   //!
71   //! \note Valid in #kStateMutable.
set_string(const StringType & string)72   void set_string(const StringType& string) { string_.assign(string); }
73 
74   //! \brief Retrieves the string to be written.
75   //!
76   //! \note Valid in any state.
string()77   const StringType& string() const { return string_; }
78 
79  private:
80   std::unique_ptr<MinidumpStringType> string_base_;
81   StringType string_;
82 
83   DISALLOW_COPY_AND_ASSIGN(MinidumpStringWriter);
84 };
85 
86 //! \brief Writes a variable-length UTF-16-encoded MINIDUMP_STRING to a minidump
87 //!     file.
88 //!
89 //! MinidumpUTF16StringWriter objects should not be instantiated directly
90 //! outside of the MinidumpWritable family of classes.
91 class MinidumpUTF16StringWriter final
92     : public MinidumpStringWriter<MinidumpStringWriterUTF16Traits> {
93  public:
MinidumpUTF16StringWriter()94   MinidumpUTF16StringWriter() : MinidumpStringWriter() {}
95   ~MinidumpUTF16StringWriter() override;
96 
97   //! \brief Converts a UTF-8 string to UTF-16 and sets it as the string to be
98   //!     written.
99   //!
100   //! \note Valid in #kStateMutable.
101   void SetUTF8(const std::string& string_utf8);
102 
103  private:
104   DISALLOW_COPY_AND_ASSIGN(MinidumpUTF16StringWriter);
105 };
106 
107 //! \brief Writes a variable-length UTF-8-encoded MinidumpUTF8String to a
108 //!     minidump file.
109 //!
110 //! MinidumpUTF8StringWriter objects should not be instantiated directly outside
111 //! of the MinidumpWritable family of classes.
112 class MinidumpUTF8StringWriter final
113     : public MinidumpStringWriter<MinidumpStringWriterUTF8Traits> {
114  public:
MinidumpUTF8StringWriter()115   MinidumpUTF8StringWriter() : MinidumpStringWriter() {}
116   ~MinidumpUTF8StringWriter() override;
117 
118   //! \brief Sets the string to be written.
119   //!
120   //! \note Valid in #kStateMutable.
SetUTF8(const std::string & string_utf8)121   void SetUTF8(const std::string& string_utf8) { set_string(string_utf8); }
122 
123   //! \brief Retrieves the string to be written.
124   //!
125   //! \note Valid in any state.
UTF8()126   const std::string& UTF8() const { return string(); }
127 
128  private:
129   DISALLOW_COPY_AND_ASSIGN(MinidumpUTF8StringWriter);
130 };
131 
132 //! \brief The writer for a MinidumpRVAList object in a minidump file,
133 //!     containing a list of \a MinidumpStringWriterType objects.
134 template <typename MinidumpStringWriterType>
135 class MinidumpStringListWriter final : public MinidumpRVAListWriter {
136  public:
137   MinidumpStringListWriter();
138   ~MinidumpStringListWriter() override;
139 
140   //! \brief Adds a new \a Traits::MinidumpStringWriterType for each element in
141   //!     \a vector to the MinidumpRVAList.
142   //!
143   //! \param[in] vector The vector to use as source data. Each string in the
144   //!     vector is treated as a UTF-8 string, and a new string writer will be
145   //!     created for each one and made a child of the MinidumpStringListWriter.
146   //!
147   //! \note Valid in #kStateMutable. No mutator methods may be called before
148   //!     this method, and it is not normally necessary to call any mutator
149   //!     methods after this method.
150   void InitializeFromVector(const std::vector<std::string>& vector);
151 
152   //! \brief Creates a new \a Traits::MinidumpStringWriterType object and adds
153   //!     it to the MinidumpRVAList.
154   //!
155   //! This object creates a new string writer with string value \a string_utf8,
156   //! takes ownership of it, and becomes its parent in the overall tree of
157   //! MinidumpWritable objects.
158   //!
159   //! \note Valid in #kStateMutable.
160   void AddStringUTF8(const std::string& string_utf8);
161 
162   //! \brief Determines whether the object is useful.
163   //!
164   //! A useful object is one that carries data that makes a meaningful
165   //! contribution to a minidump file. An object carrying entries would be
166   //! considered useful.
167   //!
168   //! \return `true` if the object is useful, `false` otherwise.
169   bool IsUseful() const;
170 
171  private:
172   DISALLOW_COPY_AND_ASSIGN(MinidumpStringListWriter);
173 };
174 
175 }  // namespace internal
176 
177 using MinidumpUTF16StringListWriter = internal::MinidumpStringListWriter<
178     internal::MinidumpUTF16StringWriter>;
179 using MinidumpUTF8StringListWriter = internal::MinidumpStringListWriter<
180     internal::MinidumpUTF8StringWriter>;
181 
182 }  // namespace crashpad
183 
184 #endif  // CRASHPAD_MINIDUMP_MINIDUMP_STRING_WRITER_H_
185