1
1
// Distributed under the MIT software license, see the accompanying
2
2
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
3
3
4
+ #include < compat/byteswap.h>
4
5
#include < crypto/common.h> // For ReadBE32
5
6
#include < logging.h>
6
7
#include < streams.h>
@@ -94,6 +95,7 @@ class MetaPage
94
95
unsigned char iv[20 ]; // Crypto IV
95
96
unsigned char chksum[16 ]; // Checksum
96
97
98
+ bool other_endian;
97
99
uint32_t expected_page_num;
98
100
99
101
MetaPage (uint32_t expected_page_num) : expected_page_num(expected_page_num) {}
@@ -110,6 +112,8 @@ class MetaPage
110
112
s >> pagesize;
111
113
s >> encrypt_algo;
112
114
115
+ other_endian = magic == BTREE_MAGIC_OE;
116
+
113
117
uint8_t uint8_type;
114
118
s >> uint8_type;
115
119
type = static_cast <PageType>(uint8_type);
@@ -124,6 +128,9 @@ class MetaPage
124
128
125
129
uint32_t uint32_flags;
126
130
s >> uint32_flags;
131
+ if (other_endian) {
132
+ uint32_flags = internal_bswap_32 (uint32_flags);
133
+ }
127
134
flags = static_cast <BTreeFlags>(uint32_flags);
128
135
129
136
s >> uid;
@@ -138,6 +145,26 @@ class MetaPage
138
145
s >> iv;
139
146
s >> chksum;
140
147
148
+ if (other_endian) {
149
+ lsn_file = internal_bswap_32 (lsn_file);
150
+ lsn_offset = internal_bswap_32 (lsn_offset);
151
+ page_num = internal_bswap_32 (page_num);
152
+ magic = internal_bswap_32 (magic);
153
+ version = internal_bswap_32 (version);
154
+ pagesize = internal_bswap_32 (pagesize);
155
+ free_list = internal_bswap_32 (free_list);
156
+ last_page = internal_bswap_32 (last_page);
157
+ partitions = internal_bswap_32 (partitions);
158
+ key_count = internal_bswap_32 (key_count);
159
+ record_count = internal_bswap_32 (record_count);
160
+ unused2 = internal_bswap_32 (unused2);
161
+ minkey = internal_bswap_32 (minkey);
162
+ re_len = internal_bswap_32 (re_len);
163
+ re_pad = internal_bswap_32 (re_pad);
164
+ root = internal_bswap_32 (root);
165
+ crypto_magic = internal_bswap_32 (crypto_magic);
166
+ }
167
+
141
168
// Page number must match
142
169
if (page_num != expected_page_num) {
143
170
throw std::runtime_error (" Meta page number mismatch" );
@@ -180,6 +207,11 @@ class RecordHeader
180
207
181
208
static constexpr size_t SIZE = 3 ; // The record header is 3 bytes
182
209
210
+ bool other_endian;
211
+
212
+ RecordHeader (bool other_endian) : other_endian(other_endian) {}
213
+ RecordHeader () = delete ;
214
+
183
215
template <typename Stream>
184
216
void Unserialize (Stream& s)
185
217
{
@@ -189,6 +221,10 @@ class RecordHeader
189
221
s >> uint8_type;
190
222
type = static_cast <RecordType>(uint8_type & ~static_cast <uint8_t >(RecordType::DELETE));
191
223
deleted = uint8_type & static_cast <uint8_t >(RecordType::DELETE);
224
+
225
+ if (other_endian) {
226
+ len = internal_bswap_16 (len);
227
+ }
192
228
}
193
229
};
194
230
@@ -236,6 +272,11 @@ class InternalRecord
236
272
237
273
data.resize (m_header.len );
238
274
s.read (AsWritableBytes (Span (data.data (), data.size ())));
275
+
276
+ if (m_header.other_endian ) {
277
+ page_num = internal_bswap_32 (page_num);
278
+ records = internal_bswap_32 (records);
279
+ }
239
280
}
240
281
};
241
282
@@ -263,6 +304,11 @@ class OverflowRecord
263
304
s >> unused2;
264
305
s >> page_number;
265
306
s >> item_len;
307
+
308
+ if (m_header.other_endian ) {
309
+ page_number = internal_bswap_32 (page_number);
310
+ item_len = internal_bswap_32 (item_len);
311
+ }
266
312
}
267
313
};
268
314
@@ -283,8 +329,9 @@ class PageHeader
283
329
static constexpr int64_t SIZE = 26 ; // The header is 26 bytes
284
330
285
331
uint32_t expected_page_num;
332
+ bool other_endian;
286
333
287
- PageHeader (uint32_t page_num) : expected_page_num(page_num) {}
334
+ PageHeader (uint32_t page_num, bool other_endian ) : expected_page_num(page_num), other_endian(other_endian ) {}
288
335
PageHeader () = delete ;
289
336
290
337
template <typename Stream>
@@ -303,6 +350,16 @@ class PageHeader
303
350
s >> uint8_type;
304
351
type = static_cast <PageType>(uint8_type);
305
352
353
+ if (other_endian) {
354
+ lsn_file = internal_bswap_32 (lsn_file);
355
+ lsn_offset = internal_bswap_32 (lsn_offset);
356
+ page_num = internal_bswap_32 (page_num);
357
+ prev_page = internal_bswap_32 (prev_page);
358
+ next_page = internal_bswap_32 (next_page);
359
+ entries = internal_bswap_16 (entries);
360
+ hf_offset = internal_bswap_16 (hf_offset);
361
+ }
362
+
306
363
if (expected_page_num != page_num) {
307
364
throw std::runtime_error (" Page number mismatch" );
308
365
}
@@ -335,6 +392,9 @@ class RecordsPage
335
392
// Get the index
336
393
uint16_t index;
337
394
s >> index;
395
+ if (m_header.other_endian ) {
396
+ index = internal_bswap_16 (index);
397
+ }
338
398
indexes.push_back (index);
339
399
pos += sizeof (uint16_t );
340
400
@@ -346,7 +406,7 @@ class RecordsPage
346
406
s.ignore (to_jump);
347
407
348
408
// Read the record
349
- RecordHeader rec_hdr;
409
+ RecordHeader rec_hdr (m_header. other_endian ) ;
350
410
s >> rec_hdr;
351
411
to_jump += RecordHeader::SIZE;
352
412
@@ -422,6 +482,9 @@ class InternalPage
422
482
// Get the index
423
483
uint16_t index;
424
484
s >> index;
485
+ if (m_header.other_endian ) {
486
+ index = internal_bswap_16 (index);
487
+ }
425
488
indexes.push_back (index);
426
489
pos += sizeof (uint16_t );
427
490
@@ -433,7 +496,7 @@ class InternalPage
433
496
s.ignore (to_jump);
434
497
435
498
// Read the record
436
- RecordHeader rec_hdr;
499
+ RecordHeader rec_hdr (m_header. other_endian ) ;
437
500
s >> rec_hdr;
438
501
to_jump += RecordHeader::SIZE;
439
502
@@ -499,7 +562,7 @@ void BerkeleyRODatabase::Open()
499
562
500
563
// Read the root page
501
564
SeekToPage (db_file, outer_meta.root , page_size);
502
- PageHeader header (outer_meta.root );
565
+ PageHeader header (outer_meta.root , outer_meta. other_endian );
503
566
db_file >> header;
504
567
if (header.type != PageType::BTREE_LEAF) {
505
568
throw std::runtime_error (" Unexpected outer database root page type" );
@@ -558,7 +621,7 @@ void BerkeleyRODatabase::Open()
558
621
// }
559
622
pages.pop_back ();
560
623
SeekToPage (db_file, curr_page, page_size);
561
- PageHeader header (curr_page);
624
+ PageHeader header (curr_page, inner_meta. other_endian );
562
625
db_file >> header;
563
626
switch (header.type ) {
564
627
case PageType::BTREE_INTERNAL: {
@@ -589,7 +652,7 @@ void BerkeleyRODatabase::Open()
589
652
uint32_t next_page = orec->page_number ;
590
653
while (next_page != 0 ) {
591
654
SeekToPage (db_file, next_page, page_size);
592
- PageHeader opage_header (next_page);
655
+ PageHeader opage_header (next_page, inner_meta. other_endian );
593
656
db_file >> opage_header;
594
657
if (opage_header.type != PageType::OVERFLOW_DATA) {
595
658
throw std::runtime_error (" Bad overflow record page type" );
0 commit comments