mercurial/parsers.c
changeset 20169 507919a34c5b
parent 20159 96b2dd77c85d
parent 20167 09e41ac6289d
child 20316 40f08c31844c
equal deleted inserted replaced
20166:7eda5bb9ec8f 20169:507919a34c5b
   153 
   153 
   154 static PyObject *parse_dirstate(PyObject *self, PyObject *args)
   154 static PyObject *parse_dirstate(PyObject *self, PyObject *args)
   155 {
   155 {
   156 	PyObject *dmap, *cmap, *parents = NULL, *ret = NULL;
   156 	PyObject *dmap, *cmap, *parents = NULL, *ret = NULL;
   157 	PyObject *fname = NULL, *cname = NULL, *entry = NULL;
   157 	PyObject *fname = NULL, *cname = NULL, *entry = NULL;
   158 	char state, *str, *cur, *end, *cpos;
   158 	char state, *cur, *str, *cpos;
   159 	int mode, size, mtime;
   159 	int mode, size, mtime;
   160 	unsigned int flen;
   160 	unsigned int flen;
   161 	int len;
   161 	int len, pos = 40;
   162 
   162 
   163 	if (!PyArg_ParseTuple(args, "O!O!s#:parse_dirstate",
   163 	if (!PyArg_ParseTuple(args, "O!O!s#:parse_dirstate",
   164 			      &PyDict_Type, &dmap,
   164 			      &PyDict_Type, &dmap,
   165 			      &PyDict_Type, &cmap,
   165 			      &PyDict_Type, &cmap,
   166 			      &str, &len))
   166 			      &str, &len))
   173 	parents = Py_BuildValue("s#s#", str, 20, str + 20, 20);
   173 	parents = Py_BuildValue("s#s#", str, 20, str + 20, 20);
   174 	if (!parents)
   174 	if (!parents)
   175 		goto quit;
   175 		goto quit;
   176 
   176 
   177 	/* read filenames */
   177 	/* read filenames */
   178 	cur = str + 40;
   178 	while (pos >= 40 && pos < len) {
   179 	end = str + len;
   179 		cur = str + pos;
   180 
       
   181 	while (cur < end - 17) {
       
   182 		/* unpack header */
   180 		/* unpack header */
   183 		state = *cur;
   181 		state = *cur;
   184 		mode = getbe32(cur + 1);
   182 		mode = getbe32(cur + 1);
   185 		size = getbe32(cur + 5);
   183 		size = getbe32(cur + 5);
   186 		mtime = getbe32(cur + 9);
   184 		mtime = getbe32(cur + 9);
   187 		flen = getbe32(cur + 13);
   185 		flen = getbe32(cur + 13);
       
   186 		pos += 17;
   188 		cur += 17;
   187 		cur += 17;
   189 		if (cur + flen > end || cur + flen < cur) {
   188 		if (flen > len - pos || flen < 0) {
   190 			PyErr_SetString(PyExc_ValueError, "overflow in dirstate");
   189 			PyErr_SetString(PyExc_ValueError, "overflow in dirstate");
   191 			goto quit;
   190 			goto quit;
   192 		}
   191 		}
   193 
   192 
   194 		entry = Py_BuildValue("ciii", state, mode, size, mtime);
   193 		entry = Py_BuildValue("ciii", state, mode, size, mtime);
   210 			fname = PyBytes_FromStringAndSize(cur, flen);
   209 			fname = PyBytes_FromStringAndSize(cur, flen);
   211 			if (!fname ||
   210 			if (!fname ||
   212 			    PyDict_SetItem(dmap, fname, entry) == -1)
   211 			    PyDict_SetItem(dmap, fname, entry) == -1)
   213 				goto quit;
   212 				goto quit;
   214 		}
   213 		}
   215 		cur += flen;
       
   216 		Py_DECREF(fname);
   214 		Py_DECREF(fname);
   217 		Py_DECREF(entry);
   215 		Py_DECREF(entry);
   218 		fname = cname = entry = NULL;
   216 		fname = cname = entry = NULL;
       
   217 		pos += flen;
   219 	}
   218 	}
   220 
   219 
   221 	ret = parents;
   220 	ret = parents;
   222 	Py_INCREF(ret);
   221 	Py_INCREF(ret);
   223 quit:
   222 quit:
  1681  * the optional "offsets" table with those entries.
  1680  * the optional "offsets" table with those entries.
  1682  */
  1681  */
  1683 static long inline_scan(indexObject *self, const char **offsets)
  1682 static long inline_scan(indexObject *self, const char **offsets)
  1684 {
  1683 {
  1685 	const char *data = PyString_AS_STRING(self->data);
  1684 	const char *data = PyString_AS_STRING(self->data);
  1686 	const char *end = data + PyString_GET_SIZE(self->data);
  1685 	Py_ssize_t pos = 0;
       
  1686 	Py_ssize_t end = PyString_GET_SIZE(self->data);
  1687 	long incr = v1_hdrsize;
  1687 	long incr = v1_hdrsize;
  1688 	Py_ssize_t len = 0;
  1688 	Py_ssize_t len = 0;
  1689 
  1689 
  1690 	while (data + v1_hdrsize <= end) {
  1690 	while (pos + v1_hdrsize <= end && pos >= 0) {
  1691 		uint32_t comp_len;
  1691 		uint32_t comp_len;
  1692 		const char *old_data;
       
  1693 		/* 3rd element of header is length of compressed inline data */
  1692 		/* 3rd element of header is length of compressed inline data */
  1694 		comp_len = getbe32(data + 8);
  1693 		comp_len = getbe32(data + pos + 8);
  1695 		incr = v1_hdrsize + comp_len;
  1694 		incr = v1_hdrsize + comp_len;
  1696 		if (incr < v1_hdrsize)
       
  1697 			break;
       
  1698 		if (offsets)
  1695 		if (offsets)
  1699 			offsets[len] = data;
  1696 			offsets[len] = data + pos;
  1700 		len++;
  1697 		len++;
  1701 		old_data = data;
  1698 		pos += incr;
  1702 		data += incr;
  1699 	}
  1703 		if (data <= old_data)
  1700 
  1704 			break;
  1701 	if (pos != end) {
  1705 	}
       
  1706 
       
  1707 	if (data != end && data + v1_hdrsize != end) {
       
  1708 		if (!PyErr_Occurred())
  1702 		if (!PyErr_Occurred())
  1709 			PyErr_SetString(PyExc_ValueError, "corrupt index file");
  1703 			PyErr_SetString(PyExc_ValueError, "corrupt index file");
  1710 		return -1;
  1704 		return -1;
  1711 	}
  1705 	}
  1712 
  1706