6
6
import random
7
7
import subprocess
8
8
import sys
9
+ import sysconfig
9
10
import textwrap
10
11
import time
11
12
import unittest
@@ -521,6 +522,7 @@ def test_parse_tuple_and_keywords(self):
521
522
self .assertRaises (ValueError , _testcapi .parse_tuple_and_keywords ,
522
523
(), {}, b'' , [42 ])
523
524
525
+
524
526
@unittest .skipUnless (threading , 'Threading required for this test.' )
525
527
class TestThreadState (unittest .TestCase ):
526
528
@@ -545,6 +547,7 @@ def callback():
545
547
t .start ()
546
548
t .join ()
547
549
550
+
548
551
class Test_testcapi (unittest .TestCase ):
549
552
def test__testcapi (self ):
550
553
for name in dir (_testcapi ):
@@ -553,5 +556,61 @@ def test__testcapi(self):
553
556
test = getattr (_testcapi , name )
554
557
test ()
555
558
559
+
560
+ class MallocTests (unittest .TestCase ):
561
+ ENV = 'debug'
562
+
563
+ def check (self , code ):
564
+ with support .SuppressCrashReport ():
565
+ out = assert_python_failure ('-c' , code , PYTHONMALLOC = self .ENV )
566
+ stderr = out .err
567
+ return stderr .decode ('ascii' , 'replace' )
568
+
569
+ def test_buffer_overflow (self ):
570
+ out = self .check ('import _testcapi; _testcapi.pymem_buffer_overflow()' )
571
+ regex = (r"Debug memory block at address p=0x[0-9a-f]+: API 'm'\n"
572
+ r" 16 bytes originally requested\n"
573
+ r" The 7 pad bytes at p-7 are FORBIDDENBYTE, as expected.\n"
574
+ r" The 8 pad bytes at tail=0x[0-9a-f]+ are not all FORBIDDENBYTE \(0x[0-9a-f]{2}\):\n"
575
+ r" at tail\+0: 0x78 \*\*\* OUCH\n"
576
+ r" at tail\+1: 0xfb\n"
577
+ r" at tail\+2: 0xfb\n"
578
+ r" at tail\+3: 0xfb\n"
579
+ r" at tail\+4: 0xfb\n"
580
+ r" at tail\+5: 0xfb\n"
581
+ r" at tail\+6: 0xfb\n"
582
+ r" at tail\+7: 0xfb\n"
583
+ r" The block was made by call #[0-9]+ to debug malloc/realloc.\n"
584
+ r" Data at p: cb cb cb cb cb cb cb cb cb cb cb cb cb cb cb cb\n"
585
+ r"Fatal Python error: bad trailing pad byte" )
586
+ self .assertRegex (out , regex )
587
+
588
+ def test_api_misuse (self ):
589
+ out = self .check ('import _testcapi; _testcapi.pymem_api_misuse()' )
590
+ regex = (r"Debug memory block at address p=0x[0-9a-f]+: API 'm'\n"
591
+ r" 16 bytes originally requested\n"
592
+ r" The 7 pad bytes at p-7 are FORBIDDENBYTE, as expected.\n"
593
+ r" The 8 pad bytes at tail=0x[0-9a-f]+ are FORBIDDENBYTE, as expected.\n"
594
+ r" The block was made by call #[0-9]+ to debug malloc/realloc.\n"
595
+ r" Data at p: .*\n"
596
+ r"Fatal Python error: bad ID: Allocated using API 'm', verified using API 'r'\n" )
597
+ self .assertRegex (out , regex )
598
+
599
+
600
+ class MallocDebugTests (MallocTests ):
601
+ ENV = 'malloc_debug'
602
+
603
+
604
+ @unittest .skipUnless (sysconfig .get_config_var ('WITH_PYMALLOC' ) == 1 ,
605
+ 'need pymalloc' )
606
+ class PymallocDebugTests (MallocTests ):
607
+ ENV = 'pymalloc_debug'
608
+
609
+
610
+ @unittest .skipUnless (Py_DEBUG , 'need Py_DEBUG' )
611
+ class DefaultMallocDebugTests (MallocTests ):
612
+ ENV = ''
613
+
614
+
556
615
if __name__ == "__main__" :
557
616
unittest .main ()
0 commit comments