Last active
December 25, 2015 14:08
-
-
Save laruence/6988427 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/ext/opcache/ZendAccelerator.c b/ext/opcache/ZendAccelerator.c | |
index 72b5a1b..48ff730 100644 | |
--- a/ext/opcache/ZendAccelerator.c | |
+++ b/ext/opcache/ZendAccelerator.c | |
@@ -37,6 +37,7 @@ | |
#include "zend_API.h" | |
#include "zend_ini.h" | |
#include "TSRM/tsrm_virtual_cwd.h" | |
+#include "ext/phar/php_phar.h" | |
#include "zend_accelerator_util_funcs.h" | |
#include "zend_accelerator_hash.h" | |
@@ -144,6 +145,21 @@ static inline int is_cacheable_stream_path(const char *filename) | |
memcmp(filename, "phar://", sizeof("phar://") - 1) == 0; | |
} | |
+static inline int is_phar_relative_alias_path(const char *filename, char **alias, int *alias_len) | |
+{ | |
+ if (memcmp(filename, "phar://", sizeof("phar://") - 1) == 0 | |
+ && filename[sizeof("phar://") - 1] != '\0' && filename[sizeof("phar://") - 1] != '/') { | |
+ char *slash; | |
+ *alias = filename + sizeof("phar://") - 1; | |
+ slash = strstr(*alias, "/"); | |
+ if (slash) { | |
+ *alias_len = slash - *alias; | |
+ return 1; | |
+ } | |
+ } | |
+ return 0; | |
+} | |
+ | |
/* O+ overrides PHP chdir() function and remembers the current working directory | |
* in ZCG(cwd) and ZCG(cwd_len). Later accel_getcwd() can use stored value and | |
* avoid getcwd() call. | |
@@ -1028,15 +1044,33 @@ char *accel_make_persistent_key_ex(zend_file_handle *file_handle, int path_lengt | |
} | |
memcpy(ZCG(key) + cur_len, include_path, include_path_len); | |
ZCG(key)[key_length] = '\0'; | |
- } else { | |
- /* not use_cwd */ | |
- key_length = path_length; | |
+ } else { | |
+ /* not use_cwd */ | |
+ key_length = path_length; | |
if ((size_t)key_length >= sizeof(ZCG(key))) { | |
ZCG(key_len) = 0; | |
return NULL; | |
+ } else { | |
+ char *alias; | |
+ int alias_len; | |
+ if (is_phar_relative_alias_path(file_handle->filename, &alias, &alias_len)) { | |
+ char *phar_path; | |
+ int phar_path_len; | |
+ if (phar_resolve_alias(alias, alias_len, &phar_path, &phar_path_len TSRMLS_CC) == SUCCESS) { | |
+ int filename_len = strlen(file_handle->filename); | |
+ memcpy(ZCG(key), "phar://", sizeof("phar://") -1); | |
+ memcpy(ZCG(key) + sizeof("phar://") - 1, phar_path, phar_path_len); | |
+ memcpy(ZCG(key) + sizeof("phar://") - 1 + phar_path_len, | |
+ alias + alias_len, filename_len - alias_len - sizeof("phar://") + 2); | |
+ key_length = filename_len + (phar_path_len - alias_len); | |
+ } else { | |
+ memcpy(ZCG(key), file_handle->filename, key_length + 1); | |
+ } | |
+ } else { | |
+ memcpy(ZCG(key), file_handle->filename, key_length + 1); | |
+ } | |
} | |
- memcpy(ZCG(key), file_handle->filename, key_length + 1); | |
- } | |
+ } | |
*key_len = ZCG(key_len) = key_length; | |
return ZCG(key); |
yes, it's by accident :)
Stepping through this, I've found some problems. For a start all phar functions return a status of SUCCESS / FAILURE ... ( 0, -1, ... ) which you assume in your calling use, but your new phar_resolve_alias()
returns a C boolean 0= failure / 1=success, so the wrong path is taken after its invocation. I suggest that you modify util.c:phar_resolve_alias()
to return SUCCESS / FAILURE.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I like how the diff also contains a bit of your shell history - happens to me too all the f'ing time :-)
I'll give this a shot in 2-3 hours. When we'll know more.
If all goes well, I'll let 20% of our traffic hit a box configured with opcache and 5.5 - then we'll get some real data.