403Webshell
Server IP : 216.92.14.13  /  Your IP : 216.73.216.171
Web Server : Apache
System : Linux vps4089.pairvps.com 5.15.0-190-generic #200-Ubuntu SMP Fri Aug 7 15:06:04 UTC 2026 x86_64
User : rmlac2fmr ( 1040637)
PHP Version : 8.2.32
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : ON  |  Pkexec : ON
Directory :  /usr/local/go/test/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /usr/local/go/test/devirtualization_nil_panics.go
// run

// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"runtime"
	"strings"
)

type A interface{ A() }

type Impl struct{}

func (*Impl) A() {}

type Impl2 struct{}

func (*Impl2) A() {}

func main() {
	shouldNilPanic(28, func() {
		var v A
		v.A()
		v = &Impl{}
	})
	shouldNilPanic(36, func() {
		var v A
		defer func() {
			v = &Impl{}
		}()
		v.A()
	})
	shouldNilPanic(43, func() {
		var v A
		f := func() {
			v = &Impl{}
		}
		v.A()
		f()
	})

	// Make sure that both devirtualized and non devirtualized
	// variants have the panic at the same line.
	shouldNilPanic(55, func() {
		var v A
		defer func() {
			v = &Impl{}
		}()
		v. // A() is on a sepearate line
			A()
	})
	shouldNilPanic(64, func() {
		var v A
		defer func() {
			v = &Impl{}
			v = &Impl2{} // assign different type, such that the call below does not get devirtualized
		}()
		v. // A() is on a sepearate line
			A()
	})
}

var cnt = 0

func shouldNilPanic(wantLine int, f func()) {
	cnt++
	defer func() {
		p := recover()
		if p == nil {
			panic("no nil deref panic")
		}
		if strings.Contains(fmt.Sprintf("%s", p), "invalid memory address or nil pointer dereference") {
			callers := make([]uintptr, 128)
			n := runtime.Callers(0, callers)
			callers = callers[:n]

			frames := runtime.CallersFrames(callers)
			line := -1
			for f, next := frames.Next(); next; f, next = frames.Next() {
				if f.Func.Name() == fmt.Sprintf("main.main.func%v", cnt) {
					line = f.Line
					break
				}
			}

			if line != wantLine {
				panic(fmt.Sprintf("invalid line number in panic = %v; want = %v", line, wantLine))
			}

			return
		}
		panic(p)
	}()
	f()
}

Youez - 2016 - github.com/yon3zu
LinuXploit