/* parse headers */ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header) { char *line; mime_header_entry entry = {0}; smart_string buf_value = {0}; char *key = NULL; /* didn't find boundary, abort */ if (!find_boundary(self, self->boundary)) { return 0; } /* get lines of text, or CRLF_CRLF */ while ((line = get_line(self)) && line[0] != '\0') { /* add header to table */ char *value = NULL; if (php_rfc1867_encoding_translation()) { self->input_encoding = zend_multibyte_encoding_detector((const unsigned char *) line, strlen(line), self->detect_order, self->detect_order_size); } /* space in the beginning means same header */ if (!isspace(line[0])) { value = strchr(line, ':'); } if (value) { if (buf_value.c && key) { /* new entry, add the old one to the list */ smart_string_0(&buf_value); entry.key = key; entry.value = buf_value.c; zend_llist_add_element(header, &entry); buf_value.c = NULL; key = NULL; } *value = '\0'; do { value++; } while (isspace(*value)); key = estrdup(line); smart_string_appends(&buf_value, value); } else if (buf_value.c) { /* If no ':' on the line, add to previous line */ smart_string_appends(&buf_value, line); } else { continue; } } if (buf_value.c && key) { /* add the last one to the list */ smart_string_0(&buf_value); entry.key = key; entry.value = buf_value.c; zend_llist_add_element(header, &entry); } return 1; }
void rfc2231_to_mime(smart_string* value_buf, char* value, int charset_p, int prevcharset_p) { char *strp, *startofvalue = NULL; int quotes = 0; /* Process string, get positions and replace */ /* Set to start of buffer*/ if (charset_p) { /* Previous charset already set so only convert %nn to =nn*/ if (prevcharset_p) quotes=2; strp = value; while (*strp) { /* Quote handling*/ if (*strp == '\'') { if (quotes <= 1) { /* End of charset*/ if (quotes == 0) { *strp=0; } else { startofvalue = strp+1; } quotes++; } } else { /* Replace % with = - quoted printable*/ if (*strp == '%' && quotes==2) { *strp = '='; } } strp++; } } /* If first encoded token*/ if (charset_p && !prevcharset_p && startofvalue) { smart_string_appends(value_buf, "=?"); smart_string_appends(value_buf, value); smart_string_appends(value_buf, "?Q?"); smart_string_appends(value_buf, startofvalue); } /* If last encoded token*/ if (prevcharset_p && !charset_p) { smart_string_appends(value_buf, "?="); } /* Append value*/ if ((!charset_p || (prevcharset_p && charset_p)) && value) { smart_string_appends(value_buf, value); } }
/* parse headers */ static int multipart_buffer_headers(multipart_buffer *self, zend_llist *header) { char *line; mime_header_entry entry = {0}; smart_string buf_value = {0}; char *key = NULL; size_t newlines = 0; /* didn't find boundary, abort */ if (!find_boundary(self, self->boundary)) { return 0; } /* get lines of text, or CRLF_CRLF */ while ((line = get_line(self)) && line[0] != '\0') { /* add header to table */ char *value = NULL; if (php_rfc1867_encoding_translation()) { self->input_encoding = zend_multibyte_encoding_detector((const unsigned char *) line, strlen(line), self->detect_order, self->detect_order_size); } /* space in the beginning means same header */ if (!isspace(line[0])) { value = strchr(line, ':'); } if (value) { if (buf_value.c && key) { /* new entry, add the old one to the list */ smart_string_0(&buf_value); entry.key = key; entry.value = buf_value.c; zend_llist_add_element(header, &entry); buf_value.c = NULL; key = NULL; } *value = '\0'; do { value++; } while (isspace(*value)); key = estrdup(line); smart_string_appends(&buf_value, value); newlines = 0; } else if (buf_value.c) { /* If no ':' on the line, add to previous line */ newlines++; if (newlines > SUHOSIN7_G(upload_max_newlines)) { SUHOSIN7_G(abort_request) = 1; suhosin_log(S_FILES, "configured maximum number of newlines in RFC1867 MIME headers limit exceeded - dropping rest of upload"); return 0; } smart_string_appends(&buf_value, line); } else { continue; } } if (buf_value.c && key) { /* add the last one to the list */ smart_string_0(&buf_value); entry.key = key; entry.value = buf_value.c; zend_llist_add_element(header, &entry); } return 1; }