PHP词法解析源码分析之PHP标签、关键字、类、数字

之前没搞过web端的程序,最近要研究webshell,发现php的语法太怪异了,干脆直接看看PHP内核词法分析的代码。

php的词法分析从zend_language_scanner.l文件中的lex_scan开始,开头代码如下:

int lex_scan(zval *zendlval TSRMLS_DC)
{
//设置当前token的首位置为当前位置
restart:
    SCNG(yy_text) = YYCURSOR;

yymore_restart:
//这段注释定义了各个类型的正则表达式匹配,在词法解析程序(如bison、re2c等)程序将本文件转化为c代码时会用到
/*!re2c
re2c:yyfill:check = 0;
LNUM    [0-9]+
DNUM    ([0-9]*"."[0-9]+)|([0-9]+"."[0-9]*)
EXPONENT_DNUM    (({LNUM}|{DNUM})[eE][+-]?{LNUM})
HNUM    "0x"[0-9a-fA-F]+
BNUM    "0b"[01]+
LABEL    [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
WHITESPACE [ \n\r\t]+
TABS_AND_SPACES [ \t]*
TOKENS [;:,.\[\]()|^&+-/*=%!~$<>?@]
ANY_CHAR [^]
NEWLINE ("\r"|"\n"|"\r\n")

/* compute yyleng before each rule */
<!*> := yyleng = YYCURSOR - SCNG(yy_text);

接下去就按照解析PHP标签、关键字、类和结构体、数字这几个方面来看lex_scan是如何解析PHP代码的。

1.匹配php标签

在zend_language_scanner.l文件里会匹配php的标签,并且匹配规则不止一种,打开了asp_tag开关还能兼容asp脚本,比较奇特。

1.1 <script language=php>

首先是匹配<script language=php>标签,源码如下,无论这里面有多少个空白字符全部无视,最后php也可以加上单引号或双引号:

<INITIAL>"<script"{WHITESPACE}+"language"{WHITESPACE}*"="{WHITESPACE}*("php"|"\"php\""|"'php'"){WHITESPACE}*">" {
    YYCTYPE *bracket = (YYCTYPE*)zend_memrchr(yytext, '<', yyleng - (sizeof("script language=php>") - 1));

    if (bracket != SCNG(yy_text)) {
        /* Handle previously scanned HTML, as possible <script> tags found are assumed to not be PHP's */
        YYCURSOR = bracket;
        goto inline_html;
    }

    HANDLE_NEWLINES(yytext, yyleng);
    ZVAL_STRINGL(zendlval, yytext, yyleng, 0); /* no copying - intentional */
    BEGIN(ST_IN_SCRIPTING);
    return T_OPEN_TAG;
}

因为<script>标签本身是在html中的,所以判断当前是否在扫描html,如果是的话就跳转到inline_html去,不然就将当前状态改为ST_IN_SCRIPTING并返回T_OPEN_TAG,表示这是一个php的标签。

1.2 <%=和<%

如果不是这个还会在匹配<%=和<%,匹配到时便会检查php.ini里面的asp_tags标签是否为On,如果是则表示进入脚本并返回T_OPEN_TAG,否则就转到inline_char_handler去执行,源码如下:

//<INITIAL>"<%=" {
   
<INITIAL>
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值