2727#include "pycore_bytesobject.h" // _PyBytes_Find()
2828#include "pycore_fileutils.h" // _Py_stat_struct
2929
30+ #include <stdbool.h>
3031#include <stddef.h> // offsetof()
3132#ifndef MS_WINDOWS
3233# include <unistd.h> // close()
@@ -302,6 +303,31 @@ static DWORD HandlePageException(EXCEPTION_POINTERS *ptrs, EXCEPTION_RECORD *rec
302303}
303304#endif
304305
306+ bool safe_memcpy (void * restrict dest , const void * restrict src , size_t count ) {
307+ #if defined(MS_WIN32 ) && !defined(DONT_USE_SEH )
308+
309+ // never fail for count 0
310+ if (count == 0 ) {
311+ return true;
312+ }
313+
314+ EXCEPTION_RECORD record ;
315+ __try {
316+ memcpy (dest , src , count );
317+ return true;
318+ }
319+ __except (HandlePageException (GetExceptionInformation (), & record )) {
320+ NTSTATUS status = record .ExceptionInformation [2 ];
321+ ULONG code = LsaNtStatusToWinError (status );
322+ PyErr_SetFromWindowsErr (code );
323+ return false;
324+ }
325+ #else
326+ memcpy (dest , src , count );
327+ return true;
328+ #endif
329+ }
330+
305331static PyObject *
306332mmap_read_method (mmap_object * self ,
307333 PyObject * args )
@@ -319,22 +345,16 @@ mmap_read_method(mmap_object *self,
319345 if (num_bytes < 0 || num_bytes > remaining )
320346 num_bytes = remaining ;
321347
322- #if defined(MS_WIN32 ) && !defined(DONT_USE_SEH )
323- EXCEPTION_RECORD record ;
324- __try {
325- result = PyBytes_FromStringAndSize (& self -> data [self -> pos ], num_bytes );
348+ result = PyBytes_FromStringAndSize (NULL , num_bytes );
349+ if (result == NULL ) {
350+ return NULL ;
351+ }
352+ if (safe_memcpy (((PyBytesObject * ) result )-> ob_sval , & self -> data [self -> pos ], num_bytes )) {
326353 self -> pos += num_bytes ;
327354 }
328- __except (HandlePageException (GetExceptionInformation (), & record )) {
329- NTSTATUS code = record .ExceptionInformation [2 ];
330- PyErr_SetFromWindowsErr (code );
331- result = NULL ;
355+ else {
356+ Py_CLEAR (result );
332357 }
333- #else
334- result = PyBytes_FromStringAndSize (& self -> data [self -> pos ], num_bytes );
335- self -> pos += num_bytes ;
336- #endif
337-
338358 return result ;
339359}
340360
0 commit comments