1 /* 2 +----------------------------------------------------------------------+ 3 | Copyright (c) The PHP Group | 4 +----------------------------------------------------------------------+ 5 | This source file is subject to version 3.01 of the PHP license, | 6 | that is bundled with this package in the file LICENSE, and is | 7 | available through the world-wide-web at the following url: | 8 | https://www.php.net/license/3_01.txt | 9 | If you did not receive a copy of the PHP license and are unable to | 10 | obtain it through the world-wide-web, please send a note to | 11 | license@php.net so we can mail you a copy immediately. | 12 +----------------------------------------------------------------------+ 13 | Author: Stig Sæther Bakken <ssb@php.net> | 14 | Marcus Boerger <helly@php.net> | 15 +----------------------------------------------------------------------+ 16 */ 17 18 /* 19 20 Comparing: sprintf, snprintf, slprintf, spprintf 21 22 sprintf offers the ability to make a lot of failures since it does not know 23 the size of the buffer it uses. Therefore usage of sprintf often 24 results in possible entries for buffer overrun attacks. So please 25 use this version only if you are sure the call is safe. sprintf 26 always terminates the buffer it writes to. 27 28 snprintf knows the buffers size and will not write behind it. But you will 29 have to use either a static buffer or allocate a dynamic buffer 30 before being able to call the function. In other words you must 31 be sure that you really know the maximum size of the buffer required. 32 A bad thing is having a big maximum while in most cases you would 33 only need a small buffer. If the size of the resulting string is 34 longer or equal to the buffer size than the buffer is not terminated. 35 The function also returns the number of chars not including the 36 terminating \0 that were needed to fully comply to the print request. 37 38 slprintf same as snprintf with the difference that it actually returns the 39 length printed not including the terminating \0. 40 41 spprintf is the dynamical version of snprintf. It allocates the buffer in size 42 as needed and allows a maximum setting as snprintf (turn this feature 43 off by setting max_len to 0). spprintf is a little bit slower than 44 snprintf and offers possible memory leaks if you miss freeing the 45 buffer allocated by the function. Therefore this function should be 46 used where either no maximum is known or the maximum is much bigger 47 than normal size required. spprintf always terminates the buffer. 48 49 Example: 50 51 #define MAX 1024 | #define MAX 1024 | #define MAX 1024 52 char buffer[MAX] | char buffer[MAX] | char *buffer; 53 | | 54 | | // No need to initialize buffer: 55 | | // spprintf ignores value of buffer 56 sprintf(buffer, "test"); | snprintf(buffer, MAX, "test"); | spprintf(&buffer, MAX, "text"); 57 | | if (!buffer) 58 | | return OUT_OF_MEMORY 59 // sprintf always terminates | // manual termination of | // spprintf allays terminates buffer 60 // buffer | // buffer *IS* required | 61 | buffer[MAX-1] = 0; | 62 action_with_buffer(buffer); | action_with_buffer(buffer); | action_with_buffer(buffer); 63 | | efree(buffer); 64 */ 65 66 #ifndef SNPRINTF_H 67 #define SNPRINTF_H 68 69 #include <stdbool.h> 70 71 BEGIN_EXTERN_C() 72 PHPAPI int ap_php_slprintf(char *buf, size_t len, const char *format,...) ZEND_ATTRIBUTE_FORMAT(printf, 3, 4); 73 PHPAPI int ap_php_vslprintf(char *buf, size_t len, const char *format, va_list ap); 74 PHPAPI int ap_php_snprintf(char *, size_t, const char *, ...) ZEND_ATTRIBUTE_FORMAT(printf, 3, 4); 75 PHPAPI int ap_php_vsnprintf(char *, size_t, const char *, va_list ap); 76 PHPAPI int ap_php_vasprintf(char **buf, const char *format, va_list ap); 77 PHPAPI int ap_php_asprintf(char **buf, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); 78 PHPAPI char * php_0cvt(double value, int ndigit, char dec_point, char exponent, char *buf); 79 PHPAPI char * php_conv_fp(char format, double num, 80 bool add_dp, int precision, char dec_point, bool * is_negative, char *buf, size_t *len); 81 82 END_EXTERN_C() 83 84 #define php_gcvt zend_gcvt 85 86 #ifdef slprintf 87 #undef slprintf 88 #endif 89 #define slprintf ap_php_slprintf 90 91 #ifdef vslprintf 92 #undef vslprintf 93 #endif 94 #define vslprintf ap_php_vslprintf 95 96 #ifdef snprintf 97 #undef snprintf 98 #endif 99 #define snprintf ap_php_snprintf 100 101 #ifdef vsnprintf 102 #undef vsnprintf 103 #endif 104 #define vsnprintf ap_php_vsnprintf 105 106 #ifndef HAVE_VASPRINTF 107 #define vasprintf ap_php_vasprintf 108 #endif 109 110 #ifndef HAVE_ASPRINTF 111 #define asprintf ap_php_asprintf 112 #endif 113 114 typedef enum { 115 LM_STD = 0, 116 #if SIZEOF_INTMAX_T 117 LM_INTMAX_T, 118 #endif 119 #if SIZEOF_PTRDIFF_T 120 LM_PTRDIFF_T, 121 #endif 122 #if SIZEOF_LONG_LONG 123 LM_LONG_LONG, 124 #endif 125 LM_SIZE_T, 126 LM_LONG, 127 LM_LONG_DOUBLE, 128 } length_modifier_e; 129 130 PHPAPI char * ap_php_conv_10(int64_t num, bool is_unsigned, 131 bool * is_negative, char *buf_end, size_t *len); 132 133 PHPAPI char * ap_php_conv_p2(uint64_t num, int nbits, 134 char format, char *buf_end, size_t *len); 135 136 #endif /* SNPRINTF_H */ 137