Skip to content

Commit 20ef868

Browse files
committed
bugfix: sf.net #897 length of literal wstring is miscalculated at compile time. Compile time evaluation of len(!"\u1234") was using the internal escaped string length instead of the actual codepoint length
1 parent a6ca278 commit 20ef868

File tree

3 files changed

+66
-19
lines changed

3 files changed

+66
-19
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Version 1.07.0
1010
- push/pop correct GL_PROJECTION matrix and GL_MODELVIEW matrix when setting up graphics screen (gothon)
1111
- fix char & wchar concatentation. For char double byte characters (such as Chinese characters), the "wstr = char & wchar" would become "wstr = char & chrw(0) & wchar" (SkyFish)
1212
- sf.net #794: literal tabs in string literals miscompiled if followed by 0-9 numeric chars
13+
- sf.net #897: length of literal wstring is miscalculated at compile time. Compile time evaluation of len(!"\u1234") was using the internal escaped string length instead of the actual codepoint length
1314

1415

1516
Version 1.06.0

src/compiler/parser-quirk-math.bas

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,10 @@ private function hLen _
7474
end if
7575

7676
'' String literal, evaluate at compile-time
77-
lgt = symbGetWstrLen( litsym ) - 1
77+
'' symbGetStrLen( litsym ) will return the number of codepoints
78+
'' that are used to store the escaped WSTRING literal, when what
79+
'' we really want is the number od codepoints unescaped.
80+
lgt = len( *hUnescapeW( symbGetVarLitTextW( litsym ) ) )
7881

7982
case FB_DATATYPE_FIXSTR
8083
'' len( fixstr ) returns the N from STRING * N, i.e. it works

tests/wstring/len.bas

Lines changed: 61 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,27 +2,70 @@
22

33
SUITE( fbc_tests.wstring_.len_ )
44

5-
const TEST_LIT = "abcdef"
5+
'' len( [w]str( literal ) ) is evaluated at compile time
6+
'' check that the compile time calculation matches the
7+
'' run time library calculation
8+
9+
const LIT_A1 = "abcdef"
10+
const LIT_W1 = wstr( "abcdef" )
11+
const LIT_W2 = !"bcd\u0065\u0066\u0067"
12+
const LIT_W3 = !"\u0063\u0064\u0065\u0065\u0067\u0068"
13+
14+
const CODE_LEN = 6
15+
616
const TEST_LEN = 32
717
const TEST_SIZ = TEST_LEN * len( wstring )
818

9-
TEST( default )
10-
11-
dim s as wstring * TEST_LEN
12-
dim ps as wstring ptr
13-
14-
s = TEST_LIT
15-
ps = @s
16-
17-
CU_ASSERT( len( s ) = len( TEST_LIT ) )
18-
19-
CU_ASSERT( sizeof( s ) = TEST_SIZ )
20-
21-
CU_ASSERT( len( *ps ) = len( TEST_LIT ) )
22-
23-
CU_ASSERT( len( ps ) = len( any ptr ) )
24-
25-
CU_ASSERT( sizeof( ps ) = sizeof( any ptr ) )
19+
#macro do_test( init_string )
20+
21+
scope
22+
dim s as wstring * TEST_LEN
23+
dim ps as wstring ptr
24+
25+
s = init_string
26+
ps = @s
27+
28+
CU_ASSERT( len( s ) = CODE_LEN )
29+
CU_ASSERT( len( *ps ) = CODE_LEN )
30+
31+
CU_ASSERT( len( s ) = len( init_string ) )
32+
33+
CU_ASSERT( sizeof( s ) = TEST_SIZ )
34+
35+
CU_ASSERT( len( *ps ) = len( init_string ) )
36+
37+
CU_ASSERT( len( ps ) = len( any ptr ) )
38+
39+
CU_ASSERT( sizeof( ps ) = sizeof( any ptr ) )
40+
end scope
41+
42+
#endmacro
43+
44+
TEST( literal )
45+
46+
do_test( "abcdef" )
47+
do_test( wstr( "abcdef" ) )
48+
do_test( !"bcd\u0065\u0066\u0067" )
49+
do_test( !"\u0063\u0064\u0065\u0065\u0067\u0068" )
50+
51+
do_test( LIT_A1 )
52+
do_test( LIT_W1 )
53+
do_test( LIT_W2 )
54+
do_test( LIT_W3 )
55+
56+
END_TEST
57+
58+
TEST( literal_const )
59+
60+
do_test( "abcdef" )
61+
do_test( wstr( "abcdef" ) )
62+
do_test( !"bcd\u0065\u0066\u0067" )
63+
do_test( !"\u0063\u0064\u0065\u0065\u0067\u0068" )
64+
65+
do_test( LIT_A1 )
66+
do_test( LIT_W1 )
67+
do_test( LIT_W2 )
68+
do_test( LIT_W3 )
2669

2770
END_TEST
2871

0 commit comments

Comments
 (0)