27
27
#include "pycore_bytesobject.h" // _PyBytes_Find()
28
28
#include "pycore_fileutils.h" // _Py_stat_struct
29
29
30
+ #include <stdbool.h>
30
31
#include <stddef.h> // offsetof()
31
32
#ifndef MS_WINDOWS
32
33
# include <unistd.h> // close()
@@ -302,6 +303,31 @@ static DWORD HandlePageException(EXCEPTION_POINTERS *ptrs, EXCEPTION_RECORD *rec
302
303
}
303
304
#endif
304
305
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
+
305
331
static PyObject *
306
332
mmap_read_method (mmap_object * self ,
307
333
PyObject * args )
@@ -319,22 +345,16 @@ mmap_read_method(mmap_object *self,
319
345
if (num_bytes < 0 || num_bytes > remaining )
320
346
num_bytes = remaining ;
321
347
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 )) {
326
353
self -> pos += num_bytes ;
327
354
}
328
- __except (HandlePageException (GetExceptionInformation (), & record )) {
329
- NTSTATUS code = record .ExceptionInformation [2 ];
330
- PyErr_SetFromWindowsErr (code );
331
- result = NULL ;
355
+ else {
356
+ Py_CLEAR (result );
332
357
}
333
- #else
334
- result = PyBytes_FromStringAndSize (& self -> data [self -> pos ], num_bytes );
335
- self -> pos += num_bytes ;
336
- #endif
337
-
338
358
return result ;
339
359
}
340
360
0 commit comments