Hi,
I modified your patch so it can capture the position where the
supposed data begins into the constant __HALT_PHP_PARSER__.
There may be a problem with my patch if more than one require()'d /
include()'d script contain __HALT_PHP_PARSER__, but it'd be
quite handy if such an issue is resolved.
<?php
$fp = fopen(__FILE__, 'rb');
fseek($fp, __HALT_PHP_PARSER__, SEEK_SET);
fpassthru($fp);
?>
<?php __HALT_PHP_PARSER__; ?>
abc
def
Moriyoshi
Index: Zend/zend_language_scanner.l
===================================================================
RCS file: /repository/ZendEngine2/zend_language_scanner.l,v
retrieving revision 1.124
diff -u -r1.124 zend_language_scanner.l
--- Zend/zend_language_scanner.l 7 Mar 2005 16:48:49 -0000 1.124
+++ Zend/zend_language_scanner.l 11 Mar 2005 23:47:11 -0000
@@ -1342,6 +1342,13 @@
return T_INLINE_HTML;
}
+<INITIAL>"<?php __HALT_PHP_PARSER__; ?>"{NEWLINE}? {
+ long fpos = (yyin ? zend_stream_ftell(yyin TSRMLS_CC): 0) +
(long)(yy_c_buf_p - (YY_CURRENT_BUFFER)->yy_ch_buf);
+ REGISTER_MAIN_LONG_CONSTANT("__HALT_PHP_PARSER__", fpos, CONST_CS);
+
+ yyterminate();
+}
+
<INITIAL>"<?"|"<script"{WHITESPACE}+"language"{WHITESPACE}*"="{WHITESPACE}*("php"|"\"php\""|"\'php\'"){WHITESPACE}*">"
{
HANDLE_NEWLINES(yytext, yyleng);
if (CG(short_tags) || yyleng>2) { /* yyleng>2 means it's not <? but
<script> */
Index: Zend/zend_stream.c
===================================================================
RCS file: /repository/ZendEngine2/zend_stream.c,v
retrieving revision 1.9
diff -u -r1.9 zend_stream.c
--- Zend/zend_stream.c 27 Sep 2004 09:03:40 -0000 1.9
+++ Zend/zend_stream.c 11 Mar 2005 23:47:12 -0000
@@ -35,6 +35,11 @@
fclose((FILE*)handle);
}
+static long zend_stream_stdio_fteller(void *handle TSRMLS_DC)
+{
+ return ftell((FILE*)handle);
+}
+
ZEND_API int zend_stream_open(const char *filename, zend_file_handle *handle
TSRMLS_DC)
{
if (zend_stream_open_function) {
@@ -80,9 +85,10 @@
}
/* promote to stream */
- file_handle->handle.stream.handle = file_handle->handle.fp;
- file_handle->handle.stream.reader = zend_stream_stdio_reader;
- file_handle->handle.stream.closer = zend_stream_stdio_closer;
+ file_handle->handle.stream.handle = file_handle->handle.fp;
+ file_handle->handle.stream.reader = zend_stream_stdio_reader;
+ file_handle->handle.stream.closer = zend_stream_stdio_closer;
+ file_handle->handle.stream.fteller = zend_stream_stdio_fteller;
file_handle->type = ZEND_HANDLE_STREAM;
file_handle->handle.stream.interactive = isatty(fileno((FILE
*)file_handle->handle.stream.handle));
@@ -121,4 +127,7 @@
return 0;
}
-
+ZEND_API long zend_stream_ftell(zend_file_handle *file_handle TSRMLS_DC)
+{
+ return
file_handle->handle.stream.fteller(file_handle->handle.stream.handle TSRMLS_CC);
+}
Index: Zend/zend_stream.h
===================================================================
RCS file: /repository/ZendEngine2/zend_stream.h,v
retrieving revision 1.6
diff -u -r1.6 zend_stream.h
--- Zend/zend_stream.h 25 Jun 2004 12:55:11 -0000 1.6
+++ Zend/zend_stream.h 11 Mar 2005 23:47:12 -0000
@@ -27,11 +27,13 @@
typedef size_t (*zend_stream_reader_t)(void *handle, char *buf, size_t len
TSRMLS_DC);
typedef void (*zend_stream_closer_t)(void *handle TSRMLS_DC);
+typedef long (*zend_stream_fteller_t)(void *handle TSRMLS_DC);
typedef struct _zend_stream {
void *handle;
zend_stream_reader_t reader;
zend_stream_closer_t closer;
+ zend_stream_fteller_t fteller;
int interactive;
} zend_stream;
@@ -52,6 +54,7 @@
ZEND_API int zend_stream_ferror(zend_file_handle *file_handle TSRMLS_DC);
ZEND_API int zend_stream_getc(zend_file_handle *file_handle TSRMLS_DC);
ZEND_API size_t zend_stream_read(zend_file_handle *file_handle, char *buf,
size_t len TSRMLS_DC);
+ZEND_API long zend_stream_ftell(zend_file_handle *file_handle TSRMLS_DC);
ZEND_API int zend_stream_fixup(zend_file_handle *file_handle TSRMLS_DC);
END_EXTERN_C()
Index: main/main.c
===================================================================
RCS file: /repository/php-src/main/main.c,v
retrieving revision 1.619
diff -u -r1.619 main.c
--- main/main.c 8 Mar 2005 21:42:10 -0000 1.619
+++ main/main.c 11 Mar 2005 23:47:20 -0000
@@ -838,6 +838,11 @@
php_stream_close((php_stream*)handle);
}
+static long stream_fteller_for_zend(void *handle TSRMLS_DC)
+{
+ return (long)php_stream_tell((php_stream*)handle);
+}
+
static int php_stream_open_for_zend(const char *filename, zend_file_handle
*handle TSRMLS_DC)
{
php_stream *stream;
@@ -851,6 +856,7 @@
handle->handle.stream.handle = stream;
handle->handle.stream.reader =
(zend_stream_reader_t)_php_stream_read;
handle->handle.stream.closer = stream_closer_for_zend;
+ handle->handle.stream.fteller = stream_fteller_for_zend;
handle->handle.stream.interactive = 0;
return SUCCESS;
On 2005/03/12, at 7:05, Ilia Alshanetsky wrote:
Wez Furlong wrote:
If you name the token __HALT_PHP_PARSER__ instead (or something
equally unlikely to be used by accident and unambiguous in meaning),
you'll get a +1 from me :-)
I aim to please ;-) Here is the revised patch that makes the token a
bit clearer and also increases the strictness of the parser. For
those of you wondering how would you quickly locate the end of script
and start of data here are some solutions:
1) while (fgets($fp) != '<?php __HALT_PHP_PARSER__; ?>'));
2) Assuming the author knows the maximum length of the actual code,
they could read X bytes and then using strpos locate the position of
the HALT token and start reading data dump from there.
$fp = fopen(__FILE__, "r");
$halt_token = "<?php "."__HALT_PHP_PARSER__"."; ?>";
$pos = strpos(fread($fp, 10000), $halt_token);
fseek($fp, $pos + strlen($halt_token));
Ilia
Index: Zend/zend_language_scanner.l
===================================================================
RCS file: /repository/ZendEngine2/zend_language_scanner.l,v
retrieving revision 1.124
diff -u -a -p -r1.124 zend_language_scanner.l
--- Zend/zend_language_scanner.l 7 Mar 2005 16:48:49 -0000 1.124
+++ Zend/zend_language_scanner.l 11 Mar 2005 21:53:04 -0000
@@ -1342,6 +1342,10 @@ NEWLINE ("\r"|"\n"|"\r\n")
return T_INLINE_HTML;
}
+<INITIAL>"<?php __HALT_PHP_PARSER__; ?>" {
+ yyterminate();
+}
+
<INITIAL>"<?"|"<script"{WHITESPACE}+"language"{WHITESPACE}*"="{WHITESPA
CE}*("php"|"\"php\""|"\'php\'"){WHITESPACE}*">" {
HANDLE_NEWLINES(yytext, yyleng);
if (CG(short_tags) || yyleng>2) { /* yyleng>2 means it's not <? but
<script> */
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php