|
@@ -22,13 +22,13 @@
|
|
|
|
|
|
static int py_is_sha(PyObject *sha)
|
|
|
{
|
|
|
- if (!PyString_CheckExact(sha))
|
|
|
- return 0;
|
|
|
+ if (!PyString_CheckExact(sha))
|
|
|
+ return 0;
|
|
|
|
|
|
- if (PyString_Size(sha) != 20)
|
|
|
- return 0;
|
|
|
+ if (PyString_Size(sha) != 20)
|
|
|
+ return 0;
|
|
|
|
|
|
- return 1;
|
|
|
+ return 1;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -79,37 +79,37 @@ static PyObject *py_apply_delta(PyObject *self, PyObject *args)
|
|
|
size_t outindex = 0;
|
|
|
int index;
|
|
|
uint8_t *out;
|
|
|
- PyObject *ret, *py_src_buf, *py_delta;
|
|
|
+ PyObject *ret, *py_src_buf, *py_delta, *ret_list;
|
|
|
|
|
|
if (!PyArg_ParseTuple(args, "OO", &py_src_buf, &py_delta))
|
|
|
return NULL;
|
|
|
|
|
|
- py_src_buf = py_chunked_as_string(py_src_buf);
|
|
|
- if (py_src_buf == NULL)
|
|
|
- return NULL;
|
|
|
+ py_src_buf = py_chunked_as_string(py_src_buf);
|
|
|
+ if (py_src_buf == NULL)
|
|
|
+ return NULL;
|
|
|
|
|
|
- py_delta = py_chunked_as_string(py_delta);
|
|
|
- if (py_delta == NULL) {
|
|
|
- Py_DECREF(py_src_buf);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
+ py_delta = py_chunked_as_string(py_delta);
|
|
|
+ if (py_delta == NULL) {
|
|
|
+ Py_DECREF(py_src_buf);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
|
|
|
src_buf = (uint8_t *)PyString_AS_STRING(py_src_buf);
|
|
|
src_buf_len = PyString_GET_SIZE(py_src_buf);
|
|
|
|
|
|
- delta = (uint8_t *)PyString_AS_STRING(py_delta);
|
|
|
- delta_len = PyString_GET_SIZE(py_delta);
|
|
|
+ delta = (uint8_t *)PyString_AS_STRING(py_delta);
|
|
|
+ delta_len = PyString_GET_SIZE(py_delta);
|
|
|
|
|
|
- index = 0;
|
|
|
- src_size = get_delta_header_size(delta, &index, delta_len);
|
|
|
- if (src_size != src_buf_len) {
|
|
|
+ index = 0;
|
|
|
+ src_size = get_delta_header_size(delta, &index, delta_len);
|
|
|
+ if (src_size != src_buf_len) {
|
|
|
PyErr_Format(PyExc_ValueError,
|
|
|
- "Unexpected source buffer size: %lu vs %d", src_size, src_buf_len);
|
|
|
+ "Unexpected source buffer size: %lu vs %d", src_size, src_buf_len);
|
|
|
Py_DECREF(py_src_buf);
|
|
|
Py_DECREF(py_delta);
|
|
|
return NULL;
|
|
|
}
|
|
|
- dest_size = get_delta_header_size(delta, &index, delta_len);
|
|
|
+ dest_size = get_delta_header_size(delta, &index, delta_len);
|
|
|
ret = PyString_FromStringAndSize(NULL, dest_size);
|
|
|
if (ret == NULL) {
|
|
|
PyErr_NoMemory();
|
|
@@ -118,107 +118,112 @@ static PyObject *py_apply_delta(PyObject *self, PyObject *args)
|
|
|
return NULL;
|
|
|
}
|
|
|
out = (uint8_t *)PyString_AsString(ret);
|
|
|
- while (index < delta_len) {
|
|
|
- char cmd = delta[index];
|
|
|
- index++;
|
|
|
- if (cmd & 0x80) {
|
|
|
- size_t cp_off = 0, cp_size = 0;
|
|
|
+ while (index < delta_len) {
|
|
|
+ char cmd = delta[index];
|
|
|
+ index++;
|
|
|
+ if (cmd & 0x80) {
|
|
|
+ size_t cp_off = 0, cp_size = 0;
|
|
|
int i;
|
|
|
- for (i = 0; i < 4; i++) {
|
|
|
- if (cmd & (1 << i)) {
|
|
|
- uint8_t x = delta[index];
|
|
|
- index++;
|
|
|
- cp_off |= x << (i * 8);
|
|
|
+ for (i = 0; i < 4; i++) {
|
|
|
+ if (cmd & (1 << i)) {
|
|
|
+ uint8_t x = delta[index];
|
|
|
+ index++;
|
|
|
+ cp_off |= x << (i * 8);
|
|
|
}
|
|
|
}
|
|
|
- for (i = 0; i < 3; i++) {
|
|
|
- if (cmd & (1 << (4+i))) {
|
|
|
- uint8_t x = delta[index];
|
|
|
- index++;
|
|
|
- cp_size |= x << (i * 8);
|
|
|
+ for (i = 0; i < 3; i++) {
|
|
|
+ if (cmd & (1 << (4+i))) {
|
|
|
+ uint8_t x = delta[index];
|
|
|
+ index++;
|
|
|
+ cp_size |= x << (i * 8);
|
|
|
}
|
|
|
}
|
|
|
- if (cp_size == 0)
|
|
|
- cp_size = 0x10000;
|
|
|
- if (cp_off + cp_size < cp_size ||
|
|
|
- cp_off + cp_size > src_size ||
|
|
|
- cp_size > dest_size)
|
|
|
- break;
|
|
|
+ if (cp_size == 0)
|
|
|
+ cp_size = 0x10000;
|
|
|
+ if (cp_off + cp_size < cp_size ||
|
|
|
+ cp_off + cp_size > src_size ||
|
|
|
+ cp_size > dest_size)
|
|
|
+ break;
|
|
|
memcpy(out+outindex, src_buf+cp_off, cp_size);
|
|
|
outindex += cp_size;
|
|
|
} else if (cmd != 0) {
|
|
|
memcpy(out+outindex, delta+index, cmd);
|
|
|
outindex += cmd;
|
|
|
- index += cmd;
|
|
|
+ index += cmd;
|
|
|
} else {
|
|
|
PyErr_SetString(PyExc_ValueError, "Invalid opcode 0");
|
|
|
Py_DECREF(ret);
|
|
|
- Py_DECREF(py_delta);
|
|
|
+ Py_DECREF(py_delta);
|
|
|
Py_DECREF(py_src_buf);
|
|
|
return NULL;
|
|
|
}
|
|
|
}
|
|
|
Py_DECREF(py_src_buf);
|
|
|
- Py_DECREF(py_delta);
|
|
|
-
|
|
|
- if (index != delta_len) {
|
|
|
+ Py_DECREF(py_delta);
|
|
|
+
|
|
|
+ if (index != delta_len) {
|
|
|
PyErr_SetString(PyExc_ValueError, "delta not empty");
|
|
|
Py_DECREF(ret);
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
if (dest_size != outindex) {
|
|
|
- PyErr_SetString(PyExc_ValueError, "dest size incorrect");
|
|
|
+ PyErr_SetString(PyExc_ValueError, "dest size incorrect");
|
|
|
Py_DECREF(ret);
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
- return Py_BuildValue("[N]", ret);
|
|
|
+ ret_list = Py_BuildValue("[N]", ret);
|
|
|
+ if (ret_list == NULL) {
|
|
|
+ Py_DECREF(ret);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ return ret_list;
|
|
|
}
|
|
|
|
|
|
static PyObject *py_bisect_find_sha(PyObject *self, PyObject *args)
|
|
|
{
|
|
|
- PyObject *unpack_name;
|
|
|
- char *sha;
|
|
|
- int sha_len;
|
|
|
+ PyObject *unpack_name;
|
|
|
+ char *sha;
|
|
|
+ int sha_len;
|
|
|
int start, end;
|
|
|
- if (!PyArg_ParseTuple(args, "iis#O", &start, &end,
|
|
|
+ if (!PyArg_ParseTuple(args, "iis#O", &start, &end,
|
|
|
&sha, &sha_len, &unpack_name))
|
|
|
- return NULL;
|
|
|
-
|
|
|
- if (sha_len != 20) {
|
|
|
- PyErr_SetString(PyExc_ValueError, "Sha is not 20 bytes long");
|
|
|
- return NULL;
|
|
|
- }
|
|
|
- if (start > end) {
|
|
|
- PyErr_SetString(PyExc_AssertionError, "start > end");
|
|
|
- return NULL;
|
|
|
- }
|
|
|
-
|
|
|
- while (start <= end) {
|
|
|
- PyObject *file_sha;
|
|
|
- int i = (start + end)/2;
|
|
|
- int cmp;
|
|
|
- file_sha = PyObject_CallFunction(unpack_name, "i", i);
|
|
|
- if (file_sha == NULL) {
|
|
|
- return NULL;
|
|
|
- }
|
|
|
- if (!py_is_sha(file_sha)) {
|
|
|
- PyErr_SetString(PyExc_TypeError, "unpack_name returned non-sha object");
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ if (sha_len != 20) {
|
|
|
+ PyErr_SetString(PyExc_ValueError, "Sha is not 20 bytes long");
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ if (start > end) {
|
|
|
+ PyErr_SetString(PyExc_AssertionError, "start > end");
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ while (start <= end) {
|
|
|
+ PyObject *file_sha;
|
|
|
+ int i = (start + end)/2;
|
|
|
+ int cmp;
|
|
|
+ file_sha = PyObject_CallFunction(unpack_name, "i", i);
|
|
|
+ if (file_sha == NULL) {
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ if (!py_is_sha(file_sha)) {
|
|
|
+ PyErr_SetString(PyExc_TypeError, "unpack_name returned non-sha object");
|
|
|
Py_DECREF(file_sha);
|
|
|
- return NULL;
|
|
|
- }
|
|
|
- cmp = memcmp(PyString_AsString(file_sha), sha, 20);
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+ cmp = memcmp(PyString_AsString(file_sha), sha, 20);
|
|
|
Py_DECREF(file_sha);
|
|
|
- if (cmp < 0)
|
|
|
- start = i + 1;
|
|
|
- else if (cmp > 0)
|
|
|
- end = i - 1;
|
|
|
- else {
|
|
|
+ if (cmp < 0)
|
|
|
+ start = i + 1;
|
|
|
+ else if (cmp > 0)
|
|
|
+ end = i - 1;
|
|
|
+ else {
|
|
|
return PyInt_FromLong(i);
|
|
|
- }
|
|
|
- }
|
|
|
- Py_RETURN_NONE;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Py_RETURN_NONE;
|
|
|
}
|
|
|
|
|
|
|