@@ -88,6 +88,7 @@ typedef struct {
88
88
char * buf ;
89
89
struct {
90
90
_Py_hashtable_t * hashtable ;
91
+ PyObject * nonref ;
91
92
} refs ;
92
93
int version ;
93
94
} WFILE ;
@@ -100,7 +101,7 @@ w_decref_entry(void *key)
100
101
}
101
102
102
103
static int
103
- w_init_refs (WFILE * wf )
104
+ w_init_refs (WFILE * wf , PyObject * nonref )
104
105
{
105
106
if (wf -> version >= 3 ) {
106
107
wf -> refs .hashtable = _Py_hashtable_new_full (_Py_hashtable_hash_ptr ,
@@ -111,6 +112,8 @@ w_init_refs(WFILE *wf)
111
112
return -1 ;
112
113
}
113
114
}
115
+ Py_XINCREF (nonref );
116
+ wf -> refs .nonref = nonref ;
114
117
return 0 ;
115
118
}
116
119
@@ -120,6 +123,7 @@ w_clear_refs(WFILE *wf)
120
123
if (wf -> refs .hashtable != NULL ) {
121
124
_Py_hashtable_destroy (wf -> refs .hashtable );
122
125
}
126
+ Py_XDECREF (wf -> refs .nonref );
123
127
}
124
128
125
129
static int
@@ -392,12 +396,20 @@ w_ref(PyObject *v, char *flag, WFILE *p)
392
396
_Py_hashtable_entry_t * entry ;
393
397
int w ;
394
398
395
- if (p -> version < 3 || p -> refs .hashtable == NULL )
399
+ if (p -> version < 3 || p -> refs .hashtable == NULL ) {
396
400
return 0 ; /* not writing object references */
401
+ }
397
402
398
403
/* if it has only one reference, it definitely isn't shared */
399
- if (Py_REFCNT (v ) == 1 )
404
+ if (Py_REFCNT (v ) == 1 ) {
400
405
return 0 ;
406
+ }
407
+ else if (p -> refs .nonref != NULL ) {
408
+ if (PySet_Contains (p -> refs .nonref , v ) == 1 ) {
409
+ return 0 ;
410
+ }
411
+ PyErr_Clear ();
412
+ }
401
413
402
414
entry = _Py_hashtable_get_entry (p -> refs .hashtable , v );
403
415
if (entry != NULL ) {
@@ -701,7 +713,7 @@ PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
701
713
char buf [BUFSIZ ];
702
714
WFILE wf ;
703
715
(void )w_init (& wf , fp , buf , version );
704
- if (w_init_refs (& wf ) != 0 ) {
716
+ if (w_init_refs (& wf , NULL ) != 0 ) {
705
717
w_clear (& wf );
706
718
return ; /* caller must check PyErr_Occurred() */
707
719
}
@@ -1715,7 +1727,7 @@ PyMarshal_WriteObjectToString(PyObject *x, int version)
1715
1727
if (w_init (& wf , NULL , NULL , version ) != 0 ) {
1716
1728
return NULL ;
1717
1729
}
1718
- if (w_init_refs (& wf ) != 0 ) {
1730
+ if (w_init_refs (& wf , NULL ) != 0 ) {
1719
1731
w_clear (& wf );
1720
1732
return NULL ;
1721
1733
}
0 commit comments