@@ -810,12 +810,12 @@ mbfl_oddlen(mbfl_string *string)
810810 /* NOT REACHED */
811811}
812812
813- static const unsigned char * mbfl_find_offset_utf8 (const mbfl_string * str , ssize_t offset ) {
813+ static const unsigned char * mbfl_find_offset_utf8 (
814+ const unsigned char * str , const unsigned char * end , ssize_t offset ) {
814815 if (offset < 0 ) {
815- const unsigned char * pos = str -> val + str -> len ;
816- const unsigned char * begin = str -> val ;
816+ const unsigned char * pos = end ;
817817 while (offset < 0 ) {
818- if (pos <= begin ) {
818+ if (pos <= str ) {
819819 return NULL ;
820820 }
821821
@@ -829,8 +829,7 @@ static const unsigned char *mbfl_find_offset_utf8(const mbfl_string *str, ssize_
829829 return pos ;
830830 } else {
831831 const unsigned char * u8_tbl = mbfl_encoding_utf8 .mblen_table ;
832- const unsigned char * pos = str -> val ;
833- const unsigned char * end = str -> val + str -> len ;
832+ const unsigned char * pos = str ;
834833 while (offset -- > 0 ) {
835834 if (pos >= end ) {
836835 return NULL ;
@@ -888,7 +887,8 @@ mbfl_strpos(
888887 needle_u8 = needle ;
889888 }
890889
891- offset_pointer = mbfl_find_offset_utf8 (haystack_u8 , offset );
890+ offset_pointer = mbfl_find_offset_utf8 (
891+ haystack_u8 -> val , haystack_u8 -> val + haystack_u8 -> len , offset );
892892 if (!offset_pointer ) {
893893 result = MBFL_ERROR_OFFSET ;
894894 goto out ;
@@ -899,99 +899,37 @@ mbfl_strpos(
899899 goto out ;
900900 }
901901
902+ const char * found_pos ;
902903 if (!reverse ) {
903- const char * found_pos = zend_memnstr (
904+ found_pos = zend_memnstr (
905+ (const char * ) offset_pointer ,
906+ (const char * ) needle_u8 -> val , needle_u8 -> len ,
907+ (const char * ) haystack_u8 -> val + haystack_u8 -> len );
908+ } else {
909+ if (offset >= 0 ) {
910+ found_pos = zend_memnrstr (
904911 (const char * ) offset_pointer ,
905912 (const char * ) needle_u8 -> val , needle_u8 -> len ,
906913 (const char * ) haystack_u8 -> val + haystack_u8 -> len );
907- if (found_pos ) {
908- result = mbfl_pointer_to_offset_utf8 (
909- haystack_u8 -> val , (const unsigned char * ) found_pos );
910- }
911- } else {
912- if (needle_u8 -> len == 0 ) {
913- size_t haystack_length = mbfl_strlen (haystack_u8 );
914- if (offset < 0 ) {
915- result = haystack_length + offset ;
916- } else {
917- result = haystack_length ;
918- }
919- goto out ;
920- }
921-
922- size_t jtbl [1 << (sizeof (unsigned char ) * 8 )];
923- size_t needle_u8_len = needle_u8 -> len , needle_len = 0 ;
924- size_t i ;
925- const unsigned char * p , * e , * q , * qe ;
926- const unsigned char * haystack_u8_val = haystack_u8 -> val ,
927- * needle_u8_val = needle_u8 -> val ;
928- for (i = 0 ; i < sizeof (jtbl ) / sizeof (* jtbl ); ++ i ) {
929- jtbl [i ] = needle_u8_len ;
930- }
931- for (i = needle_u8_len - 1 ; i > 0 ; -- i ) {
932- unsigned char c = needle_u8_val [i ];
933- jtbl [c ] = i ;
934- if (c < 0x80 ) {
935- ++ needle_len ;
936- } else if ((c & 0xc0 ) != 0x80 ) {
937- ++ needle_len ;
938- }
939- }
940- {
941- unsigned char c = needle_u8_val [0 ];
942- if (c < 0x80 ) {
943- ++ needle_len ;
944- } else if ((c & 0xc0 ) != 0x80 ) {
945- ++ needle_len ;
946- }
947- }
948- e = haystack_u8_val ;
949- p = e + haystack_u8 -> len ;
950- qe = needle_u8_val + needle_u8_len ;
951- if (offset < 0 ) {
952- if (- offset > needle_len ) {
953- offset += needle_len ;
954- while (offset < 0 ) {
955- unsigned char c ;
956- if (p <= e ) {
957- result = MBFL_ERROR_OFFSET ;
958- goto out ;
959- }
960- c = * (-- p );
961- if (c < 0x80 ) {
962- ++ offset ;
963- } else if ((c & 0xc0 ) != 0x80 ) {
964- ++ offset ;
965- }
966- }
967- }
968914 } else {
969- e = offset_pointer ;
970- }
971- if (p < e + needle_u8_len ) {
972- goto out ;
973- }
974- p -= needle_u8_len ;
975- while (p >= e ) {
976- const unsigned char * pv = p ;
977- q = needle_u8_val ;
978- for (;;) {
979- if (q == qe ) {
980- p -= needle_u8_len ;
981- result = mbfl_pointer_to_offset_utf8 (haystack_u8_val , p );
982- goto out ;
983- }
984- if (* q != * p ) {
985- break ;
986- }
987- ++ p , ++ q ;
988- }
989- p -= jtbl [* p ];
990- if (p >= pv ) {
991- p = pv - 1 ;
915+ size_t needle_len = mbfl_strlen (needle_u8 );
916+ offset_pointer = mbfl_find_offset_utf8 (
917+ offset_pointer , haystack_u8 -> val + haystack_u8 -> len , needle_len );
918+ if (!offset_pointer ) {
919+ offset_pointer = haystack_u8 -> val + haystack_u8 -> len ;
992920 }
921+
922+ found_pos = zend_memnrstr (
923+ (const char * ) haystack_u8 -> val ,
924+ (const char * ) needle_u8 -> val , needle_u8 -> len ,
925+ (const char * ) offset_pointer );
993926 }
994927 }
928+
929+ if (found_pos ) {
930+ result = mbfl_pointer_to_offset_utf8 (haystack_u8 -> val , (const unsigned char * ) found_pos );
931+ }
932+
995933out :
996934 if (haystack_u8 == & _haystack_u8 ) {
997935 mbfl_string_clear (& _haystack_u8 );
0 commit comments