Skip to content

Commit

Permalink
allow the skipping of validation when opening files
Browse files Browse the repository at this point in the history
  • Loading branch information
arnimarj committed Jan 19, 2017
1 parent c91e5df commit 00a130c
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 17 deletions.
6 changes: 6 additions & 0 deletions include/pointless/pointless_reader.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@

int pointless_open_f(pointless_t* p, const char* fname, int force_ucs2, const char** error);
int pointless_open_b(pointless_t* p, const void* buffer, size_t n_buffer, int force_ucs2, const char** error);

// use these two with care. they don't perform any validation on the underlying data, which may cause
// segfaults when accessed through the normal pointless-library functions
int pointless_open_f_skip_validate(pointless_t* p, const char* fname, int force_ucs2, const char** error);
int pointless_open_b_skip_validate(pointless_t* p, const void* buffer, size_t n_buffer, int force_ucs2, const char** error);

void pointless_close(pointless_t* p);

#endif
49 changes: 39 additions & 10 deletions python/pointless_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,24 @@ static PyObject* PyPointless_GetINode(PyPointless* self)
return PyLong_FromUnsignedLong(buf.st_ino);
}

static PyObject* PyPointless_GetFileNo(PyPointless* self)
{
if (self->p.fd == 0) {
PyErr_Format(PyExc_ValueError, "pointless object is buffer-based");
return 0;
}

int f = fileno(self->p.fd);
struct stat buf;

if (f == -1) {
PyErr_SetFromErrno(PyExc_OSError);
return 0;
}

return PyLong_FromUnsignedLong((unsigned long long)f);
}

