summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2015-07-07 10:12:51 -0700
committerStanislav Malyshev <stas@php.net>2015-07-07 10:12:51 -0700
commit6c884e8e84615488e51f1837656a5a5d0bc2449e (patch)
tree8792716795ddea24ed0ad945b423e012410cfa8d
parentc0142de470b5f57975054a51833273b01f569333 (diff)
parentb4b082e63ecab2a81e565fb07aafaaaf67b77f66 (diff)
downloadphp-git-6c884e8e84615488e51f1837656a5a5d0bc2449e.tar.gz
Merge branch 'PHP-5.5' into PHP-5.6
* PHP-5.5: Better fix for bug #69958 update news Fix bug #69669 (mysqlnd is vulnerable to BACKRONYM) Fix bug #69923 - Buffer overflow and stack smashing error in phar_fix_filepath Fix bug #69958 - Segfault in Phar::convertToData on invalid file Better fix for bug #69958 Better fix for bug #69958 update news Fix bug #69669 (mysqlnd is vulnerable to BACKRONYM) Fix bug #69923 - Buffer overflow and stack smashing error in phar_fix_filepath Fix bug #69958 - Segfault in Phar::convertToData on invalid file Conflicts: ext/phar/phar_object.c
-rw-r--r--ext/mysqlnd/mysqlnd.c60
-rw-r--r--ext/phar/phar.c10
-rw-r--r--ext/phar/phar_object.c87
-rw-r--r--ext/phar/tests/bug69958.phpt16
-rw-r--r--ext/phar/tests/bug69958.tarbin0 -> 513 bytes
5 files changed, 108 insertions, 65 deletions
diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c
index e9cdfaf294..41df2b6cae 100644
--- a/ext/mysqlnd/mysqlnd.c
+++ b/ext/mysqlnd/mysqlnd.c
@@ -401,7 +401,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_server_option)(MYSQLND_CONN_DATA * const c
int2store(buffer, (unsigned int) option);
ret = conn->m->simple_command(conn, COM_SET_OPTION, buffer, sizeof(buffer), PROT_EOF_PACKET, FALSE, TRUE TSRMLS_CC);
-
+
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
}
DBG_RETURN(ret);
@@ -490,27 +490,41 @@ mysqlnd_switch_to_ssl_if_needed(
}
#ifdef MYSQLND_SSL_SUPPORTED
- if ((greet_packet->server_capabilities & CLIENT_SSL) && (mysql_flags & CLIENT_SSL)) {
- zend_bool verify = mysql_flags & CLIENT_SSL_VERIFY_SERVER_CERT? TRUE:FALSE;
- DBG_INF("Switching to SSL");
- if (!PACKET_WRITE(auth_packet, conn)) {
- CONN_SET_STATE(conn, CONN_QUIT_SENT);
- conn->m->send_close(conn TSRMLS_CC);
- SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
- goto end;
- }
+ if (mysql_flags & CLIENT_SSL) {
+ zend_bool server_has_ssl = (greet_packet->server_capabilities & CLIENT_SSL)? TRUE:FALSE;
+ if (server_has_ssl == FALSE) {
+ goto close_conn;
+ } else {
+ zend_bool verify = mysql_flags & CLIENT_SSL_VERIFY_SERVER_CERT? TRUE:FALSE;
+ DBG_INF("Switching to SSL");
+ if (!PACKET_WRITE(auth_packet, conn)) {
+ goto close_conn;
+ }
- conn->net->data->m.set_client_option(conn->net, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (const char *) &verify TSRMLS_CC);
+ conn->net->data->m.set_client_option(conn->net, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, (const char *) &verify TSRMLS_CC);
- if (FAIL == conn->net->data->m.enable_ssl(conn->net TSRMLS_CC)) {
- goto end;
+ if (FAIL == conn->net->data->m.enable_ssl(conn->net TSRMLS_CC)) {
+ goto end;
+ }
}
}
+#else
+ auth_packet->client_flags &= ~CLIENT_SSL;
+ if (!PACKET_WRITE(auth_packet, conn)) {
+ goto close_conn;
+ }
#endif
ret = PASS;
end:
PACKET_FREE(auth_packet);
DBG_RETURN(ret);
+
+close_conn:
+ CONN_SET_STATE(conn, CONN_QUIT_SENT);
+ conn->m->send_close(conn TSRMLS_CC);
+ SET_CLIENT_ERROR(*conn->error_info, CR_SERVER_GONE_ERROR, UNKNOWN_SQLSTATE, mysqlnd_server_gone);
+ PACKET_FREE(auth_packet);
+ DBG_RETURN(ret);
}
/* }}} */
@@ -1589,7 +1603,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, sqlstate)(const MYSQLND_CONN_DATA * const conn
/* {{{ mysqlnd_old_escape_string */
-PHPAPI ulong
+PHPAPI ulong
mysqlnd_old_escape_string(char * newstr, const char * escapestr, size_t escapestr_len TSRMLS_DC)
{
DBG_ENTER("mysqlnd_old_escape_string");
@@ -1751,7 +1765,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, statistic)(MYSQLND_CONN_DATA * conn, char **me
if (PASS == (ret = PACKET_READ(stats_header, conn))) {
/* will be freed by Zend, thus don't use the mnd_ allocator */
- *message = estrndup(stats_header->message, stats_header->message_len);
+ *message = estrndup(stats_header->message, stats_header->message_len);
*message_len = stats_header->message_len;
DBG_INF(*message);
}
@@ -1877,7 +1891,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, shutdown)(MYSQLND_CONN_DATA * const conn, uint
conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
}
- DBG_RETURN(ret);
+ DBG_RETURN(ret);
}
/* }}} */
@@ -2379,7 +2393,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c
ret = FAIL;
break;
}
-
+
new_charset_name = mnd_pestrdup(value, conn->persistent);
if (!new_charset_name) {
goto oom;
@@ -2458,11 +2472,11 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option)(MYSQLND_CONN_DATA * const c
default:
ret = FAIL;
}
- conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
+ conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
DBG_RETURN(ret);
oom:
SET_OOM_ERROR(*conn->error_info);
- conn->m->local_tx_end(conn, this_func, FAIL TSRMLS_CC);
+ conn->m->local_tx_end(conn, this_func, FAIL TSRMLS_CC);
end:
DBG_RETURN(FAIL);
}
@@ -2539,7 +2553,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_client_option_2d)(MYSQLND_CONN_DATA * cons
DBG_RETURN(ret);
oom:
SET_OOM_ERROR(*conn->error_info);
- conn->m->local_tx_end(conn, this_func, FAIL TSRMLS_CC);
+ conn->m->local_tx_end(conn, this_func, FAIL TSRMLS_CC);
end:
DBG_RETURN(FAIL);
}
@@ -2580,7 +2594,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, use_result)(MYSQLND_CONN_DATA * const conn, co
conn->current_result = NULL;
} while (0);
- conn->m->local_tx_end(conn, this_func, result == NULL? FAIL:PASS TSRMLS_CC);
+ conn->m->local_tx_end(conn, this_func, result == NULL? FAIL:PASS TSRMLS_CC);
}
DBG_RETURN(result);
@@ -2638,7 +2652,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, store_result)(MYSQLND_CONN_DATA * const conn,
conn->current_result = NULL;
} while (0);
- conn->m->local_tx_end(conn, this_func, result == NULL? FAIL:PASS TSRMLS_CC);
+ conn->m->local_tx_end(conn, this_func, result == NULL? FAIL:PASS TSRMLS_CC);
}
DBG_RETURN(result);
}
@@ -2667,7 +2681,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_autocommit)(MYSQLND_CONN_DATA * conn, unsi
if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) {
ret = conn->m->query(conn, (mode) ? "SET AUTOCOMMIT=1":"SET AUTOCOMMIT=0", sizeof("SET AUTOCOMMIT=1") - 1 TSRMLS_CC);
- conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
+ conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC);
}
DBG_RETURN(ret);
diff --git a/ext/phar/phar.c b/ext/phar/phar.c
index dc5d0ea525..72d7e004b0 100644
--- a/ext/phar/phar.c
+++ b/ext/phar/phar.c
@@ -2119,7 +2119,7 @@ char *tsrm_strtok_r(char *s, const char *delim, char **last) /* {{{ */
*/
char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC) /* {{{ */
{
- char newpath[MAXPATHLEN];
+ char *newpath;
int newpath_len;
char *ptr;
char *tok;
@@ -2127,8 +2127,10 @@ char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC) /* {{{
if (PHAR_G(cwd_len) && use_cwd && path_length > 2 && path[0] == '.' && path[1] == '/') {
newpath_len = PHAR_G(cwd_len);
+ newpath = emalloc(strlen(path) + newpath_len + 1);
memcpy(newpath, PHAR_G(cwd), newpath_len);
} else {
+ newpath = emalloc(strlen(path) + 2);
newpath[0] = '/';
newpath_len = 1;
}
@@ -2151,6 +2153,7 @@ char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC) /* {{{
if (*tok == '.') {
efree(path);
*new_len = 1;
+ efree(newpath);
return estrndup("/", 1);
}
break;
@@ -2158,9 +2161,11 @@ char *phar_fix_filepath(char *path, int *new_len, int use_cwd TSRMLS_DC) /* {{{
if (tok[0] == '.' && tok[1] == '.') {
efree(path);
*new_len = 1;
+ efree(newpath);
return estrndup("/", 1);
}
}
+ efree(newpath);
return path;
}
@@ -2209,7 +2214,8 @@ last_time:
efree(path);
*new_len = newpath_len;
- return estrndup(newpath, newpath_len);
+ newpath[newpath_len] = '\0';
+ return erealloc(newpath, newpath_len + 1);
}
/* }}} */
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index 8da46c0131..49cbbf2b74 100644
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -1252,7 +1252,7 @@ PHP_METHOD(Phar, __construct)
INIT_PZVAL(&arg2);
ZVAL_LONG(&arg2, flags);
- zend_call_method_with_2_params(&zobj, Z_OBJCE_P(zobj),
+ zend_call_method_with_2_params(&zobj, Z_OBJCE_P(zobj),
&spl_ce_RecursiveDirectoryIterator->constructor, "__construct", NULL, &arg1, &arg2);
if (!phar_data->is_persistent) {
@@ -1276,7 +1276,7 @@ PHP_METHOD(Phar, getSupportedSignatures)
if (zend_parse_parameters_none() == FAILURE) {
return;
}
-
+
array_init(return_value);
add_next_index_stringl(return_value, "MD5", 3, 1);
@@ -1303,7 +1303,7 @@ PHP_METHOD(Phar, getSupportedCompression)
if (zend_parse_parameters_none() == FAILURE) {
return;
}
-
+
array_init(return_value);
phar_request_initialize(TSRMLS_C);
@@ -1548,7 +1548,7 @@ phar_spl_fileinfo:
}
return ZEND_HASH_APPLY_STOP;
}
-
+
base = temp;
base_len = strlen(base);
@@ -1737,7 +1737,7 @@ after_open_fp:
/* {{{ proto array Phar::buildFromDirectory(string base_dir[, string regex])
* Construct a phar archive from an existing directory, recursively.
* Optional second parameter is a regular expression for filtering directory contents.
- *
+ *
* Return value is an array mapping phar index to actual files added.
*/
PHP_METHOD(Phar, buildFromDirectory)
@@ -1773,7 +1773,7 @@ PHP_METHOD(Phar, buildFromDirectory)
INIT_PZVAL(&arg2);
ZVAL_LONG(&arg2, SPL_FILE_DIR_SKIPDOTS|SPL_FILE_DIR_UNIXPATHS);
- zend_call_method_with_2_params(&iter, spl_ce_RecursiveDirectoryIterator,
+ zend_call_method_with_2_params(&iter, spl_ce_RecursiveDirectoryIterator,
&spl_ce_RecursiveDirectoryIterator->constructor, "__construct", NULL, &arg, &arg2);
if (EG(exception)) {
@@ -1790,7 +1790,7 @@ PHP_METHOD(Phar, buildFromDirectory)
RETURN_FALSE;
}
- zend_call_method_with_1_params(&iteriter, spl_ce_RecursiveIteratorIterator,
+ zend_call_method_with_1_params(&iteriter, spl_ce_RecursiveIteratorIterator,
&spl_ce_RecursiveIteratorIterator->constructor, "__construct", NULL, iter);
if (EG(exception)) {
@@ -1815,7 +1815,7 @@ PHP_METHOD(Phar, buildFromDirectory)
INIT_PZVAL(&arg2);
ZVAL_STRINGL(&arg2, regex, regex_len, 0);
- zend_call_method_with_2_params(&regexiter, spl_ce_RegexIterator,
+ zend_call_method_with_2_params(&regexiter, spl_ce_RegexIterator,
&spl_ce_RegexIterator->constructor, "__construct", NULL, iteriter, &arg2);
}
@@ -2019,9 +2019,10 @@ static int phar_copy_file_contents(phar_entry_info *entry, php_stream *fp TSRMLS
}
/* }}} */
-static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool compress TSRMLS_DC) /* {{{ */
+static zval *phar_rename_archive(phar_archive_data **sphar, char *ext, zend_bool compress TSRMLS_DC) /* {{{ */
{
const char *oldname = NULL;
+ phar_archive_data *phar = *sphar;
char *oldpath = NULL;
char *basename = NULL, *basepath = NULL;
char *newname = NULL, *newpath = NULL;
@@ -2103,7 +2104,7 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c
spprintf(&newname, 0, "%s.%s", strtok(basename, "."), ext);
efree(basename);
-
+
basepath = estrndup(oldpath, (strlen(oldpath) - oldname_len));
phar->fname_len = spprintf(&newpath, 0, "%s%s", basepath, newname);
@@ -2128,7 +2129,9 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c
(*pphar)->fp = phar->fp;
phar->fp = NULL;
phar_destroy_phar_data(phar TSRMLS_CC);
+ *sphar = NULL;
phar = *pphar;
+ *sphar = NULL;
phar->refcount++;
newpath = oldpath;
goto its_ok;
@@ -2335,15 +2338,19 @@ no_copy:
phar_add_virtual_dirs(phar, newentry.filename, newentry.filename_len TSRMLS_CC);
}
- if ((ret = phar_rename_archive(phar, ext, 0 TSRMLS_CC))) {
+ if ((ret = phar_rename_archive(&phar, ext, 0 TSRMLS_CC))) {
return ret;
} else {
- zend_hash_destroy(&(phar->manifest));
- zend_hash_destroy(&(phar->mounted_dirs));
- zend_hash_destroy(&(phar->virtual_dirs));
- php_stream_close(phar->fp);
- efree(phar->fname);
- efree(phar);
+ if(phar != NULL) {
+ zend_hash_destroy(&(phar->manifest));
+ zend_hash_destroy(&(phar->mounted_dirs));
+ zend_hash_destroy(&(phar->virtual_dirs));
+ if (phar->fp) {
+ php_stream_close(phar->fp);
+ }
+ efree(phar->fname);
+ efree(phar);
+ }
return NULL;
}
}
@@ -2561,7 +2568,7 @@ PHP_METHOD(Phar, convertToData)
PHP_METHOD(Phar, isCompressed)
{
PHAR_ARCHIVE_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -2585,7 +2592,7 @@ PHP_METHOD(Phar, isWritable)
{
php_stream_statbuf ssb;
PHAR_ARCHIVE_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -2663,7 +2670,7 @@ PHP_METHOD(Phar, delete)
PHP_METHOD(Phar, getAlias)
{
PHAR_ARCHIVE_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -2680,7 +2687,7 @@ PHP_METHOD(Phar, getAlias)
PHP_METHOD(Phar, getPath)
{
PHAR_ARCHIVE_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -2796,7 +2803,7 @@ valid_alias:
PHP_METHOD(Phar, getVersion)
{
PHAR_ARCHIVE_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -2811,7 +2818,7 @@ PHP_METHOD(Phar, getVersion)
PHP_METHOD(Phar, startBuffering)
{
PHAR_ARCHIVE_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -2826,7 +2833,7 @@ PHP_METHOD(Phar, startBuffering)
PHP_METHOD(Phar, isBuffering)
{
PHAR_ARCHIVE_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -2843,7 +2850,7 @@ PHP_METHOD(Phar, stopBuffering)
char *error;
PHAR_ARCHIVE_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -3078,7 +3085,7 @@ PHP_METHOD(Phar, setSignatureAlgorithm)
PHP_METHOD(Phar, getSignature)
{
PHAR_ARCHIVE_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -3122,7 +3129,7 @@ PHP_METHOD(Phar, getSignature)
PHP_METHOD(Phar, getModified)
{
PHAR_ARCHIVE_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -3384,7 +3391,7 @@ PHP_METHOD(Phar, decompressFiles)
{
char *error;
PHAR_ARCHIVE_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -3901,7 +3908,7 @@ PHP_METHOD(Phar, getStub)
phar_entry_info *stub;
PHAR_ARCHIVE_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -4004,7 +4011,7 @@ PHP_METHOD(Phar, hasMetadata)
PHP_METHOD(Phar, getMetadata)
{
PHAR_ARCHIVE_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -4452,7 +4459,7 @@ PHP_METHOD(PharFileInfo, __construct)
INIT_PZVAL(&arg1);
ZVAL_STRINGL(&arg1, fname, fname_len, 0);
- zend_call_method_with_1_params(&zobj, Z_OBJCE_P(zobj),
+ zend_call_method_with_1_params(&zobj, Z_OBJCE_P(zobj),
&spl_ce_SplFileInfo->constructor, "__construct", NULL, &arg1);
}
/* }}} */
@@ -4490,7 +4497,7 @@ PHP_METHOD(PharFileInfo, __destruct)
PHP_METHOD(PharFileInfo, getCompressedSize)
{
PHAR_ENTRY_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -4532,7 +4539,7 @@ PHP_METHOD(PharFileInfo, isCompressed)
PHP_METHOD(PharFileInfo, getCRC32)
{
PHAR_ENTRY_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -4558,7 +4565,7 @@ PHP_METHOD(PharFileInfo, getCRC32)
PHP_METHOD(PharFileInfo, isCRCChecked)
{
PHAR_ENTRY_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -4573,7 +4580,7 @@ PHP_METHOD(PharFileInfo, isCRCChecked)
PHP_METHOD(PharFileInfo, getPharFlags)
{
PHAR_ENTRY_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -4651,7 +4658,7 @@ PHP_METHOD(PharFileInfo, chmod)
PHP_METHOD(PharFileInfo, hasMetadata)
{
PHAR_ENTRY_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -4666,7 +4673,7 @@ PHP_METHOD(PharFileInfo, hasMetadata)
PHP_METHOD(PharFileInfo, getMetadata)
{
PHAR_ENTRY_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -4747,7 +4754,7 @@ PHP_METHOD(PharFileInfo, delMetadata)
char *error;
PHAR_ENTRY_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -4805,7 +4812,7 @@ PHP_METHOD(PharFileInfo, getContent)
phar_entry_info *link;
PHAR_ENTRY_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
@@ -4979,7 +4986,7 @@ PHP_METHOD(PharFileInfo, decompress)
{
char *error;
PHAR_ENTRY_OBJECT();
-
+
if (zend_parse_parameters_none() == FAILURE) {
return;
}
diff --git a/ext/phar/tests/bug69958.phpt b/ext/phar/tests/bug69958.phpt
new file mode 100644
index 0000000000..96f2198b14
--- /dev/null
+++ b/ext/phar/tests/bug69958.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Phar: bug #69958: Segfault in Phar::convertToData on invalid file
+--XFAIL--
+Still has memory leaks, see https://bugs.php.net/bug.php?id=70005
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--FILE--
+<?php
+$tarphar = new PharData(__DIR__.'/bug69958.tar');
+$phar = $tarphar->convertToData(Phar::TAR);
+--EXPECTF--
+Fatal error: Uncaught exception 'BadMethodCallException' with message 'phar "%s/bug69958.tar" exists and must be unlinked prior to conversion' in %s/bug69958.php:%d
+Stack trace:
+#0 %s/bug69958.php(%d): PharData->convertToData(%d)
+#1 {main}
+ thrown in %s/bug69958.php on line %d
diff --git a/ext/phar/tests/bug69958.tar b/ext/phar/tests/bug69958.tar
new file mode 100644
index 0000000000..02275248bd
--- /dev/null
+++ b/ext/phar/tests/bug69958.tar
Binary files differ