3 * Copyright (C) Igor Sysoev
7 #include <ngx_config.h>
11 static u_char *ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64,
12 u_char zero, ngx_uint_t hexadecimal, ngx_uint_t width);
16 ngx_strlow(u_char *dst, u_char *src, size_t n)
19 *dst = ngx_tolower(*src);
27 ngx_cpystrn(u_char *dst, u_char *src, size_t n)
33 for ( /* void */ ; --n; dst++, src++) {
48 ngx_pstrdup(ngx_pool_t *pool, ngx_str_t *src)
52 dst = ngx_pnalloc(pool, src->len);
57 ngx_memcpy(dst, src->data, src->len);
65 * %[0][width][x][X]O off_t
67 * %[0][width][u][x|X]z ssize_t/size_t
68 * %[0][width][u][x|X]d int/u_int
69 * %[0][width][u][x|X]l long
70 * %[0][width|m][u][x|X]i ngx_int_t/ngx_uint_t
71 * %[0][width][u][x|X]D int32_t/uint32_t
72 * %[0][width][u][x|X]L int64_t/uint64_t
73 * %[0][width|m][u][x|X]A ngx_atomic_int_t/ngx_atomic_uint_t
74 * %[0][width][.width]f float
80 * %v ngx_variable_value_t *
81 * %s null-terminated string
82 * %*s length and string
90 * %S null-teminated wchar string
96 ngx_sprintf(u_char *buf, const char *fmt, ...)
102 p = ngx_vsnprintf(buf, /* STUB */ 65536, fmt, args);
110 ngx_snprintf(u_char *buf, size_t max, const char *fmt, ...)
116 p = ngx_vsnprintf(buf, max, fmt, args);
124 ngx_vsnprintf(u_char *buf, size_t max, const char *fmt, va_list args)
126 u_char *p, zero, *last;
133 ngx_uint_t width, sign, hex, max_width, frac_width, i;
135 ngx_variable_value_t *vv;
143 while (*fmt && buf < last) {
146 * "buf < last" means that we could copy at least one character:
147 * the plain character, "%%", "%c", and minus without the checking
155 zero = (u_char) ((*++fmt == '0') ? '0' : ' ');
163 while (*fmt >= '0' && *fmt <= '9') {
164 width = width * 10 + *fmt++ - '0';
196 while (*fmt >= '0' && *fmt <= '9') {
197 frac_width = frac_width * 10 + *fmt++ - '0';
203 slen = va_arg(args, size_t);
218 v = va_arg(args, ngx_str_t *);
221 len = (buf + len < last) ? len : (size_t) (last - buf);
223 buf = ngx_cpymem(buf, v->data, len);
229 vv = va_arg(args, ngx_variable_value_t *);
232 len = (buf + len < last) ? len : (size_t) (last - buf);
234 buf = ngx_cpymem(buf, vv->data, len);
240 p = va_arg(args, u_char *);
242 if (slen == (size_t) -1) {
243 while (*p && buf < last) {
248 len = (buf + slen < last) ? slen : (size_t) (last - buf);
250 buf = ngx_cpymem(buf, p, len);
258 i64 = (int64_t) va_arg(args, off_t);
263 i64 = (int64_t) va_arg(args, ngx_pid_t);
268 i64 = (int64_t) va_arg(args, time_t);
273 ms = (ngx_msec_t) va_arg(args, ngx_msec_t);
274 if ((ngx_msec_int_t) ms == -1) {
279 ui64 = (uint64_t) ms;
285 i64 = (int64_t) va_arg(args, ssize_t);
287 ui64 = (uint64_t) va_arg(args, size_t);
293 i64 = (int64_t) va_arg(args, ngx_int_t);
295 ui64 = (uint64_t) va_arg(args, ngx_uint_t);
299 width = NGX_INT_T_LEN;
306 i64 = (int64_t) va_arg(args, int);
308 ui64 = (uint64_t) va_arg(args, u_int);
314 i64 = (int64_t) va_arg(args, long);
316 ui64 = (uint64_t) va_arg(args, u_long);
322 i64 = (int64_t) va_arg(args, int32_t);
324 ui64 = (uint64_t) va_arg(args, uint32_t);
330 i64 = va_arg(args, int64_t);
332 ui64 = va_arg(args, uint64_t);
338 i64 = (int64_t) va_arg(args, ngx_atomic_int_t);
340 ui64 = (uint64_t) va_arg(args, ngx_atomic_uint_t);
344 width = NGX_ATOMIC_T_LEN;
350 f = (float) va_arg(args, double);
359 buf = ngx_sprintf_num(buf, last, ui64, zero, 0, width);
369 for (i = 0; i < frac_width; i++) {
374 * (int64_t) cast is required for msvc6:
375 * it can not convert uint64_t to double
377 ui64 = (uint64_t) ((f - (int64_t) ui64) * scale);
379 buf = ngx_sprintf_num(buf, last, ui64, '0', 0, frac_width);
388 i64 = (int64_t) va_arg(args, rlim_t);
394 ui64 = (uintptr_t) va_arg(args, void *);
398 width = NGX_PTR_SIZE * 2;
402 d = va_arg(args, int);
403 *buf++ = (u_char) (d & 0xff);
438 ui64 = (uint64_t) -i64;
441 ui64 = (uint64_t) i64;
445 buf = ngx_sprintf_num(buf, last, ui64, zero, hex, width);
459 ngx_sprintf_num(u_char *buf, u_char *last, uint64_t ui64, u_char zero,
460 ngx_uint_t hexadecimal, ngx_uint_t width)
462 u_char *p, temp[NGX_INT64_LEN + 1];
464 * we need temp[NGX_INT64_LEN] only,
465 * but icc issues the warning
469 static u_char hex[] = "0123456789abcdef";
470 static u_char HEX[] = "0123456789ABCDEF";
472 p = temp + NGX_INT64_LEN;
474 if (hexadecimal == 0) {
476 if (ui64 <= NGX_MAX_UINT32_VALUE) {
479 * To divide 64-bit numbers and to find remainders
480 * on the x86 platform gcc and icc call the libc functions
481 * [u]divdi3() and [u]moddi3(), they call another function
482 * in its turn. On FreeBSD it is the qdivrem() function,
483 * its source code is about 170 lines of the code.
484 * The glibc counterpart is about 150 lines of the code.
486 * For 32-bit numbers and some divisors gcc and icc use
487 * a inlined multiplication and shifts. For example,
488 * unsigned "i32 / 10" is compiled to
490 * (i32 * 0xCCCCCCCD) >> 35
493 ui32 = (uint32_t) ui64;
496 *--p = (u_char) (ui32 % 10 + '0');
497 } while (ui32 /= 10);
501 *--p = (u_char) (ui64 % 10 + '0');
502 } while (ui64 /= 10);
505 } else if (hexadecimal == 1) {
509 /* the "(uint32_t)" cast disables the BCC's warning */
510 *--p = hex[(uint32_t) (ui64 & 0xf)];
512 } while (ui64 >>= 4);
514 } else { /* hexadecimal == 2 */
518 /* the "(uint32_t)" cast disables the BCC's warning */
519 *--p = HEX[(uint32_t) (ui64 & 0xf)];
521 } while (ui64 >>= 4);
524 /* zero or space padding */
526 len = (temp + NGX_INT64_LEN) - p;
528 while (len++ < width && buf < last) {
532 /* number safe copy */
534 len = (temp + NGX_INT64_LEN) - p;
536 if (buf + len > last) {
540 return ngx_cpymem(buf, p, len);
545 * We use ngx_strcasecmp()/ngx_strncasecmp() for 7-bit ASCII strings only,
546 * and implement our own ngx_strcasecmp()/ngx_strncasecmp()
547 * to avoid libc locale overhead. Besides, we use the ngx_uint_t's
548 * instead of the u_char's, because they are slightly faster.
552 ngx_strcasecmp(u_char *s1, u_char *s2)
557 c1 = (ngx_uint_t) *s1++;
558 c2 = (ngx_uint_t) *s2++;
560 c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
561 c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
578 ngx_strncasecmp(u_char *s1, u_char *s2, size_t n)
583 c1 = (ngx_uint_t) *s1++;
584 c2 = (ngx_uint_t) *s2++;
586 c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
587 c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
607 ngx_strnstr(u_char *s1, char *s2, size_t len)
612 c2 = *(u_char *) s2++;
634 } while (ngx_strncmp(s1, (u_char *) s2, n) != 0);
641 * ngx_strstrn() and ngx_strcasestrn() are intended to search for static
642 * substring with known length in null-terminated string. The argument n
643 * must be length of the second substring - 1.
647 ngx_strstrn(u_char *s1, char *s2, size_t n)
651 c2 = *(u_char *) s2++;
663 } while (ngx_strncmp(s1, (u_char *) s2, n) != 0);
670 ngx_strcasestrn(u_char *s1, char *s2, size_t n)
674 c2 = (ngx_uint_t) *s2++;
675 c2 = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
679 c1 = (ngx_uint_t) *s1++;
685 c1 = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
689 } while (ngx_strncasecmp(s1, (u_char *) s2, n) != 0);
696 ngx_rstrncmp(u_char *s1, u_char *s2, size_t n)
705 if (s1[n] != s2[n]) {
706 return s1[n] - s2[n];
719 ngx_rstrncasecmp(u_char *s1, u_char *s2, size_t n)
731 if (c1 >= 'a' && c1 <= 'z') {
736 if (c2 >= 'a' && c2 <= 'z') {
754 ngx_memn2cmp(u_char *s1, u_char *s2, size_t n1, size_t n2)
768 m = ngx_memcmp(s1, s2, n);
779 ngx_atoi(u_char *line, size_t n)
787 for (value = 0; n--; line++) {
788 if (*line < '0' || *line > '9') {
792 value = value * 10 + (*line - '0');
805 ngx_atosz(u_char *line, size_t n)
813 for (value = 0; n--; line++) {
814 if (*line < '0' || *line > '9') {
818 value = value * 10 + (*line - '0');
831 ngx_atoof(u_char *line, size_t n)
839 for (value = 0; n--; line++) {
840 if (*line < '0' || *line > '9') {
844 value = value * 10 + (*line - '0');
857 ngx_atotm(u_char *line, size_t n)
865 for (value = 0; n--; line++) {
866 if (*line < '0' || *line > '9') {
870 value = value * 10 + (*line - '0');
883 ngx_hextoi(u_char *line, size_t n)
892 for (value = 0; n--; line++) {
895 if (ch >= '0' && ch <= '9') {
896 value = value * 16 + (ch - '0');
900 c = (u_char) (ch | 0x20);
902 if (c >= 'a' && c <= 'f') {
903 value = value * 16 + (c - 'a' + 10);
920 ngx_hex_dump(u_char *dst, u_char *src, size_t len)
922 static u_char hex[] = "0123456789abcdef";
925 *dst++ = hex[*src >> 4];
926 *dst++ = hex[*src++ & 0xf];
934 ngx_encode_base64(ngx_str_t *dst, ngx_str_t *src)
938 static u_char basis64[] =
939 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
946 *d++ = basis64[(s[0] >> 2) & 0x3f];
947 *d++ = basis64[((s[0] & 3) << 4) | (s[1] >> 4)];
948 *d++ = basis64[((s[1] & 0x0f) << 2) | (s[2] >> 6)];
949 *d++ = basis64[s[2] & 0x3f];
956 *d++ = basis64[(s[0] >> 2) & 0x3f];
959 *d++ = basis64[(s[0] & 3) << 4];
963 *d++ = basis64[((s[0] & 3) << 4) | (s[1] >> 4)];
964 *d++ = basis64[(s[1] & 0x0f) << 2];
970 dst->len = d - dst->data;
975 ngx_decode_base64(ngx_str_t *dst, ngx_str_t *src)
979 static u_char basis64[] = {
980 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
981 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
982 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 62, 77, 77, 77, 63,
983 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 77, 77, 77, 77, 77, 77,
984 77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
985 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 77, 77, 77, 77, 77,
986 77, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
987 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 77, 77, 77, 77, 77,
989 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
990 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
991 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
992 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
993 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
994 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
995 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77,
996 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77
999 for (len = 0; len < src->len; len++) {
1000 if (src->data[len] == '=') {
1004 if (basis64[src->data[len]] == 77) {
1017 *d++ = (u_char) (basis64[s[0]] << 2 | basis64[s[1]] >> 4);
1018 *d++ = (u_char) (basis64[s[1]] << 4 | basis64[s[2]] >> 2);
1019 *d++ = (u_char) (basis64[s[2]] << 6 | basis64[s[3]]);
1026 *d++ = (u_char) (basis64[s[0]] << 2 | basis64[s[1]] >> 4);
1030 *d++ = (u_char) (basis64[s[1]] << 4 | basis64[s[2]] >> 2);
1033 dst->len = d - dst->data;
1040 * ngx_utf8_decode() decodes two and more bytes UTF sequences only
1041 * the return values:
1042 * 0x80 - 0x10ffff valid character
1043 * 0x110000 - 0xfffffffd invalid sequence
1044 * 0xfffffffe incomplete sequence
1049 ngx_utf8_decode(u_char **p, size_t n)
1052 uint32_t u, i, valid;
1062 } else if (u > 0xe0) {
1068 } else if (u > 0xc0) {
1092 u = (u << 6) | (i & 0x3f);
1106 ngx_utf8_length(u_char *p, size_t n)
1113 for (len = 0; p < last; len++) {
1122 if (ngx_utf8_decode(&p, n) > 0x10ffff) {
1133 ngx_utf8_cpystrn(u_char *dst, u_char *src, size_t n, size_t len)
1161 if (ngx_utf8_decode(&next, len) > 0x10ffff) {
1168 while (src < next) {
1181 ngx_escape_uri(u_char *dst, u_char *src, size_t size, ngx_uint_t type)
1185 static u_char hex[] = "0123456789abcdef";
1187 /* " ", "#", "%", "?", %00-%1F, %7F-%FF */
1189 static uint32_t uri[] = {
1190 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1192 /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
1193 0x80000029, /* 1000 0000 0000 0000 0000 0000 0010 1001 */
1195 /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
1196 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
1198 /* ~}| {zyx wvut srqp onml kjih gfed cba` */
1199 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
1201 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1202 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1203 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1204 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1207 /* " ", "#", "%", "+", "?", %00-%1F, %7F-%FF */
1209 static uint32_t args[] = {
1210 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1212 /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
1213 0x80000829, /* 1000 0000 0000 0000 0000 1000 0010 1001 */
1215 /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
1216 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
1218 /* ~}| {zyx wvut srqp onml kjih gfed cba` */
1219 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
1221 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1222 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1223 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1224 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1227 /* " ", "#", """, "%", "'", %00-%1F, %7F-%FF */
1229 static uint32_t html[] = {
1230 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1232 /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
1233 0x000000ad, /* 0000 0000 0000 0000 0000 0000 1010 1101 */
1235 /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
1236 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
1238 /* ~}| {zyx wvut srqp onml kjih gfed cba` */
1239 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
1241 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1242 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1243 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1244 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1247 /* " ", """, "%", "'", %00-%1F, %7F-%FF */
1249 static uint32_t refresh[] = {
1250 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1252 /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
1253 0x00000085, /* 0000 0000 0000 0000 0000 0000 1000 0101 */
1255 /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
1256 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
1258 /* ~}| {zyx wvut srqp onml kjih gfed cba` */
1259 0x80000000, /* 1000 0000 0000 0000 0000 0000 0000 0000 */
1261 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1262 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1263 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1264 0xffffffff /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1267 /* " ", "%", %00-%1F */
1269 static uint32_t memcached[] = {
1270 0xffffffff, /* 1111 1111 1111 1111 1111 1111 1111 1111 */
1272 /* ?>=< ;:98 7654 3210 /.-, +*)( '&%$ #"! */
1273 0x00000021, /* 0000 0000 0000 0000 0000 0000 0010 0001 */
1275 /* _^]\ [ZYX WVUT SRQP ONML KJIH GFED CBA@ */
1276 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
1278 /* ~}| {zyx wvut srqp onml kjih gfed cba` */
1279 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
1281 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
1282 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
1283 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
1284 0x00000000, /* 0000 0000 0000 0000 0000 0000 0000 0000 */
1287 /* mail_auth is the same as memcached */
1289 static uint32_t *map[] =
1290 { uri, args, html, refresh, memcached, memcached };
1297 /* find the number of the characters to be escaped */
1301 for (i = 0; i < size; i++) {
1302 if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
1308 return (uintptr_t) n;
1311 for (i = 0; i < size; i++) {
1312 if (escape[*src >> 5] & (1 << (*src & 0x1f))) {
1314 *dst++ = hex[*src >> 4];
1315 *dst++ = hex[*src & 0xf];
1323 return (uintptr_t) dst;
1328 ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type)
1330 u_char *d, *s, ch, c, decoded;
1350 && (type & (NGX_UNESCAPE_URI|NGX_UNESCAPE_REDIRECT)))
1366 if (ch >= '0' && ch <= '9') {
1367 decoded = (u_char) (ch - '0');
1368 state = sw_quoted_second;
1372 c = (u_char) (ch | 0x20);
1373 if (c >= 'a' && c <= 'f') {
1374 decoded = (u_char) (c - 'a' + 10);
1375 state = sw_quoted_second;
1379 /* the invalid quoted character */
1387 case sw_quoted_second:
1391 if (ch >= '0' && ch <= '9') {
1392 ch = (u_char) ((decoded << 4) + ch - '0');
1394 if (type & NGX_UNESCAPE_REDIRECT) {
1395 if (ch > '%' && ch < 0x7f) {
1400 *d++ = '%'; *d++ = *(s - 2); *d++ = *(s - 1);
1410 c = (u_char) (ch | 0x20);
1411 if (c >= 'a' && c <= 'f') {
1412 ch = (u_char) ((decoded << 4) + c - 'a' + 10);
1414 if (type & NGX_UNESCAPE_URI) {
1424 if (type & NGX_UNESCAPE_REDIRECT) {
1430 if (ch > '%' && ch < 0x7f) {
1435 *d++ = '%'; *d++ = *(s - 2); *d++ = *(s - 1);
1444 /* the invalid quoted character */
1458 ngx_escape_html(u_char *dst, u_char *src, size_t size)
1467 for (i = 0; i < size; i++) {
1471 len += sizeof("<") - 2;
1475 len += sizeof(">") - 2;
1479 len += sizeof("&") - 2;
1487 return (uintptr_t) len;
1490 for (i = 0; i < size; i++) {
1496 *dst++ = '&'; *dst++ = 'l'; *dst++ = 't'; *dst++ = ';';
1500 *dst++ = '&'; *dst++ = 'g'; *dst++ = 't'; *dst++ = ';';
1504 *dst++ = '&'; *dst++ = 'a'; *dst++ = 'm'; *dst++ = 'p';
1514 return (uintptr_t) dst;
1518 /* ngx_sort() is implemented as insertion sort because we need stable sort */
1521 ngx_sort(void *base, size_t n, size_t size,
1522 ngx_int_t (*cmp)(const void *, const void *))
1524 u_char *p1, *p2, *p;
1526 p = ngx_alloc(size, ngx_cycle->log);
1531 for (p1 = (u_char *) base + size;
1532 p1 < (u_char *) base + n * size;
1535 ngx_memcpy(p, p1, size);
1538 p2 > (u_char *) base && cmp(p2 - size, p) > 0;
1541 ngx_memcpy(p2, p2 - size, size);
1544 ngx_memcpy(p2, p, size);
1551 #if (NGX_MEMCPY_LIMIT)
1554 ngx_memcpy(void *dst, void *src, size_t n)
1556 if (n > NGX_MEMCPY_LIMIT) {
1557 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, "memcpy %uz bytes", n);
1561 return memcpy(dst, src, n);