Author: nhosoi
Update of /cvs/dirsec/ldapserver/ldap/servers/plugins/syntaxes
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv24889/ldap/servers/plugins/syntaxes
Modified Files:
Tag: Directory71RtmBranch
string.c
Log Message:
Resolves: #182621
Summary: Allow larger regex buffer to enable long substring filters
Description: Applying the patches provided by ulf.weltman(a)hp.com.
regex.c: use dynamically allocated regex buffer, use ptrdiff_t to store the offsets to be
restored after the realloc, and use a constant for the value of "how much the NFA
buffer can grow in one iteration on the pattern".
string.c: use dynamically allocated buffer if the prepared buffer is not large enough,
used wrong pointer (pat instead of p) in a debug message, and performed an unneeded strcat
of ".*"
Index: string.c
===================================================================
RCS file: /cvs/dirsec/ldapserver/ldap/servers/plugins/syntaxes/string.c,v
retrieving revision 1.5
retrieving revision 1.5.2.1
diff -u -r1.5 -r1.5.2.1
--- string.c 19 Apr 2005 22:07:35 -0000 1.5
+++ string.c 30 Apr 2008 20:57:44 -0000 1.5.2.1
@@ -183,8 +183,8 @@
string_filter_sub( Slapi_PBlock *pb, char *initial, char **any, char *final,
Slapi_Value **bvals, int syntax )
{
- int i, j, rc;
- char *p, *end, *realval, *tmpbuf;
+ int i, j, rc, size=0;
+ char *p, *end, *realval, *tmpbuf, *bigpat = NULL;
size_t tmpbufsize;
char pat[BUFSIZ];
char buf[BUFSIZ];
@@ -192,7 +192,6 @@
LDAPDebug( LDAP_DEBUG_FILTER, "=> string_filter_sub\n",
0, 0, 0 );
-
/*
* construct a regular expression corresponding to the
* filter and let regex do the work for each value
@@ -201,16 +200,33 @@
pat[0] = '\0';
p = pat;
end = pat + sizeof(pat) - 2; /* leave room for null */
+
if ( initial != NULL ) {
- value_normalize( initial, syntax, 1 /* trim leading blanks */ );
- strcpy( p, "^" );
- p = strchr( p, '\0' );
- /* 2 * in case every char is special */
- if ( p + 2 * strlen( initial ) > end ) {
- LDAPDebug( LDAP_DEBUG_ANY, "not enough pattern space\n",
- 0, 0, 0 );
- return( -1 );
+ size = strlen( initial ) + 1; /* add 1 for "^" */
+ }
+
+ if ( any != NULL ) {
+ i = 0;
+ while ( any[i] ) {
+ size += strlen(any[i++]) + 2; /* add 2 for ".*" */
}
+ }
+
+ if ( final != NULL ) {
+ size += strlen( final ) + 3; /* add 3 for ".*" and "$" */
+ }
+
+ size *= 2; /* doubled in case all filter chars need escaping */
+ size++; /* add 1 for null */
+
+ if ( p + size > end ) {
+ bigpat = slapi_ch_malloc( size );
+ p = bigpat;
+ }
+
+ if ( initial != NULL ) {
+ value_normalize( initial, syntax, 1 /* trim leading blanks */ );
+ *p++ = '^';
filter_strcpy_special( p, initial );
p = strchr( p, '\0' );
}
@@ -218,13 +234,8 @@
for ( i = 0; any[i] != NULL; i++ ) {
value_normalize( any[i], syntax, 0 /* DO NOT trim leading blanks */ );
/* ".*" + value */
- if ( p + 2 * strlen( any[i] ) + 2 > end ) {
- LDAPDebug( LDAP_DEBUG_ANY,
- "not enough pattern space\n", 0, 0, 0 );
- return( -1 );
- }
- strcpy( p, ".*" );
- p = strchr( p, '\0' );
+ *p++ = '.';
+ *p++ = '*';
filter_strcpy_special( p, any[i] );
p = strchr( p, '\0' );
}
@@ -232,28 +243,26 @@
if ( final != NULL ) {
value_normalize( final, syntax, 0 /* DO NOT trim leading blanks */ );
/* ".*" + value */
- if ( p + 2 * strlen( final ) + 2 > end ) {
- LDAPDebug( LDAP_DEBUG_ANY, "not enough pattern space\n",
- 0, 0, 0 );
- return( -1 );
- }
- strcpy( p, ".*" );
- p = strchr( p, '\0' );
+ *p++ = '.';
+ *p++ = '*';
filter_strcpy_special( p, final );
- p = strchr( p, '\0' );
- strcpy( p, "$" );
+ strcat( p, "$" );
}
/* compile the regex */
+ p = (bigpat) ? bigpat : pat;
slapd_re_lock();
- if ( (p = slapd_re_comp( pat )) != 0 ) {
+ if ( (tmpbuf = slapd_re_comp( p )) != 0 ) {
LDAPDebug( LDAP_DEBUG_ANY, "re_comp (%s) failed (%s)\n",
pat, p, 0 );
slapd_re_unlock();
- return( -1 );
+ if( bigpat != NULL ) {
+ slapi_ch_free((void**)&bigpat );
+ }
+ return( LDAP_OPERATIONS_ERROR );
} else {
LDAPDebug( LDAP_DEBUG_TRACE, "re_comp (%s)\n",
- escape_string( pat, ebuf ), 0, 0 );
+ escape_string( p, ebuf ), 0, 0 );
}
/*
@@ -265,7 +274,7 @@
for ( j = 0; bvals[j] != NULL; j++ ) {
int tmprc;
size_t len;
- const struct berval *bvp = slapi_value_get_berval(bvals[j]);
+ const struct berval *bvp = slapi_value_get_berval(bvals[j]);
len = bvp->bv_len;
if ( len < sizeof(buf) ) {
@@ -294,6 +303,9 @@
if ( tmpbuf != NULL ) {
slapi_ch_free((void**)&tmpbuf );
}
+ if( bigpat != NULL ) {
+ slapi_ch_free((void**)&bigpat );
+ }
LDAPDebug( LDAP_DEBUG_FILTER, "<= string_filter_sub %d\n",
rc, 0, 0 );