Skip to content

Commit

Permalink
nstanceof operator shouldn't call __autoload()
Browse files Browse the repository at this point in the history
  • Loading branch information
dstogov committed Aug 19, 2005
1 parent 2b5ebdd commit d90d6c5
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 7 deletions.
1 change: 1 addition & 0 deletions NEWS
Expand Up @@ -2,6 +2,7 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 6.0
- Unicode support. (Andrei, Dmitriy, et al)
- instanceof operator shouldn't call __autoload. (Dmitry)
- cURL improvements: (Ilia)
. Added curl_setopt_array() which allows setting of multiple cURL options.
. Added CURLINFO_HEADER_OUT to facilitate request retrieval.
Expand Down
18 changes: 18 additions & 0 deletions Zend/tests/instanceof.phpt
@@ -0,0 +1,18 @@
--TEST--
instanceof shouldn't call __autoload
--FILE--
<?php
function __autoload($name) {
echo("AUTOLOAD '$name'\n");
eval("class $name {}");
}

class A {
}
$a = new A;
var_dump($a instanceof B);
var_dump($a instanceof A);
?>
--EXPECT--
bool(false)
bool(true)
11 changes: 10 additions & 1 deletion Zend/zend_compile.c
Expand Up @@ -3592,8 +3592,17 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC

void zend_do_instanceof(znode *result, znode *expr, znode *class_znode, int type TSRMLS_DC)
{
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
int last_op_number = get_next_op_number(CG(active_op_array));
zend_op *opline;

if (last_op_number > 0) {
opline = &CG(active_op_array)->opcodes[last_op_number-1];
if (opline->opcode == ZEND_FETCH_CLASS) {
opline->extended_value |= ZEND_FETCH_CLASS_NO_AUTOLOAD;
}
}

opline = get_next_op(CG(active_op_array) TSRMLS_CC);
opline->opcode = ZEND_INSTANCEOF;
opline->result.op_type = IS_TMP_VAR;
opline->result.u.var = get_temporary_variable(CG(active_op_array));
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_compile.h
Expand Up @@ -597,7 +597,7 @@ int zendlex(znode *zendlval TSRMLS_DC);
#define ZEND_FETCH_CLASS_GLOBAL 4
#define ZEND_FETCH_CLASS_AUTO 5
#define ZEND_FETCH_CLASS_INTERFACE 6

#define ZEND_FETCH_CLASS_NO_AUTOLOAD 0x80

/* variable parsing type (compile-time) */
#define ZEND_PARSED_MEMBER (1<<0)
Expand Down
25 changes: 20 additions & 5 deletions Zend/zend_execute_API.c
Expand Up @@ -1421,7 +1421,9 @@ void zend_unset_timeout(TSRMLS_D)
ZEND_API zend_class_entry *zend_u_fetch_class(zend_uchar type, void *class_name, uint class_name_len, int fetch_type TSRMLS_DC)
{
zend_class_entry **pce;
zend_bool use_autoload = (fetch_type & ZEND_FETCH_CLASS_NO_AUTOLOAD) == 0;

fetch_type = fetch_type & ~ZEND_FETCH_CLASS_NO_AUTOLOAD;
check_fetch_type:
switch (fetch_type) {
case ZEND_FETCH_CLASS_SELF:
Expand All @@ -1446,14 +1448,27 @@ ZEND_API zend_class_entry *zend_u_fetch_class(zend_uchar type, void *class_name,
break;
}

if (zend_u_lookup_class(type, class_name, class_name_len, &pce TSRMLS_CC)==FAILURE) {
if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) {
zend_error(E_ERROR, "Interface '%R' not found", type, class_name);
if (use_autoload) {
if (zend_u_lookup_class(type, class_name, class_name_len, &pce TSRMLS_CC)==FAILURE) {
if (fetch_type == ZEND_FETCH_CLASS_INTERFACE) {
zend_error(E_ERROR, "Interface '%R' not found", type, class_name);
} else {
zend_error(E_ERROR, "Class '%R' not found", type, class_name);
}
}
return *pce;
} else {
unsigned int lc_name_len;
void *lc_name = zend_u_str_case_fold(type, class_name, class_name_len, 1, &lc_name_len);

if (zend_u_hash_find(EG(class_table), type, lc_name, lc_name_len+1, (void **) &pce) == SUCCESS) {
efree(lc_name);
return *pce;
} else {
zend_error(E_ERROR, "Class '%R' not found", type, class_name);
efree(lc_name);
return NULL;
}
}
return *pce;
}

zend_class_entry *zend_fetch_class(char *class_name, uint class_name_len, int fetch_type TSRMLS_DC)
Expand Down

0 comments on commit d90d6c5

Please sign in to comment.