aboutsummaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2020-12-07 09:07:32 +0100
committerTom de Vries <tdevries@suse.de>2020-12-07 09:07:32 +0100
commitf51f9f1d0300029d33ecb73976f5d2be9b63553e (patch)
treeda77fac6d0af66cdb553d6717f498f52b758e5d5 /gdb
parent00158a68d1c382f9afe16630ac327695a4904556 (diff)
downloadgdb-f51f9f1d0300029d33ecb73976f5d2be9b63553e.zip
gdb-f51f9f1d0300029d33ecb73976f5d2be9b63553e.tar.gz
gdb-f51f9f1d0300029d33ecb73976f5d2be9b63553e.tar.bz2
[gdb/ada] Handle shrink resize in replace_operator_with_call
In replace_operator_with_call, we resize the elts array like this: ... exp->nelts = exp->nelts + 7 - oplen; exp->resize (exp->nelts); ... Although all the current callers ensure that the new size is bigger, it could also be smaller, in which case the following memmove possibly reads out of bounds: ... memmove (exp->elts + pc + 7, exp->elts + pc + oplen, EXP_ELEM_TO_BYTES (save_nelts - pc - oplen)); ... Fix this by doing the resize after the memmove in case the new size is smaller. Tested on x86_64-linux. gdb/ChangeLog: 2020-12-07 Tom de Vries <tdevries@suse.de> * ada-lang.c (replace_operator_with_call): Handle shrink resize.
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog4
-rw-r--r--gdb/ada-lang.c8
2 files changed, 10 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 3c21cff..8b94c02 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,7 @@
+2020-12-07 Tom de Vries <tdevries@suse.de>
+
+ * ada-lang.c (replace_operator_with_call): Handle shrink resize.
+
2020-12-06 Tom Tromey <tom@tromey.com>
PR ada/26999
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 7d06229..8a1d9df 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -4005,11 +4005,15 @@ replace_operator_with_call (expression_up *expp, int pc, int nargs,
expression. */
struct expression *exp = expp->get ();
int save_nelts = exp->nelts;
- exp->nelts = exp->nelts + 7 - oplen;
- exp->resize (exp->nelts);
+ int extra_elts = 7 - oplen;
+ exp->nelts += extra_elts;
+ if (extra_elts > 0)
+ exp->resize (exp->nelts);
memmove (exp->elts + pc + 7, exp->elts + pc + oplen,
EXP_ELEM_TO_BYTES (save_nelts - pc - oplen));
+ if (extra_elts < 0)
+ exp->resize (exp->nelts);
exp->elts[pc].opcode = exp->elts[pc + 2].opcode = OP_FUNCALL;
exp->elts[pc + 1].longconst = (LONGEST) nargs;