]> git.lizzy.rs Git - plan9front.git/commitdiff
games/mix: fix implementation of MOVE instruction (thanks nicolagi)
authorAlex Musolino <alex@musolino.id.au>
Fri, 27 Nov 2020 00:49:49 +0000 (11:19 +1030)
committerAlex Musolino <alex@musolino.id.au>
Fri, 27 Nov 2020 00:49:49 +0000 (11:19 +1030)
Plan 9 memcpy(2) uses the same implementation as memmove(2) to handle
overlapping ranges.  Hovewer, the MIX MOVE instruction, as described
in TAOCP, specifically does not do this.  It copies words one at a
time starting from the lowest address.

This change also expands the address validation to check that all
addresses within the source and destination ranges are valid before
proceeding.

sys/src/games/mix/mix.c

index b7f451c0cea120e085253c49941be9598b1d1454..071d10f95b37336a99eb3404e9489e6e1775bc6a 100644 (file)
@@ -729,14 +729,20 @@ void
 mixmove(int s, int f)
 {
        int d;
+       u32int *p, *q, *pe;
 
        if(f == 0)
                return;
-
+       if(s < 0 || s >= 4000 || s+f < 0 || s+f > 4000)
+               vmerror("Bad src range MOVE %d:%d", s, s+f-1);
        d = mval(ri[1], 0, MASK2);
-       if(d < 0 || d > 4000)
-               vmerror("Bad address MOVE %d", d);
-       memcpy(cells+d, cells+s, f*sizeof(u32int));
+       if(d < 0 || d >= 4000 || d+f < 0 || d+f > 4000)
+               vmerror("Bad dst range MOVE %d:%d", d, d+f-1);
+       p = cells+d;
+       q = cells+s;
+       pe = p+f;
+       while(p < pe)
+               *p++ = *q++;
        d += f;
        d &= MASK2;
        ri[1] = d < 0 ? -d|SIGNB : d;