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