diff --git a/changelog.txt b/changelog.txt index 147b009e19..f966d64111 100644 --- a/changelog.txt +++ b/changelog.txt @@ -21,6 +21,7 @@ Version 1.07.0 - sf.net #899: TRIM( wstring ) causes crash if string is single space - sf.net #900: LTRIM( wstring, filter ) and TRIM( wstring, filter ) truncate result if filter is zero length string - github #116: Fix optimizations in [L/R]TrimAny rtlib functions (SkyFish) +- github #145: WSTRING concat and assign buffer (&=) overrun Version 1.06.0 diff --git a/src/rtlib/strw_concatassign.c b/src/rtlib/strw_concatassign.c index c782d97d76..200e1f1514 100644 --- a/src/rtlib/strw_concatassign.c +++ b/src/rtlib/strw_concatassign.c @@ -19,14 +19,15 @@ FBCALL FB_WCHAR *fb_WstrConcatAssign( FB_WCHAR *dst, ssize_t dst_chars, const FB /* don't check ptr's */ if( dst_chars > 0 ) { - --dst_chars; /* less the null-term */ + /* less the null-term */ + --dst_chars; if( src_len > dst_chars - dst_len ) src_len = dst_chars - dst_len; + + fb_wstr_Copy( &dst[dst_len], src, src_len ); } - /* copy the null-term too */ - fb_wstr_Move( &dst[dst_len], src, src_len + 1 ); return dst; } diff --git a/tests/wstring/concat-assign.bas b/tests/wstring/concat-assign.bas new file mode 100644 index 0000000000..be5ae5166d --- /dev/null +++ b/tests/wstring/concat-assign.bas @@ -0,0 +1,62 @@ +#include "fbcunit.bi" +#include "chk-wstring.bi" + +SUITE( fbc_tests.wstring_.concat_assign ) + + #macro check( len_a, len_b, count, s ) + scope + dim a as wstring * len_a + dim b as wstring * len_b = s + dim r as wstring * 100 + for i as integer = 1 to count + + '' concat & assign + a &= b + + '' concat, truncate, assign + r = left( r & b, len_a - 1 ) + + CU_ASSERT_WSTRING_EQUAL( a, r ) + next + end scope + #endmacro + + #macro check_6( len_b, count, s ) + check( 1, 2, 4, s ) + check( 2, 2, 4, s ) + check( 3, 2, 4, s ) + check( 4, 2, 4, s ) + check( 5, 2, 4, s ) + check( 6, 2, 4, s ) + #endmacro + + TEST( default ) + + '' strings converted to wstring + check( 1, 1, 1, "a" ) + check( 1, 1, 2, "a" ) + + check_6( 2, 4, "a" ) + check_6( 3, 4, "ab" ) + + check_6( 4, 4, "ab" ) + check_6( 5, 4, "ab" ) + + check_6( 4, 4, "abc" ) + check_6( 5, 4, "abc" ) + + '' wstrings + check( 1, 1, 1, !"\u3041" ) + check( 1, 1, 2, !"\u3041" ) + + check_6( 2, 4, !"\u3041" ) + check_6( 3, 4, !"\u3041\u3043" ) + + check_6( 4, 4, !"\u3041\u3043" ) + check_6( 5, 4, !"\u3041\u3043" ) + + check_6( 4, 4, !"\u3041\u3043\u3045" ) + check_6( 5, 4, !"\u3041\u3043\u3045" ) + END_TEST + +END_SUITE