Skip to content

Instantly share code, notes, and snippets.

@laruence
Last active December 25, 2015 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save laruence/6988427 to your computer and use it in GitHub Desktop.
Save laruence/6988427 to your computer and use it in GitHub Desktop.
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);
@pilif
Copy link

pilif commented Oct 17, 2013

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.

@laruence
Copy link
Author

yes, it's by accident :)

@TerryE
Copy link

TerryE commented Oct 27, 2013

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