Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gh-118209: Add structured exception handling to mmap module #118213

Merged
merged 35 commits into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
4013627
add structured exception handling to mmap_read_method
Dobatymo Apr 24, 2024
6484134
📜🤖 Added by blurb_it.
blurb-it[bot] Apr 24, 2024
71218d2
adjust indentation
Dobatymo Apr 24, 2024
cd4b1fc
restructure to use safe_memcpy to avoid memory leak
Dobatymo Apr 25, 2024
cb1ef19
Apply suggestions from code review
Dobatymo Apr 25, 2024
448fa90
fix passing dest as pointer in mmap_read_byte_method
Dobatymo Apr 26, 2024
ba96163
use PyBytes_AS_STRING instead of raw access
Dobatymo Apr 26, 2024
f97d213
handle mmap_write_method
Dobatymo Apr 26, 2024
7983869
handle mmap_write_byte_method
Dobatymo Apr 26, 2024
c0bd57b
add safe_byte_copy, safe_memmove, safe_memchr, safe_copy_from_slice a…
Dobatymo Apr 30, 2024
92f4bf0
improve macro
Dobatymo May 1, 2024
364d846
Update Modules/mmapmodule.c
Dobatymo May 1, 2024
04dc2d9
handle EXCEPTION_ACCESS_VIOLATION
Dobatymo May 2, 2024
0654f9b
fix formatting
Dobatymo May 2, 2024
d3661ff
use PyBytes_FromStringAndSize instead of extracting the optization
Dobatymo May 2, 2024
30aa64b
update news entry
Dobatymo May 3, 2024
b809ce9
Update Misc/NEWS.d/next/Windows/2024-04-24-05-16-32.gh-issue-118209.R…
Dobatymo May 6, 2024
e907e6d
updated whatsnew entry
Dobatymo May 6, 2024
d1ad0ab
fix typo
Dobatymo May 6, 2024
2ca440d
fix handling some cases in mmap_subscript
Dobatymo May 6, 2024
f7c356c
add test using private function
Dobatymo May 6, 2024
0d70108
Update Lib/test/test_mmap.py
Dobatymo May 6, 2024
6f1f726
run test in subprocess
Dobatymo May 6, 2024
05e8ca0
add expected failure for find method
Dobatymo May 6, 2024
29b12bf
disable faulthandler
Dobatymo May 6, 2024
59e8c4e
typo
Dobatymo May 6, 2024
4f610a5
trailing blanks
Dobatymo May 6, 2024
aa2b41d
Update Lib/test/test_mmap.py
Dobatymo May 6, 2024
11fa04a
add asserts to tests
Dobatymo May 6, 2024
f02c83a
Update Lib/test/test_mmap.py
Dobatymo May 7, 2024
8533af5
support mmap_gfind
Dobatymo May 7, 2024
6aeaa32
aesthetics
Dobatymo May 7, 2024
9737f22
Apply suggestions from code review
Dobatymo May 7, 2024
12fb561
remove restrict for compliance with the python C dialect
Dobatymo May 8, 2024
880a9c0
Update Modules/mmapmodule.c
Dobatymo May 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix crash in :func:`mmap.read` on Windows when the underlying file operation raises errors.
60 changes: 57 additions & 3 deletions Modules/mmapmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,44 @@ do { \
} while (0)
#endif /* UNIX */

#if defined(MS_WIN32) && !defined(DONT_USE_SEH)
Dobatymo marked this conversation as resolved.
Show resolved Hide resolved
static DWORD
filter_page_exception(EXCEPTION_POINTERS *ptrs, EXCEPTION_RECORD *record)
{
*record = *ptrs->ExceptionRecord;
if (ptrs->ExceptionRecord->ExceptionCode == EXCEPTION_IN_PAGE_ERROR) {
return EXCEPTION_EXECUTE_HANDLER;
}
return EXCEPTION_CONTINUE_SEARCH;
}
#endif

int
safe_memcpy(void *restrict dest, const void *restrict src, size_t count) {
Dobatymo marked this conversation as resolved.
Show resolved Hide resolved
Dobatymo marked this conversation as resolved.
Show resolved Hide resolved
#if defined(MS_WIN32) && !defined(DONT_USE_SEH)

// never fail for count 0
if (count == 0) {
return 0;
}

EXCEPTION_RECORD record;
__try {
memcpy(dest, src, count);
return 0;
}
__except (filter_page_exception(GetExceptionInformation(), &record)) {
NTSTATUS status = record.ExceptionInformation[2];
ULONG code = LsaNtStatusToWinError(status);
PyErr_SetFromWindowsErr(code);
return -1;
}
#else
memcpy(dest, src, count);
return 0;
#endif
}

static PyObject *
mmap_read_byte_method(mmap_object *self,
PyObject *Py_UNUSED(ignored))
Expand All @@ -264,7 +302,14 @@ mmap_read_byte_method(mmap_object *self,
PyErr_SetString(PyExc_ValueError, "read byte out of range");
return NULL;
}
return PyLong_FromLong((unsigned char)self->data[self->pos++]);
unsigned char dest;
if (safe_memcpy(dest, self->data + self->pos, 1) < 0) {
Dobatymo marked this conversation as resolved.
Show resolved Hide resolved
return NULL;
}
else {
self->pos++;
return PyLong_FromLong(dest);
Dobatymo marked this conversation as resolved.
Show resolved Hide resolved
}
}

static PyObject *
Expand Down Expand Up @@ -307,8 +352,17 @@ mmap_read_method(mmap_object *self,
remaining = (self->pos < self->size) ? self->size - self->pos : 0;
if (num_bytes < 0 || num_bytes > remaining)
num_bytes = remaining;
result = PyBytes_FromStringAndSize(&self->data[self->pos], num_bytes);
self->pos += num_bytes;

result = PyBytes_FromStringAndSize(NULL, num_bytes);
if (result == NULL) {
return NULL;
}
if (safe_memcpy(((PyBytesObject *) result)->ob_sval, self->data + self->pos, num_bytes) < 0) {
Dobatymo marked this conversation as resolved.
Show resolved Hide resolved
Py_CLEAR(result);
}
else {
self->pos += num_bytes;
}
return result;
}

Expand Down