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:
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
|
||||||
}
|
}
|
||||||
xv.loadValue(loadFullValue)
|
if xv.Kind != reflect.String { // delay loading strings until we use them
|
||||||
|
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
|
||||||
}
|
}
|
||||||
yv.loadValue(loadFullValue)
|
if yv.Kind != reflect.String { // delay loading strings until we use them
|
||||||
|
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 (
|
||||||
|
Loading…
Reference in New Issue
Block a user