cgen: fix a sporadic segfault when giving -width in a string interpolation
							parent
							
								
									5f435fa1cc
								
							
						
					
					
						commit
						809676a856
					
				|  | @ -9,6 +9,10 @@ fn (mut g Gen) write_str_fn_definitions() { | ||||||
| void _STR_PRINT_ARG(const char *fmt, char** refbufp, int *nbytes, int *memsize, int guess, ...) { | void _STR_PRINT_ARG(const char *fmt, char** refbufp, int *nbytes, int *memsize, int guess, ...) { | ||||||
| 	va_list args; | 	va_list args; | ||||||
| 	va_start(args, guess); | 	va_start(args, guess); | ||||||
|  | 	// NB: (*memsize - *nbytes) === how much free space is left at the end of the current buffer refbufp
 | ||||||
|  | 	// *memsize === total length of the buffer refbufp
 | ||||||
|  | 	// *nbytes === already occupied bytes of buffer refbufp
 | ||||||
|  | 	// guess === how many bytes were taken during the current vsnprintf run
 | ||||||
| 	for(;;) { | 	for(;;) { | ||||||
| 		if (guess < *memsize - *nbytes) { | 		if (guess < *memsize - *nbytes) { | ||||||
| 			guess = vsnprintf(*refbufp + *nbytes, *memsize - *nbytes, fmt, args); | 			guess = vsnprintf(*refbufp + *nbytes, *memsize - *nbytes, fmt, args); | ||||||
|  | @ -62,7 +66,7 @@ string _STR(const char *fmt, int nfmts, ...) { | ||||||
| 						fwidth -= (s.len - utf8_str_visible_length(s)); | 						fwidth -= (s.len - utf8_str_visible_length(s)); | ||||||
| 					else | 					else | ||||||
| 						fwidth += (s.len - utf8_str_visible_length(s)); | 						fwidth += (s.len - utf8_str_visible_length(s)); | ||||||
| 					_STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+fwidth-4, fwidth, s.len, s.str); | 					_STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+s.len-4, fwidth, s.len, s.str); | ||||||
| 				} else { // %.*s
 | 				} else { // %.*s
 | ||||||
| 					_STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+s.len-4, s.len, s.str); | 					_STR_PRINT_ARG(fmt, &buf, &nbytes, &memsize, k+s.len-4, s.len, s.str); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | @ -56,7 +56,7 @@ fn test_implicit_str() { | ||||||
| 	assert text == '4242' | 	assert text == '4242' | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| fn test_string_interpolation_percent_escaping(){ | fn test_string_interpolation_percent_escaping() { | ||||||
| 	test := 'hello' | 	test := 'hello' | ||||||
| 	hello := 'world' | 	hello := 'world' | ||||||
| 	x := '%.*s$hello$test |${hello:-30s}|' | 	x := '%.*s$hello$test |${hello:-30s}|' | ||||||
|  | @ -111,7 +111,11 @@ fn test_utf8_string_interpolation() { | ||||||
| 	st := 'Sträßle' | 	st := 'Sträßle' | ||||||
| 	m := '10€' | 	m := '10€' | ||||||
| 	assert '$a $st $m' == 'à-côté Sträßle 10€' | 	assert '$a $st $m' == 'à-côté Sträßle 10€' | ||||||
| 	assert '>${a:10}< >${st:-8}< >${m:5}<-' == '>    à-côté< >Sträßle < >  10€<-' | 	zz := '>${a:10}< >${st:-8}< >${m:5}<-' | ||||||
|  | 	zz_expected := '>    à-côté< >Sträßle < >  10€<-' | ||||||
|  | 	eprintln('         zz: $zz') | ||||||
|  | 	eprintln('zz_expected: $zz_expected') | ||||||
|  | 	assert zz == zz_expected | ||||||
| 	// e := '\u20AC' // Eurosign doesn' work with MSVC and tcc
 | 	// e := '\u20AC' // Eurosign doesn' work with MSVC and tcc
 | ||||||
| 	e := '€' | 	e := '€' | ||||||
| 	assert '100.00 $e' == '100.00 €' | 	assert '100.00 $e' == '100.00 €' | ||||||
|  | @ -135,3 +139,15 @@ fn test_string_interpolation_str_evaluation() { | ||||||
| 	mut x := S{17, 13.455893} | 	mut x := S{17, 13.455893} | ||||||
| 	assert '$x' == '[17, 13.456]' | 	assert '$x' == '[17, 13.456]' | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | fn test_string_interpolation_with_negative_format_width_should_compile_and_run_without_segfaulting() { | ||||||
|  | 	// discovered during debugging VLS
 | ||||||
|  | 	i := 3 | ||||||
|  | 	input := '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | ||||||
|  | 	eprintln('---------------------------------------------------------------------------------------------') | ||||||
|  | 	eprintln('+60 ${i:10} | input.len: ${input.len:10} | ${input.bytes().hex():60} | $input') | ||||||
|  | 	eprintln('-60 ${i:10} | input.len: ${input.len:10} | ${input.bytes().hex():-60} | $input') | ||||||
|  | 	eprintln('---------------------------------------------------------------------------------------------') | ||||||
|  | 	assert true | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue