@@ -88,6 +88,7 @@ typedef struct {
8888 char * buf ;
8989 struct {
9090 _Py_hashtable_t * hashtable ;
91+ PyObject * nonref ;
9192 } refs ;
9293 int version ;
9394} WFILE ;
@@ -100,7 +101,7 @@ w_decref_entry(void *key)
100101}
101102
102103static int
103- w_init_refs (WFILE * wf )
104+ w_init_refs (WFILE * wf , PyObject * nonref )
104105{
105106 if (wf -> version >= 3 ) {
106107 wf -> refs .hashtable = _Py_hashtable_new_full (_Py_hashtable_hash_ptr ,
@@ -111,6 +112,8 @@ w_init_refs(WFILE *wf)
111112 return -1 ;
112113 }
113114 }
115+ Py_XINCREF (nonref );
116+ wf -> refs .nonref = nonref ;
114117 return 0 ;
115118}
116119
@@ -120,6 +123,7 @@ w_clear_refs(WFILE *wf)
120123 if (wf -> refs .hashtable != NULL ) {
121124 _Py_hashtable_destroy (wf -> refs .hashtable );
122125 }
126+ Py_XDECREF (wf -> refs .nonref );
123127}
124128
125129static int
@@ -392,12 +396,20 @@ w_ref(PyObject *v, char *flag, WFILE *p)
392396 _Py_hashtable_entry_t * entry ;
393397 int w ;
394398
395- if (p -> version < 3 || p -> refs .hashtable == NULL )
399+ if (p -> version < 3 || p -> refs .hashtable == NULL ) {
396400 return 0 ; /* not writing object references */
401+ }
397402
398403 /* if it has only one reference, it definitely isn't shared */
399- if (Py_REFCNT (v ) == 1 )
404+ if (Py_REFCNT (v ) == 1 ) {
400405 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+ }
401413
402414 entry = _Py_hashtable_get_entry (p -> refs .hashtable , v );
403415 if (entry != NULL ) {
@@ -701,7 +713,7 @@ PyMarshal_WriteObjectToFile(PyObject *x, FILE *fp, int version)
701713 char buf [BUFSIZ ];
702714 WFILE wf ;
703715 (void )w_init (& wf , fp , buf , version );
704- if (w_init_refs (& wf ) != 0 ) {
716+ if (w_init_refs (& wf , NULL ) != 0 ) {
705717 w_clear (& wf );
706718 return ; /* caller must check PyErr_Occurred() */
707719 }
@@ -1715,7 +1727,7 @@ PyMarshal_WriteObjectToString(PyObject *x, int version)
17151727 if (w_init (& wf , NULL , NULL , version ) != 0 ) {
17161728 return NULL ;
17171729 }
1718- if (w_init_refs (& wf ) != 0 ) {
1730+ if (w_init_refs (& wf , NULL ) != 0 ) {
17191731 w_clear (& wf );
17201732 return NULL ;
17211733 }
0 commit comments