diff options
author | John Lee <64482439+algojohnlee@users.noreply.github.com> | 2021-03-20 10:33:32 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-20 10:33:32 -0400 |
commit | 43373baab8d93fda8a72c1822a87f94c3d647af3 (patch) | |
tree | f956fdca652e516e87671f3715f511160c726bdb | |
parent | aa02b688208e0796e2247f604e3eaca277e3c6e8 (diff) | |
parent | 40192755eee671f24242d8fd6a960e486caf0389 (diff) |
Merge pull request #1994 from onetechnical/onetechnical/relbeta2.5.2v2.5.2-beta
go-algorand 2.5.2-beta
-rw-r--r-- | buildnumber.dat | 2 | ||||
-rw-r--r-- | data/transactions/logic/eval.go | 9 | ||||
-rw-r--r-- | data/transactions/logic/eval_test.go | 15 |
3 files changed, 22 insertions, 4 deletions
diff --git a/buildnumber.dat b/buildnumber.dat index d00491fd7..0cfbf0888 100644 --- a/buildnumber.dat +++ b/buildnumber.dat @@ -1 +1 @@ -1 +2 diff --git a/data/transactions/logic/eval.go b/data/transactions/logic/eval.go index 7809dd4ce..e3b24ec43 100644 --- a/data/transactions/logic/eval.go +++ b/data/transactions/logic/eval.go @@ -1924,11 +1924,14 @@ func opSetBit(cx *evalContext) { // we're thinking of the bits in the byte itself as // being big endian. So this looks "reversed" mask := byte(0x80) >> bitIdx + // Copy to avoid modifying shared slice + scratch := append([]byte(nil), target.Bytes...) if bit == uint64(1) { - target.Bytes[byteIdx] |= mask + scratch[byteIdx] |= mask } else { - target.Bytes[byteIdx] &^= mask + scratch[byteIdx] &^= mask } + cx.stack[pprev].Bytes = scratch } cx.stack = cx.stack[:prev] } @@ -1961,6 +1964,8 @@ func opSetByte(cx *evalContext) { cx.err = errors.New("setbyte index > byte length") return } + // Copy to avoid modifying shared slice + cx.stack[pprev].Bytes = append([]byte(nil), cx.stack[pprev].Bytes...) cx.stack[pprev].Bytes[cx.stack[prev].Uint] = byte(cx.stack[last].Uint) cx.stack = cx.stack[:prev] } diff --git a/data/transactions/logic/eval_test.go b/data/transactions/logic/eval_test.go index 1fd7e6495..2efe54a29 100644 --- a/data/transactions/logic/eval_test.go +++ b/data/transactions/logic/eval_test.go @@ -3900,6 +3900,14 @@ func TestBits(t *testing.T) { testAccepts(t, "byte 0x0000; int 15; int 1; setbit; byte 0x0001; ==", 3) testAccepts(t, "int 0x0000; int 3; int 1; setbit; int 0x0008; ==", 3) testAccepts(t, "int 0x0000; int 12; int 1; setbit; int 0x1000; ==", 3) + + // These test that setbyte is not modifying a shared value. + // Since neither bytec nor dup copies, the first test is + // insufficient, the setbit changes the original constant (if + // it fails to copy). + testAccepts(t, "byte 0xfffff0; dup; int 21; int 1; setbit; byte 0xfffff4; ==; pop; byte 0xfffff0; ==", 3) + testAccepts(t, "byte 0xffff; byte 0xf0; concat; dup; int 21; int 1; setbit; byte 0xfffff4; ==; pop; byte 0xfffff0; ==", 3) + } func TestBytes(t *testing.T) { @@ -3914,8 +3922,13 @@ func TestBytes(t *testing.T) { testPanics(t, `byte "john"; int 4; getbyte; int 1; ==`, 3) // past end testAccepts(t, `byte "john"; int 2; int 105; setbyte; byte "join"; ==`, 3) - // dup makes copies, modifying one does not change the other + + // These test that setbyte is not modifying a shared value. + // Since neither bytec nor dup copies, the first test is + // insufficient, the setbyte changes the original constant (if + // it fails to copy). testAccepts(t, `byte "john"; dup; int 2; int 105; setbyte; pop; byte "john"; ==`, 3) + testAccepts(t, `byte "jo"; byte "hn"; concat; dup; int 2; int 105; setbyte; pop; byte "john"; ==`, 3) } func TestSwap(t *testing.T) { |