Skip to content

Commit 7e98544

Browse files
authored
Merge pull request #201 from foglede/patch-1
解决潜在的缓冲区溢出,以及更严格的编译检查
2 parents 76c71cb + 1290312 commit 7e98544

File tree

1 file changed

+41
-28
lines changed

1 file changed

+41
-28
lines changed

src/ngx_http_php_util.c

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -47,33 +47,46 @@ occurrences(const char *needle, const char *haystack) {
4747
}
4848

4949
char *
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

Comments
 (0)