Source file test/fixedbugs/issue29312.go

     1  // run
     2  
     3  // Copyright 2020 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  // This test is not for a fix of 29312 proper, but for the patch that
     8  // makes sure we at least don't have a security hole because of 29312.
     9  
    10  // This code generates lots of types. The binary should contain
    11  // a runtime.slicetype for each of the following 253 types:
    12  //
    13  //     []*pwn
    14  //     [][]*pwn
    15  //     ...
    16  //     [][]...[][]*pwn          - 249 total "[]"
    17  //     [][]...[][][]*pwn        - 250 total "[]"
    18  //     [][]...[][][][]*pwn      - 251 total "[]"
    19  //     [][]...[][][][][]*pwn    - 252 total "[]"
    20  //     [][]...[][][][][][]*pwn  - 253 total "[]"
    21  //
    22  // The type names for these types are as follows. Because we truncate
    23  // the name at depth 250, the last few names are all identical:
    24  //
    25  //     type:[]*"".pwn
    26  //     type:[][]*"".pwn
    27  //     ...
    28  //     type:[][]...[][]*pwn       - 249 total "[]"
    29  //     type:[][]...[][][]*<...>   - 250 total "[]"
    30  //     type:[][]...[][][][]<...>  - 251 total "[]"
    31  //     type:[][]...[][][][]<...>  - 252 total "[]" (but only 251 "[]" in the name)
    32  //     type:[][]...[][][][]<...>  - 253 total "[]" (but only 251 "[]" in the name)
    33  //
    34  // Because the names of the last 3 types are all identical, the
    35  // compiler will generate only a single runtime.slicetype data
    36  // structure for all 3 underlying types. It turns out the compiler
    37  // generates just the 251-entry one. There aren't any
    38  // runtime.slicetypes generated for the final two types.
    39  //
    40  // The compiler passes type:[]...[]<...> (251 total "[]") to
    41  // fmt.Sprintf (instead of the correct 253 one). But the data
    42  // structure at runtime actually has 253 nesting levels. So we end up
    43  // calling String on something that is of type [][]*pwn instead of
    44  // something of type *pwn. The way arg passing in Go works, the
    45  // backing store pointer for the outer slice becomes the "this"
    46  // pointer of the String method, which points to the inner []*pwn
    47  // slice.  The String method then modifies the length of that inner
    48  // slice.
    49  package main
    50  
    51  import "fmt"
    52  
    53  type pwn struct {
    54  	a [3]uint
    55  }
    56  
    57  func (this *pwn) String() string {
    58  	this.a[1] = 7 // update length
    59  	return ""
    60  }
    61  
    62  func main() {
    63  	var a pwn
    64  	s := [][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]*pwn{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{{&a}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} // depth 253
    65  	fmt.Sprint(s)
    66  	n := len(s[0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0][0]) // depth 252, type []*pwn
    67  	if n != 1 {
    68  		panic(fmt.Sprintf("length was changed, want 1 got %d", n))
    69  	}
    70  }
    71  

View as plain text