mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 02:36:18 +08:00 
			
		
		
		
	proc: Bug loading maps
Past the maximum recursion depth maps shouldn't be loaded at all, adding map children and not loading them breaks assumptions in the prettyprinter. Fixes #406
This commit is contained in:
		
							
								
								
									
										262
									
								
								_fixtures/issue406.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										262
									
								
								_fixtures/issue406.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,262 @@ | |||||||
|  | package main | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"log" | ||||||
|  | 	"regexp" | ||||||
|  | 	"strings" | ||||||
|  |  | ||||||
|  | 	//	"golang.org/x/crypto/ssh/terminal" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Blacklist type is a map of Nodes with string keys | ||||||
|  | type Blacklist map[string]*Node | ||||||
|  |  | ||||||
|  | // Source type is a map of Srcs with string keys | ||||||
|  | type Source map[string]*Src | ||||||
|  |  | ||||||
|  | // Node configuration record | ||||||
|  | type Node struct { | ||||||
|  | 	Disable          bool | ||||||
|  | 	IP               string | ||||||
|  | 	Include, Exclude []string | ||||||
|  | 	Source | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Src record, struct for Source map | ||||||
|  | type Src struct { | ||||||
|  | 	Disable bool | ||||||
|  | 	Desc    string | ||||||
|  | 	Prfx    string | ||||||
|  | 	URL     string | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // String returns pretty print for the Blacklist struct | ||||||
|  | func (b Blacklist) String() (result string) { | ||||||
|  | 	//	cols, _, _ := terminal.GetSize(int(os.Stdout.Fd())) | ||||||
|  | 	cols := 20 | ||||||
|  | 	for pkey := range b { | ||||||
|  | 		result += fmt.Sprintf("Node: %v\n\tDisabled: %v\n", pkey, b[pkey].Disable) | ||||||
|  | 		result += fmt.Sprintf("\tRedirect IP: %v\n\tExclude(s):\n", b[pkey].IP) | ||||||
|  | 		for _, exclude := range b[pkey].Exclude { | ||||||
|  | 			result += fmt.Sprintf("\t\t%v\n", exclude) | ||||||
|  | 		} | ||||||
|  | 		result += fmt.Sprintf("\tInclude(s):\n") | ||||||
|  | 		for _, include := range b[pkey].Include { | ||||||
|  | 			result += fmt.Sprintf("\t\t%v\n", include) | ||||||
|  | 		} | ||||||
|  | 		for skey, src := range b[pkey].Source { | ||||||
|  | 			result += fmt.Sprintf("\tSource: %v\n\t\tDisabled: %v\n", skey, src.Disable) | ||||||
|  | 			result += fmt.Sprintf("\t\tDescription: %v\n", b[pkey].Source[skey].Desc) | ||||||
|  | 			result += fmt.Sprintf("\t\tPrefix: %v\n\t\tURL: %v\n", b[pkey].Source[skey].Prfx, b[pkey].Source[skey].URL) | ||||||
|  | 		} | ||||||
|  | 		result += fmt.Sprintln(strings.Repeat("-", cols/2)) | ||||||
|  | 	} | ||||||
|  | 	return result | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // ToBool converts a string ("true" or "false") to it's boolean equivalent | ||||||
|  | func ToBool(s string) (b bool) { | ||||||
|  | 	if len(s) == 0 { | ||||||
|  | 		log.Fatal("ERROR: variable empty, cannot convert to boolean") | ||||||
|  | 	} | ||||||
|  | 	switch s { | ||||||
|  | 	case "false": | ||||||
|  | 		b = false | ||||||
|  | 	case "true": | ||||||
|  | 		b = true | ||||||
|  | 	} | ||||||
|  | 	return b | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // Get extracts nodes from a EdgeOS/VyOS configuration structure | ||||||
|  | func Get(cfg string) { | ||||||
|  | 	type re struct { | ||||||
|  | 		brkt, cmnt, desc, dsbl, leaf, misc, mlti, mpty, name, node *regexp.Regexp | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	rx := &re{} | ||||||
|  | 	rx.brkt = regexp.MustCompile(`[}]`) | ||||||
|  | 	rx.cmnt = regexp.MustCompile(`^([\/*]+).*([*\/]+)$`) | ||||||
|  | 	rx.desc = regexp.MustCompile(`^(?:description)+\s"?([^"]+)?"?$`) | ||||||
|  | 	rx.dsbl = regexp.MustCompile(`^(disabled)+\s([\S]+)$`) | ||||||
|  | 	rx.leaf = regexp.MustCompile(`^(source)+\s([\S]+)\s[{]{1}$`) | ||||||
|  | 	rx.misc = regexp.MustCompile(`^([\w-]+)$`) | ||||||
|  | 	rx.mlti = regexp.MustCompile(`^((?:include|exclude)+)\s([\S]+)$`) | ||||||
|  | 	rx.mpty = regexp.MustCompile(`^$`) | ||||||
|  | 	rx.name = regexp.MustCompile(`^([\w-]+)\s([\S]+)$`) | ||||||
|  | 	rx.node = regexp.MustCompile(`^([\w-]+)\s[{]{1}$`) | ||||||
|  |  | ||||||
|  | 	cfgtree := make(map[string]*Node) | ||||||
|  |  | ||||||
|  | 	var tnode string | ||||||
|  | 	var leaf string | ||||||
|  |  | ||||||
|  | 	for _, line := range strings.Split(cfg, "\n") { | ||||||
|  | 		line = strings.TrimSpace(line) | ||||||
|  | 		switch { | ||||||
|  | 		case rx.mlti.MatchString(line): | ||||||
|  | 			{ | ||||||
|  | 				IncExc := rx.mlti.FindStringSubmatch(line) | ||||||
|  | 				switch IncExc[1] { | ||||||
|  | 				case "exclude": | ||||||
|  | 					cfgtree[tnode].Exclude = append(cfgtree[tnode].Exclude, IncExc[2]) | ||||||
|  | 				case "include": | ||||||
|  | 					cfgtree[tnode].Include = append(cfgtree[tnode].Include, IncExc[2]) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		case rx.node.MatchString(line): | ||||||
|  | 			{ | ||||||
|  | 				node := rx.node.FindStringSubmatch(line) | ||||||
|  | 				tnode = node[1] | ||||||
|  | 				cfgtree[tnode] = &Node{} | ||||||
|  | 				cfgtree[tnode].Source = make(map[string]*Src) | ||||||
|  | 			} | ||||||
|  | 		case rx.leaf.MatchString(line): | ||||||
|  | 			src := rx.leaf.FindStringSubmatch(line) | ||||||
|  | 			leaf = src[2] | ||||||
|  |  | ||||||
|  | 			if src[1] == "source" { | ||||||
|  | 				cfgtree[tnode].Source[leaf] = &Src{} | ||||||
|  | 			} | ||||||
|  | 		case rx.dsbl.MatchString(line): | ||||||
|  | 			{ | ||||||
|  | 				disabled := rx.dsbl.FindStringSubmatch(line) | ||||||
|  | 				cfgtree[tnode].Disable = ToBool(disabled[1]) | ||||||
|  | 			} | ||||||
|  | 		case rx.name.MatchString(line): | ||||||
|  | 			{ | ||||||
|  | 				name := rx.name.FindStringSubmatch(line) | ||||||
|  | 				switch name[1] { | ||||||
|  | 				case "prefix": | ||||||
|  | 					cfgtree[tnode].Source[leaf].Prfx = name[2] | ||||||
|  | 				case "url": | ||||||
|  | 					cfgtree[tnode].Source[leaf].URL = name[2] | ||||||
|  | 				case "description": | ||||||
|  | 					cfgtree[tnode].Source[leaf].Desc = name[2] | ||||||
|  | 				case "dns-redirect-ip": | ||||||
|  | 					cfgtree[tnode].IP = name[2] | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		case rx.desc.MatchString(line) || rx.cmnt.MatchString(line) || rx.misc.MatchString(line): | ||||||
|  | 			break | ||||||
|  | 		} | ||||||
|  | 		// fmt.Printf("%s\n", line) | ||||||
|  | 	} | ||||||
|  | 	fmt.Println(cfgtree) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func main() { | ||||||
|  | 	cfgtree := make(Blacklist) | ||||||
|  | 	for _, k := range []string{"root", "hosts", "domains"} { | ||||||
|  | 		cfgtree[k] = &Node{} | ||||||
|  | 		cfgtree[k].Source = make(Source) | ||||||
|  | 	} | ||||||
|  | 	cfgtree["hosts"].Exclude = append(cfgtree["hosts"].Exclude, "rackcdn.com", "schema.org") | ||||||
|  | 	cfgtree["hosts"].Include = append(cfgtree["hosts"].Include, "msdn.com", "badgits.org") | ||||||
|  | 	cfgtree["hosts"].IP = "192.168.168.1" | ||||||
|  | 	cfgtree["hosts"].Source["hpHosts"] = &Src{URL: "http://www.bonzon.com", Prfx: "127.0.0.0"} | ||||||
|  | 	fmt.Println(cfgtree) | ||||||
|  | 	fmt.Println(cfgtree["hosts"]) | ||||||
|  | 	Get(testdata) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | var testdata = `blacklist { | ||||||
|  | 			disabled false | ||||||
|  | 			dns-redirect-ip 0.0.0.0 | ||||||
|  | 			domains { | ||||||
|  | 					include adsrvr.org | ||||||
|  | 					include adtechus.net | ||||||
|  | 					include advertising.com | ||||||
|  | 					include centade.com | ||||||
|  | 					include doubleclick.net | ||||||
|  | 					include free-counter.co.uk | ||||||
|  | 					include intellitxt.com | ||||||
|  | 					include kiosked.com | ||||||
|  | 					source malc0de { | ||||||
|  | 							description "List of zones serving malicious executables observed by malc0de.com/database/" | ||||||
|  | 							prefix "zone " | ||||||
|  | 							url http://malc0de.com/bl/ZONES | ||||||
|  | 					} | ||||||
|  | 			} | ||||||
|  | 			exclude 122.2o7.net | ||||||
|  | 			exclude 1e100.net | ||||||
|  | 			exclude adobedtm.com | ||||||
|  | 			exclude akamai.net | ||||||
|  | 			exclude amazon.com | ||||||
|  | 			exclude amazonaws.com | ||||||
|  | 			exclude apple.com | ||||||
|  | 			exclude ask.com | ||||||
|  | 			exclude avast.com | ||||||
|  | 			exclude bitdefender.com | ||||||
|  | 			exclude cdn.visiblemeasures.com | ||||||
|  | 			exclude cloudfront.net | ||||||
|  | 			exclude coremetrics.com | ||||||
|  | 			exclude edgesuite.net | ||||||
|  | 			exclude freedns.afraid.org | ||||||
|  | 			exclude github.com | ||||||
|  | 			exclude githubusercontent.com | ||||||
|  | 			exclude google.com | ||||||
|  | 			exclude googleadservices.com | ||||||
|  | 			exclude googleapis.com | ||||||
|  | 			exclude googleusercontent.com | ||||||
|  | 			exclude gstatic.com | ||||||
|  | 			exclude gvt1.com | ||||||
|  | 			exclude gvt1.net | ||||||
|  | 			exclude hb.disney.go.com | ||||||
|  | 			exclude hp.com | ||||||
|  | 			exclude hulu.com | ||||||
|  | 			exclude images-amazon.com | ||||||
|  | 			exclude msdn.com | ||||||
|  | 			exclude paypal.com | ||||||
|  | 			exclude rackcdn.com | ||||||
|  | 			exclude schema.org | ||||||
|  | 			exclude skype.com | ||||||
|  | 			exclude smacargo.com | ||||||
|  | 			exclude sourceforge.net | ||||||
|  | 			exclude ssl-on9.com | ||||||
|  | 			exclude ssl-on9.net | ||||||
|  | 			exclude static.chartbeat.com | ||||||
|  | 			exclude storage.googleapis.com | ||||||
|  | 			exclude windows.net | ||||||
|  | 			exclude yimg.com | ||||||
|  | 			exclude ytimg.com | ||||||
|  | 			hosts { | ||||||
|  | 					include beap.gemini.yahoo.com | ||||||
|  | 					source adaway { | ||||||
|  | 							description "Blocking mobile ad providers and some analytics providers" | ||||||
|  | 							prefix "127.0.0.1 " | ||||||
|  | 							url http://adaway.org/hosts.txt | ||||||
|  | 					} | ||||||
|  | 					source malwaredomainlist { | ||||||
|  | 							description "127.0.0.1 based host and domain list" | ||||||
|  | 							prefix "127.0.0.1 " | ||||||
|  | 							url http://www.malwaredomainlist.com/hostslist/hosts.txt | ||||||
|  | 					} | ||||||
|  | 					source openphish { | ||||||
|  | 							description "OpenPhish automatic phishing detection" | ||||||
|  | 							prefix http | ||||||
|  | 							url https://openphish.com/feed.txt | ||||||
|  | 					} | ||||||
|  | 					source someonewhocares { | ||||||
|  | 							description "Zero based host and domain list" | ||||||
|  | 							prefix 0.0.0.0 | ||||||
|  | 							url http://someonewhocares.org/hosts/zero/ | ||||||
|  | 					} | ||||||
|  | 					source volkerschatz { | ||||||
|  | 							description "Ad server blacklists" | ||||||
|  | 							prefix http | ||||||
|  | 							url http://www.volkerschatz.com/net/adpaths | ||||||
|  | 					} | ||||||
|  | 					source winhelp2002 { | ||||||
|  | 							description "Zero based host and domain list" | ||||||
|  | 							prefix "0.0.0.0 " | ||||||
|  | 							url http://winhelp2002.mvps.org/hosts.txt | ||||||
|  | 					} | ||||||
|  | 					source yoyo { | ||||||
|  | 							description "Fully Qualified Domain Names only - no prefix to strip" | ||||||
|  | 							prefix "" | ||||||
|  | 							url http://pgl.yoyo.org/as/serverlist.php?hostformat=nohtml&showintro=1&mimetype=plaintext | ||||||
|  | 					} | ||||||
|  | 			} | ||||||
|  | 	}` | ||||||
| @ -734,7 +734,9 @@ func (v *Variable) loadValueInternal(recurseLevel int) { | |||||||
| 		v.Base = sv.Addr | 		v.Base = sv.Addr | ||||||
|  |  | ||||||
| 	case reflect.Map: | 	case reflect.Map: | ||||||
| 		v.loadMap(recurseLevel) | 		if recurseLevel <= maxVariableRecurse { | ||||||
|  | 			v.loadMap(recurseLevel) | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 	case reflect.String: | 	case reflect.String: | ||||||
| 		var val string | 		var val string | ||||||
| @ -1149,10 +1151,8 @@ func (v *Variable) loadMap(recurseLevel int) { | |||||||
| 		} | 		} | ||||||
| 		key := it.key() | 		key := it.key() | ||||||
| 		val := it.value() | 		val := it.value() | ||||||
| 		if recurseLevel <= maxVariableRecurse { | 		key.loadValueInternal(recurseLevel + 1) | ||||||
| 			key.loadValueInternal(recurseLevel + 1) | 		val.loadValueInternal(recurseLevel + 1) | ||||||
| 			val.loadValueInternal(recurseLevel + 1) |  | ||||||
| 		} |  | ||||||
| 		if key.Unreadable != nil || val.Unreadable != nil { | 		if key.Unreadable != nil || val.Unreadable != nil { | ||||||
| 			errcount++ | 			errcount++ | ||||||
| 		} | 		} | ||||||
| @ -1429,7 +1429,9 @@ func (v *Variable) loadInterface(recurseLevel int, loadData bool) { | |||||||
| 		// interface to nil | 		// interface to nil | ||||||
| 		data = data.maybeDereference() | 		data = data.maybeDereference() | ||||||
| 		v.Children = []Variable{*data} | 		v.Children = []Variable{*data} | ||||||
| 		v.Children[0].loadValueInternal(recurseLevel) | 		if loadData { | ||||||
|  | 			v.Children[0].loadValueInternal(recurseLevel) | ||||||
|  | 		} | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | |||||||
| @ -8,6 +8,7 @@ import ( | |||||||
|  |  | ||||||
| 	"github.com/derekparker/delve/proc" | 	"github.com/derekparker/delve/proc" | ||||||
| 	"github.com/derekparker/delve/service/api" | 	"github.com/derekparker/delve/service/api" | ||||||
|  | 	"github.com/derekparker/delve/service" | ||||||
|  |  | ||||||
| 	protest "github.com/derekparker/delve/proc/test" | 	protest "github.com/derekparker/delve/proc/test" | ||||||
| ) | ) | ||||||
| @ -645,3 +646,19 @@ func TestUnsafePointer(t *testing.T) { | |||||||
| 		} | 		} | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestIssue406(t *testing.T) { | ||||||
|  | 	withTestClient("issue406", t, func(c service.Client) { | ||||||
|  | 		locs, err := c.FindLocation(api.EvalScope{ -1, 0 },"issue406.go:146") | ||||||
|  | 		assertNoError(err, t, "FindLocation()") | ||||||
|  | 		_, err = c.CreateBreakpoint(&api.Breakpoint{ Addr: locs[0].PC }) | ||||||
|  | 		assertNoError(err, t, "CreateBreakpoint()") | ||||||
|  | 		ch := c.Continue() | ||||||
|  | 		state := <-ch | ||||||
|  | 		assertNoError(state.Err, t, "Continue()") | ||||||
|  | 		v, err := c.EvalVariable(api.EvalScope{ -1, 0 }, "cfgtree") | ||||||
|  | 		assertNoError(err, t, "EvalVariable()") | ||||||
|  | 		vs := v.MultilineString("") | ||||||
|  | 		t.Logf("cfgtree formats to: %s\n", vs) | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user
	 aarzilli
					aarzilli