@@ -47,33 +47,46 @@ occurrences(const char *needle, const char *haystack) {
4747}
4848
4949char *
50- str_replace (const char * str , const char * sub , const char * replace ) {
51- char * pos = (char * ) str ;
52- int count = occurrences (sub , str );
53-
54- if (0 >= count ) return strdup (str );
55-
56- int size = (
57- strlen (str )
58- - (strlen (sub ) * count )
59- + strlen (replace ) * count
60- ) + 1 ;
61-
62- char * result = (char * ) malloc (size );
63- if (NULL == result ) return NULL ;
64- memset (result , '\0' , size );
65- char * current ;
66- while ((current = strstr (pos , sub ))) {
67- int len = current - pos ;
68- strncat (result , pos , len );
69- strncat (result , replace , strlen (replace ));
70- pos = current + strlen (sub );
71- }
72-
73- if (pos != (str + strlen (str ))) {
74- strncat (result , pos , (str - pos ));
75- }
76-
77- return result ;
50+ str_replace (const char * str , const char * sub , const char * replace )
51+ {
52+ char * pos = (char * )str ;
53+ int count = occurrences (sub , str );
54+
55+ /* 如果没有匹配,直接返回原字符串的副本 */
56+ if (count <= 0 ) {
57+ return strdup (str );
58+ }
59+
60+ /* 计算结果字符串所需的最大空间 */
61+ int size = (int )(strlen (str ) - (strlen (sub ) * count )
62+ + (strlen (replace ) * count ) + 1 );
63+
64+ char * result = (char * )malloc (size );
65+ if (result == NULL ) {
66+ return NULL ;
67+ }
68+ memset (result , 0 , size );
69+
70+ char * current = NULL ;
71+ int offset = 0 ; /* 记录当前已经写入 result 的位置 */
72+
73+ /** 解决潜在的缓冲区溢出 **/
74+ while ((current = strstr (pos , sub )) != NULL ) {
75+ int len = (int )(current - pos );
76+ snprintf (result + offset , size - offset , "%.*s" , len , pos );
77+ offset += len ;
78+
79+ snprintf (result + offset , size - offset , "%s" , replace );
80+ offset += (int )strlen (replace );
81+
82+ pos = current + strlen (sub );
83+ }
84+
85+ /* 把剩余未匹配部分直接写入结果字符串 */
86+ if (* pos != '\0' ) {
87+ snprintf (result + offset , size - offset , "%s" , pos );
88+ }
89+
90+ return result ;
7891}
7992
0 commit comments