From 694b80a4109553aeec334cff7f5c594846464f7a Mon Sep 17 00:00:00 2001 From: lisdude Date: Mon, 24 Jan 2022 12:07:27 -0600 Subject: [PATCH] Fix refcounting issues with waifs when pushing E_PROPNF. --- docs/ChangeLog.md | 2 ++ src/execute.cc | 6 +++--- src/server.cc | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/ChangeLog.md b/docs/ChangeLog.md index 4af7abe3..8738ac63 100644 --- a/docs/ChangeLog.md +++ b/docs/ChangeLog.md @@ -19,6 +19,8 @@ - Disable virtual timers when running under the Windows Subsystem for Linux. (This fixes things like `seconds_left()` returning 0.) - Fix a potential crash when threaded SQLite functions attempt to write object numbers. - Add a ceiling to `ctime()` to prevent overflows with large integer arguments. +- Fix an issue where friendly tracebacks involving non-existent properties on waifs could crash the server. +- Fix an issue where waifs could get stuck "recycling" forever. ### New Features - Support TLS / SSL connections in both `listen()` and `open_network_connection()`. Certificate and key can be configured in options.h, specifed as command-line arguments, or given as arguments to in-MOO functions. See warnings at the end of this changelog for important information about these changes. diff --git a/src/execute.cc b/src/execute.cc index 09297359..f715802e 100644 --- a/src/execute.cc +++ b/src/execute.cc @@ -1935,7 +1935,7 @@ run(char raise, enum error resumption_error, Var * result) err = waif_get_prop(obj.v.waif, propname.v.str, &prop, RUN_ACTIV.progr); free_var(obj); if (err == E_PROPNF) - PUSH_X_NOT_FOUND(E_PROPNF, propname, var_ref(obj)); + PUSH_X_NOT_FOUND(E_PROPNF, var_ref(propname), obj); else { free_var(propname); if (err == E_NONE) @@ -1985,7 +1985,7 @@ run(char raise, enum error resumption_error, Var * result) if (err == E_NONE) PUSH(prop); else if (err == E_PROPNF) - PUSH_X_NOT_FOUND(E_PROPNF, propname, var_ref(obj)); + PUSH_X_NOT_FOUND(E_PROPNF, var_ref(propname), obj); else PUSH_ERROR(err); } else if (!obj.is_object() || propname.type != TYPE_STR) { @@ -2025,7 +2025,7 @@ run(char raise, enum error resumption_error, Var * result) } else { free_var(rhs); if (err == E_PROPNF) { - PUSH_X_NOT_FOUND(E_PROPNF, propname, var_ref(obj)); + PUSH_X_NOT_FOUND(E_PROPNF, var_ref(propname), obj); } else { free_var(propname); PUSH_ERROR(err); diff --git a/src/server.cc b/src/server.cc index 1d811e5a..1047bcb5 100644 --- a/src/server.cc +++ b/src/server.cc @@ -671,7 +671,7 @@ recycle_waifs() destroyed_waifs[x.first] = true; /* Flag it as destroyed. Now we just wait for the refcount to hit zero so we can free it. */ } - if (refcount(x.first) == 0) { + if (refcount(x.first) <= 0) { removals.push_back(x.first); } }