2581 Py_ssize_t hashwidth = 20; |
2584 Py_ssize_t hashwidth = 20; |
2582 |
2585 |
2583 PyObject *prec = NULL, *parents = NULL, *succs = NULL; |
2586 PyObject *prec = NULL, *parents = NULL, *succs = NULL; |
2584 PyObject *metadata = NULL, *ret = NULL; |
2587 PyObject *metadata = NULL, *ret = NULL; |
2585 int i; |
2588 int i; |
|
2589 |
|
2590 if (data + FM1_HEADER_SIZE > dataend) { |
|
2591 goto overflow; |
|
2592 } |
2586 |
2593 |
2587 *msize = getbe32(data); |
2594 *msize = getbe32(data); |
2588 data += 4; |
2595 data += 4; |
2589 mtime = getbefloat64(data); |
2596 mtime = getbefloat64(data); |
2590 data += 8; |
2597 data += 8; |
2599 |
2606 |
2600 nsuccs = (unsigned char)(*data++); |
2607 nsuccs = (unsigned char)(*data++); |
2601 nparents = (unsigned char)(*data++); |
2608 nparents = (unsigned char)(*data++); |
2602 nmetadata = (unsigned char)(*data++); |
2609 nmetadata = (unsigned char)(*data++); |
2603 |
2610 |
|
2611 if (databegin + *msize > dataend) { |
|
2612 goto overflow; |
|
2613 } |
|
2614 dataend = databegin + *msize; /* narrow down to marker size */ |
|
2615 |
|
2616 if (data + hashwidth > dataend) { |
|
2617 goto overflow; |
|
2618 } |
2604 prec = PyString_FromStringAndSize(data, hashwidth); |
2619 prec = PyString_FromStringAndSize(data, hashwidth); |
2605 data += hashwidth; |
2620 data += hashwidth; |
2606 if (prec == NULL) { |
2621 if (prec == NULL) { |
2607 goto bail; |
2622 goto bail; |
2608 } |
2623 } |
2609 |
2624 |
|
2625 if (data + nsuccs * hashwidth > dataend) { |
|
2626 goto overflow; |
|
2627 } |
2610 succs = readshas(data, nsuccs, hashwidth); |
2628 succs = readshas(data, nsuccs, hashwidth); |
2611 if (succs == NULL) { |
2629 if (succs == NULL) { |
2612 goto bail; |
2630 goto bail; |
2613 } |
2631 } |
2614 data += nsuccs * hashwidth; |
2632 data += nsuccs * hashwidth; |
2615 |
2633 |
2616 if (nparents == 1 || nparents == 2) { |
2634 if (nparents == 1 || nparents == 2) { |
|
2635 if (data + nparents * hashwidth > dataend) { |
|
2636 goto overflow; |
|
2637 } |
2617 parents = readshas(data, nparents, hashwidth); |
2638 parents = readshas(data, nparents, hashwidth); |
2618 if (parents == NULL) { |
2639 if (parents == NULL) { |
2619 goto bail; |
2640 goto bail; |
2620 } |
2641 } |
2621 data += nparents * hashwidth; |
2642 data += nparents * hashwidth; |
2622 } else { |
2643 } else { |
2623 parents = Py_None; |
2644 parents = Py_None; |
2624 } |
2645 } |
2625 |
2646 |
|
2647 if (data + 2 * nmetadata > dataend) { |
|
2648 goto overflow; |
|
2649 } |
2626 meta = data + (2 * nmetadata); |
2650 meta = data + (2 * nmetadata); |
2627 metadata = PyTuple_New(nmetadata); |
2651 metadata = PyTuple_New(nmetadata); |
2628 if (metadata == NULL) { |
2652 if (metadata == NULL) { |
2629 goto bail; |
2653 goto bail; |
2630 } |
2654 } |
2631 for (i = 0; i < nmetadata; i++) { |
2655 for (i = 0; i < nmetadata; i++) { |
2632 PyObject *tmp, *left = NULL, *right = NULL; |
2656 PyObject *tmp, *left = NULL, *right = NULL; |
2633 Py_ssize_t leftsize = (unsigned char)(*data++); |
2657 Py_ssize_t leftsize = (unsigned char)(*data++); |
2634 Py_ssize_t rightsize = (unsigned char)(*data++); |
2658 Py_ssize_t rightsize = (unsigned char)(*data++); |
|
2659 if (meta + leftsize + rightsize > dataend) { |
|
2660 goto overflow; |
|
2661 } |
2635 left = PyString_FromStringAndSize(meta, leftsize); |
2662 left = PyString_FromStringAndSize(meta, leftsize); |
2636 meta += leftsize; |
2663 meta += leftsize; |
2637 right = PyString_FromStringAndSize(meta, rightsize); |
2664 right = PyString_FromStringAndSize(meta, rightsize); |
2638 meta += rightsize; |
2665 meta += rightsize; |
2639 tmp = PyTuple_New(2); |
2666 tmp = PyTuple_New(2); |
2647 PyTuple_SET_ITEM(tmp, 1, right); |
2674 PyTuple_SET_ITEM(tmp, 1, right); |
2648 PyTuple_SET_ITEM(metadata, i, tmp); |
2675 PyTuple_SET_ITEM(metadata, i, tmp); |
2649 } |
2676 } |
2650 ret = Py_BuildValue("(OOHO(di)O)", prec, succs, flags, |
2677 ret = Py_BuildValue("(OOHO(di)O)", prec, succs, flags, |
2651 metadata, mtime, (int)tz * 60, parents); |
2678 metadata, mtime, (int)tz * 60, parents); |
|
2679 goto bail; /* return successfully */ |
|
2680 |
|
2681 overflow: |
|
2682 PyErr_SetString(PyExc_ValueError, "overflow in obsstore"); |
2652 bail: |
2683 bail: |
2653 Py_XDECREF(prec); |
2684 Py_XDECREF(prec); |
2654 Py_XDECREF(succs); |
2685 Py_XDECREF(succs); |
2655 Py_XDECREF(metadata); |
2686 Py_XDECREF(metadata); |
2656 if (parents != Py_None) |
2687 if (parents != Py_None) |
2658 return ret; |
2689 return ret; |
2659 } |
2690 } |
2660 |
2691 |
2661 |
2692 |
2662 static PyObject *fm1readmarkers(PyObject *self, PyObject *args) { |
2693 static PyObject *fm1readmarkers(PyObject *self, PyObject *args) { |
2663 const char *data; |
2694 const char *data, *dataend; |
2664 Py_ssize_t datalen; |
2695 Py_ssize_t datalen; |
2665 Py_ssize_t offset, stop; |
2696 Py_ssize_t offset, stop; |
2666 PyObject *markers = NULL; |
2697 PyObject *markers = NULL; |
2667 |
2698 |
2668 if (!PyArg_ParseTuple(args, "s#nn", &data, &datalen, &offset, &stop)) { |
2699 if (!PyArg_ParseTuple(args, "s#nn", &data, &datalen, &offset, &stop)) { |
2669 return NULL; |
2700 return NULL; |
2670 } |
2701 } |
|
2702 dataend = data + datalen; |
2671 data += offset; |
2703 data += offset; |
2672 markers = PyList_New(0); |
2704 markers = PyList_New(0); |
2673 if (!markers) { |
2705 if (!markers) { |
2674 return NULL; |
2706 return NULL; |
2675 } |
2707 } |
2676 while (offset < stop) { |
2708 while (offset < stop) { |
2677 uint32_t msize; |
2709 uint32_t msize; |
2678 int error; |
2710 int error; |
2679 PyObject *record = fm1readmarker(data, &msize); |
2711 PyObject *record = fm1readmarker(data, dataend, &msize); |
2680 if (!record) { |
2712 if (!record) { |
2681 goto bail; |
2713 goto bail; |
2682 } |
2714 } |
2683 error = PyList_Append(markers, record); |
2715 error = PyList_Append(markers, record); |
2684 Py_DECREF(record); |
2716 Py_DECREF(record); |