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); |
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 |