Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:10340 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 21249 invoked by uid 1010); 9 Jun 2004 10:53:08 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 21225 invoked by uid 1007); 9 Jun 2004 10:53:08 -0000 To: internals@lists.php.net Date: Wed, 09 Jun 2004 13:52:42 +0300 References: Organization: none Content-Type: text/plain; format=flowed; delsp=yes; charset=koi8-r MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID: User-Agent: Opera M2/7.50 (Win32, build 3778) X-Posted-By: 217.23.116.150 Subject: Re: [PHP-DEV] stripslashes() improvements From: valyala@tut.by ("Alexander Valyalkin") On Tue, 8 Jun 2004 16:03:19 +0200 (CEST), Derick Rethans wrote: > > You'll have to proof that by writing testcases, for example try it with > the test cases in the current source and write new ones for things that > we don't have a test case for yet. > >> -PHPAPI void php_stripslashes(char *str, int *len TSRMLS_DC) >> +PHPAPI void php_stripslashes(char *str, size_t *len TSRMLS_DC) > > You can't just change the API call, that will break things. > > > regards, > Derick Ok. First of all, my version of the stripslashes() solves following bugs: #9437 #19947 #27848 I have successfully tested my code with test case from current source /ext/standard/tests/strings/add-and-stripslashes.phpt And here is my testcase, related to mentioned bugs: Here is corrected code with standart API call: ====================cut====================== PHPAPI void php_stripslashes(char *str, int *len TSRMLS_DC) { char *s, *t; size_t l; size_t dst_len; /* length of the stripped string */ if (len != NULL) l = dst_len = (size_t) *len; else l = dst_len = strlen(str); if (l < 2) return; /* there is no characters to strip */ s = t = str; if (PG(magic_quotes_sybase)) { /* sybase magic_quotes ( '' -> ', \0 -> NULL) */ while (l > 1) { if (*t == '\'' && *(t + 1) == '\'') { *s++ = '\''; t += 2; l--; dst_len--; } else if (*t == '\\' && *(t + 1) == '0') { *s++ = '\0'; t += 2; l--; dst_len--; } else *s++ = *t++; l--; } } else { /* ordinary magic_qoutes (not sybase) ( \\ -> \, \' -> ', \" -> ", \0 -> NULL) */ while (l > 1) { if (*t == '\\') { t++; switch (*t) { case '\\' : case '\'' : case '"' : *s++ = *t++; dst_len--; break; case '0' : *s++ = '\0'; t++; dst_len--; break; default : *s++ = '\\'; *s++ = *t++; break; } l -= 2; } else { *s++ = *t++; l--; } } } if (l == 1) *s++ = *t; /* copy the last symbol */ if (len != NULL) *len = (int) dst_len; /* set length of the stripped string */ *s = '\0'; } ====================cut====================== diff: ====================cut====================== --- string.c Thu May 13 20:44:32 2004 +++ string_new.c Wed Jun 09 13:47:21 2004 @@ -2159,70 +2159,51 @@ PHPAPI void php_stripslashes(char *str, int *len TSRMLS_DC) { char *s, *t; - int l; - - if (len != NULL) { - l = *len; - } else { - l = strlen(str); - } - s = str; - t = str; + size_t l; + size_t dst_len; /* length of the stripped string */ - if (PG(magic_quotes_sybase)) { - while (l > 0) { - if (*t == '\'') { - if ((l > 0) && (t[1] == '\'')) { - t++; - if (len != NULL) - (*len)--; + if (len != NULL) l = dst_len = (size_t) *len; + else l = dst_len = strlen(str); + if (l < 2) return; /* there is no characters to strip */ + s = t = str; + + if (PG(magic_quotes_sybase)) { /* sybase magic_quotes ( '' -> ', \0 -> NULL) */ + while (l > 1) { + if (*t == '\'' && *(t + 1) == '\'') { + *s++ = '\''; + t += 2; l--; - } - *s++ = *t++; - } else if (*t == '\\' && l > 0 && t[1] == '0') { + dst_len--; + } else if (*t == '\\' && *(t + 1) == '0') { *s++='\0'; t += 2; - if (len != NULL) - (*len)--; l--; - } else { - *s++ = *t++; - } + dst_len--; + } else *s++ = *t++; l--; } - *s = '\0'; - - return; - } - - while (l > 0) { + } else { /* ordinary magic_qoutes (not sybase) ( \\ -> \, \' -> ', \" -> ", \0 -> NULL) */ + while (l > 1) { if (*t == '\\') { - t++; /* skip the slash */ - if (len != NULL) - (*len)--; - l--; - if (l > 0) { - if (*t == '0') { - *s++='\0'; t++; - } else { - *s++ = *t++; /* preserve the next character */ - } - l--; + switch (*t) { + case '\\' : + case '\'' : + case '"' : + *s++ = *t++; dst_len--; break; + case '0' : *s++ = '\0'; t++; dst_len--; break; + default : *s++ = '\\'; *s++ = *t++; break; } + l -= 2; } else { - if (s != t) { *s++ = *t++; - } else { - s++; - t++; - } l--; } } - if (s != t) { - *s = '\0'; } + if (l == 1) *s++ = *t; /* copy the last symbol */ + if (len != NULL) *len = (int) dst_len; /* set length of the stripped string */ + *s = '\0'; } /* }}} */ ====================cut====================== -- Using Opera's revolutionary e-mail client: http://www.opera.com/m2/