mirror of
				https://github.com/go-delve/delve.git
				synced 2025-10-31 18:57:18 +08:00 
			
		
		
		
	proc: increase maximum string length when loading string for binary ops (#1620)
Increases the maximum string length from 64 to 1MB when loading strings for a binary operator, also delays the loading until it's necessary. This ensures that comparison between strings will always succeed in reasonable situations. Fixes #1615
This commit is contained in:
		 Alessandro Arzilli
					Alessandro Arzilli
				
			
				
					committed by
					
						 Derek Parker
						Derek Parker
					
				
			
			
				
	
			
			
			 Derek Parker
						Derek Parker
					
				
			
						parent
						
							df65be43ae
						
					
				
				
					commit
					158fb7bfac
				
			
							
								
								
									
										21
									
								
								_fixtures/issue1615.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								_fixtures/issue1615.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | package main | ||||||
|  |  | ||||||
|  | var strings = []string{ | ||||||
|  | 	"one", | ||||||
|  | 	"two", | ||||||
|  | 	"three", | ||||||
|  | 	"four", | ||||||
|  | 	"projects/my-gcp-project-id-string/locations/us-central1/queues/my-task-queue-name", | ||||||
|  | 	"five", | ||||||
|  | 	"six", | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func f(s string) { | ||||||
|  | 	// ... | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func main() { | ||||||
|  | 	for _, s := range strings { | ||||||
|  | 		f(s) | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -983,7 +983,9 @@ func (scope *EvalScope) evalBinary(node *ast.BinaryExpr) (*Variable, error) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | 	if xv.Kind != reflect.String { // delay loading strings until we use them | ||||||
| 		xv.loadValue(loadFullValue) | 		xv.loadValue(loadFullValue) | ||||||
|  | 	} | ||||||
| 	if xv.Unreadable != nil { | 	if xv.Unreadable != nil { | ||||||
| 		return nil, xv.Unreadable | 		return nil, xv.Unreadable | ||||||
| 	} | 	} | ||||||
| @ -1004,7 +1006,9 @@ func (scope *EvalScope) evalBinary(node *ast.BinaryExpr) (*Variable, error) { | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | 	if yv.Kind != reflect.String { // delay loading strings until we use them | ||||||
| 		yv.loadValue(loadFullValue) | 		yv.loadValue(loadFullValue) | ||||||
|  | 	} | ||||||
| 	if yv.Unreadable != nil { | 	if yv.Unreadable != nil { | ||||||
| 		return nil, yv.Unreadable | 		return nil, yv.Unreadable | ||||||
| 	} | 	} | ||||||
| @ -1037,6 +1041,12 @@ func (scope *EvalScope) evalBinary(node *ast.BinaryExpr) (*Variable, error) { | |||||||
| 		return newConstant(constant.MakeBool(v), xv.mem), nil | 		return newConstant(constant.MakeBool(v), xv.mem), nil | ||||||
|  |  | ||||||
| 	default: | 	default: | ||||||
|  | 		if xv.Kind == reflect.String { | ||||||
|  | 			xv.loadValue(loadFullValueLongerStrings) | ||||||
|  | 		} | ||||||
|  | 		if yv.Kind == reflect.String { | ||||||
|  | 			yv.loadValue(loadFullValueLongerStrings) | ||||||
|  | 		} | ||||||
| 		if xv.Value == nil { | 		if xv.Value == nil { | ||||||
| 			return nil, fmt.Errorf("operator %s can not be applied to \"%s\"", node.Op.String(), exprToString(node.X)) | 			return nil, fmt.Errorf("operator %s can not be applied to \"%s\"", node.Op.String(), exprToString(node.X)) | ||||||
| 		} | 		} | ||||||
| @ -1084,6 +1094,12 @@ func compareOp(op token.Token, xv *Variable, yv *Variable) (bool, error) { | |||||||
| 				return true, nil | 				return true, nil | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|  | 		if xv.Kind == reflect.String { | ||||||
|  | 			xv.loadValue(loadFullValueLongerStrings) | ||||||
|  | 		} | ||||||
|  | 		if yv.Kind == reflect.String { | ||||||
|  | 			yv.loadValue(loadFullValueLongerStrings) | ||||||
|  | 		} | ||||||
| 		if int64(len(constant.StringVal(xv.Value))) != xv.Len || int64(len(constant.StringVal(yv.Value))) != yv.Len { | 		if int64(len(constant.StringVal(xv.Value))) != xv.Len || int64(len(constant.StringVal(yv.Value))) != yv.Len { | ||||||
| 			return false, fmt.Errorf("string too long for comparison") | 			return false, fmt.Errorf("string too long for comparison") | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -4448,3 +4448,19 @@ func TestIssue1601(t *testing.T) { | |||||||
| 		evalVariable(p, t, "C.globalq") | 		evalVariable(p, t, "C.globalq") | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func TestIssue1615(t *testing.T) { | ||||||
|  | 	// A breakpoint condition that tests for string equality with a constant string shouldn't fail with 'string too long for comparison' error | ||||||
|  |  | ||||||
|  | 	withTestProcess("issue1615", t, func(p proc.Process, fixture protest.Fixture) { | ||||||
|  | 		bp := setFileBreakpoint(p, t, fixture, 19) | ||||||
|  | 		bp.Cond = &ast.BinaryExpr{ | ||||||
|  | 			Op: token.EQL, | ||||||
|  | 			X:  &ast.Ident{Name: "s"}, | ||||||
|  | 			Y:  &ast.BasicLit{Kind: token.STRING, Value: `"projects/my-gcp-project-id-string/locations/us-central1/queues/my-task-queue-name"`}, | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		assertNoError(proc.Continue(p), t, "Continue") | ||||||
|  | 		assertLineNumber(p, t, 19, "") | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|  | |||||||
| @ -163,6 +163,7 @@ type LoadConfig struct { | |||||||
|  |  | ||||||
| var loadSingleValue = LoadConfig{false, 0, 64, 0, 0, 0} | var loadSingleValue = LoadConfig{false, 0, 64, 0, 0, 0} | ||||||
| var loadFullValue = LoadConfig{true, 1, 64, 64, -1, 0} | var loadFullValue = LoadConfig{true, 1, 64, 64, -1, 0} | ||||||
|  | var loadFullValueLongerStrings = LoadConfig{true, 1, 1024 * 1024, 64, -1, 0} | ||||||
|  |  | ||||||
| // G status, from: src/runtime/runtime2.go | // G status, from: src/runtime/runtime2.go | ||||||
| const ( | const ( | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user