Skip to content

Commit 1937d58

Browse files
authored
Merge pull request #142 from jayrm/bugfix-wstring
Fix wstring bugs in [L|R]TRIM functions - sf.net # 899 trim( wstring ) causes crash if string is single space - sf.net # 900 LTRIM and TRIM truncate result if filter is zero length string
2 parents ae9a9f3 + b3e3528 commit 1937d58

File tree

12 files changed

+825
-580
lines changed

12 files changed

+825
-580
lines changed

changelog.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Version 1.07.0
1515
- 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
1616
- github #137: Final -Wl flag takes precedence over previous. fbc now passes down all options from all -Wa, -Wc, and -Wl flags (William Breathitt Gray)
1717
- github #138: rtlib: freebsd: Fix deprecated use of VM_METER to use VM_TOTAL (William Breathitt Gray)
18+
- sf.net #899: TRIM( wstring ) causes crash if string is single space
19+
- sf.net #900: LTRIM( wstring, filter ) and TRIM( wstring, filter ) truncate result if filter is zero length string
1820

1921

2022
Version 1.06.0

src/rtlib/fb_unicode.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ typedef uint8_t UTF_8;
126126
/* Calculate the number of characters between two pointers. */
127127
static __inline__ ssize_t fb_wstr_CalcDiff( const FB_WCHAR *ini, const FB_WCHAR *end )
128128
{
129-
return ((intptr_t)end - (intptr_t)ini) / sizeof( FB_WCHAR );
129+
return end - ini;
130130
}
131131

