From e6bb90c66a5306f3db7ca38206b27685177a65cc Mon Sep 17 00:00:00 2001 From: Will Fitch Date: Sat, 18 Jan 2014 19:24:22 -0500 Subject: [PATCH 01/15] Fix #62479: Some chars not parsed in passwords This fixes an issue where backslashes and spaces aren't correctly parsed for passwords. --- NEWS | 3 ++ ext/pdo_pgsql/pgsql_driver.c | 31 +++++++++++++++-- ext/pdo_pgsql/tests/bug62479.phpt | 56 +++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 ext/pdo_pgsql/tests/bug62479.phpt diff --git a/NEWS b/NEWS index 72c09399256..e05c987052b 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,9 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 201?, PHP 5.3.29 +- PDO_pgsql: + . Fixed bug #62479 (PDO-psql cannot connect if password contains spaces) + 12 Dec 2013, PHP 5.3.28 - Openssl: diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 55f441808e2..e2ad143acdf 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -1029,6 +1029,7 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ pdo_pgsql_db_handle *H; int ret = 0; char *conn_str, *p, *e; + char *tmp_pass; long connect_timeout = 30; H = pecalloc(1, sizeof(pdo_pgsql_db_handle), dbh->is_persistent); @@ -1050,18 +1051,44 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ connect_timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 30 TSRMLS_CC); } + if (dbh->password) { + if (dbh->password[0] != '\'' && dbh->password[strlen(dbh->password) - 1] != '\'') { + char *pwd = dbh->password; + int pos = 1; + + tmp_pass = safe_emalloc(2, strlen(dbh->password), 3); + tmp_pass[0] = '\''; + + while (*pwd != '\0') { + if (*pwd == '\\' || *pwd == '\'') { + tmp_pass[pos++] = '\\'; + } + + tmp_pass[pos++] = *pwd++; + } + + tmp_pass[pos++] = '\''; + tmp_pass[pos] = '\0'; + } else { + tmp_pass = dbh->password; + } + } + /* support both full connection string & connection string + login and/or password */ if (dbh->username && dbh->password) { - spprintf(&conn_str, 0, "%s user=%s password=%s connect_timeout=%ld", dbh->data_source, dbh->username, dbh->password, connect_timeout); + spprintf(&conn_str, 0, "%s user=%s password=%s connect_timeout=%ld", dbh->data_source, dbh->username, tmp_pass, connect_timeout); } else if (dbh->username) { spprintf(&conn_str, 0, "%s user=%s connect_timeout=%ld", dbh->data_source, dbh->username, connect_timeout); } else if (dbh->password) { - spprintf(&conn_str, 0, "%s password=%s connect_timeout=%ld", dbh->data_source, dbh->password, connect_timeout); + spprintf(&conn_str, 0, "%s password=%s connect_timeout=%ld", dbh->data_source, tmp_pass, connect_timeout); } else { spprintf(&conn_str, 0, "%s connect_timeout=%ld", (char *) dbh->data_source, connect_timeout); } H->server = PQconnectdb(conn_str); + if (dbh->password && tmp_pass != dbh->password) { + efree(tmp_pass); + } efree(conn_str); diff --git a/ext/pdo_pgsql/tests/bug62479.phpt b/ext/pdo_pgsql/tests/bug62479.phpt new file mode 100644 index 00000000000..2e19f15002a --- /dev/null +++ b/ext/pdo_pgsql/tests/bug62479.phpt @@ -0,0 +1,56 @@ +--TEST-- +PDO PgSQL Bug #62479 (PDO-psql cannot connect if password contains spaces) +--SKIPIF-- +query($testQuery); +$testQuery = "DROP USER pdo_$rand"; +$db->query($testQuery); +?> +--FILE-- +setAttribute(PDO::ATTR_EMULATE_PREPARES, true); +$rand = rand(5, 400); +$user = "pdo_$rand"; +$template = "CREATE USER $user WITH PASSWORD '%s'"; +$dropUser = "DROP USER $user"; +$testQuery = 'SELECT 1 as verification'; + +// Create temp user with space in password +$sql = sprintf($template, 'my password'); +$pdo->query($sql); +$testConn = new PDO($_ENV['PDOTEST_DSN'], $user, "my password"); +$result = $testConn->query($testQuery)->fetch(); +$check = $result[0]; +var_dump($check); + +// Remove the user +$pdo->query($dropUser); + +// Create a user with a space and single quote +$sql = sprintf($template, "my pass''word"); +$pdo->query($sql); + +$testConn = new PDO($_ENV['PDOTEST_DSN'], $user, "my pass'word"); +$result = $testConn->query($testQuery)->fetch(); +$check = $result[0]; +var_dump($check); + +// Remove the user +$pdo->query($dropUser); +?> +--EXPECT-- +int(1) +int(1) + From 8aa93b7f2cb23dc4c7a051276cec833fd4343c1d Mon Sep 17 00:00:00 2001 From: Will Fitch Date: Sun, 19 Jan 2014 13:02:20 -0500 Subject: [PATCH 02/15] Revert "Fix #62479: Some chars not parsed in passwords" This reverts commit e6bb90c66a5306f3db7ca38206b27685177a65cc. --- NEWS | 3 -- ext/pdo_pgsql/pgsql_driver.c | 31 ++--------------- ext/pdo_pgsql/tests/bug62479.phpt | 56 ------------------------------- 3 files changed, 2 insertions(+), 88 deletions(-) delete mode 100644 ext/pdo_pgsql/tests/bug62479.phpt diff --git a/NEWS b/NEWS index e05c987052b..72c09399256 100644 --- a/NEWS +++ b/NEWS @@ -2,9 +2,6 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? 201?, PHP 5.3.29 -- PDO_pgsql: - . Fixed bug #62479 (PDO-psql cannot connect if password contains spaces) - 12 Dec 2013, PHP 5.3.28 - Openssl: diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index e2ad143acdf..55f441808e2 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -1029,7 +1029,6 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ pdo_pgsql_db_handle *H; int ret = 0; char *conn_str, *p, *e; - char *tmp_pass; long connect_timeout = 30; H = pecalloc(1, sizeof(pdo_pgsql_db_handle), dbh->is_persistent); @@ -1051,44 +1050,18 @@ static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ connect_timeout = pdo_attr_lval(driver_options, PDO_ATTR_TIMEOUT, 30 TSRMLS_CC); } - if (dbh->password) { - if (dbh->password[0] != '\'' && dbh->password[strlen(dbh->password) - 1] != '\'') { - char *pwd = dbh->password; - int pos = 1; - - tmp_pass = safe_emalloc(2, strlen(dbh->password), 3); - tmp_pass[0] = '\''; - - while (*pwd != '\0') { - if (*pwd == '\\' || *pwd == '\'') { - tmp_pass[pos++] = '\\'; - } - - tmp_pass[pos++] = *pwd++; - } - - tmp_pass[pos++] = '\''; - tmp_pass[pos] = '\0'; - } else { - tmp_pass = dbh->password; - } - } - /* support both full connection string & connection string + login and/or password */ if (dbh->username && dbh->password) { - spprintf(&conn_str, 0, "%s user=%s password=%s connect_timeout=%ld", dbh->data_source, dbh->username, tmp_pass, connect_timeout); + spprintf(&conn_str, 0, "%s user=%s password=%s connect_timeout=%ld", dbh->data_source, dbh->username, dbh->password, connect_timeout); } else if (dbh->username) { spprintf(&conn_str, 0, "%s user=%s connect_timeout=%ld", dbh->data_source, dbh->username, connect_timeout); } else if (dbh->password) { - spprintf(&conn_str, 0, "%s password=%s connect_timeout=%ld", dbh->data_source, tmp_pass, connect_timeout); + spprintf(&conn_str, 0, "%s password=%s connect_timeout=%ld", dbh->data_source, dbh->password, connect_timeout); } else { spprintf(&conn_str, 0, "%s connect_timeout=%ld", (char *) dbh->data_source, connect_timeout); } H->server = PQconnectdb(conn_str); - if (dbh->password && tmp_pass != dbh->password) { - efree(tmp_pass); - } efree(conn_str); diff --git a/ext/pdo_pgsql/tests/bug62479.phpt b/ext/pdo_pgsql/tests/bug62479.phpt deleted file mode 100644 index 2e19f15002a..00000000000 --- a/ext/pdo_pgsql/tests/bug62479.phpt +++ /dev/null @@ -1,56 +0,0 @@ ---TEST-- -PDO PgSQL Bug #62479 (PDO-psql cannot connect if password contains spaces) ---SKIPIF-- -query($testQuery); -$testQuery = "DROP USER pdo_$rand"; -$db->query($testQuery); -?> ---FILE-- -setAttribute(PDO::ATTR_EMULATE_PREPARES, true); -$rand = rand(5, 400); -$user = "pdo_$rand"; -$template = "CREATE USER $user WITH PASSWORD '%s'"; -$dropUser = "DROP USER $user"; -$testQuery = 'SELECT 1 as verification'; - -// Create temp user with space in password -$sql = sprintf($template, 'my password'); -$pdo->query($sql); -$testConn = new PDO($_ENV['PDOTEST_DSN'], $user, "my password"); -$result = $testConn->query($testQuery)->fetch(); -$check = $result[0]; -var_dump($check); - -// Remove the user -$pdo->query($dropUser); - -// Create a user with a space and single quote -$sql = sprintf($template, "my pass''word"); -$pdo->query($sql); - -$testConn = new PDO($_ENV['PDOTEST_DSN'], $user, "my pass'word"); -$result = $testConn->query($testQuery)->fetch(); -$check = $result[0]; -var_dump($check); - -// Remove the user -$pdo->query($dropUser); -?> ---EXPECT-- -int(1) -int(1) - From c0e34299042680da16b2ad800b5f8c1a6a009f48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Ho=C5=A1ek?= Date: Wed, 22 Jan 2014 18:54:11 +0100 Subject: [PATCH 03/15] Implement ldap_modify_batch. --- ext/ldap/ldap.c | 365 ++++++++++++++++++++ ext/ldap/php_ldap.h | 10 + ext/ldap/tests/ldap_modify_batch_basic.phpt | 109 ++++++ ext/ldap/tests/ldap_modify_batch_error.phpt | 104 ++++++ 4 files changed, 588 insertions(+) create mode 100644 ext/ldap/tests/ldap_modify_batch_basic.phpt create mode 100644 ext/ldap/tests/ldap_modify_batch_error.phpt diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index 25d6fa1159b..9d3a710b604 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -152,6 +152,15 @@ PHP_MINIT_FUNCTION(ldap) REGISTER_LONG_CONSTANT("LDAP_DEREF_FINDING", LDAP_DEREF_FINDING, CONST_PERSISTENT | CONST_CS); REGISTER_LONG_CONSTANT("LDAP_DEREF_ALWAYS", LDAP_DEREF_ALWAYS, CONST_PERSISTENT | CONST_CS); + /* Constants to be used with ldap_modify_batch() */ + REGISTER_LONG_CONSTANT("LDAP_MODIFY_BATCH_ADD", LDAP_MODIFY_BATCH_ADD, CONST_PERSISTENT | CONST_CS); + REGISTER_LONG_CONSTANT("LDAP_MODIFY_BATCH_REMOVE", LDAP_MODIFY_BATCH_REMOVE, CONST_PERSISTENT | CONST_CS); + REGISTER_LONG_CONSTANT("LDAP_MODIFY_BATCH_REMOVE_ALL", LDAP_MODIFY_BATCH_REMOVE_ALL, CONST_PERSISTENT | CONST_CS); + REGISTER_LONG_CONSTANT("LDAP_MODIFY_BATCH_REPLACE", LDAP_MODIFY_BATCH_REPLACE, CONST_PERSISTENT | CONST_CS); + REGISTER_STRING_CONSTANT("LDAP_MODIFY_BATCH_ATTRIB", LDAP_MODIFY_BATCH_ATTRIB, CONST_PERSISTENT | CONST_CS); + REGISTER_STRING_CONSTANT("LDAP_MODIFY_BATCH_MODTYPE", LDAP_MODIFY_BATCH_MODTYPE, CONST_PERSISTENT | CONST_CS); + REGISTER_STRING_CONSTANT("LDAP_MODIFY_BATCH_VALUES", LDAP_MODIFY_BATCH_VALUES, CONST_PERSISTENT | CONST_CS); + #if (LDAP_API_VERSION > 2000) || HAVE_NSLDAP || HAVE_ORALDAP_10 /* LDAP options */ REGISTER_LONG_CONSTANT("LDAP_OPT_DEREF", LDAP_OPT_DEREF, CONST_PERSISTENT | CONST_CS); @@ -1432,6 +1441,355 @@ PHP_FUNCTION(ldap_delete) } /* }}} */ +/* {{{ _ldap_str_equal_to_const + */ +static int _ldap_str_equal_to_const(const char *str, uint str_len, const char *cstr) +{ + int i; + + if (strlen(cstr) != str_len) + return 0; + + for (i = 0; i < str_len; ++i) { + if (str[i] != cstr[i]) { + return 0; + } + } + + return 1; +} +/* }}} */ + +/* {{{ _ldap_strlen_max + */ +static int _ldap_strlen_max(const char *str, uint max_len) +{ + int i; + + for (i = 0; i < max_len; ++i) { + if (str[i] == '\0') { + return i; + } + } + + return max_len; +} +/* }}} */ + +/* {{{ _ldap_hash_fetch + */ +static void _ldap_hash_fetch(zval *hashTbl, const char *key, zval **out) +{ + zval **fetched; + if (zend_hash_find(Z_ARRVAL_P(hashTbl), key, strlen(key)+1, (void **) &fetched) == SUCCESS) { + *out = *fetched; + } + else { + *out = NULL; + } +} +/* }}} */ + +/* {{{ proto bool ldap_modify_batch(resource link, string dn, array modifs) + Perform multiple modifications as part of one operation */ +PHP_FUNCTION(ldap_modify_batch) +{ + ldap_linkdata *ld; + zval *link, *mods, *mod, *modinfo, *modval; + zval *attrib, *modtype, *vals; + zval **fetched; + char *dn; + int dn_len; + int i, j, k; + int num_mods, num_modprops, num_modvals; + LDAPMod **ldap_mods; + uint oper; + + /* + $mods = array( + array( + "attrib" => "unicodePwd", + "modtype" => LDAP_MODIFY_BATCH_REMOVE, + "values" => array($oldpw) + ), + array( + "attrib" => "unicodePwd", + "modtype" => LDAP_MODIFY_BATCH_ADD, + "values" => array($newpw) + ), + array( + "attrib" => "userPrincipalName", + "modtype" => LDAP_MODIFY_BATCH_REPLACE, + "values" => array("janitor@corp.contoso.com") + ), + array( + "attrib" => "userCert", + "modtype" => LDAP_MODIFY_BATCH_REMOVE_ALL + ) + ); + */ + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsa", &link, &dn, &dn_len, &mods) != SUCCESS) { + return; + } + + ZEND_FETCH_RESOURCE(ld, ldap_linkdata *, &link, -1, "ldap link", le_link); + + /* perform validation */ + { + char *modkey; + uint modkeylen; + long modtype; + + /* to store the wrongly-typed keys */ + ulong tmpUlong; + + /* make sure the DN contains no NUL bytes */ + if (_ldap_strlen_max(dn, dn_len) != dn_len) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "DN must not contain NUL bytes"); + RETURN_FALSE; + } + + /* make sure the top level is a normal array */ + zend_hash_internal_pointer_reset(Z_ARRVAL_P(mods)); + if (zend_hash_get_current_key_type(Z_ARRVAL_P(mods)) != HASH_KEY_IS_LONG) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Modifications array must not be string-indexed"); + RETURN_FALSE; + } + + num_mods = zend_hash_num_elements(Z_ARRVAL_P(mods)); + + for (i = 0; i < num_mods; i++) { + /* is the numbering consecutive? */ + if (zend_hash_index_find(Z_ARRVAL_P(mods), i, (void **) &fetched) != SUCCESS) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Modifications array must have consecutive indices 0, 1, ..."); + RETURN_FALSE; + } + mod = *fetched; + + /* is it an array? */ + if (Z_TYPE_P(mod) != IS_ARRAY) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Each entry of modifications array must be an array itself"); + RETURN_FALSE; + } + + /* for the modification hashtable... */ + zend_hash_internal_pointer_reset(Z_ARRVAL_P(mod)); + num_modprops = zend_hash_num_elements(Z_ARRVAL_P(mod)); + + for (j = 0; j < num_modprops; j++) { + /* are the keys strings? */ + if (zend_hash_get_current_key_ex(Z_ARRVAL_P(mod), &modkey, &modkeylen, &tmpUlong, 0, NULL) != HASH_KEY_IS_STRING) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Each entry of modifications array must be string-indexed"); + RETURN_FALSE; + } + + /* modkeylen includes the terminating NUL byte; remove that */ + --modkeylen; + + /* is this a valid entry? */ + if ( + !_ldap_str_equal_to_const(modkey, modkeylen, LDAP_MODIFY_BATCH_ATTRIB) && + !_ldap_str_equal_to_const(modkey, modkeylen, LDAP_MODIFY_BATCH_MODTYPE) && + !_ldap_str_equal_to_const(modkey, modkeylen, LDAP_MODIFY_BATCH_VALUES) + ) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The only allowed keys in entries of the modifications array are '" LDAP_MODIFY_BATCH_ATTRIB "', '" LDAP_MODIFY_BATCH_MODTYPE "' and '" LDAP_MODIFY_BATCH_VALUES "'"); + RETURN_FALSE; + } + + zend_hash_get_current_data(Z_ARRVAL_P(mod), (void **) &fetched); + modinfo = *fetched; + + /* does the value type match the key? */ + if (_ldap_str_equal_to_const(modkey, modkeylen, LDAP_MODIFY_BATCH_ATTRIB)) { + if (Z_TYPE_P(modinfo) != IS_STRING) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "A '" LDAP_MODIFY_BATCH_ATTRIB "' value must be a string"); + RETURN_FALSE; + } + + if (Z_STRLEN_P(modinfo) != _ldap_strlen_max(Z_STRVAL_P(modinfo), Z_STRLEN_P(modinfo))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "A '" LDAP_MODIFY_BATCH_ATTRIB "' value must not contain NUL bytes"); + RETURN_FALSE; + } + } + else if (_ldap_str_equal_to_const(modkey, modkeylen, LDAP_MODIFY_BATCH_MODTYPE)) { + if (Z_TYPE_P(modinfo) != IS_LONG) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "A '" LDAP_MODIFY_BATCH_MODTYPE "' value must be a long"); + RETURN_FALSE; + } + + /* is the value in range? */ + modtype = Z_LVAL_P(modinfo); + if ( + modtype != LDAP_MODIFY_BATCH_ADD && + modtype != LDAP_MODIFY_BATCH_REMOVE && + modtype != LDAP_MODIFY_BATCH_REPLACE && + modtype != LDAP_MODIFY_BATCH_REMOVE_ALL + ) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The '" LDAP_MODIFY_BATCH_MODTYPE "' value must match one of the LDAP_MODIFY_BATCH_* constants"); + RETURN_FALSE; + } + + /* if it's REMOVE_ALL, there must not be a values array; otherwise, there must */ + if (modtype == LDAP_MODIFY_BATCH_REMOVE_ALL) { + if (zend_hash_exists(Z_ARRVAL_P(mod), LDAP_MODIFY_BATCH_VALUES, strlen(LDAP_MODIFY_BATCH_VALUES) + 1)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "If '" LDAP_MODIFY_BATCH_MODTYPE "' is LDAP_MODIFY_BATCH_REMOVE_ALL, a '" LDAP_MODIFY_BATCH_VALUES "' array must not be provided"); + RETURN_FALSE; + } + } + else { + if (!zend_hash_exists(Z_ARRVAL_P(mod), LDAP_MODIFY_BATCH_VALUES, strlen(LDAP_MODIFY_BATCH_VALUES) + 1)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "If '" LDAP_MODIFY_BATCH_MODTYPE "' is not LDAP_MODIFY_BATCH_REMOVE_ALL, a '" LDAP_MODIFY_BATCH_VALUES "' array must be provided"); + RETURN_FALSE; + } + } + } + else if (_ldap_str_equal_to_const(modkey, modkeylen, LDAP_MODIFY_BATCH_VALUES)) { + if (Z_TYPE_P(modinfo) != IS_ARRAY) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "A '" LDAP_MODIFY_BATCH_VALUES "' value must be an array"); + RETURN_FALSE; + } + + /* is the array not empty? */ + zend_hash_internal_pointer_reset(Z_ARRVAL_P(modinfo)); + num_modvals = zend_hash_num_elements(Z_ARRVAL_P(modinfo)); + if (num_modvals == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "A '" LDAP_MODIFY_BATCH_VALUES "' array must have at least one element"); + RETURN_FALSE; + } + + /* are its keys integers? */ + if (zend_hash_get_current_key_type(Z_ARRVAL_P(modinfo)) != HASH_KEY_IS_LONG) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "A '" LDAP_MODIFY_BATCH_VALUES "' array must not be string-indexed"); + RETURN_FALSE; + } + + /* are the keys consecutive? */ + for (k = 0; k < num_modvals; k++) { + if (zend_hash_index_find(Z_ARRVAL_P(modinfo), k, (void **) &fetched) != SUCCESS) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "A '" LDAP_MODIFY_BATCH_VALUES "' array must have consecutive indices 0, 1, ..."); + RETURN_FALSE; + } + modval = *fetched; + + /* is the data element a string? */ + if (Z_TYPE_P(modval) != IS_STRING) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Each element of a '" LDAP_MODIFY_BATCH_VALUES "' array must be a string"); + RETURN_FALSE; + } + } + } + + zend_hash_move_forward(Z_ARRVAL_P(mod)); + } + } + } + /* validation was successful */ + + /* allocate array of modifications */ + ldap_mods = safe_emalloc((num_mods+1), sizeof(LDAPMod *), 0); + + /* for each modification */ + for (i = 0; i < num_mods; i++) { + /* allocate the modification struct */ + ldap_mods[i] = safe_emalloc(1, sizeof(LDAPMod), 0); + + /* fetch the relevant data */ + zend_hash_index_find(Z_ARRVAL_P(mods), i, (void **) &fetched); + mod = *fetched; + + _ldap_hash_fetch(mod, LDAP_MODIFY_BATCH_ATTRIB, &attrib); + _ldap_hash_fetch(mod, LDAP_MODIFY_BATCH_MODTYPE, &modtype); + _ldap_hash_fetch(mod, LDAP_MODIFY_BATCH_VALUES, &vals); + + /* map the modification type */ + switch (Z_LVAL_P(modtype)) { + case LDAP_MODIFY_BATCH_ADD: + oper = LDAP_MOD_ADD; + break; + case LDAP_MODIFY_BATCH_REMOVE: + case LDAP_MODIFY_BATCH_REMOVE_ALL: + oper = LDAP_MOD_DELETE; + break; + case LDAP_MODIFY_BATCH_REPLACE: + oper = LDAP_MOD_REPLACE; + break; + default: + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unknown and uncaught modification type."); + RETURN_FALSE; + } + + /* fill in the basic info */ + ldap_mods[i]->mod_op = oper | LDAP_MOD_BVALUES; + ldap_mods[i]->mod_type = estrndup(Z_STRVAL_P(attrib), Z_STRLEN_P(attrib)); + + if (Z_LVAL_P(modtype) == LDAP_MODIFY_BATCH_REMOVE_ALL) { + /* no values */ + ldap_mods[i]->mod_bvalues = NULL; + } + else { + /* allocate space for the values as part of this modification */ + num_modvals = zend_hash_num_elements(Z_ARRVAL_P(vals)); + ldap_mods[i]->mod_bvalues = safe_emalloc((num_modvals+1), sizeof(struct berval *), 0); + + /* for each value */ + for (j = 0; j < num_modvals; j++) { + /* fetch it */ + zend_hash_index_find(Z_ARRVAL_P(vals), j, (void **) &fetched); + modval = *fetched; + + /* allocate the data struct */ + ldap_mods[i]->mod_bvalues[j] = safe_emalloc(1, sizeof(struct berval), 0); + + /* fill it */ + ldap_mods[i]->mod_bvalues[j]->bv_len = Z_STRLEN_P(modval); + ldap_mods[i]->mod_bvalues[j]->bv_val = estrndup(Z_STRVAL_P(modval), Z_STRLEN_P(modval)); + } + + /* NULL-terminate values */ + ldap_mods[i]->mod_bvalues[num_modvals] = NULL; + } + } + + /* NULL-terminate modifications */ + ldap_mods[num_mods] = NULL; + + /* perform (finally) */ + if ((i = ldap_modify_ext_s(ld->link, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Batch Modify: %s", ldap_err2string(i)); + RETVAL_FALSE; + } else RETVAL_TRUE; + + /* clean up */ + { + for (i = 0; i < num_mods; i++) { + /* attribute */ + efree(ldap_mods[i]->mod_type); + + if (ldap_mods[i]->mod_bvalues != NULL) { + /* each BER value */ + for (j = 0; ldap_mods[i]->mod_bvalues[j] != NULL; j++) { + /* free the data bytes */ + efree(ldap_mods[i]->mod_bvalues[j]->bv_val); + + /* free the bvalue struct */ + efree(ldap_mods[i]->mod_bvalues[j]); + } + + /* the BER value array */ + efree(ldap_mods[i]->mod_bvalues); + } + + /* the modification */ + efree(ldap_mods[i]); + } + + /* the modifications array */ + efree(ldap_mods); + } +} +/* }}} */ + /* {{{ proto int ldap_errno(resource link) Get the current ldap error number */ PHP_FUNCTION(ldap_errno) @@ -2516,6 +2874,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_modify, 0, 0, 3) ZEND_ARG_INFO(0, entry) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_modify_batch, 0, 0, 3) + ZEND_ARG_INFO(0, link_identifier) + ZEND_ARG_INFO(0, dn) + ZEND_ARG_ARRAY_INFO(0, modifications_info, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_ldap_mod_add, 0, 0, 3) ZEND_ARG_INFO(0, link_identifier) ZEND_ARG_INFO(0, dn) @@ -2669,6 +3033,7 @@ const zend_function_entry ldap_functions[] = { PHP_FE(ldap_dn2ufn, arginfo_ldap_dn2ufn) PHP_FE(ldap_add, arginfo_ldap_add) PHP_FE(ldap_delete, arginfo_ldap_delete) + PHP_FE(ldap_modify_batch, arginfo_ldap_modify_batch) PHP_FALIAS(ldap_modify, ldap_mod_replace, arginfo_ldap_modify) /* additional functions for attribute based modifications, Gerrit Thomson */ diff --git a/ext/ldap/php_ldap.h b/ext/ldap/php_ldap.h index e10c8a7e619..bd3731819d2 100644 --- a/ext/ldap/php_ldap.h +++ b/ext/ldap/php_ldap.h @@ -50,4 +50,14 @@ ZEND_END_MODULE_GLOBALS(ldap) #define phpext_ldap_ptr ldap_module_ptr +/* Constants for ldap_modify_batch */ +#define LDAP_MODIFY_BATCH_ADD 0x01 +#define LDAP_MODIFY_BATCH_REMOVE 0x02 +#define LDAP_MODIFY_BATCH_REMOVE_ALL 0x12 +#define LDAP_MODIFY_BATCH_REPLACE 0x03 + +#define LDAP_MODIFY_BATCH_ATTRIB "attrib" +#define LDAP_MODIFY_BATCH_MODTYPE "modtype" +#define LDAP_MODIFY_BATCH_VALUES "values" + #endif /* PHP_LDAP_H */ diff --git a/ext/ldap/tests/ldap_modify_batch_basic.phpt b/ext/ldap/tests/ldap_modify_batch_basic.phpt new file mode 100644 index 00000000000..4f6705c7e8e --- /dev/null +++ b/ext/ldap/tests/ldap_modify_batch_basic.phpt @@ -0,0 +1,109 @@ +--TEST-- +ldap_modify_batch() - Basic batch modify operation +--CREDITS-- +Patrick Allaert +Ondřej Hošek +--SKIPIF-- + + +--FILE-- + "telephoneNumber", + "modtype" => LDAP_MODIFY_BATCH_ADD, + "values" => array( + "+1 555 5551717" + ) + ), + array( + "attrib" => "sn", + "modtype" => LDAP_MODIFY_BATCH_REPLACE, + "values" => array("Brown-Smith") + ), + array( + "attrib" => "description", + "modtype" => LDAP_MODIFY_BATCH_REMOVE_ALL + ) +); + +var_dump( + ldap_modify_batch($link, "cn=userA,dc=my-domain,dc=com", $mods), + ldap_get_entries($link, ldap_search($link, "dc=my-domain,dc=com", "(sn=Brown-Smith)")) +); +?> +===DONE=== +--CLEAN-- + +--EXPECT-- +bool(true) +array(2) { + ["count"]=> + int(1) + [0]=> + array(12) { + ["objectclass"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "person" + } + [0]=> + string(11) "objectclass" + ["cn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(5) "userA" + } + [1]=> + string(2) "cn" + ["userpassword"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(4) "oops" + } + [2]=> + string(12) "userpassword" + ["telephonenumber"]=> + array(3) { + ["count"]=> + int(2) + [0]=> + string(14) "xx-xx-xx-xx-xx" + [1]=> + string(14) "+1 555 5551717" + } + [3]=> + string(15) "telephonenumber" + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(11) "Brown-Smith" + } + [4]=> + string(2) "sn" + ["count"]=> + int(5) + ["dn"]=> + string(28) "cn=userA,dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_modify_batch_error.phpt b/ext/ldap/tests/ldap_modify_batch_error.phpt new file mode 100644 index 00000000000..687c371c4db --- /dev/null +++ b/ext/ldap/tests/ldap_modify_batch_error.phpt @@ -0,0 +1,104 @@ +--TEST-- +ldap_modify_batch() - Batch modify operations that should fail +--CREDITS-- +Patrick Allaert +Ondřej Hošek +--SKIPIF-- + + +--FILE-- + "givenName", + "modtype" => LDAP_MODIFY_BATCH_ADD, + "values" => array("Jack") + ) +); + +// Too few parameters +var_dump(ldap_modify_batch()); +var_dump(ldap_modify_batch($link)); +var_dump(ldap_modify_batch($link, "dc=my-domain,dc=com")); + +// Too many parameters +var_dump(ldap_modify_batch($link, "dc=my-domain,dc=com", $addGivenName, "Invalid additional parameter")); + +// DN not found +var_dump(ldap_modify_batch($link, "dc=my-domain,dc=com", $addGivenName)); + +// Invalid DN +var_dump(ldap_modify_batch($link, "weirdAttribute=val", $addGivenName)); + +// prepare +$entry = array( + "objectClass" => array( + "top", + "dcObject", + "organization"), + "dc" => "my-domain", + "o" => "my-domain", +); + +ldap_add($link, "dc=my-domain,dc=com", $entry); + +// invalid domain +$mods = array( + array( + "attrib" => "dc", + "modtype" => LDAP_MODIFY_BATCH_REPLACE, + "values" => array("Wrong Domain") + ) +); + +var_dump(ldap_modify_batch($link, "dc=my-domain,dc=com", $mods)); + +// invalid attribute +$mods = array( + array( + "attrib" => "weirdAttribute", + "modtype" => LDAP_MODIFY_BATCH_ADD, + "values" => array("weirdVal", "anotherWeirdval") + ) +); + +var_dump(ldap_modify_batch($link, "dc=my-domain,dc=com", $mods)); +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- +Warning: ldap_modify_batch() expects exactly 3 parameters, 0 given in %s on line %d +NULL + +Warning: ldap_modify_batch() expects exactly 3 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_modify_batch() expects exactly 3 parameters, 2 given in %s on line %d +NULL + +Warning: ldap_modify_batch() expects exactly 3 parameters, 4 given in %s on line %d +NULL + +Warning: ldap_modify_batch(): Batch Modify: No such object in %s on line %d +bool(false) + +Warning: ldap_modify_batch(): Batch Modify: Invalid DN syntax in %s on line %d +bool(false) + +Warning: ldap_modify_batch(): Batch Modify: Naming violation in %s on line %d +bool(false) + +Warning: ldap_modify_batch(): Batch Modify: Undefined attribute type in %s on line %d +bool(false) +===DONE=== From 4b48b299885bf0e2f2c72902b072c28f255e8f68 Mon Sep 17 00:00:00 2001 From: Ferenc Kovacs Date: Fri, 24 Jan 2014 16:06:58 +0100 Subject: [PATCH 04/15] fix the primary qa email address and update the list of available people being able to add moderators to our lists --- README.RELEASE_PROCESS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.RELEASE_PROCESS b/README.RELEASE_PROCESS index a0c34f8f7aa..4343b6213c1 100644 --- a/README.RELEASE_PROCESS +++ b/README.RELEASE_PROCESS @@ -101,10 +101,10 @@ pointing out "the location of the release" and "the possible release date of either the next RC, or the final release". 2. Send an email (see example here http://news.php.net/php.pear.qa/5201) **To** -``php-qa@lists.php.net`` and ``primary-qa-tests@lists.php.net``. +``php-qa@lists.php.net`` and ``primary-qa-tester@lists.php.net``. This email is to notify the selected projects about a new release so that they can make sure their projects keep working. Make sure that you have been setup -as a moderator for ``primary-qa-tests@lists.php.net`` by having someone (Wez, +as a moderator for ``primary-qa-tester@lists.php.net`` by having someone (Hannes, Dan, Derick) run the following commands for you: ``ssh lists.php.net`` From e6ab180394f4d6fe2f0a50887b098af24a3d765c Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Sat, 25 Jan 2014 16:14:51 +0100 Subject: [PATCH 05/15] Fixed bug #44780: some time zone offsets not recognized by timezone_name_from_abbr. --- ext/date/lib/fallbackmap.h | 82 ++++++++++++++++++------------------ ext/date/lib/parse_date.c | 6 +-- ext/date/lib/parse_date.re | 2 +- ext/date/tests/bug44780.phpt | 10 +++++ 4 files changed, 56 insertions(+), 44 deletions(-) create mode 100644 ext/date/tests/bug44780.phpt diff --git a/ext/date/lib/fallbackmap.h b/ext/date/lib/fallbackmap.h index 4e4c23c96e0..af69482c0cb 100644 --- a/ext/date/lib/fallbackmap.h +++ b/ext/date/lib/fallbackmap.h @@ -1,40 +1,42 @@ - { "sst", 0, -11, "Pacific/Apia" }, - { "hst", 0, -10, "Pacific/Honolulu" }, - { "akst", 0, -9, "America/Anchorage" }, - { "akdt", 1, -8, "America/Anchorage" }, - { "pst", 0, -8, "America/Los_Angeles" }, - { "pdt", 1, -7, "America/Los_Angeles" }, - { "mst", 0, -7, "America/Denver" }, - { "mdt", 1, -6, "America/Denver" }, - { "cst", 0, -6, "America/Chicago" }, - { "cdt", 1, -5, "America/Chicago" }, - { "est", 0, -5, "America/New_York" }, - { "edt", 1, -4, "America/New_York" }, - { "ast", 0, -4, "America/Halifax" }, - { "adt", 1, -3, "America/Halifax" }, - { "brt", 0, -3, "America/Sao_Paulo" }, - { "brst", 1, -2, "America/Sao_Paulo" }, - { "azost", 0, -1, "Atlantic/Azores" }, - { "azodt", 1, 0, "Atlantic/Azores" }, - { "gmt", 0, 0, "Europe/London" }, - { "bst", 1, 1, "Europe/London" }, - { "cet", 0, 1, "Europe/Paris" }, - { "cest", 1, 2, "Europe/Paris" }, - { "eet", 0, 2, "Europe/Helsinki" }, - { "eest", 1, 3, "Europe/Helsinki" }, - { "msk", 0, 3, "Europe/Moscow" }, - { "msd", 1, 4, "Europe/Moscow" }, - { "gst", 0, 4, "Asia/Dubai" }, - { "pkt", 0, 5, "Asia/Karachi" }, - { "ist", 0, 5.5, "Asia/Kolkata" }, - { "npt", 0, 5.75, "Asia/Katmandu" }, - { "yekt", 1, 6, "Asia/Yekaterinburg" }, - { "novst", 1, 7, "Asia/Novosibirsk" }, - { "krat", 0, 7, "Asia/Krasnoyarsk" }, - { "krast", 1, 8, "Asia/Krasnoyarsk" }, - { "jst", 0, 9, "Asia/Tokyo" }, - { "est", 0, 10, "Australia/Melbourne" }, - { "cst", 1, 10.5, "Australia/Adelaide" }, - { "est", 1, 11, "Australia/Melbourne" }, - { "nzst", 0, 12, "Pacific/Auckland" }, - { "nzdt", 1, 13, "Pacific/Auckland" }, + { "sst", 0, -660, "Pacific/Apia" }, + { "hst", 0, -600, "Pacific/Honolulu" }, + { "akst", 0, -540, "America/Anchorage" }, + { "akdt", 1, -480, "America/Anchorage" }, + { "pst", 0, -480, "America/Los_Angeles" }, + { "pdt", 1, -420, "America/Los_Angeles" }, + { "mst", 0, -420, "America/Denver" }, + { "mdt", 1, -360, "America/Denver" }, + { "cst", 0, -360, "America/Chicago" }, + { "cdt", 1, -300, "America/Chicago" }, + { "est", 0, -300, "America/New_York" }, + { "vet", 0, -270, "America/Caracas" }, + { "edt", 1, -240, "America/New_York" }, + { "ast", 0, -240, "America/Halifax" }, + { "adt", 1, -180, "America/Halifax" }, + { "brt", 0, -180, "America/Sao_Paulo" }, + { "brst", 1, -120, "America/Sao_Paulo" }, + { "azost", 0, -60, "Atlantic/Azores" }, + { "azodt", 1, 0, "Atlantic/Azores" }, + { "gmt", 0, 0, "Europe/London" }, + { "bst", 1, 60, "Europe/London" }, + { "cet", 0, 60, "Europe/Paris" }, + { "cest", 1, 120, "Europe/Paris" }, + { "eet", 0, 120, "Europe/Helsinki" }, + { "eest", 1, 180, "Europe/Helsinki" }, + { "msk", 0, 180, "Europe/Moscow" }, + { "msd", 1, 240, "Europe/Moscow" }, + { "gst", 0, 240, "Asia/Dubai" }, + { "pkt", 0, 300, "Asia/Karachi" }, + { "ist", 0, 330, "Asia/Kolkata" }, + { "npt", 0, 345, "Asia/Katmandu" }, + { "yekt", 1, 360, "Asia/Yekaterinburg" }, + { "novst", 1, 420, "Asia/Novosibirsk" }, + { "krat", 0, 420, "Asia/Krasnoyarsk" }, + { "cst", 0, 480, "Asia/Shanghai" }, + { "krast", 1, 480, "Asia/Krasnoyarsk" }, + { "jst", 0, 540, "Asia/Tokyo" }, + { "est", 0, 600, "Australia/Melbourne" }, + { "cst", 1, 630, "Australia/Adelaide" }, + { "est", 1, 660, "Australia/Melbourne" }, + { "nzst", 0, 720, "Pacific/Auckland" }, + { "nzdt", 1, 780, "Pacific/Auckland" }, diff --git a/ext/date/lib/parse_date.c b/ext/date/lib/parse_date.c index 258c61855d4..47b48178c2d 100644 --- a/ext/date/lib/parse_date.c +++ b/ext/date/lib/parse_date.c @@ -1,10 +1,10 @@ -/* Generated by re2c 0.13.5 on Sun Aug 25 14:46:08 2013 */ +/* Generated by re2c 0.13.5 on Sat Jan 25 15:48:30 2014 */ #line 1 "ext/date/lib/parse_date.re" /* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2014 The PHP Group | + | Copyright (c) 1997-2013 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -752,7 +752,7 @@ const static timelib_tz_lookup_table* zone_search(const char *word, long gmtoffs /* Still didn't find anything, let's find the zone solely based on * offset/isdst then */ for (fmp = timelib_timezone_fallbackmap; fmp->name; fmp++) { - if ((fmp->gmtoffset * 3600) == gmtoffset && fmp->type == isdst) { + if ((fmp->gmtoffset * 60) == gmtoffset && fmp->type == isdst) { return fmp; } } diff --git a/ext/date/lib/parse_date.re b/ext/date/lib/parse_date.re index df33508f505..5b923d4bc41 100644 --- a/ext/date/lib/parse_date.re +++ b/ext/date/lib/parse_date.re @@ -750,7 +750,7 @@ const static timelib_tz_lookup_table* zone_search(const char *word, long gmtoffs /* Still didn't find anything, let's find the zone solely based on * offset/isdst then */ for (fmp = timelib_timezone_fallbackmap; fmp->name; fmp++) { - if ((fmp->gmtoffset * 3600) == gmtoffset && fmp->type == isdst) { + if ((fmp->gmtoffset * 60) == gmtoffset && fmp->type == isdst) { return fmp; } } diff --git a/ext/date/tests/bug44780.phpt b/ext/date/tests/bug44780.phpt new file mode 100644 index 00000000000..5c822d48e6a --- /dev/null +++ b/ext/date/tests/bug44780.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #44780 (some time zone offsets not recognized by timezone_name_from_abbr) +--FILE-- + +--EXPECT-- +string(12) "Asia/Kolkata" +string(13) "Asia/Shanghai" From 4e308abf28d542de0f1251b5e5c523d4701af4b4 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sat, 25 Jan 2014 22:31:31 -0800 Subject: [PATCH 06/15] fix test bug62479.phpt --- ext/pdo_pgsql/tests/bug62479.phpt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/pdo_pgsql/tests/bug62479.phpt b/ext/pdo_pgsql/tests/bug62479.phpt index 2e19f15002a..a12bb8d1ff9 100644 --- a/ext/pdo_pgsql/tests/bug62479.phpt +++ b/ext/pdo_pgsql/tests/bug62479.phpt @@ -30,7 +30,7 @@ $testQuery = 'SELECT 1 as verification'; // Create temp user with space in password $sql = sprintf($template, 'my password'); $pdo->query($sql); -$testConn = new PDO($_ENV['PDOTEST_DSN'], $user, "my password"); +$testConn = new PDO($conf['ENV']['PDOTEST_DSN'], $user, "my password"); $result = $testConn->query($testQuery)->fetch(); $check = $result[0]; var_dump($check); @@ -42,7 +42,7 @@ $pdo->query($dropUser); $sql = sprintf($template, "my pass''word"); $pdo->query($sql); -$testConn = new PDO($_ENV['PDOTEST_DSN'], $user, "my pass'word"); +$testConn = new PDO($conf['ENV']['PDOTEST_DSN'], $user, "my pass'word"); $result = $testConn->query($testQuery)->fetch(); $check = $result[0]; var_dump($check); From 22dba2f5f3211efe6c3b9bb24734c811ca64c68c Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Sun, 26 Jan 2014 13:58:13 +0100 Subject: [PATCH 07/15] Fixed bug #45543: DateTime::setTimezone can not set timezones without ID. --- ext/date/lib/timelib.h | 2 ++ ext/date/lib/timelib_structs.h | 6 ++++++ ext/date/lib/unixtime2tm.c | 28 ++++++++++++++++++++++++++++ ext/date/php_date.c | 15 +++++++++++---- ext/date/php_date.h | 11 +++-------- ext/date/tests/bug45543.phpt | 34 ++++++++++++++++++++++++++++++++++ 6 files changed, 84 insertions(+), 12 deletions(-) create mode 100644 ext/date/tests/bug45543.phpt diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h index 0396e62cabf..533c88664f9 100644 --- a/ext/date/lib/timelib.h +++ b/ext/date/lib/timelib.h @@ -91,6 +91,8 @@ int timelib_apply_localtime(timelib_time *t, unsigned int localtime); void timelib_unixtime2gmt(timelib_time* tm, timelib_sll ts); void timelib_unixtime2local(timelib_time *tm, timelib_sll ts); void timelib_update_from_sse(timelib_time *tm); +void timelib_set_timezone_from_offset(timelib_time *t, timelib_sll utc_offset); +void timelib_set_timezone_from_abbr(timelib_time *t, timelib_abbr_info abbr_info); void timelib_set_timezone(timelib_time *t, timelib_tzinfo *tz); /* From parse_tz.c */ diff --git a/ext/date/lib/timelib_structs.h b/ext/date/lib/timelib_structs.h index 2648c52e665..5185e7b40b6 100644 --- a/ext/date/lib/timelib_structs.h +++ b/ext/date/lib/timelib_structs.h @@ -172,6 +172,12 @@ typedef struct timelib_time { * 2 TimeZone abbreviation */ } timelib_time; +typedef struct timelib_abbr_info { + timelib_sll utc_offset; + char *abbr; + int dst; +} timelib_abbr_info; + typedef struct timelib_error_message { int position; char character; diff --git a/ext/date/lib/unixtime2tm.c b/ext/date/lib/unixtime2tm.c index eefbaa8f373..9870313fbce 100644 --- a/ext/date/lib/unixtime2tm.c +++ b/ext/date/lib/unixtime2tm.c @@ -214,6 +214,34 @@ void timelib_unixtime2local(timelib_time *tm, timelib_sll ts) tm->have_zone = 1; } +void timelib_set_timezone_from_offset(timelib_time *t, timelib_sll utc_offset) +{ + if (t->tz_abbr) { + free(t->tz_abbr); + } + t->tz_abbr = NULL; + + t->z = utc_offset; + t->have_zone = 1; + t->zone_type = TIMELIB_ZONETYPE_OFFSET; + t->dst = 0; + t->tz_info = NULL; +} + +void timelib_set_timezone_from_abbr(timelib_time *t, timelib_abbr_info abbr_info) +{ + if (t->tz_abbr) { + free(t->tz_abbr); + } + t->tz_abbr = strdup(abbr_info.abbr); + + t->z = abbr_info.utc_offset; + t->have_zone = 1; + t->zone_type = TIMELIB_ZONETYPE_ABBR; + t->dst = abbr_info.dst; + t->tz_info = NULL; +} + void timelib_set_timezone(timelib_time *t, timelib_tzinfo *tz) { timelib_time_offset *gmt_offset; diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 1655057212a..c0566334db4 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -2992,11 +2992,18 @@ PHP_FUNCTION(date_timezone_set) dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); DATE_CHECK_INITIALIZED(dateobj->time, DateTime); tzobj = (php_timezone_obj *) zend_object_store_get_object(timezone_object TSRMLS_CC); - if (tzobj->type != TIMELIB_ZONETYPE_ID) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only do this for zones with ID for now"); - return; + + switch (tzobj->type) { + case TIMELIB_ZONETYPE_OFFSET: + timelib_set_timezone_from_offset(dateobj->time, tzobj->tzi.utc_offset); + break; + case TIMELIB_ZONETYPE_ABBR: + timelib_set_timezone_from_abbr(dateobj->time, tzobj->tzi.z); + break; + case TIMELIB_ZONETYPE_ID: + timelib_set_timezone(dateobj->time, tzobj->tzi.tz); + break; } - timelib_set_timezone(dateobj->time, tzobj->tzi.tz); timelib_unixtime2local(dateobj->time, dateobj->time->sse); RETURN_ZVAL(object, 1, 0); diff --git a/ext/date/php_date.h b/ext/date/php_date.h index 1d6a94d0ae7..4ce730bb2ba 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -122,14 +122,9 @@ struct _php_timezone_obj { int initialized; int type; union { - timelib_tzinfo *tz; /* TIMELIB_ZONETYPE_ID; */ - timelib_sll utc_offset; /* TIMELIB_ZONETYPE_OFFSET */ - struct /* TIMELIB_ZONETYPE_ABBR */ - { - timelib_sll utc_offset; - char *abbr; - int dst; - } z; + timelib_tzinfo *tz; /* TIMELIB_ZONETYPE_ID */ + timelib_sll utc_offset; /* TIMELIB_ZONETYPE_OFFSET */ + timelib_abbr_info z; /* TIMELIB_ZONETYPE_ABBR */ } tzi; }; diff --git a/ext/date/tests/bug45543.phpt b/ext/date/tests/bug45543.phpt new file mode 100644 index 00000000000..8e36e6287cd --- /dev/null +++ b/ext/date/tests/bug45543.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test for bug #45543: DateTime::setTimezone can not set timezones without ID. +--INI-- +date.timezone=UTC +--FILE-- +format(DATE_ISO8601), PHP_EOL; + echo $d2->format(DATE_ISO8601), PHP_EOL; + $tz = $d1->getTimeZone(); + $d2->setTimeZone($tz); + echo $d1->format(DATE_ISO8601), PHP_EOL; + echo $d2->format(DATE_ISO8601), PHP_EOL; + echo PHP_EOL; +} +--EXPECT-- +2008-01-01T12:00:00-0700 +2008-01-01T12:00:00+0000 +2008-01-01T12:00:00-0700 +2008-01-01T05:00:00-0700 + +2008-01-01T12:00:00+0200 +2008-01-01T12:00:00+0000 +2008-01-01T12:00:00+0200 +2008-01-01T14:00:00+0200 + From f49965b487fa6c0cc9512c287beb357d43acfbf5 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 26 Jan 2014 15:11:15 -0800 Subject: [PATCH 08/15] XFAIL multibyte tests until they are fixed (bug 66582) --- ext/mbstring/tests/zend_multibyte-02.phpt | 2 ++ ext/mbstring/tests/zend_multibyte-06.phpt | 2 ++ ext/mbstring/tests/zend_multibyte-07.phpt | 2 ++ ext/mbstring/tests/zend_multibyte-09.phpt | 2 ++ ext/mbstring/tests/zend_multibyte-10.phpt | 2 ++ ext/mbstring/tests/zend_multibyte-11.phpt | 2 ++ ext/mbstring/tests/zend_multibyte-12.phpt | 2 ++ 7 files changed, 14 insertions(+) diff --git a/ext/mbstring/tests/zend_multibyte-02.phpt b/ext/mbstring/tests/zend_multibyte-02.phpt index 494b5041298..8e15ae8849d 100644 --- a/ext/mbstring/tests/zend_multibyte-02.phpt +++ b/ext/mbstring/tests/zend_multibyte-02.phpt @@ -1,6 +1,8 @@ --TEST-- zend multibyte (2) --SKIPIF-- +--XFAIL-- +https://bugs.php.net/bug.php?id=66582 --INI-- zend.multibyte=On zend.script_encoding=UTF-8 diff --git a/ext/mbstring/tests/zend_multibyte-06.phpt b/ext/mbstring/tests/zend_multibyte-06.phpt index 95fdd78c31c..024a67bbb6c 100644 --- a/ext/mbstring/tests/zend_multibyte-06.phpt +++ b/ext/mbstring/tests/zend_multibyte-06.phpt @@ -1,6 +1,8 @@ --TEST-- zend multibyte (6) --SKIPIF-- +--XFAIL-- +https://bugs.php.net/bug.php?id=66582 --INI-- zend.multibyte=On zend.script_encoding=EUC-JP diff --git a/ext/mbstring/tests/zend_multibyte-07.phpt b/ext/mbstring/tests/zend_multibyte-07.phpt index 3c79f84f570..08db1d0f705 100644 --- a/ext/mbstring/tests/zend_multibyte-07.phpt +++ b/ext/mbstring/tests/zend_multibyte-07.phpt @@ -1,6 +1,8 @@ --TEST-- zend multibyte (7) --SKIPIF-- +--XFAIL-- +https://bugs.php.net/bug.php?id=66582 --INI-- zend.multibyte=On zend.script_encoding=ISO-8859-1 diff --git a/ext/mbstring/tests/zend_multibyte-09.phpt b/ext/mbstring/tests/zend_multibyte-09.phpt index c088e7cddf0..8ad00b4e1e4 100644 --- a/ext/mbstring/tests/zend_multibyte-09.phpt +++ b/ext/mbstring/tests/zend_multibyte-09.phpt @@ -1,6 +1,8 @@ --TEST-- zend multibyte (9) --SKIPIF-- +--XFAIL-- +https://bugs.php.net/bug.php?id=66582 --INI-- zend.multibyte=On zend.script_encoding=cp1251 diff --git a/ext/mbstring/tests/zend_multibyte-10.phpt b/ext/mbstring/tests/zend_multibyte-10.phpt index a5ba74d50de..4d448a8ccfd 100644 --- a/ext/mbstring/tests/zend_multibyte-10.phpt +++ b/ext/mbstring/tests/zend_multibyte-10.phpt @@ -1,6 +1,8 @@ --TEST-- zend multibyte (10) --SKIPIF-- +--XFAIL-- +https://bugs.php.net/bug.php?id=66582 --FILE-- Date: Sun, 26 Jan 2014 15:14:16 -0800 Subject: [PATCH 09/15] drop precision since trigonometric functions are non-portable See: http://stackoverflow.com/questions/21212326/floating-point-arithmetic-and-reproducibility --- .../tests/math/tan_basiclong_64bit.phpt | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/ext/standard/tests/math/tan_basiclong_64bit.phpt b/ext/standard/tests/math/tan_basiclong_64bit.phpt index 8ab083d5007..3c8abe9d275 100644 --- a/ext/standard/tests/math/tan_basiclong_64bit.phpt +++ b/ext/standard/tests/math/tan_basiclong_64bit.phpt @@ -1,5 +1,7 @@ --TEST-- Test tan function : 64bit long tests +--INI-- +precision=5 --SKIPIF-- Date: Sun, 26 Jan 2014 18:28:21 +0900 Subject: [PATCH 10/15] Update source docs --- CODING_STANDARDS | 25 ++++++++++++++++++++++--- README.EXTENSIONS | 8 ++++++++ README.EXT_SKEL | 30 ++++++++++++++++++++++++------ README.SUBMITTING_PATCH | 8 ++++++++ 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/CODING_STANDARDS b/CODING_STANDARDS index 7a0562e6ca9..fccc2b873db 100644 --- a/CODING_STANDARDS +++ b/CODING_STANDARDS @@ -82,7 +82,7 @@ Exceptions: library may need to control or free the memory, or when the memory in question needs to survive between multiple requests. -Naming Conventions +User Functions/Methods Naming Conventions ------------------ 1. Function names for user-level functions should be enclosed with in @@ -163,6 +163,25 @@ Naming Conventions 'foobar' 'foo_bar' +Internal Function Naming Convensions +---------------------- + +1. Exposed module API must be named 'php_modulename_function()' to avoid + symbol collision. They should be in lowercase, with words underscore + delimited. Exposed API must be defined in 'php_modulename.h'. + + PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS); + + Unexposed module function should be static and should not be defined in + 'php_modulename.h'. + + static int php_session_destroy(TSRMLS_D) + +2. Main module source file must be named 'modulename.c'. + +3. Header file that are used by other sources must be named 'php_modulename.h'. + + Syntax and indentation ---------------------- @@ -181,9 +200,9 @@ Syntax and indentation of PHP or one of its standard modules, please maintain the K&R style. This applies to just about everything, starting with indentation and comment styles and up to function declaration - syntax. Also see Indentstyle_. + syntax. Also see Indentstyle. -.. _Indentstyle: http://www.catb.org/~esr/jargon/html/I/indent-style.html + Indentstyle: http://www.catb.org/~esr/jargon/html/I/indent-style.html 3. Be generous with whitespace and braces. Keep one empty line between the variable declaration section and the statements in a block, as well as diff --git a/README.EXTENSIONS b/README.EXTENSIONS index 06d6cdd85f2..e802af8329a 100644 --- a/README.EXTENSIONS +++ b/README.EXTENSIONS @@ -1,3 +1,11 @@ +This file describes extension module API details. Refer to +README.EXT_SKEL to create extension skeleton files. Refer to +Hacker's Guide for PHP internals. + +http://www.php.net/manual/en/internals2.php + + + Between PHP 4.0.6 and 4.1.0, the Zend module struct changed in a way that broke both source and binary compatibility. If you are maintaining a third party extension, here's how to update it: diff --git a/README.EXT_SKEL b/README.EXT_SKEL index d44fcc5c6a9..20b684ddfa6 100644 --- a/README.EXT_SKEL +++ b/README.EXT_SKEL @@ -45,12 +45,29 @@ HOW TO USE IT --proto=filename. +SOURCE AND HEADER FILE NAME + + ./ext_skel generates 'module_name.c' and 'php_module_name.h' as main source + and header files. Keep these names. + + Module functions (User functions) must be named + + module_name_function() + + When you need to expose module functions to other modules, expose functions + strictly needed by others. Exposed internal function must be named + + php_module_name_function() + + See also CODING_STANDARDS. + + FORMAT OF FUNCTION DEFINITIONS FILE All the definitions must be on one line. In it's simplest form, it's just the function name, e.g. - my_function + module_name_function but then you'll be left with an almost empty function body without any argument handling. @@ -72,8 +89,9 @@ FORMAT OF FUNCTION DEFINITIONS FILE An example: - my_function(int arg1, int arg2 [, int arg3 [, int arg4]]) this is my 1st + module_name_function(int arg1, int arg2 [, int arg3 [, int arg4]]) + Arguments arg1 and arg2 is required. Arguments arg3 and arg4 are optional. If possible, the function definition should also contain it's return type @@ -133,15 +151,15 @@ EXAMPLE The following _one_ line - bool my_drawtext(resource image, string text, resource font, int x, int y [, int color]) + bool module_name_drawtext(resource image, string text, resource font, int x, int y [, int color]) will create this function definition for you (note that there are a few question marks to be replaced by you, and you must of course add your own value definitions too): -/* {{{ proto bool my_drawtext(resource image, string text, resource font, int x, int y [, int color]) +/* {{{ proto bool module_name_drawtext(resource image, string text, resource font, int x, int y [, int color]) */ -PHP_FUNCTION(my_drawtext) +PHP_FUNCTION(module_name_drawtext) { char *text = NULL; int argc = ZEND_NUM_ARGS(); @@ -164,7 +182,7 @@ PHP_FUNCTION(my_drawtext) ZEND_FETCH_RESOURCE(???, ???, font, font_id, "???", ???_rsrc_id); } - php_error(E_WARNING, "my_drawtext: not yet implemented"); + php_error(E_WARNING, "module_name_drawtext: not yet implemented"); } /* }}} */ diff --git a/README.SUBMITTING_PATCH b/README.SUBMITTING_PATCH index 63b7156f100..57bd2881b87 100644 --- a/README.SUBMITTING_PATCH +++ b/README.SUBMITTING_PATCH @@ -50,6 +50,14 @@ Please make the mail subject prefix "[PATCH]". If attaching a patch, ensure it has a file extension of ".txt". This is because only MIME attachments of type 'text/*' are accepted. +Preferred way to propose PHP patch is sending pull request from github. + +https://github.com/php/php-src + +Fork official PHP repository and send pull request. It will be notified +to pull request mailing list. You can add pull requests to +http://bugs.php.net/ reports also. + PHP Documentation Patches ------------------------- From 76c098395df506692b1aba48ed0042cc1a27b491 Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Sun, 26 Jan 2014 18:30:25 +0900 Subject: [PATCH 11/15] Revert "Update source docs" This reverts commit 10d06cd4ff3038d2f02a18936793969e7aee0bda. --- CODING_STANDARDS | 25 +++---------------------- README.EXTENSIONS | 8 -------- README.EXT_SKEL | 30 ++++++------------------------ README.SUBMITTING_PATCH | 8 -------- 4 files changed, 9 insertions(+), 62 deletions(-) diff --git a/CODING_STANDARDS b/CODING_STANDARDS index fccc2b873db..7a0562e6ca9 100644 --- a/CODING_STANDARDS +++ b/CODING_STANDARDS @@ -82,7 +82,7 @@ Exceptions: library may need to control or free the memory, or when the memory in question needs to survive between multiple requests. -User Functions/Methods Naming Conventions +Naming Conventions ------------------ 1. Function names for user-level functions should be enclosed with in @@ -163,25 +163,6 @@ User Functions/Methods Naming Conventions 'foobar' 'foo_bar' -Internal Function Naming Convensions ----------------------- - -1. Exposed module API must be named 'php_modulename_function()' to avoid - symbol collision. They should be in lowercase, with words underscore - delimited. Exposed API must be defined in 'php_modulename.h'. - - PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS); - - Unexposed module function should be static and should not be defined in - 'php_modulename.h'. - - static int php_session_destroy(TSRMLS_D) - -2. Main module source file must be named 'modulename.c'. - -3. Header file that are used by other sources must be named 'php_modulename.h'. - - Syntax and indentation ---------------------- @@ -200,9 +181,9 @@ Syntax and indentation of PHP or one of its standard modules, please maintain the K&R style. This applies to just about everything, starting with indentation and comment styles and up to function declaration - syntax. Also see Indentstyle. + syntax. Also see Indentstyle_. - Indentstyle: http://www.catb.org/~esr/jargon/html/I/indent-style.html +.. _Indentstyle: http://www.catb.org/~esr/jargon/html/I/indent-style.html 3. Be generous with whitespace and braces. Keep one empty line between the variable declaration section and the statements in a block, as well as diff --git a/README.EXTENSIONS b/README.EXTENSIONS index e802af8329a..06d6cdd85f2 100644 --- a/README.EXTENSIONS +++ b/README.EXTENSIONS @@ -1,11 +1,3 @@ -This file describes extension module API details. Refer to -README.EXT_SKEL to create extension skeleton files. Refer to -Hacker's Guide for PHP internals. - -http://www.php.net/manual/en/internals2.php - - - Between PHP 4.0.6 and 4.1.0, the Zend module struct changed in a way that broke both source and binary compatibility. If you are maintaining a third party extension, here's how to update it: diff --git a/README.EXT_SKEL b/README.EXT_SKEL index 20b684ddfa6..d44fcc5c6a9 100644 --- a/README.EXT_SKEL +++ b/README.EXT_SKEL @@ -45,29 +45,12 @@ HOW TO USE IT --proto=filename. -SOURCE AND HEADER FILE NAME - - ./ext_skel generates 'module_name.c' and 'php_module_name.h' as main source - and header files. Keep these names. - - Module functions (User functions) must be named - - module_name_function() - - When you need to expose module functions to other modules, expose functions - strictly needed by others. Exposed internal function must be named - - php_module_name_function() - - See also CODING_STANDARDS. - - FORMAT OF FUNCTION DEFINITIONS FILE All the definitions must be on one line. In it's simplest form, it's just the function name, e.g. - module_name_function + my_function but then you'll be left with an almost empty function body without any argument handling. @@ -89,9 +72,8 @@ FORMAT OF FUNCTION DEFINITIONS FILE An example: - module_name_function(int arg1, int arg2 [, int arg3 [, int arg4]]) + my_function(int arg1, int arg2 [, int arg3 [, int arg4]]) this is my 1st - Arguments arg1 and arg2 is required. Arguments arg3 and arg4 are optional. If possible, the function definition should also contain it's return type @@ -151,15 +133,15 @@ EXAMPLE The following _one_ line - bool module_name_drawtext(resource image, string text, resource font, int x, int y [, int color]) + bool my_drawtext(resource image, string text, resource font, int x, int y [, int color]) will create this function definition for you (note that there are a few question marks to be replaced by you, and you must of course add your own value definitions too): -/* {{{ proto bool module_name_drawtext(resource image, string text, resource font, int x, int y [, int color]) +/* {{{ proto bool my_drawtext(resource image, string text, resource font, int x, int y [, int color]) */ -PHP_FUNCTION(module_name_drawtext) +PHP_FUNCTION(my_drawtext) { char *text = NULL; int argc = ZEND_NUM_ARGS(); @@ -182,7 +164,7 @@ PHP_FUNCTION(module_name_drawtext) ZEND_FETCH_RESOURCE(???, ???, font, font_id, "???", ???_rsrc_id); } - php_error(E_WARNING, "module_name_drawtext: not yet implemented"); + php_error(E_WARNING, "my_drawtext: not yet implemented"); } /* }}} */ diff --git a/README.SUBMITTING_PATCH b/README.SUBMITTING_PATCH index 57bd2881b87..63b7156f100 100644 --- a/README.SUBMITTING_PATCH +++ b/README.SUBMITTING_PATCH @@ -50,14 +50,6 @@ Please make the mail subject prefix "[PATCH]". If attaching a patch, ensure it has a file extension of ".txt". This is because only MIME attachments of type 'text/*' are accepted. -Preferred way to propose PHP patch is sending pull request from github. - -https://github.com/php/php-src - -Fork official PHP repository and send pull request. It will be notified -to pull request mailing list. You can add pull requests to -http://bugs.php.net/ reports also. - PHP Documentation Patches ------------------------- From f496aac1f6fc2b3ef30d5ed9539dbfdf9b4a1892 Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Sun, 26 Jan 2014 18:31:27 +0900 Subject: [PATCH 12/15] Update source docs --- CODING_STANDARDS | 25 ++++++++++++++++++++++--- README.EXTENSIONS | 8 ++++++++ README.EXT_SKEL | 30 ++++++++++++++++++++++++------ README.SUBMITTING_PATCH | 8 ++++++++ 4 files changed, 62 insertions(+), 9 deletions(-) diff --git a/CODING_STANDARDS b/CODING_STANDARDS index 7a0562e6ca9..fccc2b873db 100644 --- a/CODING_STANDARDS +++ b/CODING_STANDARDS @@ -82,7 +82,7 @@ Exceptions: library may need to control or free the memory, or when the memory in question needs to survive between multiple requests. -Naming Conventions +User Functions/Methods Naming Conventions ------------------ 1. Function names for user-level functions should be enclosed with in @@ -163,6 +163,25 @@ Naming Conventions 'foobar' 'foo_bar' +Internal Function Naming Convensions +---------------------- + +1. Exposed module API must be named 'php_modulename_function()' to avoid + symbol collision. They should be in lowercase, with words underscore + delimited. Exposed API must be defined in 'php_modulename.h'. + + PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS); + + Unexposed module function should be static and should not be defined in + 'php_modulename.h'. + + static int php_session_destroy(TSRMLS_D) + +2. Main module source file must be named 'modulename.c'. + +3. Header file that are used by other sources must be named 'php_modulename.h'. + + Syntax and indentation ---------------------- @@ -181,9 +200,9 @@ Syntax and indentation of PHP or one of its standard modules, please maintain the K&R style. This applies to just about everything, starting with indentation and comment styles and up to function declaration - syntax. Also see Indentstyle_. + syntax. Also see Indentstyle. -.. _Indentstyle: http://www.catb.org/~esr/jargon/html/I/indent-style.html + Indentstyle: http://www.catb.org/~esr/jargon/html/I/indent-style.html 3. Be generous with whitespace and braces. Keep one empty line between the variable declaration section and the statements in a block, as well as diff --git a/README.EXTENSIONS b/README.EXTENSIONS index 06d6cdd85f2..e802af8329a 100644 --- a/README.EXTENSIONS +++ b/README.EXTENSIONS @@ -1,3 +1,11 @@ +This file describes extension module API details. Refer to +README.EXT_SKEL to create extension skeleton files. Refer to +Hacker's Guide for PHP internals. + +http://www.php.net/manual/en/internals2.php + + + Between PHP 4.0.6 and 4.1.0, the Zend module struct changed in a way that broke both source and binary compatibility. If you are maintaining a third party extension, here's how to update it: diff --git a/README.EXT_SKEL b/README.EXT_SKEL index d44fcc5c6a9..20b684ddfa6 100644 --- a/README.EXT_SKEL +++ b/README.EXT_SKEL @@ -45,12 +45,29 @@ HOW TO USE IT --proto=filename. +SOURCE AND HEADER FILE NAME + + ./ext_skel generates 'module_name.c' and 'php_module_name.h' as main source + and header files. Keep these names. + + Module functions (User functions) must be named + + module_name_function() + + When you need to expose module functions to other modules, expose functions + strictly needed by others. Exposed internal function must be named + + php_module_name_function() + + See also CODING_STANDARDS. + + FORMAT OF FUNCTION DEFINITIONS FILE All the definitions must be on one line. In it's simplest form, it's just the function name, e.g. - my_function + module_name_function but then you'll be left with an almost empty function body without any argument handling. @@ -72,8 +89,9 @@ FORMAT OF FUNCTION DEFINITIONS FILE An example: - my_function(int arg1, int arg2 [, int arg3 [, int arg4]]) this is my 1st + module_name_function(int arg1, int arg2 [, int arg3 [, int arg4]]) + Arguments arg1 and arg2 is required. Arguments arg3 and arg4 are optional. If possible, the function definition should also contain it's return type @@ -133,15 +151,15 @@ EXAMPLE The following _one_ line - bool my_drawtext(resource image, string text, resource font, int x, int y [, int color]) + bool module_name_drawtext(resource image, string text, resource font, int x, int y [, int color]) will create this function definition for you (note that there are a few question marks to be replaced by you, and you must of course add your own value definitions too): -/* {{{ proto bool my_drawtext(resource image, string text, resource font, int x, int y [, int color]) +/* {{{ proto bool module_name_drawtext(resource image, string text, resource font, int x, int y [, int color]) */ -PHP_FUNCTION(my_drawtext) +PHP_FUNCTION(module_name_drawtext) { char *text = NULL; int argc = ZEND_NUM_ARGS(); @@ -164,7 +182,7 @@ PHP_FUNCTION(my_drawtext) ZEND_FETCH_RESOURCE(???, ???, font, font_id, "???", ???_rsrc_id); } - php_error(E_WARNING, "my_drawtext: not yet implemented"); + php_error(E_WARNING, "module_name_drawtext: not yet implemented"); } /* }}} */ diff --git a/README.SUBMITTING_PATCH b/README.SUBMITTING_PATCH index 63b7156f100..57bd2881b87 100644 --- a/README.SUBMITTING_PATCH +++ b/README.SUBMITTING_PATCH @@ -50,6 +50,14 @@ Please make the mail subject prefix "[PATCH]". If attaching a patch, ensure it has a file extension of ".txt". This is because only MIME attachments of type 'text/*' are accepted. +Preferred way to propose PHP patch is sending pull request from github. + +https://github.com/php/php-src + +Fork official PHP repository and send pull request. It will be notified +to pull request mailing list. You can add pull requests to +http://bugs.php.net/ reports also. + PHP Documentation Patches ------------------------- From d65ddb633d4fef54bd9715c4a159d8a7462eed2d Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Mon, 27 Jan 2014 06:50:11 +0900 Subject: [PATCH 13/15] Fix English and improve by Stas. Thanks :) --- CODING_STANDARDS | 9 +++++---- README.EXT_SKEL | 2 +- README.SUBMITTING_PATCH | 11 +++++++---- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/CODING_STANDARDS b/CODING_STANDARDS index fccc2b873db..bebc951452b 100644 --- a/CODING_STANDARDS +++ b/CODING_STANDARDS @@ -166,9 +166,10 @@ User Functions/Methods Naming Conventions Internal Function Naming Convensions ---------------------- -1. Exposed module API must be named 'php_modulename_function()' to avoid - symbol collision. They should be in lowercase, with words underscore - delimited. Exposed API must be defined in 'php_modulename.h'. +1. Functions that are part of the external API should be named + 'php_modulename_function()' to avoid symbol collision. They should be in + lowercase, with words underscore delimited. Exposed API must be defined + in 'php_modulename.h'. PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS); @@ -179,7 +180,7 @@ Internal Function Naming Convensions 2. Main module source file must be named 'modulename.c'. -3. Header file that are used by other sources must be named 'php_modulename.h'. +3. Header file that is used by other sources must be named 'php_modulename.h'. Syntax and indentation diff --git a/README.EXT_SKEL b/README.EXT_SKEL index 20b684ddfa6..42df006d24b 100644 --- a/README.EXT_SKEL +++ b/README.EXT_SKEL @@ -91,7 +91,7 @@ FORMAT OF FUNCTION DEFINITIONS FILE module_name_function(int arg1, int arg2 [, int arg3 [, int arg4]]) - Arguments arg1 and arg2 is required. + Arguments arg1 and arg2 are required. Arguments arg3 and arg4 are optional. If possible, the function definition should also contain it's return type diff --git a/README.SUBMITTING_PATCH b/README.SUBMITTING_PATCH index 57bd2881b87..ee8e6bbaefc 100644 --- a/README.SUBMITTING_PATCH +++ b/README.SUBMITTING_PATCH @@ -50,13 +50,16 @@ Please make the mail subject prefix "[PATCH]". If attaching a patch, ensure it has a file extension of ".txt". This is because only MIME attachments of type 'text/*' are accepted. -Preferred way to propose PHP patch is sending pull request from github. +The preferred way to propose PHP patch is sending pull request from +github. https://github.com/php/php-src -Fork official PHP repository and send pull request. It will be notified -to pull request mailing list. You can add pull requests to -http://bugs.php.net/ reports also. +Fork the official PHP repository and send a pull request. A +notification will be sent to the pull request mailing list. Sending a +note to PHP Internals list (internals@lists.php.net) may help getting +more feedback and quicker turnaround. You can also add pull requests +to bug reports at http://bugs.php.net/. PHP Documentation Patches From 4dee63ca1cb650f96c227d9169787f70b0c86bd9 Mon Sep 17 00:00:00 2001 From: Yasuo Ohgaki Date: Mon, 27 Jan 2014 18:41:31 +0900 Subject: [PATCH 14/15] Remove obsolete description --- php.ini-development | 35 ----------------------------------- php.ini-production | 35 ----------------------------------- 2 files changed, 70 deletions(-) diff --git a/php.ini-development b/php.ini-development index b935f22eb5a..962010746b9 100644 --- a/php.ini-development +++ b/php.ini-development @@ -138,16 +138,6 @@ ; Development Value: "GP" ; Production Value: "GP" -; session.bug_compat_42 -; Default Value: On -; Development Value: On -; Production Value: Off - -; session.bug_compat_warn -; Default Value: On -; Development Value: On -; Production Value: Off - ; session.gc_divisor ; Default Value: 100 ; Development Value: 1000 @@ -1476,31 +1466,6 @@ session.gc_maxlifetime = 1440 ; setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes): ; find /path/to/sessions -cmin +24 -type f | xargs rm -; PHP 4.2 and less have an undocumented feature/bug that allows you to -; to initialize a session variable in the global scope. -; PHP 4.3 and later will warn you, if this feature is used. -; You can disable the feature and the warning separately. At this time, -; the warning is only displayed, if bug_compat_42 is enabled. This feature -; introduces some serious security problems if not handled correctly. It's -; recommended that you do not use this feature on production servers. But you -; should enable this on development servers and enable the warning as well. If you -; do not enable the feature on development servers, you won't be warned when it's -; used and debugging errors caused by this can be difficult to track down. -; Default Value: On -; Development Value: On -; Production Value: Off -; http://php.net/session.bug-compat-42 -session.bug_compat_42 = On - -; This setting controls whether or not you are warned by PHP when initializing a -; session value into the global space. session.bug_compat_42 must be enabled before -; these warnings can be issued by PHP. See the directive above for more information. -; Default Value: On -; Development Value: On -; Production Value: Off -; http://php.net/session.bug-compat-warn -session.bug_compat_warn = On - ; Check HTTP Referer to invalidate externally stored URLs containing ids. ; HTTP_REFERER has to contain this substring for the session to be ; considered as valid. diff --git a/php.ini-production b/php.ini-production index 4ee7ac92ce0..d19c6b84e6f 100644 --- a/php.ini-production +++ b/php.ini-production @@ -138,16 +138,6 @@ ; Development Value: "GP" ; Production Value: "GP" -; session.bug_compat_42 -; Default Value: On -; Development Value: On -; Production Value: Off - -; session.bug_compat_warn -; Default Value: On -; Development Value: On -; Production Value: Off - ; session.gc_divisor ; Default Value: 100 ; Development Value: 1000 @@ -1476,31 +1466,6 @@ session.gc_maxlifetime = 1440 ; setting session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes): ; find /path/to/sessions -cmin +24 -type f | xargs rm -; PHP 4.2 and less have an undocumented feature/bug that allows you to -; to initialize a session variable in the global scope. -; PHP 4.3 and later will warn you, if this feature is used. -; You can disable the feature and the warning separately. At this time, -; the warning is only displayed, if bug_compat_42 is enabled. This feature -; introduces some serious security problems if not handled correctly. It's -; recommended that you do not use this feature on production servers. But you -; should enable this on development servers and enable the warning as well. If you -; do not enable the feature on development servers, you won't be warned when it's -; used and debugging errors caused by this can be difficult to track down. -; Default Value: On -; Development Value: On -; Production Value: Off -; http://php.net/session.bug-compat-42 -session.bug_compat_42 = Off - -; This setting controls whether or not you are warned by PHP when initializing a -; session value into the global space. session.bug_compat_42 must be enabled before -; these warnings can be issued by PHP. See the directive above for more information. -; Default Value: On -; Development Value: On -; Production Value: Off -; http://php.net/session.bug-compat-warn -session.bug_compat_warn = Off - ; Check HTTP Referer to invalidate externally stored URLs containing ids. ; HTTP_REFERER has to contain this substring for the session to be ; considered as valid. From e9b4bca5a00d475c4176ce24a5203d42607642e8 Mon Sep 17 00:00:00 2001 From: Bob Weinand Date: Tue, 28 Jan 2014 13:31:52 +0100 Subject: [PATCH 15/15] Fixed arginfo of PDO::__construct() to match the docs and zend_parse_parameters definition. --- ext/pdo/pdo_dbh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 64726f65dec..4f5a3917044 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -196,7 +196,7 @@ static char *dsn_from_uri(char *uri, char *buf, size_t buflen TSRMLS_DC) /* {{{ } /* }}} */ -/* {{{ proto void PDO::__construct(string dsn, string username, string passwd [, array options]) +/* {{{ proto void PDO::__construct(string dsn[, string username[, string passwd [, array options]]]) */ static PHP_METHOD(PDO, dbh_constructor) { @@ -1226,7 +1226,7 @@ static PHP_METHOD(PDO, getAvailableDrivers) /* }}} */ /* {{{ arginfo */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_pdo___construct, 0, 0, 3) +ZEND_BEGIN_ARG_INFO_EX(arginfo_pdo___construct, 0, 0, 1) ZEND_ARG_INFO(0, dsn) ZEND_ARG_INFO(0, username) ZEND_ARG_INFO(0, passwd)