[asterisk-commits] murf: branch group/http_mods r60212 -
/team/group/http_mods/main/minimime/
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Wed Apr 4 20:35:40 MST 2007
Author: murf
Date: Wed Apr 4 22:35:40 2007
New Revision: 60212
URL: http://svn.digium.com/view/asterisk?view=rev&rev=60212
Log:
OK, the code is now (I believe) thread-safe. And the length bug is fixed, I think. The test wants the length to be 1279, but that's the opaque_length. The body length not including the headers is 1168, which is what the getlength function is supposed to return... we can invent another function if you need the total length.
Modified:
team/group/http_mods/main/minimime/mimeparser.h
team/group/http_mods/main/minimime/mimeparser.l
team/group/http_mods/main/minimime/mimeparser.y
team/group/http_mods/main/minimime/mm_parse.c
Modified: team/group/http_mods/main/minimime/mimeparser.h
URL: http://svn.digium.com/view/asterisk/team/group/http_mods/main/minimime/mimeparser.h?view=diff&rev=60212&r1=60211&r2=60212
==============================================================================
--- team/group/http_mods/main/minimime/mimeparser.h (original)
+++ team/group/http_mods/main/minimime/mimeparser.h Wed Apr 4 22:35:40 2007
@@ -1,15 +1,7 @@
#ifndef _MIMEPARSER_H_INCLUDED
#define _MIMEPARSER_H_INCLUDED
-/**
- * Prototypes for functions used by the parser routines
- */
-int count_lines(char *);
-void mimieparser_yyerror(const char *);
-int dprintf2(const char *, ...);
-int mimeparser_yyparse(void);
-int mimeparser_yylex(void);
-int mimeparser_yyerror(const char *);
+#include "mm.h"
struct s_position
{
@@ -18,4 +10,58 @@
size_t end;
};
+struct lexer_state
+{
+ int header_state;
+ int lineno;
+ size_t current_pos;
+ int condition;
+
+ int is_envelope;
+
+ size_t message_len;
+ size_t buffer_length;
+
+ /* temporary marker variables */
+ size_t body_opaque_start;
+ size_t body_start;
+ size_t body_end;
+ size_t preamble_start;
+ size_t preamble_end;
+ size_t postamble_start;
+ size_t postamble_end;
+
+ char *boundary_string;
+ char *endboundary_string;
+ char *message_buffer;
+};
+
+
+struct parser_state
+{
+ MM_CTX *ctx;
+ struct mm_mimepart *envelope;
+ struct mm_mimepart *temppart;
+ struct mm_mimepart *current_mimepart;
+ struct mm_content *ctype;
+ int parsemode;
+ int have_contenttype;
+ int debug;
+ int mime_parts;
+ struct lexer_state lstate;
+};
+
+
+#include "mimeparser.tab.h"
+
+/**
+ * Prototypes for functions used by the parser routines
+ */
+int count_lines(char *);
+int dprintf2(struct parser_state *, const char *, ...);
+int mimeparser_yyparse(struct parser_state *, void *);
+int mimeparser_yylex(YYSTYPE *, void *);
+int mimeparser_yyerror(struct parser_state *, void *, const char *);
+
+
#endif /* ! _MIMEPARSER_H_INCLUDED */
Modified: team/group/http_mods/main/minimime/mimeparser.l
URL: http://svn.digium.com/view/asterisk/team/group/http_mods/main/minimime/mimeparser.l?view=diff&rev=60212&r1=60211&r2=60212
==============================================================================
--- team/group/http_mods/main/minimime/mimeparser.l (original)
+++ team/group/http_mods/main/minimime/mimeparser.l Wed Apr 4 22:35:40 2007
@@ -47,9 +47,9 @@
#define NAMEOF(v) #v
/* BC() is a debug wrapper for lex' BEGIN() macro */
#define BC(x) do { \
- dprintf2("Entering condition %d (%s) at line %d\n", x, NAMEOF(x), lineno); \
+ struct lexer_state *lstate = yyget_extra(yyscanner); \
BEGIN(x); \
- condition = x; \
+ lstate->condition = x; \
} while(0);
#define ZERO(x) memset(x, '\0', sizeof(x))
@@ -65,32 +65,13 @@
STATE_MIME
};
-int header_state = STATE_MAIL;
-int lineno = 0;
-size_t current_pos = 1;
-int condition = 0;
-
-int is_envelope = 1;
-
-extern int mime_parts;
-extern char *boundary_string;
-extern char *endboundary_string;
-
-extern const char *message_buffer;
-
-size_t message_len = 0;
-size_t buffer_length = 0;
-
-/* temporary marker variables */
-size_t body_opaque_start = 0;
-size_t body_start = 0;
-size_t body_end = 0;
-size_t preamble_start = 0;
-size_t preamble_end = 0;
-size_t postamble_start = 0;
-size_t postamble_end = 0;
+
%}
+
+%option reentrant
+%option yylineno
+%option bison-bridge
%s headers
%s header
@@ -111,55 +92,55 @@
%%
<INITIAL,headers>^[a-zA-Z]+[a-zA-Z0-9\-\_]* {
- mimeparser_yylval.string=strdup(yytext);
- current_pos += yyleng;
+ yylval_param->string=strdup(yytext);
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ lstate->current_pos += yyleng;
BC(header);
/* Depending on what header we are processing, we enter a different
* state and return a different value.
*/
if (!strcasecmp(yytext, "Content-Type")) {
- header_state = STATE_CTYPE;
+ lstate->header_state = STATE_CTYPE;
return CONTENTTYPE_HEADER;
} else if (!strcasecmp(yytext, "Content-Transfer-Encoding")) {
- header_state = STATE_CENC;
+ lstate->header_state = STATE_CENC;
return CONTENTENCODING_HEADER;
} else if (!strcasecmp(yytext, "Content-Disposition")) {
- header_state = STATE_CDISP;
+ lstate->header_state = STATE_CDISP;
return CONTENTDISPOSITION_HEADER;
} else if (!strcasecmp(yytext, "MIME-Version")) {
- header_state = STATE_MAIL;
+ lstate->header_state = STATE_MAIL;
return MIMEVERSION_HEADER;
} else {
- header_state = STATE_MAIL;
+ lstate->header_state = STATE_MAIL;
return MAIL_HEADER;
}
}
<INITIAL,headers>. {
- dprintf2("Unknown header char: %c\n", *yytext);
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ /* dprintf2("Unknown header char: %c\n", *yytext); */
+ lstate->current_pos += yyleng;
return ANY;
}
<headers>^(\r\n|\n) {
- lineno++;
- dprintf2("END OF HEADERS\n");
-
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ lstate->lineno++;
+
+ lstate->current_pos += yyleng;
/* This marks the end of headers. Depending on whether we are in the
* envelope currently we need to parse either a body or the preamble
* now.
*/
- if (is_envelope == 0 || boundary_string == NULL) {
- dprintf2("BODY!\n");
+ if (lstate->is_envelope == 0 || lstate->boundary_string == NULL) {
BC(body);
- body_start = current_pos;
+ lstate->body_start = lstate->current_pos;
} else {
- dprintf2("PREAMBLE\n");
- is_envelope = 0;
- preamble_start = current_pos;
+ lstate->is_envelope = 0;
+ lstate->preamble_start = lstate->current_pos;
BC(preamble);
}
@@ -167,93 +148,101 @@
}
<header>\: {
+ struct lexer_state *lstate = yyget_extra(yyscanner);
BC(headervalue);
- current_pos += yyleng;
+ lstate->current_pos += yyleng;
return COLON;
}
<header>(\r\n|\n) {
+ struct lexer_state *lstate = yyget_extra(yyscanner);
BC(headers);
- dprintf2("Invalid header, returning EOL\n");
- current_pos += yyleng;
+ /* dprintf2("Invalid header, returning EOL\n"); */
+ lstate->current_pos += yyleng;
return EOL;
}
<headervalue>(\n|\r\n)[\ \t]+ {
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ lstate->current_pos += yyleng;
}
<headervalue>.+|(.+(\n|\r\n)[\ \t]+.+)+ {
- if (header_state != STATE_MAIL && header_state != STATE_CENC) {
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ if (lstate->header_state != STATE_MAIL && lstate->header_state != STATE_CENC) {
REJECT;
}
- dprintf2("MAIL HEADER:%s\n", yytext);
- current_pos += yyleng;
+ lstate->current_pos += yyleng;
while (*yytext && isspace(*yytext)) yytext++;
/* Do we actually have a header value? */
if (*yytext == '\0') {
- mimeparser_yylval.string = strdup("");
+ yylval_param->string = strdup("");
} else {
- mimeparser_yylval.string=strdup(yytext);
- lineno += count_lines(yytext);
+ yylval_param->string=strdup(yytext);
+ lstate->lineno += count_lines(yytext);
}
return WORD;
}
<headervalue,tspecialvalue>(\r\n|\n) {
+ struct lexer_state *lstate = yyget_extra(yyscanner);
/* marks the end of one header line */
- lineno++;
- dprintf2("EOL\n");
+ lstate->lineno++;
BC(headers);
- current_pos += yyleng;
+ lstate->current_pos += yyleng;
return EOL;
}
<headervalue>;|;(\r\n|\n)[\ \t]+ {
- dprintf2("SEMICOLON\n");
- lineno += count_lines(yytext);
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ lstate->lineno += count_lines(yytext);
+ lstate->current_pos += yyleng;
return SEMICOLON;
}
<headervalue>\= {
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ lstate->current_pos += yyleng;
return EQUAL;
}
<headervalue>\" {
+ struct lexer_state *lstate = yyget_extra(yyscanner);
BC(tspecialvalue);
- current_pos += yyleng;
+ lstate->current_pos += yyleng;
return *yytext;
}
<headervalue>{STRING}+|{TSPECIAL_LITE}+ {
- dprintf2("W: %s\n", yytext);
- mimeparser_yylval.string=strdup(yytext);
- lineno += count_lines(yytext);
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ yylval_param->string=strdup(yytext);
+ lstate->lineno += count_lines(yytext);
+ lstate->current_pos += yyleng;
return WORD;
}
<headervalue>[\ |\t]+ {
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ lstate->current_pos += yyleng;
}
<tspecialvalue>{TSPECIAL}+ {
- dprintf2("T: %s\n", yytext);
- lineno += count_lines(yytext);
- mimeparser_yylval.string=strdup(yytext);
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ lstate->lineno += count_lines(yytext);
+ yylval_param->string=strdup(yytext);
+ lstate->current_pos += yyleng;
return TSPECIAL;
}
<tspecialvalue>\" {
+ struct lexer_state *lstate = yyget_extra(yyscanner);
BC(headervalue);
- current_pos += yyleng;
+ lstate->current_pos += yyleng;
return *yytext;
}
<body>^\-\-{TSPECIAL}+\-\- {
+ struct lexer_state *lstate = yyget_extra(yyscanner);
/**
* Make sure we only catch matching boundaries, and not other lines
* that begin and end with two dashes. If we have catched a valid
@@ -261,197 +250,210 @@
* position, put the token back on the input stream and let the
* endboundary condition parse the actual token.
*/
- if (endboundary_string != NULL) {
- if (strcmp(endboundary_string, yytext)) {
- dprintf2("YYTEXT != end_boundary: '%s'\n", yytext);
+ if (lstate->endboundary_string != NULL) {
+ if (strcmp(lstate->endboundary_string, yytext)) {
+ /* dprintf2("YYTEXT != end_boundary: '%s'\n", yytext); */
REJECT;
} else {
- current_pos += yyleng;
- dprintf2("YYTEXT == end_boundary: '%s'\n", yytext);
- if (body_start) {
- mimeparser_yylval.position.opaque_start =
- body_opaque_start;
- mimeparser_yylval.position.start = body_start;
- mimeparser_yylval.position.end = current_pos - yyleng;
- body_opaque_start = 0;
- body_start = 0;
- body_end = 0;
+ lstate->current_pos += yyleng;
+ /* dprintf2("YYTEXT == lstate->end_boundary: '%s'\n", yytext); */
+ if (lstate->body_start) {
+ yylval_param->position.opaque_start =
+ lstate->body_opaque_start;
+ yylval_param->position.start = lstate->body_start;
+ yylval_param->position.end = lstate->current_pos - yyleng;
+ lstate->body_opaque_start = 0;
+ lstate->body_start = 0;
+ lstate->body_end = 0;
yyless(0);
BC(endboundary);
return BODY;
}
}
} else {
- dprintf2("FOO!\n");
}
REJECT;
}
<body,preamble>^\-\-{TSPECIAL}+ {
+ struct lexer_state *lstate = yyget_extra(yyscanner);
/**
* Make sure we only catch matching boundaries, and not other lines
* that begin with two dashes.
*/
- if (boundary_string != NULL) {
- if (strcmp(boundary_string, yytext)) {
- dprintf2("YYTEXT != boundary: '%s'\n", yytext);
+ if (lstate->boundary_string != NULL) {
+ if (strcmp(lstate->boundary_string, yytext)) {
+ /* dprintf2("YYTEXT != boundary: '%s'\n", yytext);*/
REJECT;
} else {
- dprintf2("YYTEXT == boundary: '%s'\n", yytext);
- if (body_start) {
- mimeparser_yylval.position.opaque_start = body_opaque_start;
- mimeparser_yylval.position.start = body_start;
- mimeparser_yylval.position.end = current_pos;
- body_opaque_start = 0;
- body_start = 0;
- body_end = 0;
+ /* dprintf2("YYTEXT == boundary: '%s'\n", yytext);*/
+ if (lstate->body_start) {
+ yylval_param->position.opaque_start = lstate->body_opaque_start;
+ yylval_param->position.start = lstate->body_start;
+ yylval_param->position.end = lstate->current_pos;
+ lstate->body_opaque_start = 0;
+ lstate->body_start = 0;
+ lstate->body_end = 0;
yyless(0);
BC(boundary);
return BODY;
- } else if (preamble_start) {
- mimeparser_yylval.position.start = preamble_start;
- mimeparser_yylval.position.end = current_pos;
- preamble_start = preamble_end = 0;
+ } else if (lstate->preamble_start) {
+ yylval_param->position.start = lstate->preamble_start;
+ yylval_param->position.end = lstate->current_pos;
+ lstate->preamble_start = lstate->preamble_end = 0;
yyless(0);
BC(boundary);
return PREAMBLE;
} else {
BC(boundary);
- mimeparser_yylval.string = strdup(yytext);
- current_pos += yyleng;
+ yylval_param->string = strdup(yytext);
+ lstate->current_pos += yyleng;
return(BOUNDARY);
}
}
} else {
- dprintf2("FOO\n");
}
REJECT;
}
<body>(\r\n|\n) {
- current_pos += yyleng;
- lineno++;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ lstate->current_pos += yyleng;
+ lstate->lineno++;
}
<body>\r {
- current_pos += yyleng;
- dprintf2("stray CR in body...\n");
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ lstate->current_pos += yyleng;
+ /* dprintf2("stray CR in body...\n"); */
}
<body>[^\r\n]+ {
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ lstate->current_pos += yyleng;
}
<body><<EOF>> {
- if (boundary_string == NULL && body_start) {
- mimeparser_yylval.position.opaque_start = 0;
- mimeparser_yylval.position.start = body_start;
- mimeparser_yylval.position.end = current_pos;
- body_start = 0;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ if (lstate->boundary_string == NULL && lstate->body_start) {
+ yylval_param->position.opaque_start = 0;
+ yylval_param->position.start = lstate->body_start;
+ yylval_param->position.end = lstate->current_pos;
+ lstate->body_start = 0;
return BODY;
- } else if (body_start) {
+ } else if (lstate->body_start) {
return POSTAMBLE;
}
yyterminate();
}
<preamble,postamble>(\r\n|\n) {
- dprintf2("Preamble CR/LF at line %d\n", lineno);
- lineno++;
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ /* dprintf2("Preamble CR/LF at line %d\n", lineno); */
+ lstate->lineno++;
+ lstate->current_pos += yyleng;
}
<boundary>[^\r\n]+ {
- mimeparser_yylval.string = strdup(yytext);
- dprintf2("B: '%s'\n", yytext);
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ yylval_param->string = strdup(yytext);
+ lstate->current_pos += yyleng;
return BOUNDARY;
}
<endboundary>[^\r\n]+ {
- mimeparser_yylval.string = strdup(yytext);
- dprintf2("EB: %s\n", yytext);
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ yylval_param->string = strdup(yytext);
+ lstate->current_pos += yyleng;
return ENDBOUNDARY;
}
<boundary>(\r\n|\n) {
+ struct lexer_state *lstate = yyget_extra(yyscanner);
BC(headers);
- lineno++;
- dprintf2("Boundary end of line: %d\n", lineno);
- current_pos += yyleng;
- body_opaque_start = current_pos;
+ lstate->lineno++;
+ lstate->current_pos += yyleng;
+ lstate->body_opaque_start = lstate->current_pos;
return EOL;
}
<endboundary>(\r\n|\n) {
+ struct lexer_state *lstate = yyget_extra(yyscanner);
BC(postamble);
- lineno++;
- current_pos += yyleng;
- dprintf2("Endboundary end of line\n");
+ lstate->lineno++;
+ lstate->current_pos += yyleng;
}
<preamble>. {
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ lstate->current_pos += yyleng;
}
<postamble>. {
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ lstate->current_pos += yyleng;
}
(\r\n|\n) {
- lineno++;
- dprintf2("End of header UNCLASSED!\n");
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ lstate->lineno++;
+ lstate->current_pos += yyleng;
return EOL;
}
. {
- dprintf2("UC: '%c' in condition %d\n", *yytext, condition);
- current_pos += yyleng;
+ struct lexer_state *lstate = yyget_extra(yyscanner);
+ lstate->current_pos += yyleng;
return((int)*yytext);
}
%%
-void reset_lexer_state(void)
+void reset_lexer_state(void *yyscanner, struct parser_state *pstate)
{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ struct lexer_state *lstate = &(pstate->lstate);
+
+ yyset_extra((void*)lstate, yyscanner);
BEGIN(0);
- header_state = STATE_MAIL;
- lineno = 0;
- current_pos = 1;
- condition = 0;
-
- is_envelope = 1;
-
- message_len = 0;
- buffer_length = 0;
+ lstate->header_state = STATE_MAIL;
+ lstate->lineno = 0;
+ lstate->current_pos = 1;
+ lstate->condition = 0;
+
+ lstate->is_envelope = 1;
+
+ lstate->message_len = 0;
+ lstate->buffer_length = 0;
/* temporary marker variables */
- body_opaque_start = 0;
- body_start = 0;
- body_end = 0;
- preamble_start = 0;
- preamble_end = 0;
- postamble_start = 0;
- postamble_end = 0;
+ lstate->body_opaque_start = 0;
+ lstate->body_start = 0;
+ lstate->body_end = 0;
+ lstate->preamble_start = 0;
+ lstate->preamble_end = 0;
+ lstate->postamble_start = 0;
+ lstate->postamble_end = 0;
}
void
-PARSER_setbuffer(const char *string)
+PARSER_setbuffer(char *string, yyscan_t scanner)
{
- message_buffer = string;
- yy_scan_string(string);
+ struct lexer_state *lstate = yyget_extra(scanner);
+ lstate->message_buffer = string;
+ yy_scan_string(string, scanner);
}
void
-PARSER_setfp(FILE *fp)
+PARSER_setfp(FILE *fp, yyscan_t yyscanner)
{
- mimeparser_yyin = fp;
+ /* looks like a bug in bison 2.2a -- the wrong code is generated for yyset_in !! */
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyg->yyin_r = fp;
}
/**
Modified: team/group/http_mods/main/minimime/mimeparser.y
URL: http://svn.digium.com/view/asterisk/team/group/http_mods/main/minimime/mimeparser.y?view=diff&rev=60212&r1=60211&r2=60212
==============================================================================
--- team/group/http_mods/main/minimime/mimeparser.y (original)
+++ team/group/http_mods/main/minimime/mimeparser.y Wed Apr 4 22:35:40 2007
@@ -39,6 +39,7 @@
*/
#include <stdio.h>
#include <stdarg.h>
+#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
@@ -47,41 +48,19 @@
#include "mm.h"
#include "mm_internal.h"
-int set_boundary(char *);
-
-/* globals to get rid of */
-extern int lineno;
-extern int condition;
-char *boundary_string = NULL;
-char *endboundary_string = NULL;
-const char *message_buffer = NULL;
-extern FILE *mimeparser_yyin;
-FILE *curin;
-static int mime_parts = 0;
-static int debug = 0;
-/* MiniMIME specific object pointers */
-static MM_CTX *ctx;
-static struct mm_mimepart *envelope = NULL;
-static struct mm_mimepart *tmppart = NULL;
-static struct mm_content *ctype = NULL;
-/* Always points to the current MIME part */
-static struct mm_mimepart *current_mimepart = NULL;
-
-/* Marker for indicating a found Content-Type header */
-static int have_contenttype;
-/* The parse mode */
-static int parsemode;
-
-
-
-
-
-
-
-
-static char *PARSE_readmessagepart(size_t, size_t, size_t, size_t *);
+int set_boundary(char *,struct parser_state *);
+
+typedef void *yyscan_t;
+
+static char *PARSE_readmessagepart(size_t, size_t, size_t, size_t *,yyscan_t, struct parser_state *);
+FILE *mimeparser_yyget_in (yyscan_t yyscanner );
%}
+
+%pure-parser
+%parse-param {struct parser_state *pstate}
+%parse-param {void *yyscanner}
+%lex-param {void *yyscanner}
%union
{
@@ -137,21 +116,21 @@
multipart_message:
headers preamble
{
- mm_context_attachpart(ctx, current_mimepart);
- current_mimepart = mm_mimepart_new();
- have_contenttype = 0;
+ mm_context_attachpart(pstate->ctx, pstate->current_mimepart);
+ pstate->current_mimepart = mm_mimepart_new();
+ pstate->have_contenttype = 0;
}
mimeparts endboundary postamble
{
- dprintf2("This was a multipart message\n");
+ dprintf2(pstate,"This was a multipart message\n");
}
;
singlepart_message:
headers body
{
- dprintf2("This was a single part message\n");
- mm_context_attachpart(ctx, current_mimepart);
+ dprintf2(pstate,"This was a single part message\n");
+ mm_context_attachpart(pstate->ctx, pstate->current_mimepart);
}
;
@@ -168,7 +147,7 @@
struct mm_content *ct;
struct mm_param *param;
- if (!have_contenttype) {
+ if (!pstate->have_contenttype) {
ct = mm_content_new();
mm_content_settype(ct, "text/plain");
@@ -177,9 +156,9 @@
param->value = xstrdup("us-ascii");
mm_content_attachtypeparam(ct, param);
- mm_mimepart_attachcontenttype(current_mimepart, ct);
- }
- have_contenttype = 0;
+ mm_mimepart_attachcontenttype(pstate->current_mimepart, ct);
+ }
+ pstate->have_contenttype = 0;
}
|
header
@@ -193,12 +172,12 @@
if ($1.start != $1.end) {
preamble = PARSE_readmessagepart(0, $1.start, $1.end,
- &offset);
+ &offset,yyscanner,pstate);
if (preamble == NULL) {
return(-1);
}
- ctx->preamble = preamble;
- dprintf2("PREAMBLE:\n%s\n", preamble);
+ pstate->ctx->preamble = preamble;
+ dprintf2(pstate,"PREAMBLE:\n%s\n", preamble);
}
}
|
@@ -221,14 +200,14 @@
boundary headers body
{
- if (mm_context_attachpart(ctx, current_mimepart) == -1) {
+ if (mm_context_attachpart(pstate->ctx, pstate->current_mimepart) == -1) {
mm_errno = MM_ERROR_ERRNO;
return(-1);
}
- tmppart = mm_mimepart_new();
- current_mimepart = tmppart;
- mime_parts++;
+ pstate->temppart = mm_mimepart_new();
+ pstate->current_mimepart = pstate->temppart;
+ pstate->mime_parts++;
}
;
@@ -237,11 +216,11 @@
|
contenttype_header
{
- have_contenttype = 1;
- if (mm_content_iscomposite(envelope->type)) {
- ctx->messagetype = MM_MSGTYPE_MULTIPART;
+ pstate->have_contenttype = 1;
+ if (mm_content_iscomposite(pstate->envelope->type)) {
+ pstate->ctx->messagetype = MM_MSGTYPE_MULTIPART;
} else {
- ctx->messagetype = MM_MSGTYPE_FLAT;
+ pstate->ctx->messagetype = MM_MSGTYPE_FLAT;
}
}
|
@@ -253,10 +232,10 @@
|
invalid_header
{
- if (parsemode != MM_PARSE_LOOSE) {
+ if (pstate->parsemode != MM_PARSE_LOOSE) {
mm_errno = MM_ERROR_PARSE;
mm_error_setmsg("invalid header encountered");
- mm_error_setlineno(lineno);
+ mm_error_setlineno(pstate->lstate.lineno);
return(-1);
} else {
/* TODO: attach MM_WARNING_INVHDR */
@@ -269,56 +248,56 @@
{
struct mm_mimeheader *hdr;
hdr = mm_mimeheader_generate($1, $3);
- mm_mimepart_attachheader(current_mimepart, hdr);
+ mm_mimepart_attachheader(pstate->current_mimepart, hdr);
}
|
MAIL_HEADER COLON EOL
{
struct mm_mimeheader *hdr;
- if (parsemode != MM_PARSE_LOOSE) {
+ if (pstate->parsemode != MM_PARSE_LOOSE) {
mm_errno = MM_ERROR_MIME;
mm_error_setmsg("invalid header encountered");
- mm_error_setlineno(lineno);
+ mm_error_setlineno(pstate->lstate.lineno);
return(-1);
} else {
/* TODO: attach MM_WARNING_INVHDR */
}
hdr = mm_mimeheader_generate($1, xstrdup(""));
- mm_mimepart_attachheader(current_mimepart, hdr);
+ mm_mimepart_attachheader(pstate->current_mimepart, hdr);
}
;
contenttype_header:
CONTENTTYPE_HEADER COLON mimetype EOL
{
- mm_content_settype(ctype, "%s", $3);
- mm_mimepart_attachcontenttype(current_mimepart, ctype);
- dprintf2("Content-Type -> %s\n", $3);
- ctype = mm_content_new();
+ mm_content_settype(pstate->ctype, "%s", $3);
+ mm_mimepart_attachcontenttype(pstate->current_mimepart, pstate->ctype);
+ dprintf2(pstate,"Content-Type -> %s\n", $3);
+ pstate->ctype = mm_content_new();
}
|
CONTENTTYPE_HEADER COLON mimetype contenttype_parameters EOL
{
- mm_content_settype(ctype, "%s", $3);
- mm_mimepart_attachcontenttype(current_mimepart, ctype);
- dprintf2("Content-Type (P) -> %s\n", $3);
- ctype = mm_content_new();
+ mm_content_settype(pstate->ctype, "%s", $3);
+ mm_mimepart_attachcontenttype(pstate->current_mimepart, pstate->ctype);
+ dprintf2(pstate,"Content-Type (P) -> %s\n", $3);
+ pstate->ctype = mm_content_new();
}
;
contentdisposition_header:
CONTENTDISPOSITION_HEADER COLON content_disposition EOL
{
- dprintf2("Content-Disposition -> %s\n", $3);
- ctype->disposition_type = xstrdup($3);
+ dprintf2(pstate,"Content-Disposition -> %s\n", $3);
+ pstate->ctype->disposition_type = xstrdup($3);
}
|
CONTENTDISPOSITION_HEADER COLON content_disposition content_disposition_parameters EOL
{
- dprintf2("Content-Disposition (P) -> %s; params\n", $3);
- ctype->disposition_type = xstrdup($3);
+ dprintf2(pstate,"Content-Disposition (P) -> %s; params\n", $3);
+ pstate->ctype->disposition_type = xstrdup($3);
}
;
@@ -333,7 +312,7 @@
*/
if (strcasecmp($1, "inline") && strcasecmp($1, "attachment")
&& strncasecmp($1, "X-", 2)) {
- if (parsemode != MM_PARSE_LOOSE) {
+ if (pstate->parsemode != MM_PARSE_LOOSE) {
mm_errno = MM_ERROR_MIME;
mm_error_setmsg("invalid content-disposition");
return(-1);
@@ -348,14 +327,14 @@
contentencoding_header:
CONTENTENCODING_HEADER COLON WORD EOL
{
- dprintf2("Content-Transfer-Encoding -> %s\n", $3);
+ dprintf2(pstate,"Content-Transfer-Encoding -> %s\n", $3);
}
;
mimeversion_header:
MIMEVERSION_HEADER COLON WORD EOL
{
- dprintf2("MIME-Version -> '%s'\n", $3);
+ dprintf2(pstate,"MIME-Version -> '%s'\n", $3);
}
;
@@ -385,10 +364,10 @@
|
SEMICOLON
{
- if (parsemode != MM_PARSE_LOOSE) {
+ if (pstate->parsemode != MM_PARSE_LOOSE) {
mm_errno = MM_ERROR_MIME;
mm_error_setmsg("invalid Content-Type header");
- mm_error_setlineno(lineno);
+ mm_error_setlineno(pstate->lstate.lineno);
return(-1);
} else {
/* TODO: attach MM_WARNING_INVHDR */
@@ -403,10 +382,10 @@
|
SEMICOLON
{
- if (parsemode != MM_PARSE_LOOSE) {
+ if (pstate->parsemode != MM_PARSE_LOOSE) {
mm_errno = MM_ERROR_MIME;
mm_error_setmsg("invalid Content-Disposition header");
- mm_error_setlineno(lineno);
+ mm_error_setlineno(pstate->lstate.lineno);
return(-1);
} else {
/* TODO: attach MM_WARNING_INVHDR */
@@ -420,14 +399,14 @@
struct mm_param *param;
param = mm_param_new();
- dprintf2("Param: '%s', Value: '%s'\n", $1, $3);
+ dprintf2(pstate,"Param: '%s', Value: '%s'\n", $1, $3);
/* Catch an eventual boundary identifier */
if (!strcasecmp($1, "boundary")) {
- if (boundary_string == NULL) {
- set_boundary($3);
+ if (pstate->lstate.boundary_string == NULL) {
+ set_boundary($3,pstate);
} else {
- if (parsemode != MM_PARSE_LOOSE) {
+ if (pstate->parsemode != MM_PARSE_LOOSE) {
mm_errno = MM_ERROR_MIME;
mm_error_setmsg("duplicate boundary "
"found");
@@ -441,7 +420,7 @@
param->name = xstrdup($1);
param->value = xstrdup($3);
- mm_content_attachtypeparam(ctype, param);
+ mm_content_attachtypeparam(pstate->ctype, param);
}
;
@@ -454,7 +433,7 @@
param->name = xstrdup($1);
param->value = xstrdup($3);
- mm_content_attachdispositionparam(ctype, param);
+ mm_content_attachdispositionparam(pstate->ctype, param);
}
;
@@ -462,18 +441,18 @@
contenttype_parameter_value:
WORD
{
- dprintf2("contenttype_param_val: WORD=%s\n", $1);
+ dprintf2(pstate,"contenttype_param_val: WORD=%s\n", $1);
$$ = $1;
}
|
TSPECIAL
{
- dprintf2("contenttype_param_val: TSPECIAL\n");
+ dprintf2(pstate,"contenttype_param_val: TSPECIAL\n");
/* For broken MIME implementation */
- if (parsemode != MM_PARSE_LOOSE) {
+ if (pstate->parsemode != MM_PARSE_LOOSE) {
mm_errno = MM_ERROR_MIME;
mm_error_setmsg("tspecial without quotes");
- mm_error_setlineno(lineno);
+ mm_error_setlineno(pstate->lstate.lineno);
return(-1);
} else {
/* TODO: attach MM_WARNING_INVAL */
@@ -483,7 +462,7 @@
|
'"' TSPECIAL '"'
{
- dprintf2("contenttype_param_val: \"TSPECIAL\"\n" );
+ dprintf2(pstate,"contenttype_param_val: \"TSPECIAL\"\n" );
$$ = $2;
}
;
@@ -491,45 +470,45 @@
end_headers :
ENDOFHEADERS
{
- dprintf2("End of headers at line %d\n", lineno);
+ dprintf2(pstate,"End of headers at line %d\n", pstate->lstate.lineno);
}
;
boundary :
BOUNDARY EOL
{
- if (boundary_string == NULL) {
+ if (pstate->lstate.boundary_string == NULL) {
mm_errno = MM_ERROR_PARSE;
mm_error_setmsg("internal incosistency");
- mm_error_setlineno(lineno);
- return(-1);
- }
- if (strcmp(boundary_string, $1)) {
+ mm_error_setlineno(pstate->lstate.lineno);
+ return(-1);
+ }
+ if (strcmp(pstate->lstate.boundary_string, $1)) {
mm_errno = MM_ERROR_PARSE;
mm_error_setmsg("invalid boundary: '%s' (%d)", $1, strlen($1));
- mm_error_setlineno(lineno);
- return(-1);
- }
- dprintf2("New MIME part... (%s)\n", $1);
+ mm_error_setlineno(pstate->lstate.lineno);
+ return(-1);
+ }
+ dprintf2(pstate,"New MIME part... (%s)\n", $1);
}
;
endboundary :
ENDBOUNDARY
{
- if (endboundary_string == NULL) {
+ if (pstate->lstate.endboundary_string == NULL) {
mm_errno = MM_ERROR_PARSE;
mm_error_setmsg("internal incosistency");
- mm_error_setlineno(lineno);
- return(-1);
- }
- if (strcmp(endboundary_string, $1)) {
+ mm_error_setlineno(pstate->lstate.lineno);
+ return(-1);
+ }
+ if (strcmp(pstate->lstate.endboundary_string, $1)) {
mm_errno = MM_ERROR_PARSE;
mm_error_setmsg("invalid end boundary: %s", $1);
- mm_error_setlineno(lineno);
- return(-1);
- }
- dprintf2("End of MIME message\n");
+ mm_error_setlineno(pstate->lstate.lineno);
+ return(-1);
+ }
+ dprintf2(pstate,"End of MIME message\n");
}
;
@@ -539,18 +518,18 @@
char *body;
size_t offset;
- dprintf2("BODY (%d/%d), SIZE %d\n", $1.start, $1.end, $1.end - $1.start);
+ dprintf2(pstate,"BODY (%d/%d), SIZE %d\n", $1.start, $1.end, $1.end - $1.start);
body = PARSE_readmessagepart($1.opaque_start, $1.start, $1.end,
- &offset);
+ &offset,yyscanner,pstate);
if (body == NULL) {
return(-1);
- }
- current_mimepart->opaque_body = body;
- current_mimepart->body = body + offset;
- current_mimepart->opaque_length = strlen(body);
- current_mimepart->length = current_mimepart->opaque_length - offset - 1;
+ }
+ pstate->current_mimepart->opaque_body = body;
+ pstate->current_mimepart->body = body + offset;
+ pstate->current_mimepart->opaque_length = $1.end - $1.start - 2;
+ pstate->current_mimepart->length = pstate->current_mimepart->opaque_length - offset;
}
;
@@ -561,7 +540,7 @@
*/
static char *
PARSE_readmessagepart(size_t opaque_start, size_t real_start, size_t end,
- size_t *offset)
+ size_t *offset, yyscan_t yyscanner, struct parser_state *pstate)
{
size_t body_size;
size_t current;
@@ -597,19 +576,19 @@
if (end <= start) {
mm_errno = MM_ERROR_PARSE;
mm_error_setmsg("internal incosistency,2");
- mm_error_setlineno(lineno);
+ mm_error_setlineno(pstate->lstate.lineno);
return(NULL);
}
if (start < *offset) {
mm_errno = MM_ERROR_PARSE;
- mm_error_setmsg("internal incosistency, S:%d,O:%d,L:%d", start, offset, lineno);
- mm_error_setlineno(lineno);
+ mm_error_setmsg("internal incosistency, S:%d,O:%d,L:%d", start, offset, pstate->lstate.lineno);
+ mm_error_setlineno(pstate->lstate.lineno);
return(NULL);
}
if (start < 0 || end < 0) {
mm_errno = MM_ERROR_PARSE;
mm_error_setmsg("internal incosistency,4");
- mm_error_setlineno(lineno);
+ mm_error_setlineno(pstate->lstate.lineno);
return(NULL);
}
@@ -622,7 +601,7 @@
if (body_size < 1) {
mm_errno = MM_ERROR_PARSE;
mm_error_setmsg("size of body cannot be < 1");
- mm_error_setlineno(lineno);
+ mm_error_setlineno(pstate->lstate.lineno);
return(NULL);
}
@@ -635,13 +614,14 @@
/* Get the message body either from a stream or a memory
* buffer.
*/
- if (mimeparser_yyin != NULL) {
- current = ftell(curin);
- fseek(curin, start - 1, SEEK_SET);
- fread(body, body_size - 1, 1, curin);
- fseek(curin, current, SEEK_SET);
- } else if (message_buffer != NULL) {
- strlcpy(body, message_buffer + start - 1, body_size);
+ if (mimeparser_yyget_in(yyscanner) != NULL) {
+ FILE *x = mimeparser_yyget_in(yyscanner);
+ current = ftell(x);
+ fseek(x, start - 1, SEEK_SET);
+ fread(body, body_size - 1, 1, x);
+ fseek(x, current, SEEK_SET);
+ } else if (pstate->lstate.message_buffer != NULL) {
+ strlcpy(body, pstate->lstate.message_buffer + start - 1, body_size);
}
return(body);
@@ -649,11 +629,11 @@
}
int
-mimeparser_yyerror(const char *str)
+yyerror(struct parser_state *pstate, void *yyscanner, const char *str)
{
mm_errno = MM_ERROR_PARSE;
mm_error_setmsg("%s", str);
- mm_error_setlineno(lineno);
+ mm_error_setlineno(pstate->lstate.lineno);
return -1;
}
@@ -667,29 +647,29 @@
* Sets the boundary value for the current message
*/
int
-set_boundary(char *str)
+set_boundary(char *str, struct parser_state *pstate)
{
size_t blen;
blen = strlen(str);
- boundary_string = (char *)malloc(blen + 3);
- endboundary_string = (char *)malloc(blen + 5);
-
- if (boundary_string == NULL || endboundary_string == NULL) {
- if (boundary_string != NULL) {
- free(boundary_string);
- }
- if (endboundary_string != NULL) {
- free(endboundary_string);
+ pstate->lstate.boundary_string = (char *)malloc(blen + 3);
+ pstate->lstate.endboundary_string = (char *)malloc(blen + 5);
+
+ if (pstate->lstate.boundary_string == NULL || pstate->lstate.endboundary_string == NULL) {
+ if (pstate->lstate.boundary_string != NULL) {
+ free(pstate->lstate.boundary_string);
+ }
+ if (pstate->lstate.endboundary_string != NULL) {
+ free(pstate->lstate.endboundary_string);
}
return -1;
}
- ctx->boundary = xstrdup(str);
-
- snprintf(boundary_string, blen + 3, "--%s", str);
- snprintf(endboundary_string, blen + 5, "--%s--", str);
+ pstate->ctx->boundary = xstrdup(str);
+
+ snprintf(pstate->lstate.boundary_string, blen + 3, "--%s", str);
+ snprintf(pstate->lstate.endboundary_string, blen + 5, "--%s--", str);
return 0;
}
@@ -698,11 +678,11 @@
* Debug printf()
*/
int
-dprintf2(const char *fmt, ...)
+dprintf2(struct parser_state *pstate, const char *fmt, ...)
{
va_list ap;
char *msg;
- if (debug == 0) return 1;
+ if (pstate->debug == 0) return 1;
va_start(ap, fmt);
vasprintf(&msg, fmt, ap);
@@ -715,59 +695,51 @@
}
-void reset_environ(void)
+void reset_environ(struct parser_state *pstate)
{
- lineno = 0;
- condition = 0;
- boundary_string = NULL;
- endboundary_string = NULL;
- message_buffer = NULL;
- mime_parts = 0;
- debug = 0;
- ctx= NULL;
- envelope = NULL;
- tmppart = NULL;
- ctype = NULL;
- current_mimepart = NULL;
-
- have_contenttype = 0;
- parsemode=0;
+ pstate->lstate.lineno = 0;
+ pstate->lstate.boundary_string = NULL;
+ pstate->lstate.endboundary_string = NULL;
+ pstate->lstate.message_buffer = NULL;
+ pstate->mime_parts = 0;
+ pstate->debug = 0;
+ pstate->envelope = NULL;
+ pstate->temppart = NULL;
+ pstate->ctype = NULL;
+ pstate->current_mimepart = NULL;
+
+ pstate->have_contenttype = 0;
}
/**
* Initializes the parser engine.
*/
int
-PARSER_initialize(MM_CTX *newctx, int mode)
+PARSER_initialize(struct parser_state *pstate, void *yyscanner)
{
- void reset_lexer_state(void);
+ void reset_lexer_state(void *yyscanner, struct parser_state *);
#if 0
- if (ctx != NULL) {
- xfree(ctx);
- ctx = NULL;
- }
- if (envelope != NULL) {
- xfree(envelope);
- envelope = NULL;
+ if (pstate->ctx != NULL) {
+ xfree(pstate->ctx);
+ pstate->ctx = NULL;
+ }
+ if (pstate->envelope != NULL) {
+ xfree(pstate->envelope);
+ pstate->envelope = NULL;
}
- if (ctype != NULL) {
- xfree(ctype);
- ctype = NULL;
+ if (pstate->ctype != NULL) {
+ xfree(pstate->ctype);
+ pstate->ctype = NULL;
}
#endif
/* yydebug = 1; */
- reset_environ();
- reset_lexer_state();
-
- ctx = newctx;
- parsemode = mode;
-
- envelope = mm_mimepart_new();
- current_mimepart = envelope;
- ctype = mm_content_new();
-
- have_contenttype = 0;
-
- curin = mimeparser_yyin;
+ reset_environ(pstate);
+ reset_lexer_state(yyscanner,pstate);
+
+ pstate->envelope = mm_mimepart_new();
+ pstate->current_mimepart = pstate->envelope;
+ pstate->ctype = mm_content_new();
+
+ pstate->have_contenttype = 0;
return 1;
}
Modified: team/group/http_mods/main/minimime/mm_parse.c
URL: http://svn.digium.com/view/asterisk/team/group/http_mods/main/minimime/mm_parse.c?view=diff&rev=60212&r1=60211&r2=60212
==============================================================================
--- team/group/http_mods/main/minimime/mm_parse.c (original)
+++ team/group/http_mods/main/minimime/mm_parse.c Wed Apr 4 22:35:40 2007
@@ -47,9 +47,10 @@
#include "mimeparser.h"
#include "mimeparser.tab.h"
-void PARSER_initialize(MM_CTX *, int);
+int yyparse (struct parser_state *pstate, void *yyscanner);
+void PARSER_initialize(struct parser_state *, void *);
void PARSER_setbuffer(const char *);
-void PARSER_setfp(FILE *);
+void PARSER_setfp(FILE *,void *yyscanner);
/** @file mm_parse.c
*
@@ -82,12 +83,25 @@
int
mm_parse_mem(MM_CTX *ctx, const char *text, int parsemode, int flags)
{
- PARSER_initialize(ctx, parsemode);
+ void *yyscanner;
+ int res;
+ struct parser_state pstate;
+ typedef void *yyscan_t;
+ int mimeparser_yylex_init (yyscan_t* scanner);
+ int mimeparser_yylex_destroy (yyscan_t yyscanner );
+
+ pstate.ctx = ctx;
+ pstate.parsemode = parsemode;
+
+ mimeparser_yylex_init(&yyscanner);
+ PARSER_initialize(&pstate, yyscanner);
PARSER_setbuffer(text);
- PARSER_setfp(NULL);
+ PARSER_setfp(NULL,yyscanner);
- return mimeparser_yyparse();
+ res = mimeparser_yyparse(&pstate,yyscanner);
+ mimeparser_yylex_destroy(yyscanner);
+ return res;
}
/**
@@ -113,21 +127,32 @@
* The context needs to be initialized before using mm_context_new() and may
* be freed using mm_context_free().
*/
+typedef void *yyscan_t;
int
mm_parse_file(MM_CTX *ctx, const char *filename, int parsemode, int flags)
{
FILE *fp;
int res;
+ void *yyscanner;
+ struct parser_state pstate;
+ int mimeparser_yylex_init (yyscan_t* scanner);
+ int mimeparser_yylex_destroy (yyscan_t yyscanner );
+
+ mimeparser_yylex_init(&yyscanner);
if ((fp = fopen(filename, "r")) == NULL) {
mm_errno = MM_ERROR_ERRNO;
return -1;
}
-
- PARSER_setfp(fp);
- PARSER_initialize(ctx, parsemode);
- res = mimeparser_yyparse();
+ PARSER_setfp(fp,yyscanner);
+ PARSER_initialize(&pstate, yyscanner);
+
+ pstate.ctx = ctx;
+ pstate.parsemode = parsemode;
+
+ res = mimeparser_yyparse(&pstate,yyscanner);
+ mimeparser_yylex_destroy(yyscanner);
fclose(fp);
return res;
}
More information about the asterisk-commits
mailing list