summaryrefslogtreecommitdiff
path: root/ext/pdo/pdo.c
diff options
context:
space:
mode:
authorPierrick Charron <pierrick@php.net>2009-12-06 21:32:58 +0000
committerPierrick Charron <pierrick@php.net>2009-12-06 21:32:58 +0000
commit99ba48dc60baeb3692ec05c0f6947fc7d732fa51 (patch)
tree7585d258a4b6c55fd8486ff6cb163d3a5f0ff2e4 /ext/pdo/pdo.c
parentbf550fe8da6d9c302b64bdb1ff308ee989bd4fd3 (diff)
downloadphp-git-99ba48dc60baeb3692ec05c0f6947fc7d732fa51.tar.gz
Fixed bug #50323 (Allow use of ; in values via ;; in PDO DSN even in the middle of a string).
Diffstat (limited to 'ext/pdo/pdo.c')
-rwxr-xr-xext/pdo/pdo.c40
1 files changed, 36 insertions, 4 deletions
diff --git a/ext/pdo/pdo.c b/ext/pdo/pdo.c
index e986aaa225..0143d93e8a 100755
--- a/ext/pdo/pdo.c
+++ b/ext/pdo/pdo.c
@@ -222,6 +222,7 @@ PDO_API int php_pdo_parse_data_source(const char *data_source,
int optstart = 0;
int nlen;
int n_matches = 0;
+ int n_semicolumns = 0;
i = 0;
while (i < data_source_len) {
@@ -240,14 +241,21 @@ PDO_API int php_pdo_parse_data_source(const char *data_source,
/* now we're looking for VALUE; or just VALUE<NUL> */
semi = -1;
+ n_semicolumns = 0;
while (i < data_source_len) {
if (data_source[i] == '\0') {
semi = i++;
break;
}
- if (data_source[i] == ';' && ((i + 1 >= data_source_len) || data_source[i+1] != ';')) {
- semi = i++;
- break;
+ if (data_source[i] == ';') {
+ if ((i + 1 >= data_source_len) || data_source[i+1] != ';') {
+ semi = i++;
+ break;
+ } else {
+ n_semicolumns++;
+ i += 2;
+ continue;
+ }
}
++i;
}
@@ -264,7 +272,31 @@ PDO_API int php_pdo_parse_data_source(const char *data_source,
if (parsed[j].freeme) {
efree(parsed[j].optval);
}
- parsed[j].optval = estrndup(data_source + valstart, semi - valstart);
+
+ if (n_semicolumns == 0) {
+ parsed[j].optval = estrndup(data_source + valstart, semi - valstart - n_semicolumns);
+ } else {
+ int vlen = semi - valstart;
+ char *orig_val = data_source + valstart;
+ char *new_val = (char *) emalloc(vlen - n_semicolumns + 1);
+
+ parsed[j].optval = new_val;
+
+ while (vlen && *orig_val) {
+ *new_val = *orig_val;
+ new_val++;
+
+ if (*orig_val == ';') {
+ orig_val+=2;
+ vlen-=2;
+ } else {
+ orig_val++;
+ vlen--;
+ }
+ }
+ *new_val = '\0';
+ }
+
parsed[j].freeme = 1;
++n_matches;
break;