Skip to content

Commit 68e409f

Browse files
authored
Merge pull request #889 from schungx/master
Fix stack overflow.
2 parents a407edb + 36f6b67 commit 68e409f

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

src/types/dynamic.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ impl fmt::Debug for Dynamic {
735735
use std::collections::HashSet;
736736

737737
// Avoid infinite recursion for shared values in a reference loop.
738-
fn debug_fmt_print(
738+
fn checked_debug_fmt(
739739
f: &mut fmt::Formatter<'_>,
740740
value: &Dynamic,
741741
dict: &mut HashSet<*const Dynamic>,
@@ -744,7 +744,7 @@ impl fmt::Debug for Dynamic {
744744
Union::Shared(ref cell, ..) => match crate::func::locked_read(cell) {
745745
Some(v) => {
746746
if dict.insert(value) {
747-
debug_fmt_print(f, &v, dict)?;
747+
checked_debug_fmt(f, &v, dict)?;
748748
f.write_str(" (shared)")
749749
} else {
750750
f.write_str("<shared>")
@@ -761,7 +761,7 @@ impl fmt::Debug for Dynamic {
761761
if i > 0 {
762762
f.write_str(", ")?;
763763
}
764-
debug_fmt_print(f, v, dict)?;
764+
checked_debug_fmt(f, v, dict)?;
765765
}
766766
f.write_str("]")
767767
}
@@ -776,7 +776,7 @@ impl fmt::Debug for Dynamic {
776776
}
777777
fmt::Debug::fmt(k, f)?;
778778
f.write_str(": ")?;
779-
debug_fmt_print(f, v, dict)?;
779+
checked_debug_fmt(f, v, dict)?;
780780
}
781781
f.write_str("}")
782782
}
@@ -792,15 +792,15 @@ impl fmt::Debug for Dynamic {
792792
fmt::Debug::fmt(fnptr.fn_name(), f)?;
793793
for curry in &fnptr.curry {
794794
f.write_str(", ")?;
795-
debug_fmt_print(f, curry, dict)?;
795+
checked_debug_fmt(f, curry, dict)?;
796796
}
797797
f.write_str(")")
798798
}
799799
_ => fmt::Debug::fmt(value, f),
800800
}
801801
}
802802

803-
debug_fmt_print(f, self, &mut <_>::default())
803+
checked_debug_fmt(f, self, &mut <_>::default())
804804
}
805805
}
806806
}
@@ -1265,6 +1265,10 @@ impl Dynamic {
12651265
false
12661266
}
12671267

1268+
#[cfg(not(feature = "no_closure"))]
1269+
Union::Shared(ref cell, ..) if cfg!(feature = "unchecked") => {
1270+
crate::func::locked_read(cell).map_or(false, |v| v.is_hashable())
1271+
}
12681272
#[cfg(not(feature = "no_closure"))]
12691273
Union::Shared(..) => {
12701274
#[cfg(feature = "no_std")]
@@ -1278,10 +1282,18 @@ impl Dynamic {
12781282
dict: &mut HashSet<*const Dynamic>,
12791283
) -> bool {
12801284
match value.0 {
1281-
Union::Shared(ref cell, ..) => match crate::func::locked_read(cell) {
1282-
Some(v) => dict.insert(value) && checked_is_hashable(&v, dict),
1283-
_ => false,
1284-
},
1285+
Union::Shared(ref cell, ..) => crate::func::locked_read(cell)
1286+
.map_or(false, |v| {
1287+
dict.insert(value) && checked_is_hashable(&v, dict)
1288+
}),
1289+
#[cfg(not(feature = "no_index"))]
1290+
Union::Array(ref a, ..) => a.iter().all(|v| checked_is_hashable(v, dict)),
1291+
#[cfg(not(feature = "no_object"))]
1292+
Union::Map(ref m, ..) => m.values().all(|v| checked_is_hashable(v, dict)),
1293+
Union::FnPtr(ref f, ..) => {
1294+
f.environ.is_none()
1295+
&& f.curry().iter().all(|v| checked_is_hashable(v, dict))
1296+
}
12851297
_ => value.is_hashable(),
12861298
}
12871299
}

0 commit comments

Comments
 (0)