Skip to content

Slice capacity not preserved when taken address of and converted to another type. #496

Closed
@dmitshur

Description

@dmitshur

@neelance, I took the first failing test of #495 and looked into it. I was able to reproduce it and narrow it down to the following bug, which existed in 1.6 too, but archive/tar internals changed to start doing this pattern (and they weren't in 1.6).

--- FAIL: TestReader (0.02s)
/home/ubuntu/gopherjs/test.618412033:4
Error.stackTraceLimit=Infinity;var $global,$module;if(typeof window!=="undefined"){$global=window;}else if(typeof self!=="undefined"){$global=self;}else if(typeof global!=="undefined"){$global=global;$global.require=require;}else{$global=this;}if($global===undefined||$global.Array===undefined){throw new Error("no global object found");}if(typeof module!=="undefined"){$module=module;}var $packages={},$idCounter=0;var $keys=function(m){return m?Object.keys(m):[];};var $flushConsole=function(){};var $throwRuntimeError;var $throwNilPointerError=function(){$throwRuntimeError("invalid memory address or nil pointer dereference");};var $call=function(fn,rcvr,args){return fn.apply(rcvr,args);};var $makeFunc=function(fn){return function(){return $externalize(fn(this,new($sliceType($jsObjectPtr))($global.Array.prototype.slice.call(arguments,[]))),$emptyInterface);};};var $mapArray=function(array,f){var newArray=new array.constructor(array.length);for(var i=0;i<array.length;i++){n

Error: runtime error: slice bounds out of range
    at $callDeferred (/home/ubuntu/gopherjs/test.618412033:4:28652)
    at $panic (/home/ubuntu/gopherjs/test.618412033:4:29276)
    at $b (/home/ubuntu/gopherjs/test.618412033:36:64240)
    at $callDeferred (/home/ubuntu/gopherjs/test.618412033:4:28823)
    at $panic (/home/ubuntu/gopherjs/test.618412033:4:29276)
    at $throwRuntimeError (/home/ubuntu/gopherjs/test.618412033:7:3303)
    at $subslice (/home/ubuntu/gopherjs/test.618412033:4:2011)
    at $packages.archive/tar.AA.Chksum (/home/ubuntu/gopherjs/test.618412033:39:21828)
    at $packages.archive/tar.$ptrType.Chksum (/home/ubuntu/gopherjs/test.618412033:39:21939)
    at $packages.archive/tar.Z.GetFormat (/home/ubuntu/gopherjs/test.618412033:39:18410)
    at $packages.archive/tar.$ptrType.GetFormat (/home/ubuntu/gopherjs/test.618412033:39:19262)
    at $packages.archive/tar.AG.ptr.readHeader (/home/ubuntu/gopherjs/test.618412033:39:44422)
    at $packages.archive/tar.AG.ptr.Next (/home/ubuntu/gopherjs/test.618412033:39:30084)
    at $packages.archive/tar.BL (/home/ubuntu/gopherjs/test.618412033:39:79511)
    at $packages.testing.CA (/home/ubuntu/gopherjs/test.618412033:36:65548)
    at $goroutine (/home/ubuntu/gopherjs/test.618412033:4:29874)
    at Timeout.$runScheduled [as _onTimeout] (/home/ubuntu/gopherjs/test.618412033:4:30643)
    at tryOnTimeout (timers.js:224:11)
    at Timer.listOnTimeout (timers.js:198:5)
FAIL    archive/tar 0.427s

The problem appears to be when you have an array, and you take its address, then convert the pointer to another type, and try to access the slice.

package main

import "fmt"

const blockSize = 512

type block [blockSize]byte

type headerV7 [blockSize]byte

func main() {
    var x block

    y := (*headerV7)(&x)

    fmt.Println(y[148:][:8])
}

https://play.golang.org/p/k21kDwVgbB
http://www.gopherjs.org/playground/#/pKu10Nu76j

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions