diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index 3aa82341..c30afc74 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -27,6 +27,10 @@ static_assert(std::is_integral_v, "CsInt must be integral"); static_assert(std::is_signed_v, "CsInt must be signed"); static_assert(std::is_floating_point_v, "CsFloat must be floating point"); +struct cs_internal_error: public std::runtime_error { + using std::runtime_error::runtime_error; +}; + enum { CsIdfPersist = 1 << 0, CsIdfOverride = 1 << 1, @@ -529,15 +533,15 @@ struct CsErrorException { CsErrorException(CsState &cs, ostd::ConstCharRange msg, A &&...args): p_errmsg(), p_stack(cs) { - char fbuf[512]; - auto ret = ostd::format( - ostd::CharRange(fbuf, fbuf + sizeof(fbuf)), msg, - std::forward(args)... - ); - if ((ret < 0) || (size_t(ret) > sizeof(fbuf))) { - p_errmsg = save_msg(cs, msg); - } else { + try { + char fbuf[512]; + auto ret = ostd::format( + ostd::CharRange(fbuf, fbuf + sizeof(fbuf)), msg, + std::forward(args)... + ); p_errmsg = save_msg(cs, ostd::CharRange(fbuf, fbuf + ret)); + } catch (...) { + p_errmsg = save_msg(cs, msg); } p_stack = save_stack(cs); } @@ -716,16 +720,24 @@ private: }; template - inline std::ptrdiff_t format_int(R &&writer, CsInt val) { - return ostd::format(std::forward(writer), IntFormat, val); + inline std::size_t format_int(R &&writer, CsInt val) { + try { + return ostd::format(std::forward(writer), IntFormat, val); + } catch (ostd::format_error const &e) { + throw cs_internal_error{e.what()}; + } } template - inline std::ptrdiff_t format_float(R &&writer, CsFloat val) { - return ostd::format( - std::forward(writer), - (val == CsInt(val)) ? RoundFloatFormat : FloatFormat, val - ); + inline std::size_t format_float(R &&writer, CsFloat val) { + try { + return ostd::format( + std::forward(writer), + (val == CsInt(val)) ? RoundFloatFormat : FloatFormat, val + ); + } catch (ostd::format_error const &e) { + throw cs_internal_error{e.what()}; + } } template @@ -778,16 +790,15 @@ private: size_t ret = 0; auto nd = st.get(); while (nd) { - auto rt = ostd::format( - writer, - ((nd->index == 1) && st.gap()) - ? " ..%d) %s" : " %d) %s", - nd->index, nd->id->get_name() - ); - if (rt > 0) { - ret += size_t(rt); - } else { - return ret; + try { + ret += ostd::format( + writer, + ((nd->index == 1) && st.gap()) + ? " ..%d) %s" : " %d) %s", + nd->index, nd->id->get_name() + ); + } catch (ostd::format_error const &e) { + throw cs_internal_error{e.what()}; } nd = nd->next; if (nd) { diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 06d4a2b7..d5ac70cc 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -115,16 +115,19 @@ ostd::ConstCharRange CsErrorException::save_msg( GenState *gs = cs.p_pstate; if (gs) { /* we can attach line number */ - ostd::CharRange r(cs.p_errbuf, cs.p_errbuf + sizeof(cs.p_errbuf)); - std::ptrdiff_t sz = -1; - if (!gs->src_name.empty()) { - sz = ostd::format(r, "%s:%d: %s", gs->src_name, gs->current_line, msg); - } else { - sz = ostd::format(r, "%d: %s", gs->current_line, msg); - } - if (sz > 0) { - return ostd::ConstCharRange(cs.p_errbuf, cs.p_errbuf + sz); + std::size_t sz = 0; + try { + ostd::CharRange r(cs.p_errbuf, cs.p_errbuf + sizeof(cs.p_errbuf)); + if (!gs->src_name.empty()) { + sz = ostd::format(r, "%s:%d: %s", gs->src_name, gs->current_line, msg); + } else { + sz = ostd::format(r, "%d: %s", gs->current_line, msg); + } + } catch (ostd::format_error const &e) { + memcpy(cs.p_errbuf, msg.data(), msg.size()); + sz = msg.size(); } + return ostd::ConstCharRange(cs.p_errbuf, cs.p_errbuf + sz); } memcpy(cs.p_errbuf, msg.data(), msg.size()); return ostd::ConstCharRange(cs.p_errbuf, cs.p_errbuf + msg.size()); diff --git a/src/cubescript.cc b/src/cubescript.cc index 6d252243..54718943 100644 --- a/src/cubescript.cc +++ b/src/cubescript.cc @@ -224,15 +224,19 @@ void CsIvar::set_value(CsInt val) { CsString CsIvar::to_printable() const { CsInt i = p_storage; auto app = ostd::appender(); - if (!(get_flags() & CsIdfHex) || (i < 0)) { - format(app, IvarFormat, get_name(), i); - } else if (p_maxval == 0xFFFFFF) { - format( - app, IvarHexColorFormat, get_name(), - i, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF - ); - } else { - format(app, IvarHexFormat, get_name(), i); + try { + if (!(get_flags() & CsIdfHex) || (i < 0)) { + format(app, IvarFormat, get_name(), i); + } else if (p_maxval == 0xFFFFFF) { + format( + app, IvarHexColorFormat, get_name(), + i, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF + ); + } else { + format(app, IvarHexFormat, get_name(), i); + } + } catch (ostd::format_error const &e) { + throw cs_internal_error{e.what()}; } return std::move(app.get()); } @@ -254,7 +258,13 @@ void CsFvar::set_value(CsFloat val) { CsString CsFvar::to_printable() const { CsFloat f = p_storage; auto app = ostd::appender(); - format(app, (f == CsInt(f)) ? FvarRoundFormat : FvarFormat, get_name(), f); + try { + format( + app, (f == CsInt(f)) ? FvarRoundFormat : FvarFormat, get_name(), f + ); + } catch (ostd::format_error const &e) { + throw cs_internal_error{e.what()}; + } return std::move(app.get()); } @@ -268,10 +278,14 @@ void CsSvar::set_value(CsString val) { CsString CsSvar::to_printable() const { ostd::ConstCharRange s = p_storage; auto app = ostd::appender(); - if (ostd::find(s, '"').empty()) { - format(app, SvarFormat, get_name(), s); - } else { - format(app, SvarQuotedFormat, get_name(), s); + try { + if (ostd::find(s, '"').empty()) { + format(app, SvarFormat, get_name(), s); + } else { + format(app, SvarQuotedFormat, get_name(), s); + } + } catch (ostd::format_error const &e) { + throw cs_internal_error{e.what()}; } return std::move(app.get()); } @@ -307,13 +321,19 @@ CsState::CsState(CsAllocCb func, void *data): new_ident(static_cast(buf), CsIdfArg); } CsIdent *id = new_ident("//dummy"); - assert(id->get_index() == DummyIdx); + if (id->get_index() != DummyIdx) { + throw cs_internal_error{"invalid dummy index"}; + } id = new_ivar("numargs", MaxArguments, 0, 0); - assert(id->get_index() == NumargsIdx); + if (id->get_index() != NumargsIdx) { + throw cs_internal_error{"invalid numargs index"}; + } id = new_ivar("dbgalias", 0, 1000, 4); - assert(id->get_index() == DbgaliasIdx); + if (id->get_index() != DbgaliasIdx) { + throw cs_internal_error{"invalid dbgalias index"}; + } new_command("do", "e", [](auto &cs, auto args, auto &res) { cs.run(args[0].get_code(), res); diff --git a/src/lib_str.cc b/src/lib_str.cc index d4ba1b5a..7f03ecef 100644 --- a/src/lib_str.cc +++ b/src/lib_str.cc @@ -123,10 +123,14 @@ void cs_init_lib_string(CsState &cs) { cs.new_command("tohex", "ii", [](auto &, auto args, auto &res) { auto r = ostd::appender(); - ostd::format( - r, "0x%.*X", ostd::max(args[1].get_int(), CsInt(1)), - args[0].get_int() - ); + try { + ostd::format( + r, "0x%.*X", ostd::max(args[1].get_int(), CsInt(1)), + args[0].get_int() + ); + } catch (ostd::format_error const &e) { + throw cs_internal_error{e.what()}; + } res.set_str(std::move(r.get())); });