Beispiel #1
0
/* Tokenize a header. tokens may be NULL, in which case the number of tokens
   are counted, allowing the caller to allocate enough room */
static void tokenize(const char *header, php_rfc822_token_t *tokens,
                     int *ntokens, int report_errors) {
  register const char *p, *q, *start;
  int in_bracket = 0;

/* NB: parser assumes that the header has two bytes of NUL terminator */

  YYCURSOR = header;
  YYLIMIT = YYCURSOR + strlen(YYCURSOR) + 1;

  *ntokens = 0;

state_ground:
  start = YYCURSOR;

#if DEBUG_RFC822_SCANNER
  printf("ground: start=%p limit=%p cursor=%p: [%d] %s\n",
         start, YYLIMIT, YYCURSOR, *YYCURSOR, YYCURSOR);
#endif

{
  YYCTYPE yych;
  static const unsigned char yybm[] = {
      0, 192, 192, 192, 192, 192, 192, 192,
    192,  96,  96, 192, 192,  96, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
     96,  64,   0, 192, 192,  64, 192, 192,
     64,  64, 192, 192,  64, 192,  64,  64,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192,  64,  64,  64,  64,  64,  64,
     64, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192,  64, 192,  64, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
    192, 192, 192, 192, 192, 192, 192, 192,
  };

  if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
  yych = *YYCURSOR;
  if (yybm[0+yych] & 32) {
    goto yy4;
  }
  if (yych <= '-') {
    if (yych <= '%') {
      if (yych <= '!') {
        if (yych <= 0x00) goto yy2;
        if (yych <= ' ') goto yy21;
        goto yy19;
      } else {
        if (yych <= '"') goto yy12;
        if (yych <= '$') goto yy21;
        goto yy19;
      }
    } else {
      if (yych <= ')') {
        if (yych <= '\'') goto yy21;
        if (yych <= '(') goto yy10;
        goto yy7;
      } else {
        if (yych == ',') goto yy19;
        goto yy21;
      }
    }
  } else {
    if (yych <= '>') {
      if (yych <= ';') {
        if (yych <= '/') goto yy19;
        if (yych <= '9') goto yy21;
        goto yy19;
      } else {
        if (yych <= '<') goto yy15;
        if (yych <= '=') goto yy19;
        goto yy17;
      }
    } else {
      if (yych <= '[') {
        if (yych <= '@') goto yy19;
        if (yych <= 'Z') goto yy21;
        goto yy19;
      } else {
        if (yych <= '\\') goto yy9;
        if (yych <= ']') goto yy19;
        goto yy21;
      }
    }
  }
yy2:
  ++YYCURSOR;
  {  goto stop; }
yy4:
  ++YYCURSOR;
  if (YYLIMIT <= YYCURSOR) YYFILL(1);
  yych = *YYCURSOR;
  if (yybm[0+yych] & 32) {
    goto yy4;
  }
  {  DBG_STATE("SPACE"); goto state_ground; }
yy7:
  ++YYCURSOR;
yy8:
  {  REPORT_ERR("token not valid in ground state"); goto state_ground; }
yy9:
  yych = *++YYCURSOR;
  if (yybm[0+yych] & 128) {
    goto yy21;
  }
  goto yy8;
yy10:
  ++YYCURSOR;
  {  DBG_STATE("START COMMENT");
    if (tokens) {
      tokens->token = '(';
      tokens->value = start;
      tokens->valuelen = 0;
    }
    goto state_comment;
  }
yy12:
  ++YYCURSOR;
  if (YYLIMIT <= YYCURSOR) YYFILL(1);
  yych = *YYCURSOR;
  if (yybm[0+yych] & 64) {
    goto yy12;
  }
  if (yych >= 0x01) goto yy26;
yy15:
  ++YYCURSOR;
  if ((yych = *YYCURSOR) == '>') goto yy24;
  {   DBG_STATE("LANGLE");
    if (in_bracket) {
      REPORT_ERR("already in < bracket");
      goto state_ground;
    }
    in_bracket = 1;
    ADD_ATOM_TOKEN();
    goto state_ground;
  }
yy17:
  ++YYCURSOR;
  {  DBG_STATE("RANGLE");
    if (!in_bracket) {
      REPORT_ERR("not in < bracket");
      goto state_ground;
    }
    in_bracket = 0;
    ADD_ATOM_TOKEN();
    goto state_ground;
  }
yy19:
  ++YYCURSOR;
  {   DBG_STATE("ATOM"); ADD_ATOM_TOKEN(); goto state_ground; }
yy21:
  ++YYCURSOR;
  if (YYLIMIT <= YYCURSOR) YYFILL(1);
  yych = *YYCURSOR;
  if (yybm[0+yych] & 128) {
    goto yy21;
  }
  {  DBG_STATE("ANY");
    if (tokens) {
      tokens->token = 0;
      tokens->valuelen = YYCURSOR - start;
      tokens->value = start;
      tokens++;
    }
    ++*ntokens;
    goto state_ground;
  }
yy24:
  ++YYCURSOR;
  {  DBG_STATE("NULL <>");
    ADD_ATOM_TOKEN();
    if (tokens) {
      tokens->token = 0;
      tokens->value = "";
      tokens->valuelen = 0;
      tokens++;
    }
    ++*ntokens;
    start++;
    ADD_ATOM_TOKEN();
    goto state_ground;
  }
yy26:
  ++YYCURSOR;
  {   DBG_STATE("QUOTE STRING");
    if (tokens) {
      tokens->token = '"';
      tokens->value = start + 1;
      tokens->valuelen = YYCURSOR - start - 2;
      tokens++;
    }
    ++*ntokens;

    goto state_ground;
  }
}

state_comment:
  {
    int comment_depth = 1;
    while (1) {
      if (*YYCURSOR == 0) {
        /* unexpected end of header */
        REPORT_ERR("unexpected end of header");
        /* fake a quoted string for this last token */
        if (tokens)
          tokens->token = '"';
        ++*ntokens;
        return;
      } else if (*YYCURSOR == '(') {
        comment_depth++;
      } else if (*YYCURSOR == ')' && --comment_depth == 0) {
        /* end of nested comment sequence */
        YYCURSOR++;
        if (tokens)
          tokens->valuelen++;
        break;
      } else if (*YYCURSOR == '\\' && YYCURSOR[1]) {
        YYCURSOR++;
        if (tokens)
          tokens->valuelen++;
      }
      YYCURSOR++;
    }
    if (tokens) {
      tokens->valuelen = YYCURSOR - tokens->value;
      tokens++;
    }
    ++*ntokens;
    goto state_ground;
  }
stop:
#if DEBUG_RFC822_SCANNER
  printf("STOPing parser ntokens=%d YYCURSOR=%p YYLIMIT=%p start=%p "
         "cursor=[%d] %s start=%s\n", *ntokens,
         YYCURSOR, YYLIMIT, start, *YYCURSOR, YYCURSOR, start);
#else
  ;
#endif
}
Beispiel #2
0
int STM_Execute1( STM_StateMachine *sm, STM_StateMachine **currSm )
{
	int			action;			/* Action to execute.						*/
	STM_Input	input;			/* Input being processed.					*/
	int			nextState;		/* Next state to change to.					*/
	uint8_t    *stateData;  	/* Ptr to state data for current state.		*/
	STM_StateMachine   *svSm;	/* Saved value of STM_CurrStateMachine		*/

	ASSERT( sm != NULL );
	ASSERT( sm->magic == STM_MAGIC );

	if (( input = GetInput( sm )) == STM_INPUT_NONE )
	{
		/*
		 * No input, indicate that we didn't do anything
		 */

		return FALSE;
	}

	/*
	 * Set the global state machine variable, so that actions which use it
	 * can access this state machine. Save the old value off so that action
	 * routines can execute other state machines.
	 */

	if ( currSm != NULL )
	{
		svSm = *currSm;
		*currSm = sm;
	}

	/*
	 * We've got an input, run it through the state machine
	 */

	DBG_INPUT( "STM %s: processing input %s (%d)\n",
				sm->name, sm->currInputStr, sm->currInput );

	stateData = &sm->stateData[ sm->currState * STM_BytesPerState( sm )];

	nextState = stateData[ STM_NextStateOffset( input )];

	/*
	 * Exit the old state
	 */

	if ( nextState != sm->currState )
	{
		int		exitAction;

		/*
		 * We're leaving the old state, call the exit routine if one is
		 * defined
		 */

		exitAction = stateData[ STM_ExitOffset() ];
		ExecuteAction( sm, exitAction, "exit " );
	}

	/*
	 * Call the action routine
	 */

	action = stateData[ STM_ActionOffset( input )];
	ExecuteAction( sm, action, "" );

	if ( nextState != sm->currState )
	{
		int		enterAction;

		/*
		 * Enter the new state
		 */
	
		DBG_STATE( "STM %s: Changing states from %s (%d) to %s (%d)\n",
				   sm->name,
				   sm->stateStr[ sm->currState ], sm->currState,
				   sm->stateStr[ nextState ], nextState );

		sm->currState = nextState;
		stateData = &sm->stateData[ sm->currState * STM_BytesPerState( sm )];

		/*
		 * We're entering the new state, call the enter routine if one is
		 * defined
		 */

		enterAction = stateData[ STM_EnterOffset() ];
		ExecuteAction( sm, enterAction, "enter " );
	}

	if ( currSm != NULL )
	{
		*currSm = svSm;
	}

	/*
	 * We processed an input, tell the caller
	 */

	sm->currInput = STM_INPUT_NONE;
#if defined( STM_DEBUG )
	sm->currInputStr = "- None -";
#endif

	return TRUE;

} // STM_Execute1