summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/mbstring/mbstring.c109
-rw-r--r--ext/mbstring/mbstring.h26
-rw-r--r--main/rfc1867.c8
3 files changed, 98 insertions, 45 deletions
diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c
index a00b2b7f73..d44d51cd75 100644
--- a/ext/mbstring/mbstring.c
+++ b/ext/mbstring/mbstring.c
@@ -412,7 +412,7 @@ PHPAPI int php_mb_check_encoding_list(const char *encoding_list TSRMLS_DC) {
}
/* }}} */
-/* {{{ php_mb_parse_encoding_array
+/* {{{ static int php_mb_parse_encoding_array()
* Return 0 if input contains any illegal encoding, otherwise 1.
* Even if any illegal encoding is detected the result may contain a list
* of parsed encodings.
@@ -489,7 +489,7 @@ php_mb_parse_encoding_array(zval *array, int **return_list, int *return_size, in
/* }}} */
#if HAVE_MBREGEX
-/* {{{ php_mbregex_free_cache */
+/* {{{ static void php_mbregex_free_cache() */
static void
php_mbregex_free_cache(mb_regex_t *pre)
{
@@ -1510,38 +1510,6 @@ SAPI_POST_HANDLER_FUNC(php_mbstr_post_handler)
#define IS_SJIS1(c) ((((c)>=0x81 && (c)<=0x9f) || ((c)>=0xe0 && (c)<=0xf5)) ? 1 : 0)
#define IS_SJIS2(c) ((((c)>=0x40 && (c)<=0x7e) || ((c)>=0x80 && (c)<=0xfc)) ? 1 : 0)
-/* {{{ PHPAPI char *php_mb_strrchr() */
-PHPAPI char *php_mb_strrchr(const char *s, char c TSRMLS_DC)
-{
- unsigned char *p = (unsigned char *)s, *last = NULL;
- while(*p++) {
- if (*p == c) {
- last = p;
- }
- if (*p == '\0'){
- break;
- }
- if (MBSTRG(current_language) == mbfl_no_language_japanese
- && IS_SJIS1(*p) && IS_SJIS2(*(p+1))) {
- p++;
- }
- }
- return last;
-}
-/* }}} */
-
-/* {{{ PHPAPI int php_mb_is_mb_leadbyte() */
-PHPAPI int php_mb_is_mb_leadbyte(const char *s TSRMLS_DC)
-{
- unsigned char *p = (unsigned char *)s;
- if (MBSTRG(current_language) == mbfl_no_language_japanese
- && IS_SJIS1(*p) && IS_SJIS2(*(p+1))) {
- return 1;
- }
- return 0;
-}
-/* }}} */
-
/* {{{ SAPI_API SAPI_TREAT_DATA_FUNC(mbstr_treat_data)
* http input processing */
SAPI_API SAPI_TREAT_DATA_FUNC(mbstr_treat_data)
@@ -3477,6 +3445,79 @@ PHPAPI int php_mb_encoding_translation(TSRMLS_D)
}
/* }}} */
+/* {{{ PHPAPI size_t php_mb_mbchar_bytes_ex() */
+PHPAPI size_t php_mb_mbchar_bytes_ex(const char *s, const mbfl_encoding *enc)
+{
+ if (enc != NULL) {
+ if(enc->flag & MBFL_ENCTYPE_MBCS) {
+ if(enc->mblen_table != NULL) {
+ if (*s != '\0') return enc->mblen_table[*(unsigned char *)s];
+ }
+ } else if (enc->flag & (MBFL_ENCTYPE_WCS2BE | MBFL_ENCTYPE_WCS2LE)) {
+ return 2;
+ } else if (enc->flag & (MBFL_ENCTYPE_WCS4BE | MBFL_ENCTYPE_WCS4LE)) {
+ return 4;
+ }
+ }
+ return 1;
+}
+/* }}} */
+
+/* {{{ PHPAPI size_t php_mb_mbchar_bytes() */
+PHPAPI size_t php_mb_mbchar_bytes(const char *s TSRMLS_DC)
+{
+ return php_mb_mbchar_bytes_ex(s,
+ mbfl_no2encoding(MBSTRG(internal_encoding)));
+}
+/* }}} */
+
+/* {{{ PHPAPI char *php_mb_safe_strrchr_ex() */
+PHPAPI char *php_mb_safe_strrchr_ex(const char *s, unsigned int c, size_t nbytes, const mbfl_encoding *enc)
+{
+ register const char *p = s;
+ char *last;
+
+ if (nbytes == (size_t)-1) {
+ while (*p != '\0') {
+ if (*p == c) {
+ last = (char *)p;
+ }
+ p += php_mb_mbchar_bytes_ex(p, enc);
+ }
+ } else {
+ register size_t bcnt = nbytes;
+ register size_t nbytes_char;
+ while (bcnt > 0) {
+ if (*p == c) {
+ last = (char *)p;
+ }
+ nbytes_char = php_mb_mbchar_bytes_ex(p, enc);
+ if (bcnt < nbytes_char) {
+ return NULL;
+ }
+ p += nbytes_char;
+ bcnt -= nbytes_char;
+ }
+ }
+ return last;
+}
+/* }}} */
+
+/* {{{ PHPAPI char *php_mb_safe_strrchr() */
+PHPAPI char *php_mb_safe_strrchr(const char *s, unsigned int c, size_t nbytes TSRMLS_DC)
+{
+ return php_mb_safe_strrchr_ex(s, c, nbytes,
+ mbfl_no2encoding(MBSTRG(internal_encoding)));
+}
+/* }}} */
+
+/* {{{ PHPAPI char *php_mb_strrchr() */
+PHPAPI char *php_mb_strrchr(const char *s, char c TSRMLS_DC)
+{
+ return php_mb_safe_strrchr(s, c, -1 TSRMLS_CC);
+}
+/* }}} */
+
#ifdef ZEND_MULTIBYTE
/* {{{ PHPAPI int php_mb_set_zend_encoding() */
PHPAPI int php_mb_set_zend_encoding(TSRMLS_D)
diff --git a/ext/mbstring/mbstring.h b/ext/mbstring/mbstring.h
index d1ac666b73..37e4acdb69 100644
--- a/ext/mbstring/mbstring.h
+++ b/ext/mbstring/mbstring.h
@@ -58,10 +58,7 @@
#include "mbfilter.h"
#include "SAPI.h"
-#define PHP_MBSTRING_API 20020405
-
-PHPAPI char * php_mb_convert_encoding(char *input, size_t length, char *_to_encoding, char *_from_encodings, size_t *output_len TSRMLS_DC);
-PHPAPI int php_mb_check_encoding_list(const char *encoding_list TSRMLS_DC);
+#define PHP_MBSTRING_API 20021024
#if HAVE_MBREGEX
#include "php_mbregex.h"
@@ -109,10 +106,25 @@ PHP_FUNCTION(mb_decode_numericentity);
PHP_FUNCTION(mb_send_mail);
PHP_FUNCTION(mb_get_info);
-PHPAPI char *php_mb_strrchr(const char *s, char c TSRMLS_DC);
-PHPAPI int php_mb_is_leadbyte(const char *s TSRMLS_DC);
PHPAPI int php_mb_encoding_translation(TSRMLS_D);
+PHPAPI char *php_mb_safe_strrchr_ex(const char *s, unsigned int c,
+ size_t nbytes, const mbfl_encoding *enc);
+PHPAPI char *php_mb_safe_strrchr(const char *s, unsigned int c,
+ size_t nbytes TSRMLS_DC);
+PHPAPI char *php_mb_strrchr(const char *s, char c TSRMLS_DC);
+
+PHPAPI char * php_mb_convert_encoding(char *input, size_t length,
+ char *_to_encoding,
+ char *_from_encodings,
+ size_t *output_len TSRMLS_DC);
+
+PHPAPI int php_mb_check_encoding_list(const char *encoding_list TSRMLS_DC);
+
+PHPAPI size_t php_mb_mbchar_bytes_ex(const char *s, const mbfl_encoding *enc);
+PHPAPI size_t php_mb_mbchar_bytes(const char *s TSRMLS_DC);
+
+
ZEND_BEGIN_MODULE_GLOBALS(mbstring)
int language;
int current_language;
@@ -185,8 +197,6 @@ SAPI_API SAPI_TREAT_DATA_FUNC(mbstr_treat_data);
#define phpext_mbstring_ptr mbstring_module_ptr
-PHPAPI int php_mb_is_mb_leadbyte(const char *s TSRMLS_DC);
-
#endif /* _MBSTRING_H */
/*
diff --git a/main/rfc1867.c b/main/rfc1867.c
index cb4a778d73..7f393c6ec3 100644
--- a/main/rfc1867.c
+++ b/main/rfc1867.c
@@ -512,9 +512,11 @@ static char *substring_conf(char *start, int len, char quote TSRMLS_DC)
} else {
*resp++ = start[i];
#if HAVE_MBSTRING && !defined(COMPILE_DL_MBSTRING)
- if (php_mb_encoding_translation(TSRMLS_C) &&
- php_mb_is_mb_leadbyte(start+i TSRMLS_CC)) {
- *resp++ = start[++i];
+ if (php_mb_encoding_translation(TSRMLS_C)) {
+ size_t j = php_mb_mbchar_bytes(start+i TSRMLS_CC);
+ while (j-- > 0) {
+ *resp++ = start[++i];
+ }
}
#endif
}