/* * Checks if body_part contains a Content-Type header. Tranfers this header to * a list content_headers. (Only part before 'boundary'). * Return 1, when Content-Type headers was found, 0 otherwise */ static int check_data_content_type_header(Octstr **body_part, List **content_headers, Octstr *boundary) { long header_pos, next_header_pos; Octstr *content_header; long message_start_pos; header_pos = next_header_pos = -1; content_header = octstr_create("Content-Type"); message_start_pos = octstr_search(*body_part, boundary, 0); if ((header_pos = octstr_case_nsearch(*body_part, content_header, 0, message_start_pos)) < 0) { goto error; } if ((next_header_pos = pass_field_value(body_part, &content_header, header_pos + octstr_len(content_header))) < 0) { goto error; } if ((next_header_pos = parse_terminator(*body_part, next_header_pos)) < 0) { goto error; } octstr_delete(*body_part, header_pos, next_header_pos - header_pos); gwlist_append(*content_headers, octstr_duplicate(content_header)); octstr_destroy(content_header); return 1; error: octstr_destroy(content_header); return 0; }
/* * Extension headers are defined in rfc 822, Appendix D, as fields. We must * parse all rfc 822 headers containing a string "Content". These headers * are optional, too. For general definition of message parts see chapter 4.1. * Specifically: "everything after first null line is message body". */ static int drop_extension_headers(Octstr **body_part, Octstr *boundary) { long content_pos, next_header_pos; long next_content_part_pos; next_content_part_pos = octstr_case_search(*body_part, boundary, 0); do { if ((content_pos = octstr_case_nsearch(*body_part, octstr_imm("Content"), 0, next_content_part_pos)) < 0) return 1; if ((next_header_pos = parse_field_name(*body_part, content_pos)) < 0) return 0; if ((next_header_pos = parse_field_value(*body_part, next_header_pos)) < 0) return 0; if ((next_header_pos = parse_terminator(*body_part, next_header_pos)) == 0) return 0; } while (islwspchar(octstr_get_char(*body_part, next_header_pos))); octstr_delete(*body_part, content_pos, next_header_pos - content_pos); return 1; }
/* These thingies we after normally have after delimiters. */ static int parse_tail(Octstr **multipart, Octstr *delimiter, long boundary_pos, long *next_part_pos) { *next_part_pos = parse_transport_padding(*multipart, boundary_pos + octstr_len(delimiter)); if ((*next_part_pos = parse_terminator(*multipart, *next_part_pos)) < 0) return -1; return 0; }
/* This is actually CRLF epilogue. */ static int parse_epilogue(Octstr **mime_content) { long pos; if (octstr_len(*mime_content) == 0) return 0; if ((pos = parse_terminator(*mime_content, 0)) < 0) return -1; octstr_delete(*mime_content, 0, octstr_len(*mime_content)); return 0; }
/* * This function actually removes a header (deletes corresponding part from * the octet string body_part), in addition of all stuff prepending it. So * deleting start from the octet 0. Content_pos tells where the header starts. */ static int drop_header_true(Octstr **body_part, long content_pos) { long next_header_pos; next_header_pos = -1; if ((next_header_pos = parse_field_value(*body_part, content_pos)) == 0) return 0; if ((next_header_pos = parse_terminator(*body_part, next_header_pos)) == 0) return 0; octstr_delete(*body_part, 0, next_header_pos); return 1; }
/* * Extension headers are optional, see Push Message, chapter 6.2. Field struc- * ture is defined in rfc 822, chapter 3.2. Extension headers are defined in * rfc 2045, chapter 9, grammar in appendix A. (Only to the next null line). * Return 0 when error, 1 otherwise. */ static int pass_extension_headers(Octstr **body_part, List **content_headers, Octstr *boundary) { long next_field_part_pos, count; Octstr *header_name, *header_value; long next_content_part_pos; header_name = octstr_create(""); header_value = octstr_create(""); count = 0; next_field_part_pos = 0; next_content_part_pos = octstr_search(*body_part, boundary, 0); do { if ((octstr_case_nsearch(*body_part, octstr_imm("Content"), 0, next_content_part_pos)) < 0) goto end; if ((next_field_part_pos = pass_field_name(body_part, &header_name, next_field_part_pos)) < 0) goto error; if ((next_field_part_pos = pass_field_value(body_part, &header_value, next_field_part_pos)) < 0) goto error; if ((next_field_part_pos = parse_terminator(*body_part, next_field_part_pos)) == 0) goto error; drop_separator(&header_value, &next_field_part_pos); http_header_add(*content_headers, octstr_get_cstr(header_name), octstr_get_cstr(header_value)); } while (islwspchar(octstr_get_char(*body_part, next_field_part_pos))); octstr_delete(*body_part, 0, next_field_part_pos); /* * An intentional fall-through. We must eventually use a function for memory * cleaning. */ end: octstr_destroy(header_name); octstr_destroy(header_value); return 1; error: octstr_destroy(header_name); octstr_destroy(header_value); return 0; }
/* * We try to find an optional header, so a failure to find one is not an * error. Return -1 when error, 0 when header name not found, 1 otherwise. * Search only until 'boundary'. */ static int pass_optional_header(Octstr **body_part, char *name, List **content_headers, Octstr *boundary) { long content_pos, next_header_pos; Octstr *osname, *osvalue; long message_start_pos; content_pos = next_header_pos = -1; osname = octstr_create(name); osvalue = octstr_create(""); message_start_pos = octstr_search(*body_part, boundary, 0); if ((content_pos = octstr_case_nsearch(*body_part, osname, 0, message_start_pos)) < 0) goto noheader; if ((next_header_pos = pass_field_value(body_part, &osvalue, content_pos + octstr_len(osname))) < 0) goto error; if ((next_header_pos = parse_terminator(*body_part, next_header_pos)) == 0) goto error; drop_separator(&osvalue, &next_header_pos); http_header_add(*content_headers, name, octstr_get_cstr(osvalue)); octstr_delete(*body_part, content_pos, next_header_pos - content_pos); octstr_destroy(osname); octstr_destroy(osvalue); return 1; error: octstr_destroy(osvalue); octstr_destroy(osname); return -1; noheader: octstr_destroy(osvalue); octstr_destroy(osname); return 0; }
bool Parser::parse_statement(StatementList *list) { lexer.identify_keywords(); switch(lexeme()) { case Lexeme::KW_IF: parse_if(list); break; case Lexeme::KW_WHILE: parse_while(list); break; case Lexeme::KW_DO: parse_do(list); parse_terminator(); break; case Lexeme::KW_RETURN: parse_return(list); parse_terminator(); break; case Lexeme::KW_BREAK: parse_break(list); parse_terminator(); break; case Lexeme::KW_CONTINUE: parse_continue(list); parse_terminator(); break; case Lexeme::KW_CONST: step(); parse_local(true, parse_expression(), list); parse_terminator(); break; case Lexeme::BRACET_OPEN: list->append(parse_block<true, false>(Scope::EMPTY)); break; case Lexeme::SEMICOLON: step(); break; case Lexeme::END: case Lexeme::BRACET_CLOSE: return false; default: if(is_expression(lexeme())) { ExpressionNode *node = parse_expression(); if(lexeme() == Lexeme::IDENT && node->is_type_name(document, false)) parse_local(false, node, list); else list->append(node); parse_terminator(); } else return false; } return true; }