summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Lee <64482439+algojohnlee@users.noreply.github.com>2021-03-20 10:33:32 -0400
committerGitHub <noreply@github.com>2021-03-20 10:33:32 -0400
commit43373baab8d93fda8a72c1822a87f94c3d647af3 (patch)
treef956fdca652e516e87671f3715f511160c726bdb
parentaa02b688208e0796e2247f604e3eaca277e3c6e8 (diff)
parent40192755eee671f24242d8fd6a960e486caf0389 (diff)
Merge pull request #1994 from onetechnical/onetechnical/relbeta2.5.2v2.5.2-beta
go-algorand 2.5.2-beta
-rw-r--r--buildnumber.dat2
-rw-r--r--data/transactions/logic/eval.go9
-rw-r--r--data/transactions/logic/eval_test.go15
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) {