record.cc 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. // Copyright 2019 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "sql/recover_module/record.h"
  5. #include <cstddef>
  6. #include <limits>
  7. #include <ostream>
  8. #include <type_traits>
  9. #include "base/check_op.h"
  10. #include "base/notreached.h"
  11. #include "sql/recover_module/integers.h"
  12. #include "sql/recover_module/payload.h"
  13. #include "third_party/sqlite/sqlite3.h"
  14. namespace sql {
  15. namespace recover {
  16. RecordReader::RecordReader(LeafPayloadReader* payload_reader, int column_count)
  17. : payload_reader_(payload_reader), column_count_(column_count) {
  18. DCHECK(payload_reader != nullptr);
  19. DCHECK_GT(column_count, 0);
  20. value_headers_.reserve(column_count);
  21. }
  22. RecordReader::~RecordReader() = default;
  23. namespace {
  24. // Value type indicating a null.
  25. constexpr int kNullType = 0;
  26. // Value type indicating a 1-byte signed integer.
  27. constexpr int kInt1Type = 1;
  28. // Value type indicating a 2-byte signed big-endian integer.
  29. constexpr int kInt2Type = 2;
  30. // Value type indicating a 3-byte signed big-endian integer.
  31. constexpr int kInt3Type = 3;
  32. // Value type indicating a 4-byte signed big-endian integer.
  33. constexpr int kInt4Type = 4;
  34. // Value type indicating a 6-byte signed big-endian integer.
  35. constexpr int kInt6Type = 5;
  36. // Value type indicating an 8-byte signed big-endian integer.
  37. constexpr int kInt8Type = 6;
  38. // Value type indicating a big-endian IEEE 754 64-bit floating point number.
  39. constexpr int kDoubleType = 7;
  40. // Value type indicating the integer 0 (zero).
  41. constexpr int kIntZeroType = 8;
  42. // Value type indicating the integer 1 (one).
  43. constexpr int kIntOneType = 9;
  44. // Value types greater than or equal to this indicate blobs or text.
  45. constexpr int kMinBlobOrStringType = 12;
  46. // The return value of ParseHeaderType below.
  47. struct ParsedHeaderType {
  48. // True for the special value used to communicate a parsing error.
  49. bool IsInvalid() const {
  50. return type == ValueType::kNull && has_inline_value;
  51. }
  52. const ValueType type;
  53. const int64_t size;
  54. const int8_t inline_value;
  55. const bool has_inline_value;
  56. };
  57. // Decodes a type identifier in a SQLite record header.
  58. //
  59. // The type identifier includes the type and the size.
  60. //
  61. // Returns {kNull, 1} when parsing fails. Null values never require any extra
  62. // bytes, so this special return value will never occur during normal
  63. // processing.
  64. ParsedHeaderType ParseHeaderType(int64_t encoded_type) {
  65. static constexpr int8_t kNoInlineValue = 0;
  66. if (encoded_type == kNullType)
  67. return {ValueType::kNull, 0, kNoInlineValue, false};
  68. if (encoded_type == kInt1Type)
  69. return {ValueType::kInteger, 1, kNoInlineValue, false};
  70. if (encoded_type == kInt2Type)
  71. return {ValueType::kInteger, 2, kNoInlineValue, false};
  72. if (encoded_type == kInt3Type)
  73. return {ValueType::kInteger, 3, kNoInlineValue, false};
  74. if (encoded_type == kInt4Type)
  75. return {ValueType::kInteger, 4, kNoInlineValue, false};
  76. if (encoded_type == kInt6Type)
  77. return {ValueType::kInteger, 6, kNoInlineValue, false};
  78. if (encoded_type == kInt8Type)
  79. return {ValueType::kInteger, 8, kNoInlineValue, false};
  80. if (encoded_type == kDoubleType)
  81. return {ValueType::kFloat, 8, kNoInlineValue, false};
  82. if (encoded_type == kIntZeroType)
  83. return {ValueType::kInteger, 0, 0, true};
  84. if (encoded_type == kIntOneType)
  85. return {ValueType::kInteger, 0, 1, true};
  86. if (encoded_type < kMinBlobOrStringType) {
  87. // Types between |kIntOneType| and |kMinBlobOrStringType| are reserved for
  88. // SQLite internal usage, and should not appear in persistent databases.
  89. // This shows database corruption.
  90. return {ValueType::kNull, 0, kNoInlineValue, true};
  91. }
  92. // Blobs and texts take alternating numbers starting at 12.
  93. encoded_type -= kMinBlobOrStringType;
  94. const ValueType value_type =
  95. (encoded_type & 1) == 0 ? ValueType::kBlob : ValueType::kText;
  96. const int64_t value_size = encoded_type >> 1;
  97. return {value_type, value_size, kNoInlineValue, false};
  98. }
  99. } // namespace
  100. bool RecordReader::Initialize() {
  101. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  102. // The size of |value_headers_| is used in DCHECKs to track whether
  103. // Initialize() succeeded.
  104. value_headers_.clear();
  105. int64_t next_value_offset = InitializeHeaderBuffer();
  106. if (next_value_offset == 0)
  107. return false;
  108. const uint8_t* header_pointer = header_buffer_.data();
  109. const uint8_t* header_end = header_buffer_.data() + header_buffer_.size();
  110. for (int i = 0; i < column_count_; ++i) {
  111. int64_t encoded_type;
  112. if (header_pointer == header_end) {
  113. // SQLite versions built with SQLITE_ENABLE_NULL_TRIM don't store trailing
  114. // null type IDs in the header.
  115. encoded_type = kNullType;
  116. } else {
  117. std::tie(encoded_type, header_pointer) =
  118. ParseVarint(header_pointer, header_end);
  119. }
  120. ParsedHeaderType parsed_type = ParseHeaderType(encoded_type);
  121. if (parsed_type.IsInvalid()) {
  122. // Parsing failed. The record is corrupted.
  123. return false;
  124. }
  125. value_headers_.emplace_back(next_value_offset, parsed_type.size,
  126. parsed_type.type, parsed_type.inline_value,
  127. parsed_type.has_inline_value);
  128. next_value_offset += parsed_type.size;
  129. }
  130. DCHECK_EQ(value_headers_.size(), static_cast<size_t>(column_count_));
  131. return true;
  132. }
  133. ValueType RecordReader::GetValueType(int column_index) const {
  134. DCHECK(IsInitialized());
  135. DCHECK_GE(column_index, 0);
  136. DCHECK_LT(static_cast<size_t>(column_index), value_headers_.size());
  137. return value_headers_[column_index].type;
  138. }
  139. namespace {
  140. // Deallocates buffers passed to sqlite3_result_{blob,text}64().
  141. void ValueBytesDeleter(void* buffer) {
  142. DCHECK(buffer != nullptr);
  143. uint8_t* value_bytes = reinterpret_cast<uint8_t*>(buffer);
  144. delete[] value_bytes;
  145. }
  146. } // namespace
  147. bool RecordReader::ReadValue(int column_index,
  148. sqlite3_context* receiver) const {
  149. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  150. DCHECK(IsInitialized());
  151. DCHECK_GE(column_index, 0);
  152. DCHECK_LT(static_cast<size_t>(column_index), value_headers_.size());
  153. DCHECK(receiver != nullptr);
  154. const ValueHeader& header = value_headers_[column_index];
  155. const int64_t offset = header.offset;
  156. const int64_t size = header.size;
  157. if (header.type == ValueType::kNull) {
  158. DCHECK_EQ(size, 0);
  159. DCHECK(!header.has_inline_value);
  160. sqlite3_result_null(receiver);
  161. return true;
  162. }
  163. if (header.type == ValueType::kInteger) {
  164. if (header.has_inline_value) {
  165. sqlite3_result_int(receiver, header.inline_value);
  166. return true;
  167. }
  168. uint8_t value_bytes[8];
  169. DCHECK_GT(size, 0);
  170. DCHECK_LE(size, static_cast<int64_t>(sizeof(value_bytes)));
  171. // SQLite integers are big-endian, so the least significant bytes are at the
  172. // end of the integer's buffer.
  173. uint8_t* const first_read_byte = value_bytes + 8 - size;
  174. if (!payload_reader_->ReadPayload(offset, size, first_read_byte))
  175. return false;
  176. // Sign-extend the number.
  177. const uint8_t sign_byte = (*first_read_byte & 0x80) ? 0xff : 0;
  178. for (uint8_t* sign_extended_byte = &value_bytes[0];
  179. sign_extended_byte < first_read_byte; ++sign_extended_byte) {
  180. *sign_extended_byte = sign_byte;
  181. }
  182. const int64_t value = LoadBigEndianInt64(value_bytes);
  183. sqlite3_result_int64(receiver, value);
  184. return true;
  185. }
  186. if (header.type == ValueType::kFloat) {
  187. DCHECK_EQ(header.size, static_cast<int64_t>(sizeof(double)));
  188. DCHECK(!header.has_inline_value);
  189. union {
  190. double fp;
  191. int64_t integer;
  192. uint8_t bytes[8];
  193. } value;
  194. static_assert(sizeof(double) == 8,
  195. "double is not the correct type to represent SQLite floats");
  196. if (!payload_reader_->ReadPayload(header.offset, sizeof(double),
  197. reinterpret_cast<uint8_t*>(&value))) {
  198. return false;
  199. }
  200. // SQLite's doubles are big-endian.
  201. value.integer = LoadBigEndianInt64(value.bytes);
  202. sqlite3_result_double(receiver, value.fp);
  203. return true;
  204. }
  205. if (header.type == ValueType::kBlob || header.type == ValueType::kText) {
  206. DCHECK_GE(header.size, 0);
  207. DCHECK(!header.has_inline_value);
  208. uint8_t* const value_bytes = new uint8_t[size];
  209. if (size > 0 && !payload_reader_->ReadPayload(offset, size, value_bytes)) {
  210. delete[] value_bytes;
  211. return false;
  212. }
  213. if (header.type == ValueType::kBlob) {
  214. sqlite3_result_blob64(receiver, value_bytes, static_cast<uint64_t>(size),
  215. &ValueBytesDeleter);
  216. } else {
  217. DCHECK_EQ(header.type, ValueType::kText);
  218. const unsigned char encoding = SQLITE_UTF8;
  219. sqlite3_result_text64(receiver, reinterpret_cast<char*>(value_bytes),
  220. static_cast<uint64_t>(size), &ValueBytesDeleter,
  221. encoding);
  222. }
  223. return true;
  224. }
  225. NOTREACHED() << "Invalid value type";
  226. return false;
  227. }
  228. void RecordReader::Reset() {
  229. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  230. value_headers_.clear();
  231. }
  232. int64_t RecordReader::InitializeHeaderBuffer() {
  233. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  234. const uint8_t* const inline_payload_start =
  235. payload_reader_->ReadInlinePayload();
  236. if (inline_payload_start == nullptr) {
  237. // Read failure.
  238. return 0;
  239. }
  240. const int64_t inline_payload_size = payload_reader_->inline_payload_size();
  241. const uint8_t* const inline_payload_end =
  242. inline_payload_start + inline_payload_size;
  243. int64_t header_size;
  244. const uint8_t* payload_header_start;
  245. std::tie(header_size, payload_header_start) =
  246. ParseVarint(inline_payload_start, inline_payload_end);
  247. if (header_size < 0 || header_size > payload_reader_->payload_size()) {
  248. // The header is bigger than the entire record. This record is corrupted.
  249. return 0;
  250. }
  251. int header_size_size = payload_header_start - inline_payload_start;
  252. static_assert(std::numeric_limits<int>::max() > kMaxVarintSize,
  253. "The |header_size_size| computation above may overflow");
  254. // The header size varint is included in the header size computation.
  255. const int64_t header_data_size = header_size - header_size_size;
  256. header_buffer_.resize(header_data_size);
  257. if (!payload_reader_->ReadPayload(header_size_size, header_data_size,
  258. header_buffer_.data())) {
  259. // Read failure.
  260. return 0;
  261. }
  262. return header_size;
  263. }
  264. } // namespace recover
  265. } // namespace sql