From 81a1114ee524a44656ba092d867f0dc1e2224b5e Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 5 Apr 2019 15:24:51 +0200 Subject: [PATCH] compiler: truncate string slice indices if necessary This didn't trigger on most platforms but does trigger on AVR where almost all slice operations on strings are with integers that are bigger than uintptr. --- compiler/compiler.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/compiler/compiler.go b/compiler/compiler.go index 70b7f2a0..d91de7ff 100644 --- a/compiler/compiler.go +++ b/compiler/compiler.go @@ -1973,6 +1973,8 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { c.emitSliceBoundsCheck(frame, llvmLen, low, high, lowType, highType) + // Truncate ints bigger than uintptr. This is after the bounds + // check so it's safe. if c.targetData.TypeAllocSize(high.Type()) > c.targetData.TypeAllocSize(c.uintptrType) { high = c.builder.CreateTrunc(high, c.uintptrType, "") } @@ -2005,6 +2007,8 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { c.emitSliceBoundsCheck(frame, oldCap, low, high, lowType, highType) + // Truncate ints bigger than uintptr. This is after the bounds + // check so it's safe. if c.targetData.TypeAllocSize(low.Type()) > c.targetData.TypeAllocSize(c.uintptrType) { low = c.builder.CreateTrunc(low, c.uintptrType, "") } @@ -2038,6 +2042,15 @@ func (c *Compiler) parseExpr(frame *Frame, expr ssa.Value) (llvm.Value, error) { c.emitSliceBoundsCheck(frame, oldLen, low, high, lowType, highType) + // Truncate ints bigger than uintptr. This is after the bounds + // check so it's safe. + if c.targetData.TypeAllocSize(low.Type()) > c.targetData.TypeAllocSize(c.uintptrType) { + low = c.builder.CreateTrunc(low, c.uintptrType, "") + } + if c.targetData.TypeAllocSize(high.Type()) > c.targetData.TypeAllocSize(c.uintptrType) { + high = c.builder.CreateTrunc(high, c.uintptrType, "") + } + newPtr := c.builder.CreateGEP(oldPtr, []llvm.Value{low}, "") newLen := c.builder.CreateSub(high, low, "") str, err := c.getZeroValue(c.mod.GetTypeByName("runtime._string"))