Attached file, implements validate_file(), which implements a php space syntax 
check for PHP scripts. It returns a boolean true/false value indicating 
whether the script has parse errors or not. Essentially a "php -l" from 
within PHP.

strip_file() is added for completion (might as well :) ) and implements "php 
-w", which strips comments & whitespace from a PHP file. A quick obfuscater 
of sorts.

Any comments?

Ilia
Index: basic_functions.c
===================================================================
RCS file: /repository/php-src/ext/standard/basic_functions.c,v
retrieving revision 1.543.2.22
diff -u -3 -p -r1.543.2.22 basic_functions.c
--- basic_functions.c   29 Sep 2003 14:02:55 -0000      1.543.2.22
+++ basic_functions.c   3 Oct 2003 00:56:51 -0000
@@ -32,6 +32,72 @@
 #include "ext/session/php_session.h"
 #include "zend_operators.h"
 
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+typedef unsigned int yy_size_t;
+struct yy_buffer_state
+       {
+       FILE *yy_input_file;
+ 
+       char *yy_ch_buf;   /* input buffer */
+       char *yy_buf_pos;  /* current position in input buffer */
+ 
+       /* Size of input buffer in bytes, not including room for EOB
+        * characters.
+        */
+       yy_size_t yy_buf_size;
+ 
+       /* Number of characters read into yy_ch_buf, not including EOB
+        * characters.
+        */
+       int yy_n_chars;
+ 
+       /* Whether we "own" the buffer - i.e., we know we created it,
+        * and can realloc() it to grow it, and should free() it to
+        * delete it.
+        */
+       int yy_is_our_buffer;
+ 
+       /* Whether this is an "interactive" input source; if so, and
+        * if we're using stdio for input, then we want to use getc()
+        * instead of fread(), to make sure we stop fetching input after
+        * each newline.
+        */
+       int yy_is_interactive;
+ 
+       /* Whether we're considered to be at the beginning of a line.
+        * If so, '^' rules will be active on the next match, otherwise
+        * not.
+        */
+       int yy_at_bol;
+ 
+       /* Whether to try to fill the input buffer when we reach the
+        * end of it.
+        */
+       int yy_fill_buffer;
+ 
+       int yy_buffer_status;
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+       /* When an EOF's been seen but there's still some text to process
+        * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+        * shouldn't try reading from the input source any more.  We might
+        * still have a bunch of tokens to match, though, because of
+        * possible backing-up.
+        *
+        * When we actually see the EOF, we change the status to "new"
+        * (via yyrestart()), so that the user can continue scanning by
+        * just pointing yyin at a new input file.
+        */
+#define YY_BUFFER_EOF_PENDING 2
+       };
+
+#include "zend.h"
+#include "zend_language_scanner.h"
+#include "zend_language_parser.h"
+
+#define zendtext LANG_SCNG(yy_text)
+#define zendleng LANG_SCNG(yy_leng)
+
 #include <stdarg.h>
 #include <stdlib.h>
 #include <math.h>
@@ -561,6 +627,8 @@ function_entry basic_functions[] = {
        PHP_FE(highlight_file,                                                         
                                         NULL)
        PHP_FALIAS(show_source,                 highlight_file,                        
                         NULL)
        PHP_FE(highlight_string,                                                       
                                         NULL)
+       PHP_FE(strip_file,                                                             
                                 NULL)
+       PHP_FE(validate_file,                                                          
                                 NULL)
 
        PHP_FE(ini_get,                                                                
                                                 NULL)
        PHP_FE(ini_get_all,                                                            
                                                 NULL)
@@ -2179,6 +2247,107 @@ PHP_FUNCTION(highlight_file)
 }
 /* }}} */
 
