/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * processDirective * * THIS IS THE ONLY EXTERNAL ENTRY POINT * * A directive character has been found. * Decide what to do and return a pointer to the character * where scanning is to resume. */ LOCAL char * processDirective(char * scan) { char * eodir = end_of_directive(scan); /* * Ignore '#!' as a comment, enabling a definition file to behave * as a script that gets interpreted by autogen. :-) */ if (*scan == '!') return eodir; scan = SPN_WHITESPACE_CHARS(scan); if (! IS_ALPHABETIC_CHAR(*scan)) return doDir_invalid(DIR_INVALID, scan, eodir); return doDir_directive_disp(scan, eodir); }
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * processDirective * * THIS IS THE ONLY EXTERNAL ENTRY POINT * * A directive character has been found. * Decide what to do and return a pointer to the character * where scanning is to resume. */ LOCAL char* processDirective(char* pzScan) { const tDirTable* pTbl = dirTable; char* pzDir; char* pzEnd; /* * Search for the end of the #-directive. * Replace "\\\n" sequences with " ". */ for (;;) { pzEnd = strchr(pzScan, NL); if (pzEnd == NULL) { /* * The end of the directive is the end of the string */ pzEnd = pzScan + strlen(pzScan); break; } pCurCtx->lineNo++; if (pzEnd[-1] != '\\') { /* * The end of the directive is the end of the line * and the line has not been continued. */ *(pzEnd++) = NUL; break; } /* * Replace the escape-newline pair with spaces and * find the next end of line */ pzEnd[-1] = pzEnd[0] = ' '; } /* * Ignore ``#!'' as a comment, enabling a definition file to behave * as a script that gets interpreted by autogen. :-) */ if (*pzScan == '!') return pzEnd; /* * Find the start of the directive name */ while (IS_WHITESPACE_CHAR(*pzScan)) pzScan++; pzDir = pzScan; /* * Find the *END* of the directive name. If no name, bail out. */ while (IS_ALPHABETIC_CHAR(*pzScan)) pzScan++; if (pzDir == pzScan) return pzEnd; /* * IF there is anything that follows the name, ... */ if (*pzScan != NUL) { /* * IF something funny immediately follows the directive name, * THEN we will ignore it completely. */ if (! IS_WHITESPACE_CHAR(*pzScan)) return pzEnd; /* * Terminate the name being defined * and find the start of anything else. */ *pzScan++ = NUL; while (IS_WHITESPACE_CHAR(*pzScan)) pzScan++; } /* * Trim off trailing white space */ { char* pz = pzScan + strlen(pzScan); while ((pz > pzScan) && IS_WHITESPACE_CHAR(pz[-1])) pz--; *pz = NUL; } pTbl = dirTable + (int)findDirective(pzDir); return (*(pTbl->pDirProc))(pzScan, pzEnd); }
/* * fixupSubblockString */ static char* fixupSubblockString(char const * pzSrc) { char * pzString; char * pzDest; char * pzCopy; pzString = strdup(pzSrc); /* * Make sure we find the '=' separator */ { char * p = strchr(pzString, '='); if (p == NULL) die(zNoList, pzString); /* * Trim the name */ pzDest = p++; while ((pzDest > pzString) && IS_HORIZ_WHITE_CHAR(pzDest[-1])) pzDest--; *(pzDest++) = NUL; /* * Make sure at least one attribute name is defined */ while (IS_WHITESPACE_CHAR(*p)) p++; if (*p == NUL) die(zNoList, pzString); pzCopy = p; } for (;;) { /* * Attribute names must start with an alpha */ if (! IS_ALPHABETIC_CHAR(*pzCopy)) { fprintf(stderr, "ERROR: attribute names must start " "with an alphabetic character:\n\t%s\n", pzString); USAGE(EXIT_FAILURE); } /* * Copy the name. */ while (IS_OPTION_NAME_CHAR(*pzCopy)) *pzDest++ = *pzCopy++; /* * Skip over one comma (optional) and any white space. * If there is a newline, it must be after the comma. */ while (IS_HORIZ_WHITE_CHAR(*pzCopy)) pzCopy++; if (*pzCopy == ',') pzCopy++; while (IS_WHITESPACE_CHAR(*pzCopy)) pzCopy++; if (*pzCopy == NUL) break; /* * The final string contains only one space between attributes */ *pzDest++ = ' '; } *pzDest = NUL; return pzString; }
/** * Run the FSM. Will return CGI_ST_DONE or CGI_ST_INVALID */ te_cgi_state cgi_run_fsm( char const * pzSrc, int inlen, char * pzOut, int outlen ) { te_cgi_state cgi_state = CGI_ST_INIT; te_cgi_event trans_evt; te_cgi_state nxtSt; te_cgi_trans trans; char const * saved_pzSrc = pzSrc; int saved_inlen = inlen; char * saved_pzOut = pzOut; int saved_outlen = outlen; (void)saved_pzSrc; (void)saved_inlen; (void)saved_pzOut; (void)saved_outlen; while (cgi_state < CGI_ST_INVALID) { /* START == FIND TRANSITION == DO NOT CHANGE THIS COMMENT */ char curCh; if (--inlen < 0) { trans_evt = CGI_EV_END; curCh = NUL; } else { if (outlen < 4) { static char const exhaustion[] = "output space exhausted\n"; if (saved_outlen > (int)sizeof(exhaustion)) memcpy(saved_pzOut, exhaustion, sizeof(exhaustion)); return CGI_ST_INVALID; } curCh = *(pzSrc++); if (IS_ALPHABETIC_CHAR( curCh )) trans_evt = CGI_EV_ALPHA; else if (IS_DEC_DIGIT_CHAR( curCh )) trans_evt = CGI_EV_NAME_CHAR; else switch (curCh) { case '_': trans_evt = CGI_EV_NAME_CHAR; break; case '=': trans_evt = CGI_EV_EQUAL; break; case '+': trans_evt = CGI_EV_SPACE; curCh = ' '; break; case '%': trans_evt = CGI_EV_ESCAPE; break; case '&': trans_evt = CGI_EV_SEPARATOR; break; default: trans_evt = CGI_EV_OTHER; break; } } /* END == FIND TRANSITION == DO NOT CHANGE THIS COMMENT */ #ifndef __COVERITY__ if (trans_evt >= CGI_EV_INVALID) { nxtSt = CGI_ST_INVALID; trans = CGI_TR_INVALID; } else #endif /* __COVERITY__ */ { const t_cgi_transition * ttbl = cgi_trans_table[ cgi_state ] + trans_evt; nxtSt = ttbl->next_state; trans = ttbl->transition; } switch (trans) { case CGI_TR_INVALID: /* START == INVALID == DO NOT CHANGE THIS COMMENT */ exit( cgi_invalid_transition( cgi_state, trans_evt )); /* END == INVALID == DO NOT CHANGE THIS COMMENT */ break; case CGI_TR_NAME_EQUAL: /* START == NAME_EQUAL == DO NOT CHANGE THIS COMMENT */ strcpy( pzOut, "='" ); outlen -= 2; pzOut += 2; /* END == NAME_EQUAL == DO NOT CHANGE THIS COMMENT */ break; case CGI_TR_SEPARATE: /* START == SEPARATE == DO NOT CHANGE THIS COMMENT */ strcpy( pzOut, "';\n" ); outlen -= 2; pzOut += 3; /* END == SEPARATE == DO NOT CHANGE THIS COMMENT */ break; case CGI_TR_STASH: /* START == STASH == DO NOT CHANGE THIS COMMENT */ *(pzOut++) = curCh; outlen--; /* END == STASH == DO NOT CHANGE THIS COMMENT */ break; case CGI_TR_VALUE_ESCAPE: /* START == VALUE_ESCAPE == DO NOT CHANGE THIS COMMENT */ { char z[4]; if (inlen < 2) exit( cgi_invalid_transition( cgi_state, trans_evt )); z[0] = *(pzSrc++); z[1] = *(pzSrc++); z[2] = NUL; inlen -= 2; /* * We must backslash quote certain characters that are %-quoted * in the input string: */ switch (*(pzOut++) = (char)strtol( z, NULL, 16 )) { case '\'': case '\\': case '#': pzOut[0] = pzOut[-1]; pzOut[-1] = '\\'; pzOut++; } } /* END == VALUE_ESCAPE == DO NOT CHANGE THIS COMMENT */ break; default: /* START == BROKEN MACHINE == DO NOT CHANGE THIS COMMENT */ exit( cgi_invalid_transition( cgi_state, trans_evt )); /* END == BROKEN MACHINE == DO NOT CHANGE THIS COMMENT */ } cgi_state = nxtSt; } return cgi_state; }