static PyObject* PyPointless_GetRefs(PyPointless* self)
{
return Py_BuildValue("{s:n,s:n,s:n,s:n,s:n}",
Expand All @@ -97,10 +115,11 @@ static PyObject* PyPointless_sizeof(PyPointless* self)
}

static PyMethodDef PyPointless_methods[] = {
{"__sizeof__", (PyCFunction)PyPointless_sizeof, METH_NOARGS, "get size in bytes of backing file or buffer"},
{"GetRoot", (PyCFunction)PyPointless_GetRoot, METH_NOARGS, "get pointless root object" },
{"GetINode", (PyCFunction)PyPointless_GetINode, METH_NOARGS, "get inode of file descriptor" },
{"GetRefs", (PyCFunction)PyPointless_GetRefs, METH_NOARGS, "get inside-reference count to base object" },
{"__sizeof__", (PyCFunction)PyPointless_sizeof, METH_NOARGS, "get size in bytes of backing file or buffer"},
{"GetRoot", (PyCFunction)PyPointless_GetRoot, METH_NOARGS, "get pointless root object" },
{"GetINode", (PyCFunction)PyPointless_GetINode, METH_NOARGS, "get inode of file descriptor" },
{"GetFileNo", (PyCFunction)PyPointless_GetFileNo, METH_NOARGS, "get file descriptor" },
{"GetRefs", (PyCFunction)PyPointless_GetRefs, METH_NOARGS, "get inside-reference count to base object" },
{NULL}
};

Expand Down Expand Up @@ -143,14 +162,17 @@ static int PyPointless_init(PyPointless* self, PyObject* args, PyObject* kwds)
self->n_set_refs = 0;

PyObject* allow_print = Py_True;
static char* kwargs[] = {"filename_or_buffer", "allow_print", 0};
PyObject* validate = Py_True;
static char* kwargs[] = {"filename_or_buffer", "allow_print", "validate", 0};

if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O!", kwargs, &fname_or_buffer, &PyBool_Type, &allow_print))
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O!O!", kwargs, &fname_or_buffer, &PyBool_Type, &allow_print, &PyBool_Type, &validate))
return -1;

if (allow_print == Py_False)
self->allow_print = 0;

int do_validate = (validate == Py_True);

#ifdef Py_UNICODE_WIDE
int force_ucs2 = 0;
#else
Expand Down Expand Up @@ -184,10 +206,17 @@ static int PyPointless_init(PyPointless* self, PyObject* args, PyObject* kwds)

Py_BEGIN_ALLOW_THREADS

if (fname_)
i = pointless_open_f(&self->p, fname_, force_ucs2, &error);
else
i = pointless_open_b(&self->p, buf, buflen, force_ucs2, &error);
if (do_validate) {
if (fname_)
i = pointless_open_f(&self->p, fname_, force_ucs2, &error);
else
i = pointless_open_b(&self->p, buf, buflen, force_ucs2, &error);
} else {
if (fname_)
i = pointless_open_f_skip_validate(&self->p, fname_, force_ucs2, &error);
else
i = pointless_open_b_skip_validate(&self->p, buf, buflen, force_ucs2, &error);
}

Py_END_ALLOW_THREADS

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def build_judy():

setup(
name = 'pointless',
version = '0.2.8',
version = '0.2.8.1',
maintainer = 'Arni Mar Jonsson',
maintainer_email = '[email protected]',
url = 'https://github.com/arnimarj/py-pointless',
Expand Down
36 changes: 30 additions & 6 deletions src/pointless_reader.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <pointless/pointless_reader.h>

static int pointless_init(pointless_t* p, void* buf, uint64_t buflen, int force_ucs2, const char** error)
static int pointless_init(pointless_t* p, void* buf, uint64_t buflen, int force_ucs2, int do_validate, const char** error)
{
// our header
if (buflen < sizeof(pointless_header_t)) {
Expand Down Expand Up @@ -77,10 +77,14 @@ static int pointless_init(pointless_t* p, void* buf, uint64_t buflen, int force_
pointless_validate_context_t context;
context.p = p;
context.force_ucs2 = force_ucs2;
return pointless_validate(&context, error);

if (do_validate)
return pointless_validate(&context, error);
else
return 1;
}

int pointless_open_f(pointless_t* p, const char* fname, int force_ucs2, const char** error)
static int _pointless_open_f(pointless_t* p, const char* fname, int force_ucs2, int do_validate, const char** error)
{
p->fd = 0;
p->fd_len = 0;
Expand Down Expand Up @@ -139,14 +143,24 @@ int pointless_open_f(pointless_t* p, const char* fname, int force_ucs2, const ch
return 0;
}

if (!pointless_init(p, p->fd_ptr, p->fd_len, force_ucs2, error)) {
if (!pointless_init(p, p->fd_ptr, p->fd_len, force_ucs2, do_validate, error)) {
pointless_close(p);
return 0;
}

return 1;
}

int pointless_open_f(pointless_t* p, const char* fname, int force_ucs2, const char** error)
{
return _pointless_open_f(p, fname, force_ucs2, 1, error);
}

int pointless_open_f_skip_validate(pointless_t* p, const char* fname, int force_ucs2, const char** error)
{
return _pointless_open_f(p, fname, force_ucs2, 0, error);
}

void pointless_close(pointless_t* p)
{
if (p->fd_ptr)
Expand All @@ -158,7 +172,7 @@ void pointless_close(pointless_t* p)
pointless_free(p->buf);
}

int pointless_open_b(pointless_t* p, const void* buffer, size_t n_buffer, int force_ucs2, const char** error)
static int _pointless_open_b(pointless_t* p, const void* buffer, size_t n_buffer, int force_ucs2, int do_validate, const char** error)
{
p->fd = 0;
p->fd_len = 0;
Expand All @@ -174,14 +188,24 @@ int pointless_open_b(pointless_t* p, const void* buffer, size_t n_buffer, int fo

memcpy(p->buf, buffer, n_buffer);

if (!pointless_init(p, p->buf, p->buflen, force_ucs2, error)) {
if (!pointless_init(p, p->buf, p->buflen, force_ucs2, do_validate, error)) {
pointless_close(p);
return 0;
}

return 1;
}

int pointless_open_b(pointless_t* p, const void* buffer, size_t n_buffer, int force_ucs2, const char** error)
{
return _pointless_open_b(p, buffer, n_buffer, force_ucs2, 1, error);
}

int pointless_open_b_skip_validate(pointless_t* p, const void* buffer, size_t n_buffer, int force_ucs2, const char** error)
{
return _pointless_open_b(p, buffer, n_buffer, force_ucs2, 0, error);
}

pointless_value_t* pointless_root(pointless_t* p)
{
return &p->header->root;
Expand Down

0 comments on commit 00a130c

Please sign in to comment.