+/* {{{ proto string strip_file(string file_name)
+   Return source with stripped comments and whitespace */
+PHP_FUNCTION(strip_file)
+{
+       char *filename;
+       int filename_len;
+       zend_lex_state original_lex_state;
+       zend_file_handle file_handle = {0};
+       char resolved_path[MAXPATHLEN];
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, 
&filename_len) == FAILURE) {
+               RETURN_FALSE;
+       }
+
+       if (!VCWD_REALPATH(filename, resolved_path)) {
+               RETURN_FALSE;
+       }
+
+       if (PG(safe_mode) && (!php_checkuid(resolved_path, NULL, 
CHECKUID_ALLOW_ONLY_FILE))) {
+               RETURN_FALSE;
+       }
+
+       if (php_check_open_basedir(resolved_path TSRMLS_CC)) {
+               RETURN_FALSE;
+       }
+
+       php_start_ob_buffer(NULL, 0, 1 TSRMLS_CC);
+
+       file_handle.type = ZEND_HANDLE_FILENAME;
+       file_handle.filename = resolved_path;
+       file_handle.free_filename = 0;
+       file_handle.opened_path = NULL;
+       zend_save_lexical_state(&original_lex_state TSRMLS_CC);
+       if (open_file_for_scanning(&file_handle TSRMLS_CC)==FAILURE) {
+               RETURN_EMPTY_STRING();
+       }
+
+       zend_strip(TSRMLS_C);
+       
+       zend_destroy_file_handle(&file_handle TSRMLS_CC);
+       zend_restore_lexical_state(&original_lex_state TSRMLS_CC);
+
+       php_ob_get_buffer(return_value TSRMLS_CC);
+       php_end_ob_buffer(0, 0 TSRMLS_CC);
+
+       return;
+}
+/* }}} */
+
+/* {{{ proto bool validate_file(string file_name)
+   Check the syntax of the specified file. */
+PHP_FUNCTION(validate_file)
+{
+       char *filename;
+       int filename_len;
+       zend_file_handle file_handle = {0};
+       char resolved_path[MAXPATHLEN];
+       zend_lex_state original_lex_state;
+       
+       int old_errors = PG(display_errors);
+       int old_track_errors = PG(track_errors);
+       int log_errors = PG(log_errors);
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, 
&filename_len) == FAILURE) {
+               RETURN_FALSE;
+       }
+
+       if (!VCWD_REALPATH(filename, resolved_path)) {
+               RETURN_FALSE;
+       }
+
+       if (PG(safe_mode) && (!php_checkuid(resolved_path, NULL, 
CHECKUID_ALLOW_ONLY_FILE))) {
+               RETURN_FALSE;
+       }
+
+       if (php_check_open_basedir(resolved_path TSRMLS_CC)) {
+               RETURN_FALSE;
+       }
+
+       file_handle.type = ZEND_HANDLE_FILENAME;
+       file_handle.filename = resolved_path;
+       file_handle.free_filename = 0;
+       file_handle.opened_path = NULL; 
+
+       PG(log_errors) = PG(display_errors) = 0;
+       PG(track_errors) = 1;
+
+       if (php_lint_script(&file_handle TSRMLS_CC) != SUCCESS) {
+               RETVAL_FALSE;
+       } else {
+               RETVAL_TRUE;
+       }
+
+       PG(display_errors) = old_errors;
+       PG(log_errors) = log_errors;
+       PG(track_errors) = old_track_errors;
+
+       return;
+}
+/* }}} */
+
 /* {{{ proto bool highlight_string(string string [, bool return] )
    Syntax highlight a string or optionally return it */
 PHP_FUNCTION(highlight_string)
@@ -2187,6 +2356,7 @@ PHP_FUNCTION(highlight_string)
        zend_syntax_highlighter_ini syntax_highlighter_ini;
        char *hicompiled_string_description;
        zend_bool  i = 0;
+       int old_error_reporting = EG(error_reporting);
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|b", &expr, &i) == 
FAILURE) {
                RETURN_FALSE;
@@ -2197,6 +2367,8 @@ PHP_FUNCTION(highlight_string)
                php_start_ob_buffer (NULL, 0, 1 TSRMLS_CC);
        }
 
+       EG(error_reporting) = E_ERROR;
+
        php_get_highlight_struct(&syntax_highlighter_ini);
 
        hicompiled_string_description = 
zend_make_compiled_string_description("highlighted code" TSRMLS_CC);
@@ -2206,6 +2378,8 @@ PHP_FUNCTION(highlight_string)
                RETURN_FALSE;
        }
        efree(hicompiled_string_description);
+
+       EG(error_reporting) = old_error_reporting;
 
        if (i) {
                php_ob_get_buffer (return_value TSRMLS_CC);
Index: basic_functions.h
===================================================================
RCS file: /repository/php-src/ext/standard/basic_functions.h,v
retrieving revision 1.109.2.1
diff -u -3 -p -r1.109.2.1 basic_functions.h
--- basic_functions.h   31 Dec 2002 16:35:25 -0000      1.109.2.1
+++ basic_functions.h   3 Oct 2003 00:56:51 -0000
@@ -72,6 +72,8 @@ PHP_FUNCTION(call_user_method_array);
 PHP_FUNCTION(register_shutdown_function);
 PHP_FUNCTION(highlight_file);
 PHP_FUNCTION(highlight_string);
+PHP_FUNCTION(strip_file);
+PHP_FUNCTION(validate_file);
 ZEND_API void php_get_highlight_struct(zend_syntax_highlighter_ini 
*syntax_highlighter_ini);
 
 PHP_FUNCTION(ini_get);

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to