Mercurial > octave
changeset 32215:ce1ae40de0f0 stable
subsasgn: Avoid panic on invalid field names (bug #64213).
* libinterp/octave-value/ov-struct.cc (octave_struct::subsasgn,
octave_scalar_struct::subsasgn): Throw an exception if field name is not a
string instead of panicking. Add tests.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Fri, 28 Jul 2023 16:24:32 +0200 |
parents | 3321783e9fe5 |
children | f8b53be9844e ae8c5b698912 |
files | libinterp/octave-value/ov-struct.cc |
diffstat | 1 files changed, 56 insertions(+), 17 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/octave-value/ov-struct.cc Mon Jul 24 13:30:54 2023 -0400 +++ b/libinterp/octave-value/ov-struct.cc Fri Jul 28 16:24:32 2023 +0200 @@ -306,7 +306,7 @@ octave_value t_rhs = rhs; if (idx.front ().empty ()) - error ("missing index in indexed assignment"); + error ("subsasgn: missing index in indexed assignment"); if (n > 1 && ! (type.length () == 2 && type[0] == '(' && type[1] == '.')) { @@ -321,9 +321,11 @@ octave_value_list key_idx = *++p; - panic_if (key_idx.length () != 1); - - std::string key = key_idx(0).string_value (); + if (key_idx.length () != 1) + error ("subsasgn: dynamic structure field names must be strings"); + + std::string key + = key_idx(0).xstring_value ("dynamic structure field names must be strings"); maybe_warn_invalid_field_name (key, "subsasgn"); @@ -377,9 +379,11 @@ { octave_value_list key_idx = idx.front (); - panic_if (key_idx.length () != 1); - - std::string key = key_idx(0).string_value (); + if (key_idx.length () != 1) + error ("subsasgn: dynamic structure field names must be strings"); + + std::string key + = key_idx(0).xstring_value ("subsasgn: dynamic structure field names must be strings"); maybe_warn_invalid_field_name (key, "subsasgn"); @@ -443,9 +447,11 @@ octave_value_list key_idx = *++p; octave_value_list idxf = idx.front (); - panic_if (key_idx.length () != 1); - - std::string key = key_idx(0).string_value (); + if (key_idx.length () != 1) + error ("subsasgn: dynamic structure field names must be strings"); + + std::string key + = key_idx(0).xstring_value ("subsasgn: dynamic structure field names must be strings"); maybe_warn_invalid_field_name (key, "subsasgn"); @@ -514,9 +520,11 @@ { octave_value_list key_idx = idx.front (); - panic_if (key_idx.length () != 1); - - std::string key = key_idx(0).string_value (); + if (key_idx.length () != 1) + error ("subsasgn: dynamic structure field names must be strings"); + + std::string key + = key_idx(0).xstring_value ("subsasgn: dynamic structure field names must be strings"); maybe_warn_invalid_field_name (key, "subsasgn"); @@ -558,6 +566,21 @@ return retval; } +/* +%!test +%! x(1:2) = struct (); +%! idx = struct ("type", {"()", ".", "."}, "subs", {{1}, "a", "b"}); +%! x = subsasgn (x, idx, 42); +%! assert (x(1).a.b, 42); +%! assert (isempty (x(2).a)); + +%!test <*64213> +%! x(1:2) = struct (); +%! idx = struct ("type", {"()", "."}, "subs", {{1}, {"a", "b"}}); +%! fail ("x = subsasgn (x, idx, 42);", ... +%! "structure field names must be strings"); +*/ + octave_value octave_struct::do_index_op (const octave_value_list& idx, bool resize_ok) { @@ -1221,7 +1244,7 @@ octave_value retval; if (idx.front ().empty ()) - error ("missing index in indexed assignment"); + error ("subsasgn: missing index in indexed assignment"); if (type[0] == '.') { @@ -1231,9 +1254,11 @@ octave_value_list key_idx = idx.front (); - panic_if (key_idx.length () != 1); - - std::string key = key_idx(0).string_value (); + if (key_idx.length () != 1) + error ("subsasgn: structure field names must be strings"); + + std::string key + = key_idx(0).xstring_value ("subsasgn: structure field names must be strings"); maybe_warn_invalid_field_name (key, "subsasgn"); @@ -1284,6 +1309,20 @@ return retval; } +/* +%!test +%! x = struct (); +%! idx = struct ("type", ".", "subs", {"a", "b"}); +%! x = subsasgn (x, idx, 42); +%! assert (x.a.b, 42); + +%!test <*64213> +%! x = struct (); +%! idx = struct ("type", ".", "subs", {{"a", "b"}}); +%! fail ("x = subsasgn (x, idx, 42)", ... +%! "structure field names must be strings"); +*/ + octave_value octave_scalar_struct::do_index_op (const octave_value_list& idx, bool resize_ok) {