1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2017 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: Anatol Belski <ab@php.net> |
16 +----------------------------------------------------------------------+
17 */
18
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22
23 #include "phpdbg.h"
24 #include "phpdbg_eol.h"
25
26 ZEND_EXTERN_MODULE_GLOBALS(phpdbg)
27
28 #define EOL_LIST_LEN 4
29 struct phpdbg_eol_rep phpdbg_eol_list[EOL_LIST_LEN] = {
30 {"CRLF", "\r\n", PHPDBG_EOL_CRLF},
31 /* {"LFCR", "\n\r", PHPDBG_EOL_LFCR},*/
32 {"LF", "\n", PHPDBG_EOL_LF},
33 {"CR", "\r", PHPDBG_EOL_CR},
34 };
35
phpdbg_eol_global_update(char * name)36 int phpdbg_eol_global_update(char *name)
37 {
38
39 if (0 == memcmp(name, "CRLF", 4) || 0 == memcmp(name, "crlf", 4) || 0 == memcmp(name, "DOS", 3) || 0 == memcmp(name, "dos", 3)) {
40 PHPDBG_G(eol) = PHPDBG_EOL_CRLF;
41 } else if (0 == memcmp(name, "LF", 2) || 0 == memcmp(name, "lf", 2) || 0 == memcmp(name, "UNIX", 4) || 0 == memcmp(name, "unix", 4)) {
42 PHPDBG_G(eol) = PHPDBG_EOL_LF;
43 } else if (0 == memcmp(name, "CR", 2) || 0 == memcmp(name, "cr", 2) || 0 == memcmp(name, "MAC", 3) || 0 == memcmp(name, "mac", 3)) {
44 PHPDBG_G(eol) = PHPDBG_EOL_CR;
45 } else {
46 return FAILURE;
47 }
48
49 return SUCCESS;
50 }
51
phpdbg_eol_name(int id)52 char *phpdbg_eol_name(int id)
53 {
54 size_t i = 0;
55
56 while (i < EOL_LIST_LEN) {
57
58 if (id == phpdbg_eol_list[i].id) {
59 return phpdbg_eol_list[i].name;
60 }
61
62 i++;
63 }
64
65 return NULL;
66 }
67
phpdbg_eol_rep(int id)68 char *phpdbg_eol_rep(int id)
69 {
70 size_t i = 0;
71
72 while (i < EOL_LIST_LEN) {
73
74 if (id == phpdbg_eol_list[i].id) {
75 return phpdbg_eol_list[i].rep;
76 }
77
78 i++;
79 }
80
81 return NULL;
82 }
83
84
85 /* Inspired by https://ccrma.stanford.edu/~craig/utility/flip/flip.cpp */
phpdbg_eol_convert(char ** str,int * len)86 void phpdbg_eol_convert(char **str, int *len)
87 {
88 char *in = *str, *out ;
89 int in_len = *len, out_len, cursor, i;
90 char last, cur;
91
92 if ((PHPDBG_G(flags) & PHPDBG_IS_REMOTE) != PHPDBG_IS_REMOTE) {
93 return;
94 }
95
96 out_len = *len;
97 if (PHPDBG_EOL_CRLF == PHPDBG_G(eol)) { /* XXX add LFCR case if it's gonna be needed */
98 /* depending on the source EOL the out str will have all CR/LF duplicated */
99 for (i = 0; i < in_len; i++) {
100 if (0x0a == in[i] || 0x0d == in[i]) {
101 out_len++;
102 }
103 }
104 out = (char *)emalloc(out_len);
105
106 last = cur = in[0];
107 i = cursor = 0;
108 for (; i < in_len;) {
109 if (0x0a == cur && last != 0x0d) {
110 out[cursor] = 0x0d;
111 cursor++;
112 out[cursor] = cur;
113 } else if(0x0d == cur) {
114 if (i + 1 < in_len && 0x0a != in[i+1]) {
115 out[cursor] = cur;
116 cursor++;
117 out[cursor] = 0x0a;
118 last = 0x0a;
119 } else {
120 out[cursor] = 0x0d;
121 last = 0x0d;
122 }
123 } else {
124 out[cursor] = cur;
125 last = cur;
126 }
127
128 i++;
129 cursor++;
130 cur = in[i];
131 }
132
133 } else if (PHPDBG_EOL_LF == PHPDBG_G(eol) || PHPDBG_EOL_CR == PHPDBG_G(eol)) {
134 char want, kick;
135
136 if (PHPDBG_EOL_LF == PHPDBG_G(eol)) {
137 want = 0x0a;
138 kick = 0x0d;
139 } else {
140 want = 0x0d;
141 kick = 0x0a;
142 }
143
144 /* We gonna have a smaller or equally long string, estimation is almost neglecting */
145 out = (char *)emalloc(out_len);
146
147 last = cur = in[0];
148 i = cursor = 0;
149 for (; cursor < in_len;) {
150 if (kick == cur) {
151 out[cursor] = want;
152 } else if (want == cur) {
153 if (kick != last) {
154 out[cursor] = want;
155 }
156 } else {
157 out[cursor] = cur;
158 }
159
160 last = cur;
161 cursor++;
162 cur = in[cursor];
163 }
164 } else {
165 return;
166 }
167
168 efree(*str);
169 *str = erealloc(out, cursor);
170 *len = cursor;
171 in = NULL;
172 }
173