Coverage Report

Created: 2025-09-27 06:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/Zend/zend_highlight.c
Line
Count
Source
1
/*
2
   +----------------------------------------------------------------------+
3
   | Zend Engine                                                          |
4
   +----------------------------------------------------------------------+
5
   | Copyright (c) Zend Technologies Ltd. (http://www.zend.com)           |
6
   +----------------------------------------------------------------------+
7
   | This source file is subject to version 2.00 of the Zend license,     |
8
   | that is bundled with this package in the file LICENSE, and is        |
9
   | available through the world-wide-web at the following url:           |
10
   | http://www.zend.com/license/2_00.txt.                                |
11
   | If you did not receive a copy of the Zend license and are unable to  |
12
   | obtain it through the world-wide-web, please send a note to          |
13
   | license@zend.com so we can mail you a copy immediately.              |
14
   +----------------------------------------------------------------------+
15
   | Authors: Andi Gutmans <andi@php.net>                                 |
16
   |          Zeev Suraski <zeev@php.net>                                 |
17
   +----------------------------------------------------------------------+
18
*/
19
20
#include "zend.h"
21
#include <zend_language_parser.h>
22
#include "zend_compile.h"
23
#include "zend_highlight.h"
24
#include "zend_ptr_stack.h"
25
#include "zend_globals.h"
26
#include "zend_exceptions.h"
27
28
ZEND_API void zend_html_putc(char c)
29
34.2M
{
30
34.2M
  switch (c) {
31
743k
    case '<':
32
743k
      ZEND_PUTS("&lt;");
33
743k
      break;
34
106k
    case '>':
35
106k
      ZEND_PUTS("&gt;");
36
106k
      break;
37
72.3k
    case '&':
38
72.3k
      ZEND_PUTS("&amp;");
39
72.3k
      break;
40
201k
    case '\t':
41
201k
      ZEND_PUTS("    ");
42
201k
      break;
43
33.0M
    default:
44
33.0M
      ZEND_PUTC(c);
45
33.0M
      break;
46
34.2M
  }
47
34.2M
}
48
49
50
ZEND_API void zend_html_puts(const char *s, size_t len)
51
6.82M
{
52
6.82M
  const unsigned char *ptr = (const unsigned char*)s, *end = ptr + len;
53
6.82M
  unsigned char *filtered = NULL;
54
6.82M
  size_t filtered_len;
55
56
6.82M
  if (LANG_SCNG(output_filter)) {
57
0
    LANG_SCNG(output_filter)(&filtered, &filtered_len, ptr, len);
58
0
    ptr = filtered;
59
0
    end = filtered + filtered_len;
60
0
  }
61
62
39.9M
  while (ptr<end) {
63
33.1M
    if (*ptr==' ') {
64
2.73M
      do {
65
2.73M
        zend_html_putc(*ptr);
66
2.73M
      } while ((++ptr < end) && (*ptr==' '));
67
31.4M
    } else {
68
31.4M
      zend_html_putc(*ptr++);
69
31.4M
    }
70
33.1M
  }
71
72
6.82M
  if (LANG_SCNG(output_filter)) {
73
0
    efree(filtered);
74
0
  }
75
6.82M
}
76
77
78
ZEND_API void zend_highlight(zend_syntax_highlighter_ini *syntax_highlighter_ini)
79
22.1k
{
80
22.1k
  zval token;
81
22.1k
  int token_type;
82
22.1k
  char *last_color = syntax_highlighter_ini->highlight_html;
83
22.1k
  char *next_color;
84
85
22.1k
  zend_printf("<pre><code style=\"color: %s\">", last_color);
86
  /* highlight stuff coming back from zendlex() */
87
6.84M
  while ((token_type=lex_scan(&token, NULL))) {
88
6.82M
    switch (token_type) {
89
24.0k
      case T_INLINE_HTML:
90
24.0k
        next_color = syntax_highlighter_ini->highlight_html;
91
24.0k
        break;
92
60.2k
      case T_COMMENT:
93
62.5k
      case T_DOC_COMMENT:
94
62.5k
        next_color = syntax_highlighter_ini->highlight_comment;
95
62.5k
        break;
96
24.7k
      case T_OPEN_TAG:
97
25.0k
      case T_OPEN_TAG_WITH_ECHO:
98
30.5k
      case T_CLOSE_TAG:
99
30.6k
      case T_LINE:
100
30.7k
      case T_FILE:
101
30.8k
      case T_DIR:
102
31.0k
      case T_TRAIT_C:
103
31.8k
      case T_METHOD_C:
104
32.1k
      case T_FUNC_C:
105
32.2k
      case T_PROPERTY_C:
106
32.9k
      case T_NS_C:
107
33.2k
      case T_CLASS_C:
108
33.2k
        next_color = syntax_highlighter_ini->highlight_default;
109
33.2k
        break;
110
11.2k
      case '"':
111
55.2k
      case T_ENCAPSED_AND_WHITESPACE:
112
148k
      case T_CONSTANT_ENCAPSED_STRING:
113
148k
        next_color = syntax_highlighter_ini->highlight_string;
114
148k
        break;
115
990k
      case T_WHITESPACE:
116
990k
        zend_html_puts((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));  /* no color needed */
117
990k
        ZVAL_UNDEF(&token);
118
990k
        continue;
119
0
        break;
120
5.56M
      default:
121
5.56M
        if (Z_TYPE(token) == IS_UNDEF) {
122
4.24M
          next_color = syntax_highlighter_ini->highlight_keyword;
123
4.24M
        } else {
124
1.31M
          next_color = syntax_highlighter_ini->highlight_default;
125
1.31M
        }
126
5.56M
        break;
127
6.82M
    }
128
129
5.83M
    if (last_color != next_color) {
130
2.49M
      if (last_color != syntax_highlighter_ini->highlight_html) {
131
2.46M
        zend_printf("</span>");
132
2.46M
      }
133
2.49M
      last_color = next_color;
134
2.49M
      if (last_color != syntax_highlighter_ini->highlight_html) {
135
2.48M
        zend_printf("<span style=\"color: %s\">", last_color);
136
2.48M
      }
137
2.49M
    }
138
139
5.83M
    zend_html_puts((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
140
141
5.83M
    if (Z_TYPE(token) == IS_STRING) {
142
1.24M
      switch (token_type) {
143
0
        case T_OPEN_TAG:
144
0
        case T_OPEN_TAG_WITH_ECHO:
145
0
        case T_CLOSE_TAG:
146
0
        case T_WHITESPACE:
147
0
        case T_COMMENT:
148
0
        case T_DOC_COMMENT:
149
0
          break;
150
1.24M
        default:
151
1.24M
          zval_ptr_dtor_str(&token);
152
1.24M
          break;
153
1.24M
      }
154
1.24M
    }
155
5.83M
    ZVAL_UNDEF(&token);
156
5.83M
  }
157
158
22.1k
  if (last_color != syntax_highlighter_ini->highlight_html) {
159
19.5k
    zend_printf("</span>");
160
19.5k
  }
161
22.1k
  zend_printf("</code></pre>");
162
163
  /* Discard parse errors thrown during tokenization */
164
22.1k
  zend_clear_exception();
165
22.1k
}
166
167
ZEND_API void zend_strip(void)
168
0
{
169
0
  zval token;
170
0
  int token_type;
171
0
  int prev_space = 0;
172
173
0
  while ((token_type=lex_scan(&token, NULL))) {
174
0
    switch (token_type) {
175
0
      case T_WHITESPACE:
176
0
        if (!prev_space) {
177
0
          zend_write(" ", sizeof(" ") - 1);
178
0
          prev_space = 1;
179
0
        }
180
0
        ZEND_FALLTHROUGH;
181
0
      case T_COMMENT:
182
0
      case T_DOC_COMMENT:
183
0
        ZVAL_UNDEF(&token);
184
0
        continue;
185
186
0
      case T_END_HEREDOC:
187
0
        zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
188
        /* read the following character, either newline or ; */
189
0
        if (lex_scan(&token, NULL) != T_WHITESPACE) {
190
0
          zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
191
0
        }
192
0
        zend_write("\n", sizeof("\n") - 1);
193
0
        prev_space = 1;
194
0
        ZVAL_UNDEF(&token);
195
0
        continue;
196
197
0
      default:
198
0
        zend_write((char*)LANG_SCNG(yy_text), LANG_SCNG(yy_leng));
199
0
        break;
200
0
    }
201
202
0
    if (Z_TYPE(token) == IS_STRING) {
203
0
      switch (token_type) {
204
0
        case T_OPEN_TAG:
205
0
        case T_OPEN_TAG_WITH_ECHO:
206
0
        case T_CLOSE_TAG:
207
0
        case T_WHITESPACE:
208
0
        case T_COMMENT:
209
0
        case T_DOC_COMMENT:
210
0
          break;
211
212
0
        default:
213
0
          zval_ptr_dtor_str(&token);
214
0
          break;
215
0
      }
216
0
    }
217
0
    prev_space = 0;
218
0
    ZVAL_UNDEF(&token);
219
0
  }
220
221
  /* Discard parse errors thrown during tokenization */
222
0
  zend_clear_exception();
223
0
}