PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LCOV - code coverage report
Current view: top level - sapi/phpdbg - phpdbg_out.c (source / functions) Hit Total Coverage
Test: PHP Code Coverage Lines: 277 684 40.5 %
Date: 2018-09-22 Functions: 13 18 72.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :    +----------------------------------------------------------------------+
       3             :    | PHP Version 7                                                        |
       4             :    +----------------------------------------------------------------------+
       5             :    | Copyright (c) 1997-2018 The PHP Group                                |
       6             :    +----------------------------------------------------------------------+
       7             :    | This source file is subject to version 3.01 of the PHP 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.php.net/license/3_01.txt                                  |
      11             :    | If you did not receive a copy of the PHP license and are unable to   |
      12             :    | obtain it through the world-wide-web, please send a note to          |
      13             :    | license@php.net so we can mail you a copy immediately.               |
      14             :    +----------------------------------------------------------------------+
      15             :    | Authors: Felipe Pena <felipe@php.net>                                |
      16             :    | Authors: Joe Watkins <joe.watkins@live.co.uk>                        |
      17             :    | Authors: Bob Weinand <bwoebi@php.net>                                |
      18             :    +----------------------------------------------------------------------+
      19             : */
      20             : 
      21             : #include "zend.h"
      22             : #include "php.h"
      23             : #include "spprintf.h"
      24             : #include "phpdbg.h"
      25             : #include "phpdbg_io.h"
      26             : #include "phpdbg_eol.h"
      27             : #include "ext/standard/html.h"
      28             : 
      29             : #ifdef _WIN32
      30             : #       include "win32/time.h"
      31             : #endif
      32             : 
      33             : ZEND_EXTERN_MODULE_GLOBALS(phpdbg)
      34             : 
      35             : /* copied from php-src/main/snprintf.c and slightly modified */
      36             : /*
      37             :  * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions
      38             :  *
      39             :  * XXX: this is a magic number; do not decrease it
      40             :  * Emax = 1023
      41             :  * NDIG = 320
      42             :  * NUM_BUF_SIZE >= strlen("-") + Emax + strlrn(".") + NDIG + strlen("E+1023") + 1;
      43             :  */
      44             : #define NUM_BUF_SIZE        2048
      45             : 
      46             : /*
      47             :  * Descriptor for buffer area
      48             :  */
      49             : struct buf_area {
      50             :         char *buf_end;
      51             :         char *nextb; /* pointer to next byte to read/write   */
      52             : };
      53             : 
      54             : typedef struct buf_area buffy;
      55             : 
      56             : /*
      57             :  * The INS_CHAR macro inserts a character in the buffer and writes
      58             :  * the buffer back to disk if necessary
      59             :  * It uses the char pointers sp and bep:
      60             :  *      sp points to the next available character in the buffer
      61             :  *      bep points to the end-of-buffer+1
      62             :  * While using this macro, note that the nextb pointer is NOT updated.
      63             :  *
      64             :  * NOTE: Evaluation of the c argument should not have any side-effects
      65             :  */
      66             : #define INS_CHAR(c, sp, bep, cc) \
      67             :         {                            \
      68             :                 if (sp < bep)            \
      69             :                 {                        \
      70             :                         *sp++ = c;           \
      71             :                 }                        \
      72             :                 cc++;                    \
      73             :         }
      74             : 
      75             : #define NUM( c )                        ( c - '0' )
      76             : 
      77             : #define STR_TO_DEC( str, num )          \
      78             :     num = NUM( *str++ ) ;               \
      79             :     while ( isdigit((int)*str ) )               \
      80             :     {                                   \
      81             :         num *= 10 ;                     \
      82             :         num += NUM( *str++ ) ;          \
      83             :     }
      84             : 
      85             : /*
      86             :  * This macro does zero padding so that the precision
      87             :  * requirement is satisfied. The padding is done by
      88             :  * adding '0's to the left of the string that is going
      89             :  * to be printed.
      90             :  */
      91             : #define FIX_PRECISION( adjust, precision, s, s_len )    \
      92             :     if ( adjust )                                       \
      93             :         while ( s_len < precision )                  \
      94             :         {                                               \
      95             :             *--s = '0' ;                                \
      96             :             s_len++ ;                                   \
      97             :         }
      98             : 
      99             : /*
     100             :  * Macro that does padding. The padding is done by printing
     101             :  * the character ch.
     102             :  */
     103             : #define PAD( width, len, ch )   do              \
     104             :         {                                       \
     105             :             INS_CHAR( ch, sp, bep, cc ) ;       \
     106             :             width-- ;                           \
     107             :         }                                       \
     108             :         while ( width > len )
     109             : 
     110             : /*
     111             :  * Prefix the character ch to the string str
     112             :  * Increase length
     113             :  * Set the has_prefix flag
     114             :  */
     115             : #define PREFIX( str, length, ch )        *--str = ch ; length++ ; has_prefix = YES
     116             : 
     117             : 
     118             : #ifdef HAVE_LOCALE_H
     119             : #include <locale.h>
     120             : #define LCONV_DECIMAL_POINT (*lconv->decimal_point)
     121             : #else
     122             : #define LCONV_DECIMAL_POINT '.'
     123             : #endif
     124             : #define NUL '\0'
     125             : #define S_NULL "(null)"
     126             : #define S_NULL_LEN 6
     127             : #define FLOAT_DIGITS 6
     128             : 
     129             : /*
     130             :  * Do format conversion placing the output in buffer
     131             :  */
     132        2896 : static int format_converter(register buffy *odp, const char *fmt, zend_bool escape_xml, va_list ap) {
     133             :         char *sp;
     134             :         char *bep;
     135        2896 :         int cc = 0;
     136             :         int i;
     137             : 
     138        2896 :         char *s = NULL, *free_s = NULL;
     139             :         size_t s_len;
     140             :         zend_bool free_zcopy;
     141             :         zval *zvp, zcopy;
     142             : 
     143        2896 :         int min_width = 0;
     144        2896 :         int precision = 0;
     145             :         enum {
     146             :                 LEFT, RIGHT
     147             :         } adjust;
     148             :         char pad_char;
     149             :         char prefix_char;
     150             : 
     151             :         double fp_num;
     152        2896 :         wide_int i_num = (wide_int) 0;
     153             :         u_wide_int ui_num;
     154             : 
     155             :         char num_buf[NUM_BUF_SIZE];
     156             :         char char_buf[2];                       /* for printing %% and %<unknown> */
     157             : 
     158             : #ifdef HAVE_LOCALE_H
     159        2896 :         struct lconv *lconv = NULL;
     160             : #endif
     161             : 
     162             :         /*
     163             :          * Flag variables
     164             :          */
     165             :         length_modifier_e modifier;
     166             :         boolean_e alternate_form;
     167             :         boolean_e print_sign;
     168             :         boolean_e print_blank;
     169             :         boolean_e adjust_precision;
     170             :         boolean_e adjust_width;
     171             :         bool_int is_negative;
     172             : 
     173        2896 :         sp = odp->nextb;
     174        2896 :         bep = odp->buf_end;
     175             : 
     176       26960 :         while (*fmt) {
     177       21168 :                 if (*fmt != '%') {
     178       17122 :                         INS_CHAR(*fmt, sp, bep, cc);
     179             :                 } else {
     180             :                         /*
     181             :                          * Default variable settings
     182             :                          */
     183        4046 :                         adjust = RIGHT;
     184        4046 :                         alternate_form = print_sign = print_blank = NO;
     185        4046 :                         pad_char = ' ';
     186        4046 :                         prefix_char = NUL;
     187        4046 :                         free_zcopy = 0;
     188             : 
     189        4046 :                         fmt++;
     190             : 
     191             :                         /*
     192             :                          * Try to avoid checking for flags, width or precision
     193             :                          */
     194        4046 :                         if (isascii((int)*fmt) && !islower((int)*fmt)) {
     195             :                                 /*
     196             :                                  * Recognize flags: -, #, BLANK, +
     197             :                                  */
     198         636 :                                 for (;; fmt++) {
     199        3604 :                                         if (*fmt == '-')
     200         236 :                                                 adjust = LEFT;
     201        2732 :                                         else if (*fmt == '+')
     202           0 :                                                 print_sign = YES;
     203        2732 :                                         else if (*fmt == '#')
     204           4 :                                                 alternate_form = YES;
     205        2728 :                                         else if (*fmt == ' ')
     206           0 :                                                 print_blank = YES;
     207        2728 :                                         else if (*fmt == '0')
     208         396 :                                                 pad_char = '0';
     209             :                                         else
     210        2332 :                                                 break;
     211             :                                 }
     212             : 
     213             :                                 /*
     214             :                                  * Check if a width was specified
     215             :                                  */
     216        2332 :                                 if (isdigit((int)*fmt)) {
     217         670 :                                         STR_TO_DEC(fmt, min_width);
     218         670 :                                         adjust_width = YES;
     219        1662 :                                 } else if (*fmt == '*') {
     220           0 :                                         min_width = va_arg(ap, int);
     221           0 :                                         fmt++;
     222           0 :                                         adjust_width = YES;
     223           0 :                                         if (min_width < 0) {
     224           0 :                                                 adjust = LEFT;
     225           0 :                                                 min_width = -min_width;
     226             :                                         }
     227             :                                 } else
     228        1662 :                                         adjust_width = NO;
     229             : 
     230             :                                 /*
     231             :                                  * Check if a precision was specified
     232             :                                  */
     233        4664 :                                 if (*fmt == '.') {
     234        1658 :                                         adjust_precision = YES;
     235        1658 :                                         fmt++;
     236        1658 :                                         if (isdigit((int)*fmt)) {
     237           0 :                                                 STR_TO_DEC(fmt, precision);
     238        1658 :                                         } else if (*fmt == '*') {
     239        1658 :                                                 precision = va_arg(ap, int);
     240        1658 :                                                 fmt++;
     241        1658 :                                                 if (precision < 0)
     242           0 :                                                         precision = 0;
     243             :                                         } else
     244           0 :                                                 precision = 0;
     245             : 
     246        1658 :                                         if (precision > FORMAT_CONV_MAX_PRECISION && *fmt != 's' && *fmt != 'v' && *fmt != 'b') {
     247           0 :                                                 precision = FORMAT_CONV_MAX_PRECISION;
     248             :                                         }
     249             :                                 } else
     250         674 :                                         adjust_precision = NO;
     251             :                         } else
     252        1714 :                                 adjust_precision = adjust_width = NO;
     253             : 
     254             :                         /*
     255             :                          * Modifier check
     256             :                          */
     257        4046 :                         switch (*fmt) {
     258           0 :                                 case 'L':
     259           0 :                                         fmt++;
     260           0 :                                         modifier = LM_LONG_DOUBLE;
     261           0 :                                         break;
     262           0 :                                 case 'I':
     263           0 :                                         fmt++;
     264             : #if SIZEOF_LONG_LONG
     265           0 :                                         if (*fmt == '6' && *(fmt+1) == '4') {
     266           0 :                                                 fmt += 2;
     267           0 :                                                 modifier = LM_LONG_LONG;
     268             :                                         } else
     269             : #endif
     270           0 :                                                 if (*fmt == '3' && *(fmt+1) == '2') {
     271           0 :                                                         fmt += 2;
     272           0 :                                                         modifier = LM_LONG;
     273             :                                                 } else {
     274             : #ifdef _WIN64
     275             :                                                         modifier = LM_LONG_LONG;
     276             : #else
     277           0 :                                                         modifier = LM_LONG;
     278             : #endif
     279             :                                                 }
     280           0 :                                         break;
     281         238 :                                 case 'l':
     282         238 :                                         fmt++;
     283             : #if SIZEOF_LONG_LONG
     284         238 :                                         if (*fmt == 'l') {
     285           0 :                                                 fmt++;
     286           0 :                                                 modifier = LM_LONG_LONG;
     287             :                                         } else
     288             : #endif
     289         238 :                                                 modifier = LM_LONG;
     290         238 :                                         break;
     291           2 :                                         case 'z':
     292           2 :                                         fmt++;
     293           2 :                                         modifier = LM_SIZE_T;
     294           2 :                                         break;
     295           0 :                                 case 'j':
     296           0 :                                         fmt++;
     297             : #if SIZEOF_INTMAX_T
     298           0 :                                         modifier = LM_INTMAX_T;
     299             : #else
     300             :                                         modifier = LM_SIZE_T;
     301             : #endif
     302           0 :                                         break;
     303           0 :                                 case 't':
     304           0 :                                         fmt++;
     305             : #if SIZEOF_PTRDIFF_T
     306           0 :                                         modifier = LM_PTRDIFF_T;
     307             : #else
     308             :                                         modifier = LM_SIZE_T;
     309             : #endif
     310           0 :                                         break;
     311           0 :                                 case 'h':
     312           0 :                                         fmt++;
     313           0 :                                         if (*fmt == 'h') {
     314           0 :                                                 fmt++;
     315             :                                         }
     316             :                                         /* these are promoted to int, so no break */
     317             :                                 default:
     318        3806 :                                         modifier = LM_STD;
     319        3806 :                                         break;
     320             :                         }
     321             : 
     322             :                         /*
     323             :                          * Argument extraction and printing.
     324             :                          * First we determine the argument type.
     325             :                          * Then, we convert the argument to a string.
     326             :                          * On exit from the switch, s points to the string that
     327             :                          * must be printed, s_len has the length of the string
     328             :                          * The precision requirements, if any, are reflected in s_len.
     329             :                          *
     330             :                          * NOTE: pad_char may be set to '0' because of the 0 flag.
     331             :                          *   It is reset to ' ' by non-numeric formats
     332             :                          */
     333        4046 :                         switch (*fmt) {
     334           0 :                                 case 'Z':
     335           0 :                                         zvp = (zval *) va_arg(ap, zval *);
     336           0 :                                         free_zcopy = zend_make_printable_zval(zvp, &zcopy);
     337           0 :                                         if (free_zcopy) {
     338           0 :                                                 zvp = &zcopy;
     339             :                                         }
     340           0 :                                         s_len = Z_STRLEN_P(zvp);
     341           0 :                                         s = Z_STRVAL_P(zvp);
     342           0 :                                         if (adjust_precision && precision < s_len) {
     343           0 :                                                 s_len = precision;
     344             :                                         }
     345           0 :                                         break;
     346         718 :                                 case 'u':
     347         718 :                                         switch(modifier) {
     348         602 :                                                 default:
     349         602 :                                                         i_num = (wide_int) va_arg(ap, unsigned int);
     350         602 :                                                         break;
     351           0 :                                                 case LM_LONG_DOUBLE:
     352           0 :                                                         goto fmt_error;
     353         116 :                                                 case LM_LONG:
     354         116 :                                                         i_num = (wide_int) va_arg(ap, unsigned long int);
     355         116 :                                                         break;
     356           0 :                                                 case LM_SIZE_T:
     357           0 :                                                         i_num = (wide_int) va_arg(ap, size_t);
     358           0 :                                                         break;
     359             : #if SIZEOF_LONG_LONG
     360           0 :                                                 case LM_LONG_LONG:
     361           0 :                                                         i_num = (wide_int) va_arg(ap, u_wide_int);
     362           0 :                                                         break;
     363             : #endif
     364             : #if SIZEOF_INTMAX_T
     365           0 :                                                 case LM_INTMAX_T:
     366           0 :                                                         i_num = (wide_int) va_arg(ap, uintmax_t);
     367           0 :                                                         break;
     368             : #endif
     369             : #if SIZEOF_PTRDIFF_T
     370           0 :                                                 case LM_PTRDIFF_T:
     371           0 :                                                         i_num = (wide_int) va_arg(ap, ptrdiff_t);
     372           0 :                                                         break;
     373             : #endif
     374             :                                         }
     375             :                                         /*
     376             :                                          * The rest also applies to other integer formats, so fall
     377             :                                          * into that case.
     378             :                                          */
     379        1110 :                                 case 'd':
     380             :                                 case 'i':
     381             :                                         /*
     382             :                                          * Get the arg if we haven't already.
     383             :                                          */
     384        1110 :                                         if ((*fmt) != 'u') {
     385         392 :                                                 switch(modifier) {
     386         272 :                                                         default:
     387         272 :                                                                 i_num = (wide_int) va_arg(ap, int);
     388         272 :                                                                 break;
     389           0 :                                                         case LM_LONG_DOUBLE:
     390           0 :                                                                 goto fmt_error;
     391         118 :                                                         case LM_LONG:
     392         118 :                                                                 i_num = (wide_int) va_arg(ap, long int);
     393         118 :                                                                 break;
     394           2 :                                                         case LM_SIZE_T:
     395             : #if SIZEOF_SSIZE_T
     396           2 :                                                                 i_num = (wide_int) va_arg(ap, ssize_t);
     397             : #else
     398             :                                                                 i_num = (wide_int) va_arg(ap, size_t);
     399             : #endif
     400           2 :                                                                 break;
     401             : #if SIZEOF_LONG_LONG
     402           0 :                                                         case LM_LONG_LONG:
     403           0 :                                                                 i_num = (wide_int) va_arg(ap, wide_int);
     404           0 :                                                                 break;
     405             : #endif
     406             : #if SIZEOF_INTMAX_T
     407           0 :                                                         case LM_INTMAX_T:
     408           0 :                                                                 i_num = (wide_int) va_arg(ap, intmax_t);
     409           0 :                                                                 break;
     410             : #endif
     411             : #if SIZEOF_PTRDIFF_T
     412           0 :                                                         case LM_PTRDIFF_T:
     413           0 :                                                                 i_num = (wide_int) va_arg(ap, ptrdiff_t);
     414           0 :                                                                 break;
     415             : #endif
     416             :                                                 }
     417         718 :                                         }
     418        1110 :                                         s = ap_php_conv_10(i_num, (*fmt) == 'u', &is_negative,
     419             :                                                                 &num_buf[NUM_BUF_SIZE], &s_len);
     420        1110 :                                         FIX_PRECISION(adjust_precision, precision, s, s_len);
     421             : 
     422        1110 :                                         if (*fmt != 'u') {
     423         392 :                                                 if (is_negative) {
     424           0 :                                                         prefix_char = '-';
     425         392 :                                                 } else if (print_sign) {
     426           0 :                                                         prefix_char = '+';
     427         392 :                                                 } else if (print_blank) {
     428           0 :                                                         prefix_char = ' ';
     429             :                                                 }
     430             :                                         }
     431        1110 :                                         break;
     432             : 
     433             : 
     434           0 :                                 case 'o':
     435           0 :                                         switch(modifier) {
     436           0 :                                                 default:
     437           0 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned int);
     438           0 :                                                         break;
     439           0 :                                                 case LM_LONG_DOUBLE:
     440           0 :                                                         goto fmt_error;
     441           0 :                                                 case LM_LONG:
     442           0 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned long int);
     443           0 :                                                         break;
     444           0 :                                                 case LM_SIZE_T:
     445           0 :                                                         ui_num = (u_wide_int) va_arg(ap, size_t);
     446           0 :                                                         break;
     447             : #if SIZEOF_LONG_LONG
     448           0 :                                                 case LM_LONG_LONG:
     449           0 :                                                         ui_num = (u_wide_int) va_arg(ap, u_wide_int);
     450           0 :                                                         break;
     451             : #endif
     452             : #if SIZEOF_INTMAX_T
     453           0 :                                                 case LM_INTMAX_T:
     454           0 :                                                         ui_num = (u_wide_int) va_arg(ap, uintmax_t);
     455           0 :                                                         break;
     456             : #endif
     457             : #if SIZEOF_PTRDIFF_T
     458           0 :                                                 case LM_PTRDIFF_T:
     459           0 :                                                         ui_num = (u_wide_int) va_arg(ap, ptrdiff_t);
     460           0 :                                                         break;
     461             : #endif
     462             :                                         }
     463           0 :                                         s = ap_php_conv_p2(ui_num, 3, *fmt, &num_buf[NUM_BUF_SIZE], &s_len);
     464           0 :                                         FIX_PRECISION(adjust_precision, precision, s, s_len);
     465           0 :                                         if (alternate_form && *s != '0') {
     466           0 :                                                 *--s = '0';
     467           0 :                                                 s_len++;
     468             :                                         }
     469           0 :                                         break;
     470             : 
     471             : 
     472           4 :                                 case 'x':
     473             :                                 case 'X':
     474           4 :                                         switch(modifier) {
     475           0 :                                                 default:
     476           0 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned int);
     477           0 :                                                         break;
     478           0 :                                                 case LM_LONG_DOUBLE:
     479           0 :                                                         goto fmt_error;
     480           4 :                                                 case LM_LONG:
     481           4 :                                                         ui_num = (u_wide_int) va_arg(ap, unsigned long int);
     482           4 :                                                         break;
     483           0 :                                                 case LM_SIZE_T:
     484           0 :                                                         ui_num = (u_wide_int) va_arg(ap, size_t);
     485           0 :                                                         break;
     486             : #if SIZEOF_LONG_LONG
     487           0 :                                                 case LM_LONG_LONG:
     488           0 :                                                         ui_num = (u_wide_int) va_arg(ap, u_wide_int);
     489           0 :                                                         break;
     490             : #endif
     491             : #if SIZEOF_INTMAX_T
     492           0 :                                                 case LM_INTMAX_T:
     493           0 :                                                         ui_num = (u_wide_int) va_arg(ap, uintmax_t);
     494           0 :                                                         break;
     495             : #endif
     496             : #if SIZEOF_PTRDIFF_T
     497           0 :                                                 case LM_PTRDIFF_T:
     498           0 :                                                         ui_num = (u_wide_int) va_arg(ap, ptrdiff_t);
     499           0 :                                                         break;
     500             : #endif
     501             :                                         }
     502           4 :                                         s = ap_php_conv_p2(ui_num, 4, *fmt, &num_buf[NUM_BUF_SIZE], &s_len);
     503           4 :                                         FIX_PRECISION(adjust_precision, precision, s, s_len);
     504           4 :                                         if (alternate_form && i_num != 0) {
     505           0 :                                                 *--s = *fmt;    /* 'x' or 'X' */
     506           0 :                                                 *--s = '0';
     507           0 :                                                 s_len += 2;
     508             :                                         }
     509           4 :                                         break;
     510             : 
     511             : 
     512        2860 :                                 case 's':
     513             :                                 case 'v':
     514        2860 :                                         s = va_arg(ap, char *);
     515        2860 :                                         if (s != NULL) {
     516        2860 :                                                 if (adjust_precision) {
     517        1658 :                                                         s_len = precision;
     518             :                                                 } else {
     519        1202 :                                                         s_len = strlen(s);
     520             :                                                 }
     521             : 
     522        2860 :                                                 if (escape_xml) {
     523             :                                                         /* added: support for xml escaping */
     524             : 
     525           0 :                                                         int old_slen = s_len, i = 0;
     526           0 :                                                         char *old_s = s, *s_ptr;
     527           0 :                                                         free_s = s_ptr = s = emalloc(old_slen * 6 + 1);
     528             :                                                         do {
     529           0 :                                                                 if (old_s[i] == '&' || old_s[i] == '"' || old_s[i] == '<') {
     530           0 :                                                                         *s_ptr++ = '&';
     531           0 :                                                                         switch (old_s[i]) {
     532           0 :                                                                                 case '"':
     533           0 :                                                                                         s_len += 5;
     534           0 :                                                                                         *s_ptr++ = 'q';
     535           0 :                                                                                         *s_ptr++ = 'u';
     536           0 :                                                                                         *s_ptr++ = 'o';
     537           0 :                                                                                         *s_ptr++ = 't';
     538           0 :                                                                                         break;
     539           0 :                                                                                 case '<':
     540           0 :                                                                                         s_len += 3;
     541           0 :                                                                                         *s_ptr++ = 'l';
     542           0 :                                                                                         *s_ptr++ = 't';
     543           0 :                                                                                         break;
     544           0 :                                                                                 case '&':
     545           0 :                                                                                         s_len += 4;
     546           0 :                                                                                         *s_ptr++ = 'a';
     547           0 :                                                                                         *s_ptr++ = 'm';
     548           0 :                                                                                         *s_ptr++ = 'p';
     549           0 :                                                                                         break;
     550             :                                                                         }
     551           0 :                                                                         *s_ptr++ = ';';
     552             :                                                                 } else {
     553           0 :                                                                         *s_ptr++ = old_s[i];
     554             :                                                                 }
     555           0 :                                                         } while (i++ < old_slen);
     556             :                                                 }
     557             :                                         } else {
     558           0 :                                                 s = S_NULL;
     559           0 :                                                 s_len = S_NULL_LEN;
     560             :                                         }
     561        2860 :                                         pad_char = ' ';
     562        2860 :                                         break;
     563             : 
     564             : 
     565           2 :                                 case 'b':
     566           2 :                                         if (escape_xml) {
     567           0 :                                                 s = PHPDBG_G(err_buf).xml;
     568             :                                         } else {
     569           2 :                                                 s = PHPDBG_G(err_buf).msg;
     570             :                                         }
     571             : 
     572           2 :                                         if (s != NULL) {
     573           2 :                                                 if (escape_xml) {
     574           0 :                                                         s_len = PHPDBG_G(err_buf).xmllen;
     575             :                                                 } else {
     576           2 :                                                         s_len = PHPDBG_G(err_buf).msglen;
     577             :                                                 }
     578             : 
     579           2 :                                                 if (adjust_precision && precision != s_len) {
     580           0 :                                                         s_len = precision;
     581             :                                                 }
     582             :                                         } else {
     583           0 :                                                 s = "";
     584           0 :                                                 s_len = 0;
     585             :                                         }
     586           2 :                                         pad_char = ' ';
     587           2 :                                         break;
     588             : 
     589             : 
     590           0 :                                 case 'r':
     591           0 :                                         if (PHPDBG_G(req_id)) {
     592           0 :                                                 s_len = spprintf(&s, 0, "req=\"%lu\"", PHPDBG_G(req_id));
     593           0 :                                                 free_s = s;
     594             :                                         } else {
     595           0 :                                                 s = "";
     596           0 :                                                 s_len = 0;
     597             :                                         }
     598           0 :                                         break;
     599             : 
     600             : 
     601           0 :                                 case 'f':
     602             :                                 case 'F':
     603             :                                 case 'e':
     604             :                                 case 'E':
     605             : 
     606           0 :                                         switch(modifier) {
     607           0 :                                                 case LM_LONG_DOUBLE:
     608           0 :                                                         fp_num = (double) va_arg(ap, long double);
     609           0 :                                                         break;
     610           0 :                                                 case LM_STD:
     611           0 :                                                         fp_num = va_arg(ap, double);
     612           0 :                                                         break;
     613           0 :                                                 default:
     614           0 :                                                         goto fmt_error;
     615             :                                         }
     616             : 
     617           0 :                                         if (zend_isnan(fp_num)) {
     618           0 :                                                 s = "NAN";
     619           0 :                                                 s_len = 3;
     620           0 :                                         } else if (zend_isinf(fp_num)) {
     621           0 :                                                 s = "INF";
     622           0 :                                                 s_len = 3;
     623             :                                         } else {
     624             : #ifdef HAVE_LOCALE_H
     625           0 :                                                 if (!lconv) {
     626           0 :                                                         lconv = localeconv();
     627             :                                                 }
     628             : #endif
     629           0 :                                                 s = php_conv_fp((*fmt == 'f')?'F':*fmt, fp_num, alternate_form,
     630             :                                                  (adjust_precision == NO) ? FLOAT_DIGITS : precision,
     631           0 :                                                  (*fmt == 'f')?LCONV_DECIMAL_POINT:'.',
     632             :                                                                         &is_negative, &num_buf[1], &s_len);
     633           0 :                                                 if (is_negative)
     634           0 :                                                         prefix_char = '-';
     635           0 :                                                 else if (print_sign)
     636           0 :                                                         prefix_char = '+';
     637           0 :                                                 else if (print_blank)
     638           0 :                                                         prefix_char = ' ';
     639             :                                         }
     640           0 :                                         break;
     641             : 
     642             : 
     643           0 :                                 case 'g':
     644             :                                 case 'k':
     645             :                                 case 'G':
     646             :                                 case 'H':
     647           0 :                                         switch(modifier) {
     648           0 :                                                 case LM_LONG_DOUBLE:
     649           0 :                                                         fp_num = (double) va_arg(ap, long double);
     650           0 :                                                         break;
     651           0 :                                                 case LM_STD:
     652           0 :                                                         fp_num = va_arg(ap, double);
     653           0 :                                                         break;
     654           0 :                                                 default:
     655           0 :                                                         goto fmt_error;
     656             :                                         }
     657             : 
     658           0 :                                         if (zend_isnan(fp_num)) {
     659           0 :                                                 s = "NAN";
     660           0 :                                                 s_len = 3;
     661           0 :                                                 break;
     662           0 :                                         } else if (zend_isinf(fp_num)) {
     663           0 :                                                 if (fp_num > 0) {
     664           0 :                                                         s = "INF";
     665           0 :                                                         s_len = 3;
     666             :                                                 } else {
     667           0 :                                                         s = "-INF";
     668           0 :                                                         s_len = 4;
     669             :                                                 }
     670           0 :                                                 break;
     671             :                                         }
     672             : 
     673           0 :                                         if (adjust_precision == NO) {
     674           0 :                                                 precision = FLOAT_DIGITS;
     675           0 :                                         } else if (precision == 0) {
     676           0 :                                                 precision = 1;
     677             :                                         }
     678             :                                         /*
     679             :                                          * * We use &num_buf[ 1 ], so that we have room for the sign
     680             :                                          */
     681             : #ifdef HAVE_LOCALE_H
     682           0 :                                         if (!lconv) {
     683           0 :                                                 lconv = localeconv();
     684             :                                         }
     685             : #endif
     686           0 :                                         s = php_gcvt(fp_num, precision, (*fmt=='H' || *fmt == 'k') ? '.' : LCONV_DECIMAL_POINT, (*fmt == 'G' || *fmt == 'H')?'E':'e', &num_buf[1]);
     687           0 :                                         if (*s == '-') {
     688           0 :                                                 prefix_char = *s++;
     689           0 :                                         } else if (print_sign) {
     690           0 :                                                 prefix_char = '+';
     691           0 :                                         } else if (print_blank) {
     692           0 :                                                 prefix_char = ' ';
     693             :                                         }
     694             : 
     695           0 :                                         s_len = strlen(s);
     696             : 
     697           0 :                                         if (alternate_form && (strchr(s, '.')) == NULL) {
     698           0 :                                                 s[s_len++] = '.';
     699             :                                         }
     700           0 :                                         break;
     701             : 
     702             : 
     703           0 :                                 case 'c':
     704           0 :                                         char_buf[0] = (char) (va_arg(ap, int));
     705           0 :                                         s = &char_buf[0];
     706           0 :                                         s_len = 1;
     707           0 :                                         pad_char = ' ';
     708           0 :                                         break;
     709             : 
     710             : 
     711           0 :                                 case '%':
     712           0 :                                         char_buf[0] = '%';
     713           0 :                                         s = &char_buf[0];
     714           0 :                                         s_len = 1;
     715           0 :                                         pad_char = ' ';
     716           0 :                                         break;
     717             : 
     718             : 
     719           0 :                                 case 'n':
     720           0 :                                         *(va_arg(ap, int *)) = cc;
     721           0 :                                         goto skip_output;
     722             : 
     723             :                                         /*
     724             :                                          * Always extract the argument as a "char *" pointer. We
     725             :                                          * should be using "void *" but there are still machines
     726             :                                          * that don't understand it.
     727             :                                          * If the pointer size is equal to the size of an unsigned
     728             :                                          * integer we convert the pointer to a hex number, otherwise
     729             :                                          * we print "%p" to indicate that we don't handle "%p".
     730             :                                          */
     731          70 :                                 case 'p':
     732             :                                         if (sizeof(char *) <= sizeof(u_wide_int)) {
     733          70 :                                                 ui_num = (u_wide_int)((size_t) va_arg(ap, char *));
     734          70 :                                                 s = ap_php_conv_p2(ui_num, 4, 'x',
     735             :                                                                 &num_buf[NUM_BUF_SIZE], &s_len);
     736          70 :                                                 if (ui_num != 0) {
     737          70 :                                                         *--s = 'x';
     738          70 :                                                         *--s = '0';
     739          70 :                                                         s_len += 2;
     740             :                                                 }
     741             :                                         } else {
     742             :                                                 s = "%p";
     743             :                                                 s_len = 2;
     744             :                                         }
     745          70 :                                         pad_char = ' ';
     746          70 :                                         break;
     747             : 
     748             : 
     749           0 :                                 case NUL:
     750             :                                         /*
     751             :                                          * The last character of the format string was %.
     752             :                                          * We ignore it.
     753             :                                          */
     754           0 :                                         continue;
     755             : 
     756             : 
     757           0 : fmt_error:
     758           0 :                                 php_error(E_ERROR, "Illegal length modifier specified '%c' in s[np]printf call", *fmt);
     759             :                                         /*
     760             :                                          * The default case is for unrecognized %'s.
     761             :                                          * We print %<char> to help the user identify what
     762             :                                          * option is not understood.
     763             :                                          * This is also useful in case the user wants to pass
     764             :                                          * the output of format_converter to another function
     765             :                                          * that understands some other %<char> (like syslog).
     766             :                                          * Note that we can't point s inside fmt because the
     767             :                                          * unknown <char> could be preceded by width etc.
     768             :                                          */
     769           0 :                                 default:
     770           0 :                                         char_buf[0] = '%';
     771           0 :                                         char_buf[1] = *fmt;
     772           0 :                                         s = char_buf;
     773           0 :                                         s_len = 2;
     774           0 :                                         pad_char = ' ';
     775           0 :                                         break;
     776             :                         }
     777             : 
     778        4046 :                         if (prefix_char != NUL) {
     779           0 :                                 *--s = prefix_char;
     780           0 :                                 s_len++;
     781             :                         }
     782        4046 :                         if (adjust_width && adjust == RIGHT && min_width > s_len) {
     783         434 :                                 if (pad_char == '0' && prefix_char != NUL) {
     784           0 :                                         INS_CHAR(*s, sp, bep, cc)
     785           0 :                                                 s++;
     786           0 :                                         s_len--;
     787           0 :                                         min_width--;
     788             :                                 }
     789        1736 :                                 PAD(min_width, s_len, pad_char);
     790             :                         }
     791             :                         /*
     792             :                          * Print the string s.
     793             :                          */
     794       86958 :                         for (i = s_len; i != 0; i--) {
     795       82912 :                                 INS_CHAR(*s, sp, bep, cc);
     796       82912 :                                 s++;
     797             :                         }
     798             : 
     799        4046 :                         if (adjust_width && adjust == LEFT && min_width > s_len)
     800         928 :                                 PAD(min_width, s_len, pad_char);
     801        4046 :                         if (free_zcopy) {
     802             :                                 zval_dtor(&zcopy);
     803             :                         }
     804             :                 }
     805       25214 : skip_output:
     806       21168 :                 if (free_s) {
     807           0 :                         efree(free_s);
     808           0 :                         free_s = NULL;
     809             :                 }
     810             : 
     811       21168 :                 fmt++;
     812             :         }
     813        2896 :         odp->nextb = sp;
     814        2896 :         return (cc);
     815             : }
     816             : 
     817        2896 : static void strx_printv(int *ccp, char *buf, size_t len, const char *format, zend_bool escape_xml, va_list ap) {
     818             :         buffy od;
     819             :         int cc;
     820             : 
     821             :         /*
     822             :          * First initialize the descriptor
     823             :          * Notice that if no length is given, we initialize buf_end to the
     824             :          * highest possible address.
     825             :          */
     826        2896 :         if (len == 0) {
     827        1448 :                 od.buf_end = (char *) ~0;
     828        1448 :                 od.nextb   = (char *) ~0;
     829             :         } else {
     830        1448 :                 od.buf_end = &buf[len-1];
     831        1448 :                 od.nextb   = buf;
     832             :         }
     833             : 
     834             :         /*
     835             :          * Do the conversion
     836             :          */
     837        2896 :         cc = format_converter(&od, format, escape_xml, ap);
     838        2896 :         if (len != 0 && od.nextb <= od.buf_end) {
     839        1448 :                 *(od.nextb) = '\0';
     840             :         }
     841        2896 :         if (ccp) {
     842        2896 :                 *ccp = cc;
     843             :         }
     844        2896 : }
     845             : 
     846        2896 : static int phpdbg_xml_vsnprintf(char *buf, size_t len, const char *format, zend_bool escape_xml, va_list ap) {
     847             :         int cc;
     848             : 
     849        2896 :         strx_printv(&cc, buf, len, format, escape_xml, ap);
     850        2896 :         return (cc);
     851             : }
     852             : 
     853        1448 : PHPDBG_API int phpdbg_xml_vasprintf(char **buf, const char *format, zend_bool escape_xml, va_list ap) {
     854             :         va_list ap2;
     855             :         int cc;
     856             : 
     857        1448 :         va_copy(ap2, ap);
     858        1448 :         cc = phpdbg_xml_vsnprintf(NULL, 0, format, escape_xml, ap2);
     859        1448 :         va_end(ap2);
     860             : 
     861        1448 :         *buf = NULL;
     862             : 
     863        1448 :         if (cc >= 0) {
     864        1448 :                 if ((*buf = emalloc(++cc)) != NULL) {
     865        1448 :                         if ((cc = phpdbg_xml_vsnprintf(*buf, cc, format, escape_xml, ap)) < 0) {
     866           0 :                                 efree(*buf);
     867           0 :                                 *buf = NULL;
     868             :                         }
     869             :                 }
     870             :         }
     871             : 
     872        1448 :         return cc;
     873             : }
     874             : /* copy end */
     875             : 
     876           0 : PHPDBG_API int _phpdbg_xml_asprintf(char **buf, const char *format, zend_bool escape_xml, ...) {
     877             :         int ret;
     878             :         va_list va;
     879             : 
     880           0 :         va_start(va, escape_xml);
     881           0 :         ret = phpdbg_xml_vasprintf(buf, format, escape_xml, va);
     882           0 :         va_end(va);
     883             : 
     884           0 :         return ret;
     885             : }
     886             : 
     887         322 : PHPDBG_API int _phpdbg_asprintf(char **buf, const char *format, ...) {
     888             :         int ret;
     889             :         va_list va;
     890             : 
     891         322 :         va_start(va, format);
     892         322 :         ret = phpdbg_xml_vasprintf(buf, format, 0, va);
     893         322 :         va_end(va);
     894             : 
     895         322 :         return ret;
     896             : }
     897             : 
     898           0 : static int phpdbg_encode_xml(char **buf, char *msg, int msglen, int from, char *to) {
     899             :         int i;
     900           0 :         int tolen = to ? strlen(to) : 5;
     901           0 :         char *tmp = *buf = emalloc(msglen * tolen);
     902           0 :         for (i = 0; i++ < msglen; msg++) {
     903           0 :                 if (*msg == '&') {
     904           0 :                         memcpy(tmp, ZEND_STRL("&amp;"));
     905           0 :                         tmp += sizeof("&amp;") - 1;
     906           0 :                 } else if (*msg == '<') {
     907           0 :                         memcpy(tmp, ZEND_STRL("&lt;"));
     908           0 :                         tmp += sizeof("&lt;") - 1;
     909           0 :                 } else if (((int) *msg) == from) {
     910           0 :                         memcpy(tmp, to, tolen);
     911           0 :                         tmp += tolen;
     912             :                 } else {
     913           0 :                         *tmp++ = *msg;
     914             :                 }
     915             :         }
     916             : 
     917             :         {
     918           0 :                 int len = tmp - *buf;
     919           0 :                 *buf = erealloc(*buf, len + 1);
     920           0 :                 return len;
     921             :         }
     922             : }
     923             : 
     924           0 : static void phpdbg_encode_ctrl_chars(char **buf, int *buflen) {
     925             :         char *tmp, *tmpptr;
     926             :         int len;
     927             :         int i;
     928             : 
     929           0 :         tmp = tmpptr = emalloc(*buflen * 5);
     930             : 
     931           0 :         for (i = 0; i < *buflen; i++) {
     932           0 :                 if ((*buf)[i] < 0x20) {
     933           0 :                         *tmpptr++ = '&';
     934           0 :                         *tmpptr++ = '#';
     935           0 :                         if ((unsigned int) ((*buf)[i]) > 9) {
     936           0 :                                 *tmpptr++ = ((*buf)[i] / 10) + '0';
     937             :                         }
     938           0 :                         *tmpptr++ = ((*buf)[i] % 10) + '0';
     939           0 :                         *tmpptr++ = ';';
     940             :                 } else {
     941           0 :                         *tmpptr++ = (*buf)[i];
     942             :                 }
     943             :         }
     944             : 
     945           0 :         len = tmpptr - tmp;
     946             : 
     947           0 :         efree(*buf);
     948           0 :         *buf = erealloc(tmp, len + 1);
     949           0 :         *buflen = len;
     950           0 : }
     951             : 
     952        1007 : static int phpdbg_process_print(int fd, int type, const char *tag, const char *msg, int msglen, const char *xml, int xmllen) {
     953        1007 :         char *msgout = NULL, *buf;
     954             :         int msgoutlen, xmloutlen, buflen;
     955             :         const char *severity;
     956             : 
     957        1007 :         if ((PHPDBG_G(flags) & PHPDBG_WRITE_XML) && PHPDBG_G(in_script_xml) && PHPDBG_G(in_script_xml) != type) {
     958           0 :                 phpdbg_mixed_write(fd, ZEND_STRL("</stream>"));
     959           0 :                 PHPDBG_G(in_script_xml) = 0;
     960             :         }
     961             : 
     962        1007 :         switch (type) {
     963          12 :                 case P_ERROR:
     964          12 :                         severity = "error";
     965          12 :                         if (!PHPDBG_G(last_was_newline)) {
     966           0 :                                 if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
     967           0 :                                         phpdbg_mixed_write(fd, ZEND_STRL("<phpdbg>\n" "</phpdbg>"));
     968             :                                 } else {
     969           0 :                                         phpdbg_mixed_write(fd, ZEND_STRL("\n"));
     970             :                                 }
     971           0 :                                 PHPDBG_G(last_was_newline) = 1;
     972             :                         }
     973          12 :                         if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) {
     974           0 :                                 msgoutlen = phpdbg_asprintf(&msgout, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_ERROR]->code, msglen, msg);
     975             :                         } else {
     976          12 :                                 msgoutlen = phpdbg_asprintf(&msgout, "[%.*s]\n", msglen, msg);
     977             :                         }
     978          12 :                         break;
     979             : 
     980         211 :                 case P_NOTICE:
     981         211 :                         severity = "notice";
     982         211 :                         if (!PHPDBG_G(last_was_newline)) {
     983          27 :                                 if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
     984           0 :                                         phpdbg_mixed_write(fd, ZEND_STRL("<phpdbg>\n" "</phpdbg>"));
     985             :                                 } else {
     986          27 :                                         phpdbg_mixed_write(fd, ZEND_STRL("\n"));
     987             :                                 }
     988          27 :                                 PHPDBG_G(last_was_newline) = 1;
     989             :                         }
     990         211 :                         if (PHPDBG_G(flags) & PHPDBG_IS_COLOURED) {
     991           0 :                                 msgoutlen = phpdbg_asprintf(&msgout, "\033[%sm[%.*s]\033[0m\n", PHPDBG_G(colors)[PHPDBG_COLOR_NOTICE]->code, msglen, msg);
     992             :                         } else {
     993         211 :                                 msgoutlen = phpdbg_asprintf(&msgout, "[%.*s]\n", msglen, msg);
     994             :                         }
     995         211 :                         break;
     996             : 
     997          74 :                 case P_WRITELN:
     998          74 :                         severity = "normal";
     999          74 :                         if (msg) {
    1000          74 :                                 msgoutlen = phpdbg_asprintf(&msgout, "%.*s\n", msglen, msg);
    1001             :                         } else {
    1002           0 :                                 msgoutlen = 1;
    1003           0 :                                 msgout = estrdup("\n");
    1004             :                         }
    1005          74 :                         PHPDBG_G(last_was_newline) = 1;
    1006          74 :                         break;
    1007             : 
    1008         423 :                 case P_WRITE:
    1009         423 :                         severity = "normal";
    1010         423 :                         if (msg) {
    1011         423 :                                 msgout = estrndup(msg, msglen);
    1012         423 :                                 msgoutlen = msglen;
    1013         423 :                                 PHPDBG_G(last_was_newline) = msg[msglen - 1] == '\n';
    1014             :                         } else {
    1015           0 :                                 msgoutlen = 0;
    1016           0 :                                 msgout = estrdup("");
    1017             :                         }
    1018         423 :                         break;
    1019             : 
    1020         287 :                 case P_STDOUT:
    1021             :                 case P_STDERR:
    1022         287 :                         if (msg) {
    1023         287 :                                 PHPDBG_G(last_was_newline) = msg[msglen - 1] == '\n';
    1024         287 :                                 if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
    1025             :                                         zend_string *encoded;
    1026             : 
    1027           0 :                                         if (PHPDBG_G(in_script_xml) != type) {
    1028             :                                                 char *stream_buf;
    1029           0 :                                                 int stream_buflen = phpdbg_asprintf(&stream_buf, "<stream type=\"%s\">", type == P_STDERR ? "stderr" : "stdout");
    1030           0 :                                                 phpdbg_mixed_write(fd, stream_buf, stream_buflen);
    1031           0 :                                                 efree(stream_buf);
    1032           0 :                                                 PHPDBG_G(in_script_xml) = type;
    1033             :                                         }
    1034           0 :                                         encoded = php_escape_html_entities((unsigned char *) msg, msglen, 0, ENT_NOQUOTES, PG(internal_encoding) && PG(internal_encoding)[0] ? PG(internal_encoding) : (SG(default_charset) ? SG(default_charset) : "UTF-8"));
    1035           0 :                                         buflen = ZSTR_LEN(encoded);
    1036           0 :                                         memcpy(buf = emalloc(buflen + 1), ZSTR_VAL(encoded), buflen);
    1037           0 :                                         phpdbg_encode_ctrl_chars(&buf, &buflen);
    1038           0 :                                         phpdbg_mixed_write(fd, buf, buflen);
    1039           0 :                                         efree(buf);
    1040             :                                 } else {
    1041         287 :                                         phpdbg_mixed_write(fd, msg, msglen);
    1042             :                                 }
    1043         287 :                                 return msglen;
    1044             :                         }
    1045           0 :                 break;
    1046             : 
    1047             :                 /* no formatting on logging output */
    1048           0 :                 case P_LOG:
    1049           0 :                         severity = "log";
    1050           0 :                         if (msg) {
    1051             :                                 struct timeval tp;
    1052           0 :                                 if (gettimeofday(&tp, NULL) == SUCCESS) {
    1053           0 :                                         msgoutlen = phpdbg_asprintf(&msgout, "[%ld %.8F]: %.*s\n", tp.tv_sec, tp.tv_usec / 1000000., msglen, msg);
    1054             :                                 } else {
    1055           0 :                                         msgoutlen = FAILURE;
    1056             :                                 }
    1057             :                         }
    1058           0 :                         break;
    1059             :         }
    1060             : 
    1061         720 :         if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
    1062             :                 char *xmlout;
    1063             : 
    1064           0 :                 if (PHPDBG_G(req_id)) {
    1065           0 :                         char *xmlbuf = NULL;
    1066           0 :                         xmllen = phpdbg_asprintf(&xmlbuf, "req=\"%lu\" %.*s", PHPDBG_G(req_id), xmllen, xml);
    1067           0 :                         xml = xmlbuf;
    1068             :                 }
    1069           0 :                 if (msgout) {
    1070           0 :                         buflen = phpdbg_encode_xml(&buf, msgout, msgoutlen, '"', "&quot;");
    1071           0 :                         xmloutlen = phpdbg_asprintf(&xmlout, "<%s severity=\"%s\" %.*s msgout=\"%.*s\" />", tag, severity, xmllen, xml, buflen, buf);
    1072             : 
    1073           0 :                         efree(buf);
    1074             :                 } else {
    1075           0 :                         xmloutlen = phpdbg_asprintf(&xmlout, "<%s severity=\"%s\" %.*s msgout=\"\" />", tag, severity, xmllen, xml);
    1076             :                 }
    1077             : 
    1078           0 :                 phpdbg_encode_ctrl_chars(&xmlout, &xmloutlen);
    1079           0 :                 phpdbg_eol_convert(&xmlout, &xmloutlen);
    1080           0 :                 phpdbg_mixed_write(fd, xmlout, xmloutlen);
    1081           0 :                 efree(xmlout);
    1082         720 :         } else if (msgout) {
    1083         720 :                 phpdbg_eol_convert(&msgout, &msgoutlen);
    1084         720 :                 phpdbg_mixed_write(fd, msgout, msgoutlen);
    1085             :         }
    1086             : 
    1087         720 :         if (PHPDBG_G(req_id) && (PHPDBG_G(flags) & PHPDBG_WRITE_XML)) {
    1088           0 :                 efree((char *) xml);
    1089             :         }
    1090             : 
    1091         720 :         if (msgout) {
    1092         720 :                 efree(msgout);
    1093             :         }
    1094             : 
    1095         720 :         return msgout ? msgoutlen : xmloutlen;
    1096             : } /* }}} */
    1097             : 
    1098        1022 : PHPDBG_API int phpdbg_vprint(int type, int fd, const char *tag, const char *xmlfmt, const char *strfmt, va_list args) {
    1099        1022 :         char *msg = NULL, *xml = NULL;
    1100        1022 :         int msglen = 0, xmllen = 0;
    1101             :         int len;
    1102             :         va_list argcpy;
    1103             : 
    1104        1022 :         if (strfmt != NULL && strlen(strfmt) > 0L) {
    1105        1022 :                 va_copy(argcpy, args);
    1106        1022 :                 msglen = phpdbg_xml_vasprintf(&msg, strfmt, 0, argcpy);
    1107        1022 :                 va_end(argcpy);
    1108             :         }
    1109             : 
    1110        1022 :         if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
    1111           0 :                 if (xmlfmt != NULL && strlen(xmlfmt) > 0L) {
    1112           0 :                         va_copy(argcpy, args);
    1113           0 :                         xmllen = phpdbg_xml_vasprintf(&xml, xmlfmt, 1, argcpy);
    1114           0 :                         va_end(argcpy);
    1115             :                 } else {
    1116           0 :                         xml = estrdup("");
    1117             :                 }
    1118             :         }
    1119             : 
    1120        1022 :         if (PHPDBG_G(err_buf).active && type != P_STDOUT && type != P_STDERR) {
    1121          15 :                 phpdbg_free_err_buf();
    1122             : 
    1123          15 :                 PHPDBG_G(err_buf).type = type;
    1124          15 :                 PHPDBG_G(err_buf).fd = fd;
    1125          15 :                 PHPDBG_G(err_buf).tag = estrdup(tag);
    1126          15 :                 PHPDBG_G(err_buf).msg = msg;
    1127          15 :                 PHPDBG_G(err_buf).msglen = msglen;
    1128          15 :                 if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
    1129           0 :                         PHPDBG_G(err_buf).xml = xml;
    1130           0 :                         PHPDBG_G(err_buf).xmllen = xmllen;
    1131             :                 }
    1132             : 
    1133          15 :                 return msglen;
    1134             :         }
    1135             : 
    1136        1007 :         len = phpdbg_process_print(fd, type, tag, msg, msglen, xml, xmllen);
    1137             : 
    1138        1007 :         if (msg) {
    1139        1007 :                 efree(msg);
    1140             :         }
    1141             : 
    1142        1007 :         if (xml) {
    1143           0 :                 efree(xml);
    1144             :         }
    1145             : 
    1146        1007 :         return len;
    1147             : }
    1148             : 
    1149         571 : PHPDBG_API void phpdbg_free_err_buf(void) {
    1150         571 :         if (PHPDBG_G(err_buf).type == 0) {
    1151         556 :                 return;
    1152             :         }
    1153             : 
    1154          15 :         PHPDBG_G(err_buf).type = 0;
    1155             : 
    1156          15 :         efree(PHPDBG_G(err_buf).tag);
    1157          15 :         efree(PHPDBG_G(err_buf).msg);
    1158          15 :         if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
    1159           0 :                 efree(PHPDBG_G(err_buf).xml);
    1160             :         }
    1161             : }
    1162             : 
    1163         806 : PHPDBG_API void phpdbg_activate_err_buf(zend_bool active) {
    1164         806 :         PHPDBG_G(err_buf).active = active;
    1165         806 : }
    1166             : 
    1167           1 : PHPDBG_API int phpdbg_output_err_buf(const char *tag, const char *xmlfmt, const char *strfmt, ...) {
    1168             :         int len;
    1169             :         va_list args;
    1170           1 :         int errbuf_active = PHPDBG_G(err_buf).active;
    1171             : 
    1172           1 :         if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) {
    1173           0 :                 return 0;
    1174             :         }
    1175             : 
    1176           1 :         PHPDBG_G(err_buf).active = 0;
    1177             : 
    1178           1 :         va_start(args, strfmt);
    1179           1 :         len = phpdbg_vprint(PHPDBG_G(err_buf).type, PHPDBG_G(err_buf).fd, tag ? tag : PHPDBG_G(err_buf).tag, xmlfmt, strfmt, args);
    1180           1 :         va_end(args);
    1181             : 
    1182           1 :         PHPDBG_G(err_buf).active = errbuf_active;
    1183           1 :         phpdbg_free_err_buf();
    1184             : 
    1185           1 :         return len;
    1186             : }
    1187             : 
    1188        1108 : PHPDBG_API int phpdbg_print(int type, int fd, const char *tag, const char *xmlfmt, const char *strfmt, ...) {
    1189             :         va_list args;
    1190             :         int len;
    1191             : 
    1192        1108 :         if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) {
    1193          87 :                 return 0;
    1194             :         }
    1195             : 
    1196        1021 :         va_start(args, strfmt);
    1197        1021 :         len = phpdbg_vprint(type, fd, tag, xmlfmt, strfmt, args);
    1198        1021 :         va_end(args);
    1199             : 
    1200        1021 :         return len;
    1201             : }
    1202             : 
    1203         290 : PHPDBG_API int phpdbg_xml_internal(int fd, const char *fmt, ...) {
    1204         290 :         int len = 0;
    1205             : 
    1206         290 :         if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) {
    1207           0 :                 return 0;
    1208             :         }
    1209             : 
    1210         290 :         if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
    1211             :                 va_list args;
    1212             :                 char *buffer;
    1213             :                 int buflen;
    1214             : 
    1215           0 :                 va_start(args, fmt);
    1216           0 :                 buflen = phpdbg_xml_vasprintf(&buffer, fmt, 1, args);
    1217           0 :                 va_end(args);
    1218             : 
    1219           0 :                 phpdbg_encode_ctrl_chars(&buffer, &buflen);
    1220             : 
    1221           0 :                 if (PHPDBG_G(in_script_xml)) {
    1222           0 :                         phpdbg_mixed_write(fd, ZEND_STRL("</stream>"));
    1223           0 :                         PHPDBG_G(in_script_xml) = 0;
    1224             :                 }
    1225             : 
    1226           0 :                 len = phpdbg_mixed_write(fd, buffer, buflen);
    1227           0 :                 efree(buffer);
    1228             :         }
    1229             : 
    1230         290 :         return len;
    1231             : }
    1232             : 
    1233           0 : PHPDBG_API int phpdbg_log_internal(int fd, const char *fmt, ...) {
    1234             :         va_list args;
    1235             :         char *buffer;
    1236             :         int buflen;
    1237           0 :         int len = 0;
    1238             : 
    1239           0 :         va_start(args, fmt);
    1240           0 :         buflen = phpdbg_xml_vasprintf(&buffer, fmt, 0, args);
    1241           0 :         va_end(args);
    1242             : 
    1243           0 :         len = phpdbg_mixed_write(fd, buffer, buflen);
    1244           0 :         efree(buffer);
    1245             : 
    1246           0 :         return len;
    1247             : }
    1248             : 
    1249         104 : PHPDBG_API int phpdbg_out_internal(int fd, const char *fmt, ...) {
    1250             :         va_list args;
    1251             :         char *buffer;
    1252             :         int buflen;
    1253         104 :         int len = 0;
    1254             : 
    1255         104 :         if (PHPDBG_G(flags) & PHPDBG_DISCARD_OUTPUT) {
    1256           0 :                 return 0;
    1257             :         }
    1258             : 
    1259         104 :         va_start(args, fmt);
    1260         104 :         buflen = phpdbg_xml_vasprintf(&buffer, fmt, 0, args);
    1261         104 :         va_end(args);
    1262             : 
    1263         104 :         if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
    1264             :                 char *msg;
    1265             :                 int msglen;
    1266             : 
    1267           0 :                 msglen = phpdbg_encode_xml(&msg, buffer, buflen, 256, NULL);
    1268           0 :                 phpdbg_encode_ctrl_chars(&msg, &msglen);
    1269           0 :                 phpdbg_eol_convert(&msg, &msglen);
    1270             : 
    1271           0 :                 if (PHPDBG_G(in_script_xml)) {
    1272           0 :                         phpdbg_mixed_write(fd, ZEND_STRL("</stream>"));
    1273           0 :                         PHPDBG_G(in_script_xml) = 0;
    1274             :                 }
    1275             : 
    1276           0 :                 phpdbg_mixed_write(fd, ZEND_STRL("<phpdbg>"));
    1277           0 :                 len = phpdbg_mixed_write(fd, msg, msglen);
    1278           0 :                 phpdbg_mixed_write(fd, ZEND_STRL("</phpdbg>"));
    1279             :         } else {
    1280         104 :                 phpdbg_eol_convert(&buffer, &buflen);
    1281         104 :                 len = phpdbg_mixed_write(fd, buffer, buflen);
    1282             :         }
    1283             : 
    1284         104 :         efree(buffer);
    1285         104 :         return len;
    1286             : }
    1287             : 
    1288             : 
    1289           0 : PHPDBG_API int phpdbg_rlog_internal(int fd, const char *fmt, ...) { /* {{{ */
    1290           0 :         int rc = 0;
    1291             : 
    1292             :         va_list args;
    1293             :         struct timeval tp;
    1294             : 
    1295           0 :         va_start(args, fmt);
    1296           0 :         if (gettimeofday(&tp, NULL) == SUCCESS) {
    1297             :                 char friendly[100];
    1298           0 :                 char *format = NULL, *buffer = NULL, *outbuf = NULL;
    1299           0 :                 const time_t tt = tp.tv_sec;
    1300             : 
    1301             : #ifdef PHP_WIN32
    1302             :                 strftime(friendly, 100, "%a %b %d %H.%%04d %Y", localtime(&tt));
    1303             : #else
    1304           0 :                 strftime(friendly, 100, "%a %b %d %T.%%04d %Y", localtime(&tt));
    1305             : #endif
    1306           0 :                 phpdbg_asprintf(&buffer, friendly, tp.tv_usec/1000);
    1307           0 :                 phpdbg_asprintf(&format, "[%s]: %s\n", buffer, fmt);
    1308           0 :                 rc = phpdbg_xml_vasprintf(&outbuf, format, 0, args);
    1309             : 
    1310           0 :                 if (outbuf) {
    1311           0 :                         rc = phpdbg_mixed_write(fd, outbuf, rc);
    1312           0 :                         efree(outbuf);
    1313             :                 }
    1314             : 
    1315           0 :                 efree(format);
    1316           0 :                 efree(buffer);
    1317             :         }
    1318           0 :         va_end(args);
    1319             : 
    1320           0 :         return rc;
    1321             : } /* }}} */

Generated by: LCOV version 1.10

Generated at Sat, 22 Sep 2018 10:27:04 +0000 (8 hours ago)

Copyright © 2005-2018 The PHP Group
All rights reserved.