]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix spurious "[string too long]" error
authorDmitriy Vyukov <dvyukov@google.com>
Tue, 8 Jul 2014 18:37:18 +0000 (22:37 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Tue, 8 Jul 2014 18:37:18 +0000 (22:37 +0400)
Maxstring is not updated in the new string routines,
this makes runtime think that long strings are bogus.
Fixes #8339.

LGTM=crawshaw, iant
R=golang-codereviews, crawshaw, iant
CC=golang-codereviews, khr, rsc
https://golang.org/cl/110930043

src/pkg/runtime/string_test.go
src/pkg/runtime/stubs.goc

index b05e0c7dd0e24a3a9c30bab8a54afd6d1f771672..73ac95e018a0c4de30d51121a54255de05cc15e7 100644 (file)
@@ -6,6 +6,7 @@ package runtime_test
 
 import (
        "runtime"
+       "strings"
        "testing"
 )
 
@@ -122,3 +123,25 @@ func TestStringW(t *testing.T) {
                }
        }
 }
+
+func TestLargeStringConcat(t *testing.T) {
+       output := executeTest(t, largeStringConcatSource, nil)
+       want := "panic: " + strings.Repeat("0", 1<<10) + strings.Repeat("1", 1<<10) +
+               strings.Repeat("2", 1<<10) + strings.Repeat("3", 1<<10)
+       if !strings.HasPrefix(output, want) {
+               t.Fatalf("output does not start with %q:\n%s", want, output)
+       }
+}
+
+var largeStringConcatSource = `
+package main
+import "strings"
+func main() {
+       s0 := strings.Repeat("0", 1<<10)
+       s1 := strings.Repeat("1", 1<<10)
+       s2 := strings.Repeat("2", 1<<10)
+       s3 := strings.Repeat("3", 1<<10)
+       s := s0 + s1 + s2 + s3
+       panic(s)
+}
+`
index 901efa4d199a3ebb1668ba665c55d0c64ba54cae..137c10e2970f2e43e45a44d552e2a707a81aa117 100644 (file)
@@ -24,6 +24,7 @@ package runtime
 
 #pragma textflag NOSPLIT
 func rawstring(size intgo) (s String, b Slice) {
+       uintptr ms;
        byte *p;
 
        p = runtime·mallocgc(size, 0, FlagNoScan|FlagNoZero);
@@ -32,6 +33,11 @@ func rawstring(size intgo) (s String, b Slice) {
        b.array = p;
        b.len = size;
        b.cap = size;
+       for(;;) {
+               ms = runtime·maxstring;
+               if((uintptr)size <= ms || runtime·casp((void**)&runtime·maxstring, (void*)ms, (void*)size))
+                       break;
+       }
 }
 
 #pragma textflag NOSPLIT