/* * Boundary misses crlf here. This is intentional: Kannel header parsing pro- * cess drops this terminator. */ static int parse_preamble(Octstr **mime_content, Octstr *boundary) { long boundary_pos, next_part_pos; Octstr *dash_boundary; boundary_pos = next_part_pos = -1; dash_boundary = make_start_delimiter(boundary); if ((boundary_pos = octstr_search(*mime_content, dash_boundary, 0)) < 0) goto error; if (parse_tail(mime_content, dash_boundary, boundary_pos, &next_part_pos) < 0) goto error; octstr_delete(*mime_content, 0, next_part_pos); octstr_destroy(dash_boundary); return 0; error: octstr_destroy(dash_boundary); return -1; }
/* * Splits the first body part away from the multipart message. A body part end with * either with another body or with a close delimiter. We first split the body and * then remove the separating stuff from the remainder. If we have the last body * part, we must parse all closing stuff. * Returns 1, there is still another body part in the multipart message * 0, if there is none * -1, when parsing error. */ static int parse_body_part (Octstr **multipart, Octstr *boundary, Octstr **body_part) { Octstr *part_delimiter, *close_delimiter; long boundary_pos, /* start of the boundary */ close_delimiter_pos, /* start of the close delimiter */ next_part_pos, /* start of the next part */ epilogue_pos; /* start of the epilogue */ part_delimiter = make_part_delimiter(boundary); close_delimiter = make_close_delimiter(boundary); if ((close_delimiter_pos = octstr_search(*multipart, close_delimiter, 0)) < 0) goto error; boundary_pos = octstr_search(*multipart, part_delimiter, 0); if (boundary_pos == close_delimiter_pos) { octstr_split_by_pos(multipart, body_part, close_delimiter_pos); if ((epilogue_pos = parse_close_delimiter(close_delimiter, *multipart, 0)) < 0) goto error; epilogue_pos = parse_transport_padding(*multipart, epilogue_pos); octstr_delete(*multipart, 0, epilogue_pos); goto last_part; } octstr_split_by_pos(multipart, body_part, boundary_pos); if (parse_tail(multipart, part_delimiter, 0, &next_part_pos) < 0) { goto error; } octstr_delete(*multipart, 0, next_part_pos); octstr_destroy(part_delimiter); octstr_destroy(close_delimiter); return 1; error: octstr_destroy(part_delimiter); octstr_destroy(close_delimiter); return -1; last_part: octstr_destroy(part_delimiter); octstr_destroy(close_delimiter); return 0; }
bool Parser::parse() { skip_newline(false); while (1) { ptr<Token> token = cur(); if (!token->type()) { break; } eat(); if (*token == '\n') { continue; } if (*token == TOKEN_INCLUDE) { bool old_skip_newline = skip_newline(); skip_newline(false); token = cur(); if (*token == TOKEN_CONST_STRING && look()->is_eol()) { eat(); eat(); skip_newline(old_skip_newline); ptr<Path> path = object<Path>(token->text()); if (_input.is_root()) { _symbols.exportSymbol(object<IncludeTree>(path)); } _input.load(path); } else { log_expect(token->loc(), "string eol"); } continue; } SegmentToken *seg = nullptr; if (token->type() == TOKEN_SEGMENT) { seg = static_cast<SegmentToken*>(token.get()); if (!seg->name()) { bool old_skip_newline = skip_newline(); skip_newline(false); if (!look()->is_eol()) { log_expect(token->loc(), "eol"); } skip_newline(old_skip_newline); eat(); } else { seg = nullptr; } } switch (_phase) { case PARSE_PHASE_HEAD: if (seg) { _phase = PARSE_PHASE_BODY; continue; } skip_newline(false); parse_head(token); break; case PARSE_PHASE_BODY: if (seg) { _phase = PARSE_PHASE_TAIL; continue; } skip_newline(true); parse_body(token); break; case PARSE_PHASE_TAIL: if (seg) { log_error(token->loc(), "too more segment declear."); } skip_newline(false); parse_tail(token); break; } } return true; }