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()
@@ -255,6 +256,44 @@ do { \
255
256
} while (0)
256
257
#endif /* UNIX */
257
258
259
+ #if defined(MS_WIN32 ) && !defined(DONT_USE_SEH )
260
+ static DWORD
261
+ HandlePageException (EXCEPTION_POINTERS * ptrs , EXCEPTION_RECORD * record )
262
+ {
263
+ * record = * ptrs -> ExceptionRecord ;
264
+ if (ptrs -> ExceptionRecord -> ExceptionCode == EXCEPTION_IN_PAGE_ERROR ) {
265
+ return EXCEPTION_EXECUTE_HANDLER ;
266
+ }
267
+ return EXCEPTION_CONTINUE_SEARCH ;
268
+ }
269
+ #endif
270
+
271
+ bool
272
+ safe_memcpy (void * restrict dest , const void * restrict src , size_t count ) {
273
+ #if defined(MS_WIN32 ) && !defined(DONT_USE_SEH )
274
+
275
+ // never fail for count 0
276
+ if (count == 0 ) {
277
+ return true;
278
+ }
279
+
280
+ EXCEPTION_RECORD record ;
281
+ __try {
282
+ memcpy (dest , src , count );
283
+ return true;
284
+ }
285
+ __except (HandlePageException (GetExceptionInformation (), & record )) {
286
+ NTSTATUS status = record .ExceptionInformation [2 ];
287
+ ULONG code = LsaNtStatusToWinError (status );
288
+ PyErr_SetFromWindowsErr (code );
289
+ return false;
290
+ }
291
+ #else
292
+ memcpy (dest , src , count );
293
+ return true;
294
+ #endif
295
+ }
296
+
258
297
static PyObject *
259
298
mmap_read_byte_method (mmap_object * self ,
260
299
PyObject * Py_UNUSED (ignored ))
@@ -264,7 +303,14 @@ mmap_read_byte_method(mmap_object *self,
264
303
PyErr_SetString (PyExc_ValueError , "read byte out of range" );
265
304
return NULL ;
266
305
}
267
- return PyLong_FromLong ((unsigned char )self -> data [self -> pos ++ ]);
306
+ unsigned char dest ;
307
+ if (safe_memcpy (dest , self -> data + self -> pos , 1 )) {
308
+ self -> pos ++ ;
309
+ return PyLong_FromLong (dest );
310
+ }
311
+ else {
312
+ return NULL ;
313
+ }
268
314
}
269
315
270
316
static PyObject *
@@ -291,17 +337,6 @@ mmap_read_line_method(mmap_object *self,
291
337
return result ;
292
338
}
293
339
294
- #if defined(MS_WIN32 ) && !defined(DONT_USE_SEH )
295
- static DWORD HandlePageException (EXCEPTION_POINTERS * ptrs , EXCEPTION_RECORD * record )
296
- {
297
- * record = * ptrs -> ExceptionRecord ;
298
- if (ptrs -> ExceptionRecord -> ExceptionCode == EXCEPTION_IN_PAGE_ERROR ) {
299
- return EXCEPTION_EXECUTE_HANDLER ;
300
- }
301
- return EXCEPTION_CONTINUE_SEARCH ;
302
- }
303
- #endif
304
-
305
340
static PyObject *
306
341
mmap_read_method (mmap_object * self ,
307
342
PyObject * args )
@@ -319,22 +354,16 @@ mmap_read_method(mmap_object *self,
319
354
if (num_bytes < 0 || num_bytes > remaining )
320
355
num_bytes = remaining ;
321
356
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 );
357
+ result = PyBytes_FromStringAndSize (NULL , num_bytes );
358
+ if (result == NULL ) {
359
+ return NULL ;
360
+ }
361
+ if (safe_memcpy (((PyBytesObject * ) result )-> ob_sval , self -> data + self -> pos , num_bytes )) {
326
362
self -> pos += num_bytes ;
327
363
}
328
- __except (HandlePageException (GetExceptionInformation (), & record )) {
329
- NTSTATUS code = record .ExceptionInformation [2 ];
330
- PyErr_SetFromWindowsErr (code );
331
- result = NULL ;
364
+ else {
365
+ Py_CLEAR (result );
332
366
}
333
- #else
334
- result = PyBytes_FromStringAndSize (& self -> data [self -> pos ], num_bytes );
335
- self -> pos += num_bytes ;
336
- #endif
337
-
338
367
return result ;
339
368
}
340
369
0 commit comments