From cf39db36fea07c7b35e50e47f6c76d4c3f15100e Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Sat, 20 May 2023 17:17:54 +0200 Subject: [PATCH] interp: fix subtle bug in pointer xor If a pointer value was xor'ed with a value other than 0, it would not have been run at runtime but instead would fall through to the generic integer operations. This would likely result in a "cannot convert pointer to integer" panic. This commit fixes this subtle case. --- interp/interpreter.go | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/interp/interpreter.go b/interp/interpreter.go index 46aa9d1f..1ec4597e 100644 --- a/interp/interpreter.go +++ b/interp/interpreter.go @@ -736,30 +736,25 @@ func (r *runner) run(fn *function, params []value, parentMem *memoryView, indent if err == nil { // The lhs is a pointer. This sometimes happens for particular // pointer tricks. - switch inst.opcode { - case llvm.Add: + if inst.opcode == llvm.Add { // This likely means this is part of a // unsafe.Pointer(uintptr(ptr) + offset) pattern. lhsPtr = lhsPtr.addOffset(int64(rhs.Uint())) locals[inst.localIndex] = lhsPtr - continue - case llvm.Xor: - if rhs.Uint() == 0 { - // Special workaround for strings.noescape, see - // src/strings/builder.go in the Go source tree. This is - // the identity operator, so we can return the input. - locals[inst.localIndex] = lhs - continue - } - default: + } else if inst.opcode == llvm.Xor && rhs.Uint() == 0 { + // Special workaround for strings.noescape, see + // src/strings/builder.go in the Go source tree. This is + // the identity operator, so we can return the input. + locals[inst.localIndex] = lhs + } else { // Catch-all for weird operations that should just be done // at runtime. err := r.runAtRuntime(fn, inst, locals, &mem, indent) if err != nil { return nil, mem, err } - continue } + continue } var result uint64 switch inst.opcode {