summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS23
-rw-r--r--ext/curl/interface.c3
-rw-r--r--ext/fileinfo/tests/bug68819_002.phpt2
-rw-r--r--ext/odbc/php_odbc.c40
-rw-r--r--ext/odbc/php_odbc_includes.h8
-rw-r--r--ext/odbc/tests/bug47803.phpt185
-rw-r--r--ext/odbc/tests/config.inc17
-rw-r--r--ext/pdo_dblib/dblib_driver.c3
-rw-r--r--ext/pdo_dblib/dblib_stmt.c27
-rw-r--r--ext/pdo_dblib/tests/bug_54648.phpt26
-rw-r--r--ext/pdo_dblib/tests/bug_68957.phpt29
-rw-r--r--ext/pdo_dblib/tests/bug_69757.phpt4
-rw-r--r--ext/phar/phar.c7
-rw-r--r--ext/phar/tar.c4
-rw-r--r--ext/phar/tests/bug71625.phpt25
-rw-r--r--ext/phar/tests/tar/bug71317-duplicate-filename.phpt50
-rw-r--r--ext/phar/tests/tar/bug71504.phpt18
-rw-r--r--ext/phar/tests/tar/files/HTML_CSS-1.5.4.tgzbin0 -> 45553 bytes
-rw-r--r--ext/zip/php_zip.c2
-rw-r--r--ext/zip/php_zip.h1
-rw-r--r--ext/zip/zip_stream.c1
-rw-r--r--main/main.c3
22 files changed, 438 insertions, 40 deletions
diff --git a/NEWS b/NEWS
index 37ffc6aa24..96bbcb6685 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,28 @@
PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+?? ??? 2016, PHP 5.6.20
+
+- Core:
+ . Fixed bug #71596 (Segmentation fault on ZTS with date function
+ (setlocale)). (Anatol)
+
+- Curl:
+ . Fixed bug #71694 (Support constant CURLM_ADDED_ALREADY). (mpyw)
+
+- ODBC:
+ . Fixed bug #47803, #69526 (Executing prepared statements is succesfull only
+ for the first two statements). (einavitamar at gmail dot com, Anatol)
+
+- PDO_DBlib:
+ . Bug #54648 (PDO::MSSQL forces format of datetime fields).
+ (steven dot lambeth at gmx dot de, Anatol)
+
+- Phar:
+ . Fixed bug #71625 (Crash in php7.dll with bad phar filename).
+ (Anatol)
+ . Fixed bug #71504 (Parsing of tar file with duplicate filenames causes
+ memory leak). (Jos Elstgeest)
+
03 Mar 2016, PHP 5.6.19
- CLI server:
diff --git a/ext/curl/interface.c b/ext/curl/interface.c
index d9aab7541c..98cc5e2bb4 100644
--- a/ext/curl/interface.c
+++ b/ext/curl/interface.c
@@ -831,6 +831,9 @@ PHP_MINIT_FUNCTION(curl)
REGISTER_CURL_CONSTANT(CURLM_INTERNAL_ERROR);
REGISTER_CURL_CONSTANT(CURLM_OK);
REGISTER_CURL_CONSTANT(CURLM_OUT_OF_MEMORY);
+#if LIBCURL_VERSION_NUM >= 0x072001 /* Available since 7.32.1 */
+ REGISTER_CURL_CONSTANT(CURLM_ADDED_ALREADY);
+#endif
/* Curl proxy constants */
REGISTER_CURL_CONSTANT(CURLPROXY_HTTP);
diff --git a/ext/fileinfo/tests/bug68819_002.phpt b/ext/fileinfo/tests/bug68819_002.phpt
index cec238d63e..7d5f6c642d 100644
--- a/ext/fileinfo/tests/bug68819_002.phpt
+++ b/ext/fileinfo/tests/bug68819_002.phpt
@@ -12,7 +12,7 @@ $string .= "\r\n";
$string .= "''''";
// Total string length > 8192
-$string .= str_repeat(chr(rand(32, 127)), 8184);
+$string .= str_repeat("a", 8184);
// Ending in this string
$string .= "say";
diff --git a/ext/odbc/php_odbc.c b/ext/odbc/php_odbc.c
index 33ef0c229a..bde6c1ed14 100644
--- a/ext/odbc/php_odbc.c
+++ b/ext/odbc/php_odbc.c
@@ -442,6 +442,9 @@ static void _free_odbc_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)
* zend_list_delete(res->conn_ptr->id);
*/
}
+ if (res->param_info) {
+ efree(res->param_info);
+ }
efree(res);
}
}
@@ -1183,6 +1186,7 @@ PHP_FUNCTION(odbc_prepare)
odbc_result *result = NULL;
odbc_connection *conn;
RETCODE rc;
+ int i;
#ifdef HAVE_SQL_EXTENDED_FETCH
SQLUINTEGER scrollopts;
#endif
@@ -1196,6 +1200,7 @@ PHP_FUNCTION(odbc_prepare)
result = (odbc_result *)ecalloc(1, sizeof(odbc_result));
result->numparams = 0;
+ result->param_info = NULL;
rc = PHP_ODBC_SQLALLOCSTMT(conn->hdbc, &(result->stmt));
if (rc == SQL_INVALID_HANDLE) {
@@ -1252,6 +1257,19 @@ PHP_FUNCTION(odbc_prepare)
zend_list_addref(conn->id);
result->conn_ptr = conn;
result->fetched = 0;
+
+ result->param_info = (odbc_param_info *) safe_emalloc(sizeof(odbc_param_info), result->numparams, 0);
+ for (i=0;i<result->numparams;i++) {
+ rc = SQLDescribeParam(result->stmt, (SQLUSMALLINT)(i+1), &result->param_info[i].sqltype, &result->param_info[i].precision,
+ &result->param_info[i].scale, &result->param_info[i].nullable);
+ if (rc == SQL_ERROR) {
+ odbc_sql_error(result->conn_ptr, result->stmt, "SQLDescribeParameter");
+ SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
+ efree(result->param_info);
+ efree(result);
+ RETURN_FALSE;
+ }
+ }
ZEND_REGISTER_RESOURCE(return_value, result, le_result);
}
/* }}} */
@@ -1272,9 +1290,7 @@ PHP_FUNCTION(odbc_execute)
params_t *params = NULL;
char *filename;
unsigned char otype;
- SQLSMALLINT sqltype, ctype, scale;
- SQLSMALLINT nullable;
- SQLULEN precision;
+ SQLSMALLINT ctype;
odbc_result *result;
int numArgs, i, ne;
RETCODE rc;
@@ -1332,22 +1348,10 @@ PHP_FUNCTION(odbc_execute)
RETURN_FALSE;
}
- rc = SQLDescribeParam(result->stmt, (SQLUSMALLINT)i, &sqltype, &precision, &scale, &nullable);
params[i-1].vallen = Z_STRLEN_PP(tmp);
params[i-1].fp = -1;
- if (rc == SQL_ERROR) {
- odbc_sql_error(result->conn_ptr, result->stmt, "SQLDescribeParameter");
- SQLFreeStmt(result->stmt, SQL_RESET_PARAMS);
- for (i = 0; i < result->numparams; i++) {
- if (params[i].fp != -1) {
- close(params[i].fp);
- }
- }
- efree(params);
- RETURN_FALSE;
- }
- if (IS_SQL_BINARY(sqltype)) {
+ if (IS_SQL_BINARY(result->param_info[i-1].sqltype)) {
ctype = SQL_C_BINARY;
} else {
ctype = SQL_C_CHAR;
@@ -1394,7 +1398,7 @@ PHP_FUNCTION(odbc_execute)
params[i-1].vallen = SQL_LEN_DATA_AT_EXEC(0);
rc = SQLBindParameter(result->stmt, (SQLUSMALLINT)i, SQL_PARAM_INPUT,
- ctype, sqltype, precision, scale,
+ ctype, result->param_info[i-1].sqltype, result->param_info[i-1].precision, result->param_info[i-1].scale,
(void *)params[i-1].fp, 0,
&params[i-1].vallen);
} else {
@@ -1406,7 +1410,7 @@ PHP_FUNCTION(odbc_execute)
}
rc = SQLBindParameter(result->stmt, (SQLUSMALLINT)i, SQL_PARAM_INPUT,
- ctype, sqltype, precision, scale,
+ ctype, result->param_info[i-1].sqltype, result->param_info[i-1].precision, result->param_info[i-1].scale,
Z_STRVAL_PP(tmp), 0,
&params[i-1].vallen);
}
diff --git a/ext/odbc/php_odbc_includes.h b/ext/odbc/php_odbc_includes.h
index 8ba8d7cc80..7dd6167d43 100644
--- a/ext/odbc/php_odbc_includes.h
+++ b/ext/odbc/php_odbc_includes.h
@@ -233,6 +233,13 @@ typedef struct odbc_result_value {
SQLLEN coltype;
} odbc_result_value;
+typedef struct odbc_param_info {
+ SQLSMALLINT sqltype;
+ SQLSMALLINT scale;
+ SQLSMALLINT nullable;
+ SQLULEN precision;
+} odbc_param_info;
+
typedef struct odbc_result {
ODBC_SQL_STMT_T stmt;
odbc_result_value *values;
@@ -244,6 +251,7 @@ typedef struct odbc_result {
long longreadlen;
int binmode;
int fetched;
+ odbc_param_info * param_info;
odbc_connection *conn_ptr;
} odbc_result;
diff --git a/ext/odbc/tests/bug47803.phpt b/ext/odbc/tests/bug47803.phpt
new file mode 100644
index 0000000000..9a2600dd18
--- /dev/null
+++ b/ext/odbc/tests/bug47803.phpt
@@ -0,0 +1,185 @@
+--TEST--
+Bug #47803 Executing prepared statements is succesfull only for the first two statements
+--SKIPIF--
+<?php include 'skipif.inc'; ?>
+--FILE--
+<?php
+
+include dirname(__FILE__) . "/config.inc";
+
+$create_table = "CREATE TABLE FOO(
+ [PAR_ID] [int] NOT NULL,
+ [PAR_INT] [int] NULL,
+ [PAR_CHR] [varchar](500) NULL
+)";
+
+$inserts = "INSERT INTO FOO
+ ([PAR_ID]
+ ,[PAR_INT]
+ ,[PAR_CHR])
+ VALUES
+ (1,14,''),
+ (2,30,''),
+ (3,7,''),
+ (4,7,''),
+ (5,0,''),
+ (6,0,''),
+ (7,20130901,''),
+ (8,20140201,''),
+ (9,20140201,''),
+ (10,20140620,''),
+ (11,221,'')";
+
+
+date_default_timezone_set('Europe/Warsaw');
+
+$link = odbc_connect($dsn, $user, $pass);
+
+odbc_exec($link, 'CREATE DATABASE odbcTEST');
+odbc_exec($link, $create_table);
+odbc_exec($link, $inserts);
+
+$upd_params = array(
+ array('id'=>1, 'name'=>'test 1'),
+ array('id'=>2, 'name'=>'test 2'),
+ array('id'=>3, 'name'=>'test 3'),
+ array('id'=>4, 'name'=>'test 4'),
+ array('id'=>5, 'name'=>'test 5'),
+ array('id'=>10, 'name'=>'test 10'),
+ array('id'=>9, 'name'=>'test 9'),
+ array('id'=>8, 'name'=>'test 8'),
+ array('id'=>7, 'name'=>'test 7'),
+ array('id'=>6, 'name'=>'test 6'),
+);
+$sql = "UPDATE FOO
+ SET [PAR_CHR] = ?
+ WHERE [PAR_ID] = ?";
+$result = odbc_prepare($link, $sql);
+if (!$result) {
+ print ('[sql] prep: '.$sql);
+ goto out;
+}
+foreach ($upd_params as &$k) {
+ if(!odbc_execute($result, array($k['name'], $k['id']))) {
+ print ('[sql] exec: '."array({$k['name']}, {$k['id']})");
+ goto out;
+ }
+}
+odbc_free_result($result);
+
+$sql = "SELECT * FROM FOO WHERE [PAR_ID] = ?";
+$result = odbc_prepare($link, $sql);
+if (!$result) {
+ print ('[sql] prep: '.$sql);
+ goto out;
+}
+foreach ($upd_params as $k) {
+ if(!odbc_execute($result, array($k['id']))) {
+ print ('[sql] exec: '."array({$k['id']})");
+ goto out;
+ }
+ while (($r = odbc_fetch_array($result)) !== false) {
+ var_dump($r);
+ }
+}
+
+out:
+if ($result) odbc_free_result($result);
+odbc_close($link);
+
+?>
+==DONE==
+--EXPECT--
+array(3) {
+ ["PAR_ID"]=>
+ string(1) "1"
+ ["PAR_INT"]=>
+ string(2) "14"
+ ["PAR_CHR"]=>
+ string(6) "test 1"
+}
+array(3) {
+ ["PAR_ID"]=>
+ string(1) "2"
+ ["PAR_INT"]=>
+ string(2) "30"
+ ["PAR_CHR"]=>
+ string(6) "test 2"
+}
+array(3) {
+ ["PAR_ID"]=>
+ string(1) "3"
+ ["PAR_INT"]=>
+ string(1) "7"
+ ["PAR_CHR"]=>
+ string(6) "test 3"
+}
+array(3) {
+ ["PAR_ID"]=>
+ string(1) "4"
+ ["PAR_INT"]=>
+ string(1) "7"
+ ["PAR_CHR"]=>
+ string(6) "test 4"
+}
+array(3) {
+ ["PAR_ID"]=>
+ string(1) "5"
+ ["PAR_INT"]=>
+ string(1) "0"
+ ["PAR_CHR"]=>
+ string(6) "test 5"
+}
+array(3) {
+ ["PAR_ID"]=>
+ string(2) "10"
+ ["PAR_INT"]=>
+ string(8) "20140620"
+ ["PAR_CHR"]=>
+ string(7) "test 10"
+}
+array(3) {
+ ["PAR_ID"]=>
+ string(1) "9"
+ ["PAR_INT"]=>
+ string(8) "20140201"
+ ["PAR_CHR"]=>
+ string(6) "test 9"
+}
+array(3) {
+ ["PAR_ID"]=>
+ string(1) "8"
+ ["PAR_INT"]=>
+ string(8) "20140201"
+ ["PAR_CHR"]=>
+ string(6) "test 8"
+}
+array(3) {
+ ["PAR_ID"]=>
+ string(1) "7"
+ ["PAR_INT"]=>
+ string(8) "20130901"
+ ["PAR_CHR"]=>
+ string(6) "test 7"
+}
+array(3) {
+ ["PAR_ID"]=>
+ string(1) "7"
+ ["PAR_INT"]=>
+ string(8) "20130901"
+ ["PAR_CHR"]=>
+ string(6) "test 7"
+}
+==DONE==
+--CLEAN--
+<?php
+include 'config.inc';
+
+$conn = odbc_connect($dsn, $user, $pass);
+
+odbc_exec($conn, 'DROP TABLE FOO');
+odbc_exec($conn, 'DROP DATABASE odbcTEST');
+
+odbc_close($conn);
+
+?>
diff --git a/ext/odbc/tests/config.inc b/ext/odbc/tests/config.inc
index a88eea4ed0..dcc4cbb3bf 100644
--- a/ext/odbc/tests/config.inc
+++ b/ext/odbc/tests/config.inc
@@ -3,6 +3,17 @@
putenv('ODBCINI=/etc/odbc.ini');
putenv('ODBCSYSINI=/etc');
-$dsn = 'myodbc3';
-$user = 'root';
-$pass = '';
+$dsn = getenv("ODBC_TEST_DSN");
+$user = getenv("ODBC_TEST_USER");
+$pass = getenv("ODBC_TEST_PASS");
+
+if (false === $dsn) {
+ $dsn = 'myodbc3';
+}
+if (false === $user) {
+ $user = 'root';
+}
+if (false == $pass) {
+ $pass = '';
+}
+
diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c
index 26ee139d2d..70b4402982 100644
--- a/ext/pdo_dblib/dblib_driver.c
+++ b/ext/pdo_dblib/dblib_driver.c
@@ -286,8 +286,6 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
};
- nvers = sizeof(tdsver)/sizeof(tdsver[0]);
-
struct pdo_data_src_parser vars[] = {
{ "charset", NULL, 0 }
,{ "appname", "PHP " PDO_DBLIB_FLAVOUR, 0 }
@@ -298,6 +296,7 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
};
nvars = sizeof(vars)/sizeof(vars[0]);
+ nvers = sizeof(tdsver)/sizeof(tdsver[0]);
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, nvars);
diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c
index 19967ef7da..86c6d8308b 100644
--- a/ext/pdo_dblib/dblib_stmt.c
+++ b/ext/pdo_dblib/dblib_stmt.c
@@ -103,9 +103,6 @@ static int pdo_dblib_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
/* Cancel any pending results */
dbcancel(H->link);
- efree(stmt->columns);
- stmt->columns = NULL;
-
return 1;
}
@@ -113,9 +110,6 @@ static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
{
pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
- efree(stmt->columns);
- stmt->columns = NULL;
-
efree(S);
return 1;
@@ -211,7 +205,7 @@ static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
col->name = estrdup(fname);
col->namelen = strlen(col->name);
} else {
- col->namelen = spprintf(&col->name, NULL, "computed%d", colno);
+ col->namelen = spprintf(&col->name, 0, "computed%d", colno);
}
col->maxlen = dbcollen(H->link, colno+1);
col->param_type = PDO_PARAM_STR;
@@ -271,6 +265,25 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
*ptr = tmp_ptr;
break;
}
+ case SQLDATETIM4:
+ case SQLDATETIME: {
+ DBDATETIME dt;
+ DBDATEREC di;
+
+ dbconvert(H->link, coltype, (BYTE*) *ptr, -1, SQLDATETIME, (LPBYTE) &dt, -1);
+ dbdatecrack(H->link, &di, &dt);
+
+ *len = spprintf((char**) &tmp_ptr, 20, "%d-%02d-%02d %02d:%02d:%02d",
+#ifdef PHP_DBLIB_IS_MSSQL || MSDBLIB
+ di.year, di.month, di.day, di.hour, di.minute, di.second
+#else
+ di.dateyear, di.datemonth+1, di.datedmonth, di.datehour, di.dateminute, di.datesecond
+#endif
+ );
+
+ *ptr = (char*) tmp_ptr;
+ break;
+ }
default:
if (dbwillconvert(coltype, SQLCHAR)) {
tmp_len = 32 + (2 * (*len)); /* FIXME: We allocate more than we need here */
diff --git a/ext/pdo_dblib/tests/bug_54648.phpt b/ext/pdo_dblib/tests/bug_54648.phpt
new file mode 100644
index 0000000000..aa9f292669
--- /dev/null
+++ b/ext/pdo_dblib/tests/bug_54648.phpt
@@ -0,0 +1,26 @@
+--TEST--
+PDO_DBLIB: Does not force correct dateformat
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_dblib')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/config.inc';
+$db->query('set dateformat ymd');
+$rs = $db->query("select cast('1950-01-18 23:00:00' as smalldatetime) as sdt, cast('2030-01-01 23:59:59' as datetime) as dt");
+var_dump($rs->fetchAll(PDO::FETCH_ASSOC));
+echo "Done.\n";
+?>
+--EXPECT--
+array(1) {
+ [0]=>
+ array(2) {
+ ["sdt"]=>
+ string(19) "1950-01-18 23:00:00"
+ ["dt"]=>
+ string(19) "2030-01-01 23:59:59"
+ }
+}
+Done.
diff --git a/ext/pdo_dblib/tests/bug_68957.phpt b/ext/pdo_dblib/tests/bug_68957.phpt
new file mode 100644
index 0000000000..3d6e2fd13d
--- /dev/null
+++ b/ext/pdo_dblib/tests/bug_68957.phpt
@@ -0,0 +1,29 @@
+--TEST--
+PDO_DBLIB bug #68957 PDO::query doesn't support several queries
+--SKIPIF--
+<?php
+if (!extension_loaded('pdo_dblib')) die('skip not loaded');
+require dirname(__FILE__) . '/config.inc';
+?>
+--FILE--
+<?php
+require dirname(__FILE__) . '/config.inc';
+
+$query = "declare @myInt int = 1; select @myInt;";
+$stmt = $db->query($query);
+$stmt->nextRowset(); // Added line
+$rows = $stmt->fetchAll();
+print_r($rows);
+
+?>
+--EXPECT--
+Array
+(
+ [0] => Array
+ (
+ [computed0] => 1
+ [0] => 1
+ )
+
+)
+
diff --git a/ext/pdo_dblib/tests/bug_69757.phpt b/ext/pdo_dblib/tests/bug_69757.phpt
index 6c4aee0b6d..611f41bec1 100644
--- a/ext/pdo_dblib/tests/bug_69757.phpt
+++ b/ext/pdo_dblib/tests/bug_69757.phpt
@@ -11,8 +11,8 @@ require __DIR__ . '/config.inc';
$sql = "
exec dbo.sp_executesql N'
- SELECT * FROM sysobjects
- SELECT * FROM syscolumns
+ SELECT TOP 1 * FROM sysobjects
+ SELECT TOP 1 * FROM syscolumns
'
";
$stmt = $db->query($sql);
diff --git a/ext/phar/phar.c b/ext/phar/phar.c
index 02776458f3..228dfcaaaf 100644
--- a/ext/phar/phar.c
+++ b/ext/phar/phar.c
@@ -1791,8 +1791,11 @@ static int phar_analyze_path(const char *fname, const char *ext, int ext_len, in
#ifdef PHP_WIN32
phar_unixify_path_separators(realpath, strlen(realpath));
#endif
- slash = strstr(realpath, filename) + ((ext - fname) + ext_len);
- *slash = '\0';
+ slash = strstr(realpath, filename);
+ if (slash) {
+ slash += ((ext - fname) + ext_len);
+ *slash = '\0';
+ }
slash = strrchr(realpath, '/');
if (slash) {
diff --git a/ext/phar/tar.c b/ext/phar/tar.c
index 1fcfe52756..62edcb59f1 100644
--- a/ext/phar/tar.c
+++ b/ext/phar/tar.c
@@ -500,7 +500,9 @@ bail:
entry.link = estrndup(hdr->linkname, linkname_len);
}
phar_set_inode(&entry TSRMLS_CC);
- zend_hash_add(&myphar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), (void **) &newentry);
+
+ zend_hash_update(&myphar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), (void **) &newentry);
+ ZEND_ASSERT(newentry != NULL);
if (entry.is_persistent) {
++entry.manifest_pos;
diff --git a/ext/phar/tests/bug71625.phpt b/ext/phar/tests/bug71625.phpt
new file mode 100644
index 0000000000..d57ba5ef71
--- /dev/null
+++ b/ext/phar/tests/bug71625.phpt
@@ -0,0 +1,25 @@
+--TEST--
+Phar - Bug #71625 - Crash in php7.dll
+--INI--
+phar.readonly=0
+--SKIPIF--
+<?php
+
+if (!extension_loaded("phar") || !extension_loaded("zlib")) die("skip");
+if(substr(PHP_OS, 0, 3) != 'WIN' ) {
+ die('skip windows only test');
+}
+
+?>
+--FILE--
+<?php
+$phar = new Phar("A:A:.phar");
+$phar["hello_habr.txt"] = '<? Hello Habr!?>';
+?>
+DONE
+--EXPECTF--
+Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Cannot create phar 'A:A:.phar', file extension (or combination) not recognised or the directory does not exist' in %sbug71625.php:%d
+Stack trace:
+#0 %sbug71625.php(%d): Phar->__construct('A:A:.phar')
+#1 {main}
+ thrown in %sbug71625.php on line %d
diff --git a/ext/phar/tests/tar/bug71317-duplicate-filename.phpt b/ext/phar/tests/tar/bug71317-duplicate-filename.phpt
new file mode 100644
index 0000000000..bcbccab1c8
--- /dev/null
+++ b/ext/phar/tests/tar/bug71317-duplicate-filename.phpt
@@ -0,0 +1,50 @@
+--TEST--
+Bug #71317: regression in opening tar based phar files
+--SKIPIF--
+<?php if (!extension_loaded('phar')) die('skip'); ?>
+<?php if (!extension_loaded("spl")) die("skip SPL not available"); ?>
+<?php if (!extension_loaded("zlib")) die("skip zlib not available"); ?>
+--FILE--
+<?php
+include dirname(__FILE__) . '/files/tarmaker.php.inc';
+
+$testDirectory = __DIR__ . '/files/test_bug71317';
+$testTarFilename = __DIR__ . '/files/test_bug71317.tar';
+
+$tar = new tarmaker($testTarFilename, 'none');
+$tar->init();
+$tar->addFile('file1.txt', 'file1');
+$tar->addFile('file2.txt', 'file2');
+$tar->addFile('file3.txt', 'file3');
+$tar->addFile('file4.txt', 'file4');
+$tar->addFile('file5.txt', 'file5');
+$tar->addFile('file2.txt', 'file2a');
+$tar->close();
+
+$fname = str_replace('\\', '/', $testTarFilename);
+try {
+ mkdir($testDirectory);
+ $tar = new PharData($fname);
+ $tar->extractTo($testDirectory);
+
+ $fileContent = file_get_contents($testDirectory . '/file2.txt');
+ $expectedContent = 'file2a';
+ if ($fileContent !== $expectedContent) {
+ throw new Exception(sprintf('Contents of file2.txt ("%s") is invalid, expected "%s"', $fileContent, $expectedContent));
+ }
+} catch(Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+?>
+===DONE===
+--CLEAN--
+<?php
+$testDirectory = __DIR__ . '/files/test_bug71317';
+$testTarFilename = __DIR__ . '/files/test_bug71317.tar';
+
+unlink($testTarFilename);
+array_map('unlink', glob($testDirectory . "/*.txt"));
+rmdir($testDirectory);
+?>
+--EXPECT--
+===DONE===
diff --git a/ext/phar/tests/tar/bug71504.phpt b/ext/phar/tests/tar/bug71504.phpt
new file mode 100644
index 0000000000..e85078810e
--- /dev/null
+++ b/ext/phar/tests/tar/bug71504.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Bug #71504: Parsing of tar file with duplicate filenames causes memory leak
+--SKIPIF--
+<?php if (!extension_loaded('phar')) die('skip'); ?>
+<?php if (!extension_loaded("spl")) die("skip SPL not available"); ?>
+<?php if (!extension_loaded("zlib")) die("skip zlib not available"); ?>
+--FILE--
+<?php
+$fname = str_replace('\\', '/', dirname(__FILE__) . '/files/HTML_CSS-1.5.4.tgz');
+try {
+ $tar = new PharData($fname);
+} catch(Exception $e) {
+ echo $e->getMessage() . "\n";
+}
+?>
+===DONE===
+--EXPECT--
+===DONE===
diff --git a/ext/phar/tests/tar/files/HTML_CSS-1.5.4.tgz b/ext/phar/tests/tar/files/HTML_CSS-1.5.4.tgz
new file mode 100644
index 0000000000..d0b2313e7a
--- /dev/null
+++ b/ext/phar/tests/tar/files/HTML_CSS-1.5.4.tgz
Binary files differ
diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c
index ccd0467fd3..1791548e0e 100644
--- a/ext/zip/php_zip.c
+++ b/ext/zip/php_zip.c
@@ -16,7 +16,6 @@
+----------------------------------------------------------------------+
*/
-/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -3162,7 +3161,6 @@ static PHP_MINFO_FUNCTION(zip)
php_info_print_table_start();
php_info_print_table_row(2, "Zip", "enabled");
- php_info_print_table_row(2, "Extension Version","$Id$");
php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION);
php_info_print_table_row(2, "Libzip version", LIBZIP_VERSION);
diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h
index 73fa9e114f..657f178891 100644
--- a/ext/zip/php_zip.h
+++ b/ext/zip/php_zip.h
@@ -16,7 +16,6 @@
+----------------------------------------------------------------------+
*/
-/* $Id$ */
#ifndef PHP_ZIP_H
#define PHP_ZIP_H
diff --git a/ext/zip/zip_stream.c b/ext/zip/zip_stream.c
index 980488ae4a..1cd134ecfb 100644
--- a/ext/zip/zip_stream.c
+++ b/ext/zip/zip_stream.c
@@ -16,7 +16,6 @@
+----------------------------------------------------------------------+
*/
-/* $Id$ */
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
diff --git a/main/main.c b/main/main.c
index 877507d8b8..ab55b5b831 100644
--- a/main/main.c
+++ b/main/main.c
@@ -1622,6 +1622,9 @@ int php_request_startup(TSRMLS_D)
#endif /* HAVE_DTRACE */
#ifdef PHP_WIN32
+# if defined(ZTS)
+ _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
+# endif
PG(com_initialized) = 0;
#endif