diff options
| author | Russ Cox <rsc@golang.org> | 2010-02-16 10:16:24 -0800 | 
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2010-02-16 10:16:24 -0800 | 
| commit | e4c58d0c6be314f729ba3423df6721494f0a9eb6 (patch) | |
| tree | 18a8791aa3ca8b379dcf92365528bf5727496755 /src | |
| parent | 71ba525b1f6053a972f1f3c2870bfcf434dde77b (diff) | |
| download | golang-e4c58d0c6be314f729ba3423df6721494f0a9eb6.tar.gz | |
gc: test & fix handling of very long string constants
R=ken2
CC=golang-dev
http://codereview.appspot.com/207106
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/gc/lex.c | 21 | ||||
| -rw-r--r-- | src/cmd/gc/subr.c | 24 | 
2 files changed, 33 insertions, 12 deletions
| diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c index 9c1cbfcf0..60c08ebb7 100644 --- a/src/cmd/gc/lex.c +++ b/src/cmd/gc/lex.c @@ -420,7 +420,7 @@ struct Loophack {  static int32  _yylex(void)  { -	int c, c1, clen, escflag; +	int c, c1, clen, escflag, ncp;  	vlong v;  	char *cp;  	Rune rune; @@ -490,20 +490,22 @@ l0:  	case '"':  		/* "..." */  		strcpy(lexbuf, "\"<string>\""); -		cp = mal(sizeof(int32)); +		cp = mal(8);  		clen = sizeof(int32); +		ncp = 8;  		for(;;) { +			if(clen+UTFmax > ncp) { +				cp = remal(cp, ncp, ncp); +				ncp += ncp; +			}  			if(escchar('"', &escflag, &v))  				break;  			if(v < Runeself || escflag) { -				cp = remal(cp, clen, 1);  				cp[clen++] = v;  			} else { -				// botch - this limits size of runes  				rune = v;  				c = runelen(rune); -				cp = remal(cp, clen, c);  				runetochar(cp+clen, &rune);  				clen += c;  			} @@ -513,10 +515,15 @@ l0:  	case '`':  		/* `...` */  		strcpy(lexbuf, "`<string>`"); -		cp = mal(sizeof(int32)); +		cp = mal(8);  		clen = sizeof(int32); +		ncp = 8;  		for(;;) { +			if(clen == ncp) { +				cp = remal(cp, clen, ncp); +				ncp += ncp; +			}  			c = getc();  			if(c == EOF) {  				yyerror("eof in string"); @@ -524,14 +531,12 @@ l0:  			}  			if(c == '`')  				break; -			cp = remal(cp, clen, 1);  			cp[clen++] = c;  		}  	strlit:  		*(int32*)cp = clen-sizeof(int32);	// length  		do { -			cp = remal(cp, clen, 1);  			cp[clen++] = 0;  		} while(clen & MAXALIGN);  		yylval.val.u.sval = (Strlit*)cp; diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 3e58415a8..ee47cc8e1 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -364,7 +364,7 @@ importdot(Pkg *opkg, Node *pack)  	}  } -void +static void  gethunk(void)  {  	char *h; @@ -374,7 +374,7 @@ gethunk(void)  	if(thunk >= 10L*NHUNK)  		nh = 10L*NHUNK;  	h = (char*)malloc(nh); -	if(h == (char*)-1) { +	if(h == nil) {  		flusherrors();  		yyerror("out of memory");  		errorexit(); @@ -389,11 +389,22 @@ mal(int32 n)  {  	void *p; +	if(n >= NHUNK) { +		p = malloc(n); +		if(p == nil) { +			flusherrors(); +			yyerror("out of memory"); +			errorexit(); +		} +		memset(p, 0, n); +		return p; +	} +  	while((uintptr)hunk & MAXALIGN) {  		hunk++;  		nhunk--;  	} -	while(nhunk < n) +	if(nhunk < n)  		gethunk();  	p = hunk; @@ -410,7 +421,12 @@ remal(void *p, int32 on, int32 n)  	q = (uchar*)p + on;  	if(q != hunk || nhunk < n) { -		while(nhunk < on+n) +		if(on+n >= NHUNK) { +			q = mal(on+n); +			memmove(q, p, on); +			return q; +		} +		if(nhunk < on+n)  			gethunk();  		memmove(hunk, p, on);  		p = hunk; | 
