Show More
@@ -136,19 +136,29 b' static const long v2_entry_size = 96;' | |||||
136 | static const long format_v1 = 1; /* Internal only, could be any number */ |
|
136 | static const long format_v1 = 1; /* Internal only, could be any number */ | |
137 | static const long format_v2 = 2; /* Internal only, could be any number */ |
|
137 | static const long format_v2 = 2; /* Internal only, could be any number */ | |
138 |
|
138 | |||
139 | static const long entry_offset_high = 0; |
|
139 | static const long entry_v1_offset_high = 0; | |
140 | static const long entry_offset_offset_flags = 4; |
|
140 | static const long entry_v1_offset_offset_flags = 4; | |
141 | static const long entry_offset_comp_len = 8; |
|
141 | static const long entry_v1_offset_comp_len = 8; | |
142 | static const long entry_offset_uncomp_len = 12; |
|
142 | static const long entry_v1_offset_uncomp_len = 12; | |
143 | static const long entry_offset_base_rev = 16; |
|
143 | static const long entry_v1_offset_base_rev = 16; | |
144 | static const long entry_offset_link_rev = 20; |
|
144 | static const long entry_v1_offset_link_rev = 20; | |
145 | static const long entry_offset_parent_1 = 24; |
|
145 | static const long entry_v1_offset_parent_1 = 24; | |
146 | static const long entry_offset_parent_2 = 28; |
|
146 | static const long entry_v1_offset_parent_2 = 28; | |
147 | static const long entry_offset_node_id = 32; |
|
147 | static const long entry_v1_offset_node_id = 32; | |
148 | static const long entry_offset_sidedata_offset = 64; |
|
148 | ||
149 |
static const long entry_offset_ |
|
149 | static const long entry_v2_offset_high = 0; | |
150 |
static const long entry_offset_ |
|
150 | static const long entry_v2_offset_offset_flags = 4; | |
151 |
static const long entry_offset_ |
|
151 | static const long entry_v2_offset_comp_len = 8; | |
|
152 | static const long entry_v2_offset_uncomp_len = 12; | |||
|
153 | static const long entry_v2_offset_base_rev = 16; | |||
|
154 | static const long entry_v2_offset_link_rev = 20; | |||
|
155 | static const long entry_v2_offset_parent_1 = 24; | |||
|
156 | static const long entry_v2_offset_parent_2 = 28; | |||
|
157 | static const long entry_v2_offset_node_id = 32; | |||
|
158 | static const long entry_v2_offset_sidedata_offset = 64; | |||
|
159 | static const long entry_v2_offset_sidedata_comp_len = 72; | |||
|
160 | static const long entry_v2_offset_all_comp_mode = 76; | |||
|
161 | static const long entry_v2_offset_padding_start = 77; | |||
152 |
|
162 | |||
153 | static const char comp_mode_inline = 2; |
|
163 | static const char comp_mode_inline = 2; | |
154 | static const char rank_unknown = -1; |
|
164 | static const char rank_unknown = -1; | |
@@ -220,8 +230,16 b' static inline int index_get_parents(inde' | |||||
220 | { |
|
230 | { | |
221 | const char *data = index_deref(self, rev); |
|
231 | const char *data = index_deref(self, rev); | |
222 |
|
232 | |||
223 | ps[0] = getbe32(data + entry_offset_parent_1); |
|
233 | if (self->format_version == format_v1) { | |
224 |
ps[ |
|
234 | ps[0] = getbe32(data + entry_v1_offset_parent_1); | |
|
235 | ps[1] = getbe32(data + entry_v1_offset_parent_2); | |||
|
236 | } else if (self->format_version == format_v2) { | |||
|
237 | ps[0] = getbe32(data + entry_v2_offset_parent_1); | |||
|
238 | ps[1] = getbe32(data + entry_v2_offset_parent_2); | |||
|
239 | } else { | |||
|
240 | raise_revlog_error(); | |||
|
241 | return -1; | |||
|
242 | } | |||
225 |
|
243 | |||
226 | /* If index file is corrupted, ps[] may point to invalid revisions. So |
|
244 | /* If index file is corrupted, ps[] may point to invalid revisions. So | |
227 | * there is a risk of buffer overflow to trust them unconditionally. */ |
|
245 | * there is a risk of buffer overflow to trust them unconditionally. */ | |
@@ -268,14 +286,32 b' static inline int64_t index_get_start(in' | |||||
268 | return 0; |
|
286 | return 0; | |
269 |
|
287 | |||
270 | data = index_deref(self, rev); |
|
288 | data = index_deref(self, rev); | |
271 | offset = getbe32(data + entry_offset_offset_flags); |
|
289 | ||
272 | if (rev == 0) { |
|
290 | if (self->format_version == format_v1) { | |
273 | /* mask out version number for the first entry */ |
|
291 | offset = getbe32(data + entry_v1_offset_offset_flags); | |
274 | offset &= 0xFFFF; |
|
292 | if (rev == 0) { | |
|
293 | /* mask out version number for the first entry */ | |||
|
294 | offset &= 0xFFFF; | |||
|
295 | } else { | |||
|
296 | uint32_t offset_high = | |||
|
297 | getbe32(data + entry_v1_offset_high); | |||
|
298 | offset |= ((uint64_t)offset_high) << 32; | |||
|
299 | } | |||
|
300 | } else if (self->format_version == format_v2) { | |||
|
301 | offset = getbe32(data + entry_v2_offset_offset_flags); | |||
|
302 | if (rev == 0) { | |||
|
303 | /* mask out version number for the first entry */ | |||
|
304 | offset &= 0xFFFF; | |||
|
305 | } else { | |||
|
306 | uint32_t offset_high = | |||
|
307 | getbe32(data + entry_v2_offset_high); | |||
|
308 | offset |= ((uint64_t)offset_high) << 32; | |||
|
309 | } | |||
275 | } else { |
|
310 | } else { | |
276 | uint32_t offset_high = getbe32(data + entry_offset_high); |
|
311 | raise_revlog_error(); | |
277 | offset |= ((uint64_t)offset_high) << 32; |
|
312 | return -1; | |
278 | } |
|
313 | } | |
|
314 | ||||
279 | return (int64_t)(offset >> 16); |
|
315 | return (int64_t)(offset >> 16); | |
280 | } |
|
316 | } | |
281 |
|
317 | |||
@@ -289,7 +325,14 b' static inline int index_get_length(index' | |||||
289 |
|
325 | |||
290 | data = index_deref(self, rev); |
|
326 | data = index_deref(self, rev); | |
291 |
|
327 | |||
292 | tmp = (int)getbe32(data + entry_offset_comp_len); |
|
328 | if (self->format_version == format_v1) { | |
|
329 | tmp = (int)getbe32(data + entry_v1_offset_comp_len); | |||
|
330 | } else if (self->format_version == format_v2) { | |||
|
331 | tmp = (int)getbe32(data + entry_v2_offset_comp_len); | |||
|
332 | } else { | |||
|
333 | raise_revlog_error(); | |||
|
334 | return -1; | |||
|
335 | } | |||
293 | if (tmp < 0) { |
|
336 | if (tmp < 0) { | |
294 | PyErr_Format(PyExc_OverflowError, |
|
337 | PyErr_Format(PyExc_OverflowError, | |
295 | "revlog entry size out of bound (%d)", tmp); |
|
338 | "revlog entry size out of bound (%d)", tmp); | |
@@ -334,38 +377,66 b' static PyObject *index_get(indexObject *' | |||||
334 | if (data == NULL) |
|
377 | if (data == NULL) | |
335 | return NULL; |
|
378 | return NULL; | |
336 |
|
379 | |||
337 | offset_flags = getbe32(data + entry_offset_offset_flags); |
|
|||
338 | /* |
|
|||
339 | * The first entry on-disk needs the version number masked out, |
|
|||
340 | * but this doesn't apply if entries are added to an empty index. |
|
|||
341 | */ |
|
|||
342 | if (self->length && pos == 0) |
|
|||
343 | offset_flags &= 0xFFFF; |
|
|||
344 | else { |
|
|||
345 | uint32_t offset_high = getbe32(data + entry_offset_high); |
|
|||
346 | offset_flags |= ((uint64_t)offset_high) << 32; |
|
|||
347 | } |
|
|||
348 |
|
||||
349 | comp_len = getbe32(data + entry_offset_comp_len); |
|
|||
350 | uncomp_len = getbe32(data + entry_offset_uncomp_len); |
|
|||
351 | base_rev = getbe32(data + entry_offset_base_rev); |
|
|||
352 | link_rev = getbe32(data + entry_offset_link_rev); |
|
|||
353 | parent_1 = getbe32(data + entry_offset_parent_1); |
|
|||
354 | parent_2 = getbe32(data + entry_offset_parent_2); |
|
|||
355 | c_node_id = data + entry_offset_node_id; |
|
|||
356 |
|
||||
357 | if (self->format_version == format_v1) { |
|
380 | if (self->format_version == format_v1) { | |
|
381 | offset_flags = getbe32(data + entry_v1_offset_offset_flags); | |||
|
382 | /* | |||
|
383 | * The first entry on-disk needs the version number masked out, | |||
|
384 | * but this doesn't apply if entries are added to an empty | |||
|
385 | * index. | |||
|
386 | */ | |||
|
387 | if (self->length && pos == 0) | |||
|
388 | offset_flags &= 0xFFFF; | |||
|
389 | else { | |||
|
390 | uint32_t offset_high = | |||
|
391 | getbe32(data + entry_v1_offset_high); | |||
|
392 | offset_flags |= ((uint64_t)offset_high) << 32; | |||
|
393 | } | |||
|
394 | ||||
|
395 | comp_len = getbe32(data + entry_v1_offset_comp_len); | |||
|
396 | uncomp_len = getbe32(data + entry_v1_offset_uncomp_len); | |||
|
397 | base_rev = getbe32(data + entry_v1_offset_base_rev); | |||
|
398 | link_rev = getbe32(data + entry_v1_offset_link_rev); | |||
|
399 | parent_1 = getbe32(data + entry_v1_offset_parent_1); | |||
|
400 | parent_2 = getbe32(data + entry_v1_offset_parent_2); | |||
|
401 | c_node_id = data + entry_v1_offset_node_id; | |||
|
402 | ||||
358 | sidedata_offset = 0; |
|
403 | sidedata_offset = 0; | |
359 | sidedata_comp_len = 0; |
|
404 | sidedata_comp_len = 0; | |
360 | data_comp_mode = comp_mode_inline; |
|
405 | data_comp_mode = comp_mode_inline; | |
361 | sidedata_comp_mode = comp_mode_inline; |
|
406 | sidedata_comp_mode = comp_mode_inline; | |
362 | } else { |
|
407 | } else if (self->format_version == format_v2) { | |
363 |
|
|
408 | offset_flags = getbe32(data + entry_v2_offset_offset_flags); | |
|
409 | /* | |||
|
410 | * The first entry on-disk needs the version number masked out, | |||
|
411 | * but this doesn't apply if entries are added to an empty | |||
|
412 | * index. | |||
|
413 | */ | |||
|
414 | if (self->length && pos == 0) | |||
|
415 | offset_flags &= 0xFFFF; | |||
|
416 | else { | |||
|
417 | uint32_t offset_high = | |||
|
418 | getbe32(data + entry_v2_offset_high); | |||
|
419 | offset_flags |= ((uint64_t)offset_high) << 32; | |||
|
420 | } | |||
|
421 | ||||
|
422 | comp_len = getbe32(data + entry_v2_offset_comp_len); | |||
|
423 | uncomp_len = getbe32(data + entry_v2_offset_uncomp_len); | |||
|
424 | base_rev = getbe32(data + entry_v2_offset_base_rev); | |||
|
425 | link_rev = getbe32(data + entry_v2_offset_link_rev); | |||
|
426 | parent_1 = getbe32(data + entry_v2_offset_parent_1); | |||
|
427 | parent_2 = getbe32(data + entry_v2_offset_parent_2); | |||
|
428 | c_node_id = data + entry_v2_offset_node_id; | |||
|
429 | ||||
|
430 | sidedata_offset = | |||
|
431 | getbe64(data + entry_v2_offset_sidedata_offset); | |||
364 | sidedata_comp_len = |
|
432 | sidedata_comp_len = | |
365 | getbe32(data + entry_offset_sidedata_comp_len); |
|
433 | getbe32(data + entry_v2_offset_sidedata_comp_len); | |
366 | data_comp_mode = data[entry_offset_all_comp_mode] & 3; |
|
434 | data_comp_mode = data[entry_v2_offset_all_comp_mode] & 3; | |
367 | sidedata_comp_mode = |
|
435 | sidedata_comp_mode = | |
368 | ((data[entry_offset_all_comp_mode] >> 2) & 3); |
|
436 | ((data[entry_v2_offset_all_comp_mode] >> 2) & 3); | |
|
437 | } else { | |||
|
438 | raise_revlog_error(); | |||
|
439 | return NULL; | |||
369 | } |
|
440 | } | |
370 |
|
441 | |||
371 | return Py_BuildValue(tuple_format, offset_flags, comp_len, uncomp_len, |
|
442 | return Py_BuildValue(tuple_format, offset_flags, comp_len, uncomp_len, | |
@@ -429,6 +500,7 b' static const char *index_node(indexObjec' | |||||
429 | { |
|
500 | { | |
430 | Py_ssize_t length = index_length(self); |
|
501 | Py_ssize_t length = index_length(self); | |
431 | const char *data; |
|
502 | const char *data; | |
|
503 | const char *node_id; | |||
432 |
|
504 | |||
433 | if (pos == nullrev) |
|
505 | if (pos == nullrev) | |
434 | return nullid; |
|
506 | return nullid; | |
@@ -437,7 +509,17 b' static const char *index_node(indexObjec' | |||||
437 | return NULL; |
|
509 | return NULL; | |
438 |
|
510 | |||
439 | data = index_deref(self, pos); |
|
511 | data = index_deref(self, pos); | |
440 | return data ? data + entry_offset_node_id : NULL; |
|
512 | ||
|
513 | if (self->format_version == format_v1) { | |||
|
514 | node_id = data + entry_v1_offset_node_id; | |||
|
515 | } else if (self->format_version == format_v2) { | |||
|
516 | node_id = data + entry_v2_offset_node_id; | |||
|
517 | } else { | |||
|
518 | raise_revlog_error(); | |||
|
519 | return NULL; | |||
|
520 | } | |||
|
521 | ||||
|
522 | return data ? node_id : NULL; | |||
441 | } |
|
523 | } | |
442 |
|
524 | |||
443 | /* |
|
525 | /* | |
@@ -520,28 +602,50 b' static PyObject *index_append(indexObjec' | |||||
520 | } |
|
602 | } | |
521 | rev = self->length + self->new_length; |
|
603 | rev = self->length + self->new_length; | |
522 | data = self->added + self->entry_size * self->new_length++; |
|
604 | data = self->added + self->entry_size * self->new_length++; | |
523 | putbe32(offset_flags >> 32, data + entry_offset_high); |
|
605 | ||
524 | putbe32(offset_flags & 0xffffffffU, data + entry_offset_offset_flags); |
|
606 | if (self->format_version == format_v1) { | |
525 |
putbe32( |
|
607 | putbe32(offset_flags >> 32, data + entry_v1_offset_high); | |
526 | putbe32(uncomp_len, data + entry_offset_uncomp_len); |
|
608 | putbe32(offset_flags & 0xffffffffU, | |
527 | putbe32(base_rev, data + entry_offset_base_rev); |
|
609 | data + entry_v1_offset_offset_flags); | |
528 |
putbe32( |
|
610 | putbe32(comp_len, data + entry_v1_offset_comp_len); | |
529 |
putbe32( |
|
611 | putbe32(uncomp_len, data + entry_v1_offset_uncomp_len); | |
530 |
putbe32( |
|
612 | putbe32(base_rev, data + entry_v1_offset_base_rev); | |
531 | memcpy(data + entry_offset_node_id, c_node_id, c_node_id_len); |
|
613 | putbe32(link_rev, data + entry_v1_offset_link_rev); | |
532 | /* Padding since SHA-1 is only 20 bytes for now */ |
|
614 | putbe32(parent_1, data + entry_v1_offset_parent_1); | |
533 | memset(data + entry_offset_node_id + c_node_id_len, 0, |
|
615 | putbe32(parent_2, data + entry_v1_offset_parent_2); | |
534 |
|
|
616 | memcpy(data + entry_v1_offset_node_id, c_node_id, | |
535 | if (self->format_version == format_v2) { |
|
617 | c_node_id_len); | |
536 | putbe64(sidedata_offset, data + entry_offset_sidedata_offset); |
|
618 | /* Padding since SHA-1 is only 20 bytes for now */ | |
|
619 | memset(data + entry_v1_offset_node_id + c_node_id_len, 0, | |||
|
620 | entry_v1_offset_node_id - c_node_id_len); | |||
|
621 | } else if (self->format_version == format_v2) { | |||
|
622 | putbe32(offset_flags >> 32, data + entry_v2_offset_high); | |||
|
623 | putbe32(offset_flags & 0xffffffffU, | |||
|
624 | data + entry_v2_offset_offset_flags); | |||
|
625 | putbe32(comp_len, data + entry_v2_offset_comp_len); | |||
|
626 | putbe32(uncomp_len, data + entry_v2_offset_uncomp_len); | |||
|
627 | putbe32(base_rev, data + entry_v2_offset_base_rev); | |||
|
628 | putbe32(link_rev, data + entry_v2_offset_link_rev); | |||
|
629 | putbe32(parent_1, data + entry_v2_offset_parent_1); | |||
|
630 | putbe32(parent_2, data + entry_v2_offset_parent_2); | |||
|
631 | memcpy(data + entry_v2_offset_node_id, c_node_id, | |||
|
632 | c_node_id_len); | |||
|
633 | /* Padding since SHA-1 is only 20 bytes for now */ | |||
|
634 | memset(data + entry_v2_offset_node_id + c_node_id_len, 0, | |||
|
635 | entry_v2_offset_node_id - c_node_id_len); | |||
|
636 | putbe64(sidedata_offset, | |||
|
637 | data + entry_v2_offset_sidedata_offset); | |||
537 | putbe32(sidedata_comp_len, |
|
638 | putbe32(sidedata_comp_len, | |
538 | data + entry_offset_sidedata_comp_len); |
|
639 | data + entry_v2_offset_sidedata_comp_len); | |
539 | comp_field = data_comp_mode & 3; |
|
640 | comp_field = data_comp_mode & 3; | |
540 | comp_field = comp_field | (sidedata_comp_mode & 3) << 2; |
|
641 | comp_field = comp_field | (sidedata_comp_mode & 3) << 2; | |
541 | data[entry_offset_all_comp_mode] = comp_field; |
|
642 | data[entry_v2_offset_all_comp_mode] = comp_field; | |
542 | /* Padding for 96 bytes alignment */ |
|
643 | /* Padding for 96 bytes alignment */ | |
543 | memset(data + entry_offset_padding_start, 0, |
|
644 | memset(data + entry_v2_offset_padding_start, 0, | |
544 | self->entry_size - entry_offset_padding_start); |
|
645 | self->entry_size - entry_v2_offset_padding_start); | |
|
646 | } else { | |||
|
647 | raise_revlog_error(); | |||
|
648 | return NULL; | |||
545 | } |
|
649 | } | |
546 |
|
650 | |||
547 | if (self->ntinitialized) |
|
651 | if (self->ntinitialized) | |
@@ -596,11 +700,11 b' static PyObject *index_replace_sidedata_' | |||||
596 | /* Find the newly added node, offset from the "already on-disk" length |
|
700 | /* Find the newly added node, offset from the "already on-disk" length | |
597 | */ |
|
701 | */ | |
598 | data = self->added + self->entry_size * (rev - self->length); |
|
702 | data = self->added + self->entry_size * (rev - self->length); | |
599 | putbe64(offset_flags, data + entry_offset_high); |
|
703 | putbe64(offset_flags, data + entry_v2_offset_high); | |
600 | putbe64(sidedata_offset, data + entry_offset_sidedata_offset); |
|
704 | putbe64(sidedata_offset, data + entry_v2_offset_sidedata_offset); | |
601 | putbe32(sidedata_comp_len, data + entry_offset_sidedata_comp_len); |
|
705 | putbe32(sidedata_comp_len, data + entry_v2_offset_sidedata_comp_len); | |
602 | data[entry_offset_all_comp_mode] = |
|
706 | data[entry_v2_offset_all_comp_mode] = | |
603 | (data[entry_offset_all_comp_mode] & ~(3 << 2)) | |
|
707 | (data[entry_v2_offset_all_comp_mode] & ~(3 << 2)) | | |
604 | ((comp_mode & 3) << 2); |
|
708 | ((comp_mode & 3) << 2); | |
605 |
|
709 | |||
606 | Py_RETURN_NONE; |
|
710 | Py_RETURN_NONE; | |
@@ -1144,7 +1248,15 b' static inline int index_baserev(indexObj' | |||||
1144 | data = index_deref(self, rev); |
|
1248 | data = index_deref(self, rev); | |
1145 | if (data == NULL) |
|
1249 | if (data == NULL) | |
1146 | return -2; |
|
1250 | return -2; | |
1147 | result = getbe32(data + entry_offset_base_rev); |
|
1251 | ||
|
1252 | if (self->format_version == format_v1) { | |||
|
1253 | result = getbe32(data + entry_v1_offset_base_rev); | |||
|
1254 | } else if (self->format_version == format_v2) { | |||
|
1255 | result = getbe32(data + entry_v2_offset_base_rev); | |||
|
1256 | } else { | |||
|
1257 | raise_revlog_error(); | |||
|
1258 | return -1; | |||
|
1259 | } | |||
1148 |
|
1260 | |||
1149 | if (result > rev) { |
|
1261 | if (result > rev) { | |
1150 | PyErr_Format( |
|
1262 | PyErr_Format( | |
@@ -2756,10 +2868,18 b' static Py_ssize_t inline_scan(indexObjec' | |||||
2756 | while (pos + self->entry_size <= end && pos >= 0) { |
|
2868 | while (pos + self->entry_size <= end && pos >= 0) { | |
2757 | uint32_t comp_len, sidedata_comp_len = 0; |
|
2869 | uint32_t comp_len, sidedata_comp_len = 0; | |
2758 | /* 3rd element of header is length of compressed inline data */ |
|
2870 | /* 3rd element of header is length of compressed inline data */ | |
2759 | comp_len = getbe32(data + pos + entry_offset_comp_len); |
|
2871 | if (self->format_version == format_v1) { | |
2760 | if (self->entry_size == v2_entry_size) { |
|
2872 | comp_len = | |
|
2873 | getbe32(data + pos + entry_v1_offset_comp_len); | |||
|
2874 | sidedata_comp_len = 0; | |||
|
2875 | } else if (self->format_version == format_v2) { | |||
|
2876 | comp_len = | |||
|
2877 | getbe32(data + pos + entry_v2_offset_comp_len); | |||
2761 | sidedata_comp_len = getbe32( |
|
2878 | sidedata_comp_len = getbe32( | |
2762 | data + pos + entry_offset_sidedata_comp_len); |
|
2879 | data + pos + entry_v2_offset_sidedata_comp_len); | |
|
2880 | } else { | |||
|
2881 | raise_revlog_error(); | |||
|
2882 | return -1; | |||
2763 | } |
|
2883 | } | |
2764 | incr = self->entry_size + comp_len + sidedata_comp_len; |
|
2884 | incr = self->entry_size + comp_len + sidedata_comp_len; | |
2765 | if (offsets) |
|
2885 | if (offsets) |
General Comments 0
You need to be logged in to leave comments.
Login now