Browse Source

Fix bug #26574 (basename() doesn't work properly with multibyte characters)

PEAR_1_4DEV
Moriyoshi Koizumi 23 years ago
parent
commit
b2cd08f33d
  1. 7
      ext/standard/ftp_fopen_wrapper.c
  2. 2
      ext/standard/php_string.h
  3. 103
      ext/standard/string.c

7
ext/standard/ftp_fopen_wrapper.c

@ -562,7 +562,7 @@ static size_t php_ftp_dirstream_read(php_stream *stream, char *buf, size_t count
php_stream *innerstream = (php_stream *)stream->abstract;
size_t tmp_len;
char *basename;
int basename_len;
size_t basename_len;
if (count != sizeof(php_stream_dirent)) {
return 0;
@ -586,8 +586,9 @@ static size_t php_ftp_dirstream_read(php_stream *stream, char *buf, size_t count
return 0;
}
memcpy(ent->d_name, basename, MIN((int)sizeof(ent->d_name), basename_len)-1);
ent->d_name[sizeof(ent->d_name)-1] = '\0';
tmp_len = MIN(sizeof(ent->d_name), basename_len) - 1;
memcpy(ent->d_name, basename, tmp_len);
ent->d_name[tmp_len] = '\0';
efree(basename);
return sizeof(php_stream_dirent);

2
ext/standard/php_string.h

@ -122,7 +122,7 @@ PHPAPI char *php_addslashes(char *str, int length, int *new_length, int freeit T
PHPAPI char *php_addcslashes(char *str, int length, int *new_length, int freeit, char *what, int wlength TSRMLS_DC);
PHPAPI void php_stripslashes(char *str, int *len TSRMLS_DC);
PHPAPI void php_stripcslashes(char *str, int *len);
PHPAPI void php_basename(char *str, size_t len , char *suffix, size_t sufflen, char **p_ret, int *p_len);
PHPAPI void php_basename(char *str, size_t len , char *suffix, size_t sufflen, char **p_ret, size_t *p_len);
PHPAPI size_t php_dirname(char *str, size_t len);
PHPAPI char *php_stristr(unsigned char *s, unsigned char *t, size_t s_len, size_t t_len);
PHPAPI char *php_str_to_str_ex(char *haystack, int length, char *needle,

103
ext/standard/string.c

@ -1068,56 +1068,69 @@ PHP_FUNCTION(strtolower)
/* {{{ php_basename
*/
PHPAPI void php_basename(char *s, size_t len, char *suffix, size_t sufflen, char **p_ret, int *p_len)
PHPAPI void php_basename(char *s, size_t len, char *suffix, size_t sufflen, char **p_ret, size_t *p_len)
{
char *ret=NULL, *c;
c = s + len - 1;
/* strip trailing slashes */
while (*c == '/'
char *ret = NULL, *c, *comp, *cend;
size_t inc_len, cnt;
int state;
c = comp = cend = s;
cnt = len;
state = 0;
while (cnt > 0) {
inc_len = (*c == '\0' ? 1: php_mblen(c, cnt));
switch (inc_len) {
case -2:
case -1:
inc_len = 1;
php_mblen(NULL, 0);
break;
case 0:
goto quit_loop;
case 1:
#ifdef PHP_WIN32
|| (*c == '\\' && !IsDBCSLeadByte(*(c-1)))
if (*c == '/' || *c == '\\') {
#else
if (*c == '/') {
#endif
) {
c--;
len--;
if (state == 1) {
state = 0;
cend = c;
}
} else {
if (state == 0) {
comp = c;
state = 1;
}
}
default:
break;
}
c += inc_len;
cnt -= inc_len;
}
/* do suffix removal as the unix command does */
if (suffix && (len > sufflen)) {
if (!memcmp(suffix, c-sufflen+1, sufflen)) {
if( (*(c-sufflen) != '/')
#ifdef PHP_WIN32
&& ( *(c-sufflen) != '\\' || IsDBCSLeadByte(*(c-sufflen-1)))
#endif
) {
c -= sufflen;
len -= sufflen;
}
}
quit_loop:
if (state == 1) {
cend = c;
}
while(c>=s) {
if(*c == '/'
#ifdef PHP_WIN32
|| ( *c == '\\' && !IsDBCSLeadByte(*(c-1)))
#endif
) {
c++;
break;
}
c--;
if (suffix != NULL && sufflen < (cend - comp) &&
memcmp(cend - sufflen, suffix, sufflen) == 0) {
cend -= sufflen;
}
if (c<s) c=s;
len -= (c-s);
ret = emalloc(len+1);
memcpy(ret, c, len);
len = cend - comp;
ret = emalloc(len + 1);
memcpy(ret, comp, len);
ret[len] = '\0';
if(p_ret) *p_ret = ret;
if(p_len) *p_len = len;
if (p_ret) {
*p_ret = ret;
}
if (p_len) {
*p_len = len;
}
}
/* }}} */
@ -1126,14 +1139,15 @@ PHPAPI void php_basename(char *s, size_t len, char *suffix, size_t sufflen, char
PHP_FUNCTION(basename)
{
char *string, *suffix = NULL, *ret;
int string_len, suffix_len = 0, ret_len;
int string_len, suffix_len = 0;
size_t ret_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &string, &string_len, &suffix, &suffix_len) == FAILURE) {
return;
}
php_basename(string, string_len, suffix, suffix_len, &ret, &ret_len);
RETURN_STRINGL(ret, ret_len, 0);
php_basename(string, string_len, suffix, suffix_len, &ret, &ret_len);
RETURN_STRINGL(ret, (int)ret_len, 0);
}
/* }}} */
@ -1230,7 +1244,8 @@ PHP_FUNCTION(pathinfo)
{
zval *tmp;
char *path, *ret = NULL;
int path_len, ret_len;
int path_len;
size_t ret_len;
long opt = PHP_PATHINFO_ALL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &path, &path_len, &opt) == FAILURE) {

Loading…
Cancel
Save