mercurial/parsers.c
changeset 26591 042344313939
parent 26590 473a63c45394
child 26630 3111b45a2bbf
equal deleted inserted replaced
26590:473a63c45394 26591:042344313939
  2547 	return NULL;
  2547 	return NULL;
  2548 }
  2548 }
  2549 
  2549 
  2550 #define BUMPED_FIX 1
  2550 #define BUMPED_FIX 1
  2551 #define USING_SHA_256 2
  2551 #define USING_SHA_256 2
       
  2552 #define FM1_HEADER_SIZE (4 + 8 + 2 + 2 + 1 + 1 + 1)
  2552 
  2553 
  2553 static PyObject *readshas(
  2554 static PyObject *readshas(
  2554 	const char *source, unsigned char num, Py_ssize_t hashwidth)
  2555 	const char *source, unsigned char num, Py_ssize_t hashwidth)
  2555 {
  2556 {
  2556 	int i;
  2557 	int i;
  2568 		source += hashwidth;
  2569 		source += hashwidth;
  2569 	}
  2570 	}
  2570 	return list;
  2571 	return list;
  2571 }
  2572 }
  2572 
  2573 
  2573 static PyObject *fm1readmarker(const char *data, uint32_t *msize)
  2574 static PyObject *fm1readmarker(const char *databegin, const char *dataend,
  2574 {
  2575 			       uint32_t *msize)
       
  2576 {
       
  2577 	const char *data = databegin;
  2575 	const char *meta;
  2578 	const char *meta;
  2576 
  2579 
  2577 	double mtime;
  2580 	double mtime;
  2578 	int16_t tz;
  2581 	int16_t tz;
  2579 	uint16_t flags;
  2582 	uint16_t flags;
  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);