PluginProbe
ManageWP Worker / 4.9.25
ManageWP Worker v4.9.25
4.9.38 4.9.37 4.9.36 4.9.35 4.9.34 3.8.7 3.8.8 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.18 3.9.19 3.9.2 3.9.20 3.9.21 3.9.22 3.9.23 3.9.24 All 73 releases
worker / src / PHPSecLib / File / ANSI.php

ANSI.php in ManageWP Worker 4.9.25, at src/PHPSecLib/File/ANSI.php

605 lines 21.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Pure-PHP ANSI Decoder
5 *
6 * PHP versions 4 and 5
7 *
8 * If you call read() in Net_SSH2 you may get {@link http://en.wikipedia.org/wiki/ANSI_escape_code ANSI escape codes} back.
9 * They'd look like chr(0x1B) . '[00m' or whatever (0x1B = ESC). They tell a
10 * {@link http://en.wikipedia.org/wiki/Terminal_emulator terminal emulator} how to format the characters, what
11 * color to display them in, etc. File_ANSI is a {@link http://en.wikipedia.org/wiki/VT100 VT100} terminal emulator.
12 *
13 * LICENSE: Permission is hereby granted, free of charge, to any person obtaining a copy
14 * of this software and associated documentation files (the "Software"), to deal
15 * in the Software without restriction, including without limitation the rights
16 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17 * copies of the Software, and to permit persons to whom the Software is
18 * furnished to do so, subject to the following conditions:
19 *
20 * The above copyright notice and this permission notice shall be included in
21 * all copies or substantial portions of the Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29 * THE SOFTWARE.
30 *
31 * @category File
32 * @package File_ANSI
33 * @author Jim Wigginton <terrafrost@php.net>
34 * @copyright MMXII Jim Wigginton
35 * @license http://www.opensource.org/licenses/mit-license.html MIT License
36 * @link http://phpseclib.sourceforge.net
37 */
38
39 /**
40 * Pure-PHP ANSI Decoder
41 *
42 * @package File_ANSI
43 * @author Jim Wigginton <terrafrost@php.net>
44 * @access public
45 */
46 class File_ANSI
47 {
48 /**
49 * Max Width
50 *
51 * @var Integer
52 * @access private
53 */
54 public $max_x;
55
56 /**
57 * Max Height
58 *
59 * @var Integer
60 * @access private
61 */
62 public $max_y;
63
64 /**
65 * Max History
66 *
67 * @var Integer
68 * @access private
69 */
70 public $max_history;
71
72 /**
73 * History
74 *
75 * @var Array
76 * @access private
77 */
78 public $history;
79
80 /**
81 * History Attributes
82 *
83 * @var Array
84 * @access private
85 */
86 public $history_attrs;
87
88 /**
89 * Current Column
90 *
91 * @var Integer
92 * @access private
93 */
94 public $x;
95
96 /**
97 * Current Row
98 *
99 * @var Integer
100 * @access private
101 */
102 public $y;
103
104 /**
105 * Old Column
106 *
107 * @var Integer
108 * @access private
109 */
110 public $old_x;
111
112 /**
113 * Old Row
114 *
115 * @var Integer
116 * @access private
117 */
118 public $old_y;
119
120 /**
121 * An empty attribute row
122 *
123 * @var Array
124 * @access private
125 */
126 public $attr_row;
127
128 /**
129 * The current screen text
130 *
131 * @var Array
132 * @access private
133 */
134 public $screen;
135
136 /**
137 * The current screen attributes
138 *
139 * @var Array
140 * @access private
141 */
142 public $attrs;
143
144 /**
145 * The current foreground color
146 *
147 * @var String
148 * @access private
149 */
150 public $foreground;
151
152 /**
153 * The current background color
154 *
155 * @var String
156 * @access private
157 */
158 public $background;
159
160 /**
161 * Bold flag
162 *
163 * @var Boolean
164 * @access private
165 */
166 public $bold;
167
168 /**
169 * Underline flag
170 *
171 * @var Boolean
172 * @access private
173 */
174 public $underline;
175
176 /**
177 * Blink flag
178 *
179 * @var Boolean
180 * @access private
181 */
182 public $blink;
183
184 /**
185 * Reverse flag
186 *
187 * @var Boolean
188 * @access private
189 */
190 public $reverse;
191
192 /**
193 * Color flag
194 *
195 * @var Boolean
196 * @access private
197 */
198 public $color;
199
200 /**
201 * Current ANSI code
202 *
203 * @var String
204 * @access private
205 */
206 public $ansi;
207
208 /**
209 * Default Constructor.
210 *
211 * @return File_ANSI
212 * @access public
213 */
214 public function __construct()
215 {
216 $this->setHistory(200);
217 $this->setDimensions(80, 24);
218 }
219
220 /**
221 * Set terminal width and height
222 *
223 * Resets the screen as well
224 *
225 * @param Integer $x
226 * @param Integer $y
227 *
228 * @access public
229 */
230 public function setDimensions($x, $y)
231 {
232 $this->max_x = $x - 1;
233 $this->max_y = $y - 1;
234 $this->x = $this->y = 0;
235 $this->history = $this->history_attrs = array();
236 $this->attr_row = array_fill(0, $this->max_x + 1, '');
237 $this->screen = array_fill(0, $this->max_y + 1, '');
238 $this->attrs = array_fill(0, $this->max_y + 1, $this->attr_row);
239 $this->foreground = 'white';
240 $this->background = 'black';
241 $this->bold = false;
242 $this->underline = false;
243 $this->blink = false;
244 $this->reverse = false;
245 $this->color = false;
246
247 $this->ansi = '';
248 }
249
250 /**
251 * Set the number of lines that should be logged past the terminal height
252 *
253 * @param Integer $x
254 * @param Integer $y
255 *
256 * @access public
257 */
258 public function setHistory($history)
259 {
260 $this->max_history = $history;
261 }
262
263 /**
264 * Load a string
265 *
266 * @param String $source
267 *
268 * @access public
269 */
270 public function loadString($source)
271 {
272 $this->setDimensions($this->max_x + 1, $this->max_y + 1);
273 $this->appendString($source);
274 }
275
276 /**
277 * Appdend a string
278 *
279 * @param String $source
280 *
281 * @access public
282 */
283 public function appendString($source)
284 {
285 for ($i = 0; $i < strlen($source); $i++) {
286 if (strlen($this->ansi)) {
287 $this->ansi .= $source[$i];
288 $chr = ord($source[$i]);
289 // http://en.wikipedia.org/wiki/ANSI_escape_code#Sequence_elements
290 // single character CSI's not currently supported
291 switch (true) {
292 case $this->ansi == "\x1B=":
293 $this->ansi = '';
294 continue 2;
295 case strlen($this->ansi) == 2 && $chr >= 64 && $chr <= 95 && $chr != ord('['):
296 case strlen($this->ansi) > 2 && $chr >= 64 && $chr <= 126:
297 break;
298 default:
299 continue 2;
300 }
301 // http://ascii-table.com/ansi-escape-sequences-vt-100.php
302 switch ($this->ansi) {
303 case "\x1B[H": // Move cursor to upper left corner
304 $this->old_x = $this->x;
305 $this->old_y = $this->y;
306 $this->x = $this->y = 0;
307 break;
308 case "\x1B[J": // Clear screen from cursor down
309 $this->history = array_merge($this->history, array_slice(array_splice($this->screen, $this->y + 1), 0, $this->old_y));
310 $this->screen = array_merge($this->screen, array_fill($this->y, $this->max_y, ''));
311
312 $this->history_attrs = array_merge($this->history_attrs, array_slice(array_splice($this->attrs, $this->y + 1), 0, $this->old_y));
313 $this->attrs = array_merge($this->attrs, array_fill($this->y, $this->max_y, $this->attr_row));
314
315 if (count($this->history) == $this->max_history) {
316 array_shift($this->history);
317 array_shift($this->history_attrs);
318 }
319 case "\x1B[K": // Clear screen from cursor right
320 $this->screen[$this->y] = substr($this->screen[$this->y], 0, $this->x);
321
322 array_splice($this->attrs[$this->y], $this->x + 1);
323 break;
324 case "\x1B[2K": // Clear entire line
325 $this->screen[$this->y] = str_repeat(' ', $this->x);
326 $this->attrs[$this->y] = $this->attr_row;
327 break;
328 case "\x1B[?1h": // set cursor key to application
329 case "\x1B[?25h": // show the cursor
330 break;
331 case "\x1BE": // Move to next line
332 $this->_newLine();
333 $this->x = 0;
334 break;
335 default:
336 switch (true) {
337 case preg_match('#\x1B\[(\d+);(\d+)H#', $this->ansi, $match): // Move cursor to screen location v,h
338 $this->old_x = $this->x;
339 $this->old_y = $this->y;
340 $this->x = $match[2] - 1;
341 $this->y = $match[1] - 1;
342 break;
343 case preg_match('#\x1B\[(\d+)C#', $this->ansi, $match): // Move cursor right n lines
344 $this->old_x = $this->x;
345 $x = $match[1] - 1;
346 break;
347 case preg_match('#\x1B\[(\d+);(\d+)r#', $this->ansi, $match): // Set top and bottom lines of a window
348 break;
349 case preg_match('#\x1B\[(\d*(?:;\d*)*)m#', $this->ansi, $match): // character attributes
350 $mods = explode(';', $match[1]);
351 foreach ($mods as $mod) {
352 switch ($mod) {
353 case 0: // Turn off character attributes
354 $this->attrs[$this->y][$this->x] = '';
355
356 if ($this->bold) {
357 $this->attrs[$this->y][$this->x] .= '</b>';
358 }
359 if ($this->underline) {
360 $this->attrs[$this->y][$this->x] .= '</u>';
361 }
362 if ($this->blink) {
363 $this->attrs[$this->y][$this->x] .= '</blink>';
364 }
365 if ($this->color) {
366 $this->attrs[$this->y][$this->x] .= '</span>';
367 }
368
369 if ($this->reverse) {
370 $temp = $this->background;
371 $this->background = $this->foreground;
372 $this->foreground = $temp;
373 }
374
375 $this->bold = $this->underline = $this->blink = $this->color = $this->reverse = false;
376 break;
377 case 1: // Turn bold mode on
378 if (!$this->bold) {
379 $this->attrs[$this->y][$this->x] = '<b>';
380 $this->bold = true;
381 }
382 break;
383 case 4: // Turn underline mode on
384 if (!$this->underline) {
385 $this->attrs[$this->y][$this->x] = '<u>';
386 $this->underline = true;
387 }
388 break;
389 case 5: // Turn blinking mode on
390 if (!$this->blink) {
391 $this->attrs[$this->y][$this->x] = '<blink>';
392 $this->blink = true;
393 }
394 break;
395 case 7: // Turn reverse video on
396 $this->reverse = !$this->reverse;
397 $temp = $this->background;
398 $this->background = $this->foreground;
399 $this->foreground = $temp;
400 $this->attrs[$this->y][$this->x] = '<span style="color: '.$this->foreground.'; background: '.$this->background.'">';
401 if ($this->color) {
402 $this->attrs[$this->y][$this->x] = '</span>'.$this->attrs[$this->y][$this->x];
403 }
404 $this->color = true;
405 break;
406 default: // set colors
407 //$front = $this->reverse ? &$this->background : &$this->foreground;
408 $front = &$this->{$this->reverse ? 'background' : 'foreground'};
409 //$back = $this->reverse ? &$this->foreground : &$this->background;
410 $back = &$this->{$this->reverse ? 'foreground' : 'background'};
411 switch ($mod) {
412 case 30:
413 $front = 'black';
414 break;
415 case 31:
416 $front = 'red';
417 break;
418 case 32:
419 $front = 'green';
420 break;
421 case 33:
422 $front = 'yellow';
423 break;
424 case 34:
425 $front = 'blue';
426 break;
427 case 35:
428 $front = 'magenta';
429 break;
430 case 36:
431 $front = 'cyan';
432 break;
433 case 37:
434 $front = 'white';
435 break;
436
437 case 40:
438 $back = 'black';
439 break;
440 case 41:
441 $back = 'red';
442 break;
443 case 42:
444 $back = 'green';
445 break;
446 case 43:
447 $back = 'yellow';
448 break;
449 case 44:
450 $back = 'blue';
451 break;
452 case 45:
453 $back = 'magenta';
454 break;
455 case 46:
456 $back = 'cyan';
457 break;
458 case 47:
459 $back = 'white';
460 break;
461
462 default:
463 user_error('Unsupported attribute: '.$mod);
464 $this->ansi = '';
465 break 2;
466 }
467
468 unset($temp);
469 $this->attrs[$this->y][$this->x] = '<span style="color: '.$this->foreground.'; background: '.$this->background.'">';
470 if ($this->color) {
471 $this->attrs[$this->y][$this->x] = '</span>'.$this->attrs[$this->y][$this->x];
472 }
473 $this->color = true;
474 }
475 }
476 break;
477 default:
478 user_error("{$this->ansi} unsupported\r\n");
479 }
480 }
481 $this->ansi = '';
482 continue;
483 }
484
485 switch ($source[$i]) {
486 case "\r":
487 $this->x = 0;
488 break;
489 case "\n":
490 $this->_newLine();
491 break;
492 case "\x0F": // shift
493 break;
494 case "\x1B": // start ANSI escape code
495 $this->ansi .= "\x1B";
496 break;
497 default:
498 $this->screen[$this->y] = substr_replace(
499 $this->screen[$this->y],
500 $source[$i],
501 $this->x,
502 1
503 );
504
505 if ($this->x > $this->max_x) {
506 $this->x = 0;
507 $this->y++;
508 } else {
509 $this->x++;
510 }
511 }
512 }
513 }
514
515 /**
516 * Add a new line
517 *
518 * Also update the $this->screen and $this->history buffers
519 *
520 * @access private
521 */
522 public function _newLine()
523 {
524 //if ($this->y < $this->max_y) {
525 // $this->y++;
526 //}
527
528 while ($this->y >= $this->max_y) {
529 $this->history = array_merge($this->history, array(array_shift($this->screen)));
530 $this->screen[] = '';
531
532 $this->history_attrs = array_merge($this->history_attrs, array(array_shift($this->attrs)));
533 $this->attrs[] = $this->attr_row;
534
535 if (count($this->history) >= $this->max_history) {
536 array_shift($this->history);
537 array_shift($this->history_attrs);
538 }
539
540 $this->y--;
541 }
542 $this->y++;
543 }
544
545 /**
546 * Returns the current screen without preformating
547 *
548 * @access private
549 * @return String
550 */
551 public function _getScreen()
552 {
553 $output = '';
554 for ($i = 0; $i <= $this->max_y; $i++) {
555 for ($j = 0; $j <= $this->max_x + 1; $j++) {
556 if (isset($this->attrs[$i][$j])) {
557 $output .= $this->attrs[$i][$j];
558 }
559 if (isset($this->screen[$i][$j])) {
560 $output .= htmlspecialchars($this->screen[$i][$j]);
561 }
562 }
563 $output .= "\r\n";
564 }
565
566 return rtrim($output);
567 }
568
569 /**
570 * Returns the current screen
571 *
572 * @access public
573 * @return String
574 */
575 public function getScreen()
576 {
577 return '<pre style="color: white; background: black" width="'.($this->max_x + 1).'">'.$this->_getScreen().'</pre>';
578 }
579
580 /**
581 * Returns the current screen and the x previous lines
582 *
583 * @access public
584 * @return String
585 */
586 public function getHistory()
587 {
588 $scrollback = '';
589 for ($i = 0; $i < count($this->history); $i++) {
590 for ($j = 0; $j <= $this->max_x + 1; $j++) {
591 if (isset($this->history_attrs[$i][$j])) {
592 $scrollback .= $this->history_attrs[$i][$j];
593 }
594 if (isset($this->history[$i][$j])) {
595 $scrollback .= htmlspecialchars($this->history[$i][$j]);
596 }
597 }
598 $scrollback .= "\r\n";
599 }
600 $scrollback .= $this->_getScreen();
601
602 return '<pre style="color: white; background: black" width="'.($this->max_x + 1).'">'.$scrollback.'</pre>';
603 }
604 }
605