/*
 * 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;

}
Exemple #3
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; 
}