132132
static __inline__ FB_WCHAR *fb_wstr_AllocTemp( ssize_t chars )
@@ -220,12 +220,12 @@ static __inline__ const FB_WCHAR *fb_wstr_SkipCharRev( const FB_WCHAR *s, ssize_
220220
return s;
221221

222222
/* fixed-len's are filled with null's as in PB, strip them too */
223-
const FB_WCHAR *p = &s[chars-1];
223+
const FB_WCHAR *p = &s[chars];
224224
while( chars > 0 )
225225
{
226-
if( *p != c )
227-
return p;
228226
--p;
227+
if( *p != c )
228+
return ++p;
229229
--chars;
230230
}
231231

src/rtlib/strw_ltrim.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ FBCALL FB_WCHAR *fb_WstrLTrim ( const FB_WCHAR *src )
1919
return NULL;
2020

2121
/* alloc temp string */
22-
dst = fb_wstr_AllocTemp( len );
22+
dst = fb_wstr_AllocTemp( len );
2323
if( dst != NULL )
2424
fb_wstr_Copy( dst, p, len );
2525

src/rtlib/strw_ltrimex.c

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,48 +4,48 @@
44

55
FBCALL FB_WCHAR *fb_WstrLTrimEx ( const FB_WCHAR *src, const FB_WCHAR *pattern )
66
{
7-
FB_WCHAR *dst;
7+
FB_WCHAR *dst;
88
ssize_t len;
9-
const FB_WCHAR *p = NULL;
9+
const FB_WCHAR *p = src;
1010

11-
if( src == NULL ) {
12-
return NULL;
13-
}
11+
if( src == NULL ) {
12+
return NULL;
13+
}
1414

15-
{
16-
ssize_t len_pattern = fb_wstr_Len( pattern );
17-
len = fb_wstr_Len( src );
18-
if( len >= len_pattern ) {
19-
if( len_pattern==1 ) {
20-
p = fb_wstr_SkipChar( src,
21-
len,
22-
*pattern );
23-
len = len - (ssize_t)(p - src);
15+
{
16+
ssize_t len_pattern = fb_wstr_Len( pattern );
17+
len = fb_wstr_Len( src );
18+
if( len >= len_pattern ) {
19+
if( len_pattern==1 ) {
20+
p = fb_wstr_SkipChar( src,
21+
len,
22+
*pattern );
23+
len -= fb_wstr_CalcDiff( src, p );
2424

25-
} else if( len_pattern != 0 ) {
26-
p = src;
27-
while (len >= len_pattern ) {
28-
if( fb_wstr_Compare( p, pattern, len_pattern )!=0 )
29-
break;
30-
p += len_pattern;
31-
len -= len_pattern;
32-
}
33-
}
34-
}
25+
} else if( len_pattern != 0 ) {
26+
p = src;
27+
while (len >= len_pattern ) {
28+
if( fb_wstr_Compare( p, pattern, len_pattern )!=0 )
29+
break;
30+
p += len_pattern;
31+
len -= len_pattern;
32+
}
33+
}
34+
}
3535
}
3636

3737
if( len > 0 )
3838
{
3939
/* alloc temp string */
40-
dst = fb_wstr_AllocTemp( len );
40+
dst = fb_wstr_AllocTemp( len );
4141
if( dst != NULL )
4242
{
4343
/* simple copy */
4444
fb_wstr_Copy( dst, p, len );
4545
}
4646
else
4747
dst = NULL;
48-
}
48+
}
4949
else
5050
dst = NULL;
5151

src/rtlib/strw_rtrim.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ FBCALL FB_WCHAR *fb_WstrRTrim ( const FB_WCHAR *src )
1616
return NULL;
1717

1818
p = fb_wstr_SkipCharRev( src, chars, _LC(' ') );
19-
chars = fb_wstr_CalcDiff( src, p ) + 1;
19+
chars = fb_wstr_CalcDiff( src, p );
2020
if( chars <= 0 )
2121
return NULL;
2222

2323
/* alloc temp string */
24-
dst = fb_wstr_AllocTemp( chars );
24+
dst = fb_wstr_AllocTemp( chars );
2525
if( dst != NULL )
2626
{
2727
/* simple copy */

src/rtlib/strw_rtrimex.c

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,54 +4,54 @@
44

55
FBCALL FB_WCHAR *fb_WstrRTrimEx ( const FB_WCHAR *src, const FB_WCHAR *pattern )
66
{
7-
FB_WCHAR *dst;
7+
FB_WCHAR *dst;
88
ssize_t len;
9-
const FB_WCHAR *p = NULL;
9+
const FB_WCHAR *p = src;
1010

11-
if( src == NULL ) {
12-
return NULL;
13-
}
11+
if( src == NULL ) {
12+
return NULL;
13+
}
1414

1515
{
1616
ssize_t len_pattern = fb_wstr_Len( pattern );
1717
len = fb_wstr_Len( src );
1818
if( len >= len_pattern )
1919
{
20-
if( len_pattern==1 ) {
21-
p = fb_wstr_SkipCharRev( src,
22-
len,
23-
*pattern );
24-
len = (ssize_t)(p - src) + 1;
20+
if( len_pattern==1 ) {
21+
p = fb_wstr_SkipCharRev( src,
22+
len,
23+
*pattern );
24+
len = fb_wstr_CalcDiff( src, p );
2525

26-
} else if( len_pattern != 0 ) {
27-
ssize_t test_index = len - len_pattern;
28-
p = src;
29-
while (len >= len_pattern ) {
30-
if( fb_wstr_Compare( p + test_index,
31-
pattern,
32-
len_pattern )!=0 )
33-
break;
34-
test_index -= len_pattern;
35-
}
36-
len = test_index + len_pattern;
37-
}
26+
} else if( len_pattern != 0 ) {
27+
ssize_t test_index = len - len_pattern;
28+
p = src;
29+
while (len >= len_pattern ) {
30+
if( fb_wstr_Compare( p + test_index,
31+
pattern,
32+
len_pattern )!=0 )
33+
break;
34+
test_index -= len_pattern;
35+
}
36+
len = test_index + len_pattern;
37+
}
3838
}
39-
}
39+
}
4040

4141
if( len > 0 )
4242
{
4343
/* alloc temp string */
44-
dst = fb_wstr_AllocTemp( len );
44+
dst = fb_wstr_AllocTemp( len );
4545
if( dst != NULL )
4646
{
4747
/* simple copy */
4848
fb_wstr_Copy( dst, src, len );
4949
}
5050
else
5151
dst = NULL;
52-
}
52+
}
5353
else
5454
dst = NULL;
5555

56-
return dst;
56+
return dst;
5757
}

src/rtlib/strw_trim.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ FBCALL FB_WCHAR *fb_WstrTrim ( const FB_WCHAR *src )
1616
return NULL;
1717

1818
p = fb_wstr_SkipCharRev( src, chars, _LC(' ') );
19-
chars = fb_wstr_CalcDiff( src, p ) + 1;
19+
chars = fb_wstr_CalcDiff( src, p );
2020
if( chars <= 0 )
2121
return NULL;
2222

@@ -26,7 +26,7 @@ FBCALL FB_WCHAR *fb_WstrTrim ( const FB_WCHAR *src )
2626
return NULL;
2727

2828
/* alloc temp string */
29-
dst = fb_wstr_AllocTemp( chars );
29+
dst = fb_wstr_AllocTemp( chars );
3030
if( dst != NULL )
3131
{
3232
/* simple copy */

src/rtlib/strw_trimex.c

Lines changed: 45 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,69 +4,69 @@
44

55
FBCALL FB_WCHAR *fb_WstrTrimEx ( const FB_WCHAR *src, const FB_WCHAR *pattern )
66
{
7-
FB_WCHAR *dst;
7+
FB_WCHAR *dst;
88
ssize_t len;
9-
const FB_WCHAR *p = NULL;
9+
const FB_WCHAR *p = src;
1010

11-
if( src == NULL ) {
12-
return NULL;
13-
}
11+
if( src == NULL ) {
12+
return NULL;
13+
}
1414

15-
{
16-
ssize_t len_pattern = fb_wstr_Len( pattern );
17-
len = fb_wstr_Len( src );
18-
if( len >= len_pattern ) {
19-
if( len_pattern==1 ) {
20-
p = fb_wstr_SkipChar( src,
21-
len,
22-
*pattern );
23-
len = len - (ssize_t)(p - src);
15+
{
16+
ssize_t len_pattern = fb_wstr_Len( pattern );
17+
len = fb_wstr_Len( src );
18+
if( len >= len_pattern ) {
19+
if( len_pattern==1 ) {
20+
p = fb_wstr_SkipChar( src,
21+
len,
22+
*pattern );
23+
len -= fb_wstr_CalcDiff( src, p );
2424

25-
} else if( len_pattern != 0 ) {
26-
p = src;
27-
while (len >= len_pattern ) {
28-
if( fb_wstr_Compare( p, pattern, len_pattern )!=0 )
29-
break;
30-
p += len_pattern;
31-
len -= len_pattern;
32-
}
33-
}
34-
}
35-
if( len >= len_pattern ) {
36-
if( len_pattern==1 ) {
37-
const FB_WCHAR *p_tmp =
38-
fb_wstr_SkipCharRev( p,
39-
len,
40-
*pattern );
41-
len = (ssize_t)(p_tmp - p) + 1;
25+
} else if( len_pattern != 0 ) {
26+
p = src;
27+
while (len >= len_pattern ) {
28+
if( fb_wstr_Compare( p, pattern, len_pattern )!=0 )
29+
break;
30+
p += len_pattern;
31+
len -= len_pattern;
32+
}
33+
}
34+
}
35+
if( len >= len_pattern ) {
36+
if( len_pattern==1 ) {
37+
const FB_WCHAR *p_tmp =
38+
fb_wstr_SkipCharRev( p,
39+
len,
40+
*pattern );
41+
len = fb_wstr_CalcDiff( p, p_tmp );
4242

43-
} else if( len_pattern != 0 ) {
44-
ssize_t test_index = len - len_pattern;
45-
while (len >= len_pattern ) {
46-
if( fb_wstr_Compare( p + test_index,
47-
pattern,
48-
len_pattern )!=0 )
49-
break;
50-
test_index -= len_pattern;
51-
}
52-
len = test_index + len_pattern;
43+
} else if( len_pattern != 0 ) {
44+
ssize_t test_index = len - len_pattern;
45+
while (len >= len_pattern ) {
46+
if( fb_wstr_Compare( p + test_index,
47+
pattern,
48+
len_pattern )!=0 )
49+
break;
50+
test_index -= len_pattern;
51+
}
52+
len = test_index + len_pattern;
5353

54-
}
55-
}
54+
}
55+
}
5656
}
5757

5858
if( len > 0 )
5959
{
6060
/* alloc temp string */
61-
dst = fb_wstr_AllocTemp( len );
61+
dst = fb_wstr_AllocTemp( len );
6262
if( dst != NULL )
6363
{
6464
/* simple copy */
6565
fb_wstr_Copy( dst, p, len );
6666
}
6767
else
6868
dst = NULL;
69-
}
69+
}
7070
else
7171
dst = NULL;
7272

tests/wstring/chk-wstring.bi

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
3+
#macro CU_ASSERT_WSTRING_EQUAL( a, b )
4+
5+
'' length check
6+
CU_ASSERT( len(a) = len(b) )
7+
8+
'' comparison check
9+
CU_ASSERT_EQUAL(a, b)
10+
11+
'' byte-by-byte check
12+
scope
13+
if(len(a) = len(b)) then
14+
do
15+
for i as integer = 0 to len(a) - 1
16+
if(a[i] <> b[i]) then
17+
CU_FAIL()
18+
exit do
19+
end if
20+
next
21+
CU_PASS()
22+
loop until true
23+
end if
24+
end scope
25+
26+
#endmacro

0 commit comments

Comments
 (0)