237 |
return result; |
return result; |
238 |
} |
} |
239 |
|
|
240 |
|
static unsigned int hex_value(char c) { |
241 |
|
if ('0' <= c && c <= '9') { |
242 |
|
return c - '0'; |
243 |
|
} |
244 |
|
else if ('A' <= c && c <= 'F') { |
245 |
|
return c - 'A'; |
246 |
|
} |
247 |
|
else if ('a' <= c && c <= 'f') { |
248 |
|
return c - 'a'; |
249 |
|
} |
250 |
|
else { |
251 |
|
return 0; |
252 |
|
} |
253 |
|
} |
254 |
|
|
255 |
|
static char * decode_uri_component(const char * s) { |
256 |
|
size_t length = strlen(s); |
257 |
|
char * result = xmalloc(length + 1); |
258 |
|
char * p = result; |
259 |
|
while (*s != '\0') { |
260 |
|
if (*s == '%') { |
261 |
|
if (s[1] == '\0' || s[2] == '\0') { |
262 |
|
*p = '\0'; |
263 |
|
return result; |
264 |
|
} |
265 |
|
*p = hex_value(s[1]) * 16 + hex_value(s[2]); |
266 |
|
s += 2; |
267 |
|
} |
268 |
|
else { |
269 |
|
*p = *s; |
270 |
|
} |
271 |
|
p++; |
272 |
|
s++; |
273 |
|
} |
274 |
|
*p = '\0'; |
275 |
|
return result; |
276 |
|
} |
277 |
|
|
278 |
static const char * get_entity(char c) { |
static const char * get_entity(char c) { |
279 |
switch(c) { |
switch(c) { |
280 |
case '<': |
case '<': |
614 |
} |
} |
615 |
|
|
616 |
mkdir_if_necessary(report_directory); |
mkdir_if_necessary(report_directory); |
617 |
char * path = make_path(report_directory, "jscoverage.json"); |
char * current_report_directory; |
618 |
|
if (str_starts_with(abs_path, "/jscoverage-store/") && abs_path[18] != '\0') { |
619 |
|
char * dir = decode_uri_component(abs_path + 18); |
620 |
|
current_report_directory = make_path(report_directory, dir); |
621 |
|
free(dir); |
622 |
|
} |
623 |
|
else { |
624 |
|
current_report_directory = xstrdup(report_directory); |
625 |
|
} |
626 |
|
mkdir_if_necessary(current_report_directory); |
627 |
|
char * path = make_path(current_report_directory, "jscoverage.json"); |
628 |
|
|
629 |
/* check if the JSON file exists */ |
/* check if the JSON file exists */ |
630 |
struct stat buf; |
struct stat buf; |
641 |
} |
} |
642 |
} |
} |
643 |
if (result != 0) { |
if (result != 0) { |
644 |
|
free(current_report_directory); |
645 |
free(path); |
free(path); |
646 |
Coverage_delete(coverage); |
Coverage_delete(coverage); |
647 |
send_response(exchange, 500, "Could not merge with existing coverage data\n"); |
send_response(exchange, 500, "Could not merge with existing coverage data\n"); |
653 |
free(path); |
free(path); |
654 |
Coverage_delete(coverage); |
Coverage_delete(coverage); |
655 |
if (result != 0) { |
if (result != 0) { |
656 |
|
free(current_report_directory); |
657 |
send_response(exchange, 500, "Could not write coverage data\n"); |
send_response(exchange, 500, "Could not write coverage data\n"); |
658 |
return; |
return; |
659 |
} |
} |
660 |
|
|
661 |
/* copy other files */ |
/* copy other files */ |
662 |
jscoverage_copy_resources(report_directory); |
jscoverage_copy_resources(current_report_directory); |
663 |
path = make_path(report_directory, "jscoverage.js"); |
path = make_path(current_report_directory, "jscoverage.js"); |
664 |
|
free(current_report_directory); |
665 |
FILE * f = fopen(path, "ab"); |
FILE * f = fopen(path, "ab"); |
666 |
free(path); |
free(path); |
667 |
if (f == NULL) { |
if (f == NULL) { |
719 |
} |
} |
720 |
|
|
721 |
static void instrument_js(const char * id, const uint16_t * characters, size_t num_characters, Stream * output_stream) { |
static void instrument_js(const char * id, const uint16_t * characters, size_t num_characters, Stream * output_stream) { |
722 |
|
const struct Resource * resource = get_resource("report.js"); |
723 |
|
Stream_write(output_stream, resource->data, resource->length); |
724 |
|
|
725 |
LOCK(&javascript_mutex); |
LOCK(&javascript_mutex); |
726 |
jscoverage_instrument_js(id, characters, num_characters, output_stream); |
jscoverage_instrument_js(id, characters, num_characters, output_stream); |
727 |
UNLOCK(&javascript_mutex); |
UNLOCK(&javascript_mutex); |
|
|
|
|
const struct Resource * resource = get_resource("report.js"); |
|
|
Stream_write(output_stream, resource->data, resource->length); |
|
728 |
} |
} |
729 |
|
|
730 |
static bool is_hop_by_hop_header(const char * h) { |
static bool is_hop_by_hop_header(const char * h) { |
1092 |
else if (strcmp(argv[i], "--report-dir") == 0) { |
else if (strcmp(argv[i], "--report-dir") == 0) { |
1093 |
i++; |
i++; |
1094 |
if (i == argc) { |
if (i == argc) { |
1095 |
fatal("--report-dir: option requires an argument"); |
fatal_command_line("--report-dir: option requires an argument"); |
1096 |
} |
} |
1097 |
report_directory = argv[i]; |
report_directory = argv[i]; |
1098 |
} |
} |
1103 |
else if (strcmp(argv[i], "--document-root") == 0) { |
else if (strcmp(argv[i], "--document-root") == 0) { |
1104 |
i++; |
i++; |
1105 |
if (i == argc) { |
if (i == argc) { |
1106 |
fatal("--document-root: option requires an argument"); |
fatal_command_line("--document-root: option requires an argument"); |
1107 |
} |
} |
1108 |
document_root = argv[i]; |
document_root = argv[i]; |
1109 |
} |
} |
1114 |
else if (strcmp(argv[i], "--encoding") == 0) { |
else if (strcmp(argv[i], "--encoding") == 0) { |
1115 |
i++; |
i++; |
1116 |
if (i == argc) { |
if (i == argc) { |
1117 |
fatal("--encoding: option requires an argument"); |
fatal_command_line("--encoding: option requires an argument"); |
1118 |
} |
} |
1119 |
jscoverage_encoding = argv[i]; |
jscoverage_encoding = argv[i]; |
1120 |
} |
} |
1125 |
else if (strcmp(argv[i], "--ip-address") == 0) { |
else if (strcmp(argv[i], "--ip-address") == 0) { |
1126 |
i++; |
i++; |
1127 |
if (i == argc) { |
if (i == argc) { |
1128 |
fatal("--ip-address: option requires an argument"); |
fatal_command_line("--ip-address: option requires an argument"); |
1129 |
} |
} |
1130 |
ip_address = argv[i]; |
ip_address = argv[i]; |
1131 |
} |
} |
1140 |
else if (strcmp(argv[i], "--no-instrument") == 0) { |
else if (strcmp(argv[i], "--no-instrument") == 0) { |
1141 |
i++; |
i++; |
1142 |
if (i == argc) { |
if (i == argc) { |
1143 |
fatal("--no-instrument: option requires an argument"); |
fatal_command_line("--no-instrument: option requires an argument"); |
1144 |
} |
} |
1145 |
no_instrument[num_no_instrument] = argv[i]; |
no_instrument[num_no_instrument] = argv[i]; |
1146 |
num_no_instrument++; |
num_no_instrument++; |
1153 |
else if (strcmp(argv[i], "--port") == 0) { |
else if (strcmp(argv[i], "--port") == 0) { |
1154 |
i++; |
i++; |
1155 |
if (i == argc) { |
if (i == argc) { |
1156 |
fatal("--port: option requires an argument"); |
fatal_command_line("--port: option requires an argument"); |
1157 |
} |
} |
1158 |
port = argv[i]; |
port = argv[i]; |
1159 |
} |
} |
1170 |
} |
} |
1171 |
|
|
1172 |
else if (strncmp(argv[i], "-", 1) == 0) { |
else if (strncmp(argv[i], "-", 1) == 0) { |
1173 |
fatal("unrecognized option `%s'", argv[i]); |
fatal_command_line("unrecognized option `%s'", argv[i]); |
1174 |
} |
} |
1175 |
else { |
else { |
1176 |
fatal("too many arguments"); |
fatal_command_line("too many arguments"); |
1177 |
} |
} |
1178 |
} |
} |
1179 |
|
|
1181 |
char * end; |
char * end; |
1182 |
unsigned long numeric_port = strtoul(port, &end, 10); |
unsigned long numeric_port = strtoul(port, &end, 10); |
1183 |
if (*end != '\0') { |
if (*end != '\0') { |
1184 |
fatal("--port: option must be an integer"); |
fatal_command_line("--port: option must be an integer"); |
1185 |
} |
} |
1186 |
if (numeric_port > UINT16_MAX) { |
if (numeric_port > UINT16_MAX) { |
1187 |
fatal("--port: option must be 16 bits"); |
fatal_command_line("--port: option must be 16 bits"); |
1188 |
} |
} |
1189 |
|
|
1190 |
/* is this a shutdown? */ |
/* is this a shutdown? */ |