📄 htp.c
字号:
HtpMsg(MSG_INFO, task->infile, "dereferencing block macro \"%s\"", name); /* build a new task structure */ newTask.infile = &incfile; newTask.outfile = task->outfile; newTask.sourceFilename = task->sourceFilename; /* re-use current variable store if no local variable store was */ /* allocated, otherwise use the new one */ newTask.varstore = topVarstore; /* process the new input file */ result = ProcessTask(&newTask); /* remove the new context (and make sure it is, in fact, the block's */ /* context) */ if(topVarstore == &varstore) { assert(PeekVariableStoreContext(topVarstore) == topVarstore); PopVariableStoreContext(topVarstore); DestroyVariableStore(&varstore); } CloseFile(&incfile); FreeMemory(name); /* if the new file did not process, return an error, otherwise discard */ /* the markup */ return (result == TRUE) ? DISCARD_MARKUP : MARKUP_ERROR; } else { /* fatal error */ printf("%s: fatal internal error (USE)\n", PROGRAM_NAME); FreeMemory(name); exit(1); /* to prevent compiler warning */ return MARKUP_ERROR; }} /*// Block macro destructor callback ... used whenever a block macro is// destroyed with a RemoveVariable() or ClearVariableList()*/void BlockDestructor(const char *name, const char *value, uint type, uint flags, void *param){ UNREF_PARAM(name); UNREF_PARAM(type); UNREF_PARAM(flags); /* in debug versions of htp, a special "secret" option can be set to */ /* keep BLOCK temporary files around, for later inspection ... */ /* not real useful in release versions */#if DEBUG if(KEEPTEMP == FALSE) { remove(value); } else { HtpMsg(MSG_INFO, NULL, "DEBUG: keeping temporary file %s", value); }#else /* simply delete the temporary file holding the block macro text */ DEBUG_PRINT(("deleting file %s for block macro %s\n", value, name)); remove(value);#endif /* DEF macros use param */ if(param != NULL) { FreeMemory(param); }}uint BlockProcessor(TASK *task, HTML_MARKUP *htmlMarkup, char **newPlaintext){ char *name; char *plaintext; char newfile[MAX_PATHNAME_LEN]; HTML_MARKUP newHtml; TEXTFILE blockFile; BOOL result; static uint blockDepth = 0; uint markupType; BOOL blockMacro; uint macroType; const char *macroTypeName; const char *openTag; const char *closeTag; const char *defName; char *param; UNREF_PARAM(newPlaintext); /* first: is this a BLOCK macro or a DEF macro? This function is */ /* overloaded to handle both types, and must internally change its */ /* functionality for each type */ /* if this is false, this is a DEF macro */ if(stricmp(htmlMarkup->tag, "BLOCK") == 0) { blockMacro = TRUE; macroType = VAR_TYPE_BLOCK_MACRO; macroTypeName = "BLOCK"; openTag = "BLOCK"; closeTag = "/BLOCK"; } else { assert(stricmp(htmlMarkup->tag, "DEF") == 0); blockMacro = FALSE; macroType = VAR_TYPE_DEF_MACRO; macroTypeName = "DEF"; openTag = "DEF"; closeTag = "/DEF"; } /* check markup */ if(blockMacro == TRUE) { /* is a name specified? (only one name can be specified) */ if(htmlMarkup->attribCount != 1) { HtpMsg(MSG_ERROR, task->infile, "bad BLOCK markup specified"); return MARKUP_ERROR; } /* no extra varstore parameter for a block macro */ param = NULL; } else { /* DEF requires at least one parameter */ if(htmlMarkup->attribCount == 0) { HtpMsg(MSG_ERROR, task->infile, "bad DEF markup specified"); return MARKUP_ERROR; } /* check that the NAME attribute is present */ if(IsAttributeInMarkup(htmlMarkup, "NAME") == FALSE) { HtpMsg(MSG_ERROR, task->infile, "DEF requires NAME attribute"); return MARKUP_ERROR; } if(MarkupAttributeValue(htmlMarkup, "NAME") == NULL) { HtpMsg(MSG_ERROR, task->infile, "DEF requires a NAME attribute to have a value"); return MARKUP_ERROR; } /* if OPTION is specified, squirrel it away with the macro */ if(IsAttributeInMarkup(htmlMarkup, "OPTION") == TRUE) { if((param = DuplicateString(MarkupAttributeValue(htmlMarkup, "OPTION"))) == NULL) { HtpMsg(MSG_ERROR, task->infile, "unable to create OPTION copy for DEF macro"); return MARKUP_ERROR; } } else { param = NULL; } } /* create a temporary filename to save the text block into */ if(CreateTempFilename(newfile, MAX_PATHNAME_LEN) == FALSE) { HtpMsg(MSG_ERROR, task->infile, "unable to generate temporary filename for %s macro", macroTypeName); FreeMemory(param); return MARKUP_ERROR; } /* try and create the temporary file */ if(OpenFile(newfile, newfile, "w", &blockFile) == FALSE) { HtpMsg(MSG_ERROR, task->infile, "unable to create temporary file \"%s\" for %s macro", newfile, macroTypeName); FreeMemory(param); return MARKUP_ERROR; } /* need a private copy of the macro name */ if(blockMacro == TRUE) { if((name = DuplicateString(htmlMarkup->attrib[0].name)) == NULL) { HtpMsg(MSG_ERROR, task->infile, "unable to allocate memory for %s macro", macroTypeName); FreeMemory(param); CloseFile(&blockFile); return MARKUP_ERROR; } } else { defName = MarkupAttributeValue(htmlMarkup, "NAME"); assert(defName != NULL); if((name = DuplicateString(defName)) == NULL) { HtpMsg(MSG_ERROR, task->infile, "unable to allocate memory for %s macro", macroTypeName); FreeMemory(param); CloseFile(&blockFile); return MARKUP_ERROR; } } /* store the block file name and the block macro name as a variable */ if(StoreVariable(task->varstore, name, newfile, macroType, VAR_FLAG_NONE, param, BlockDestructor) == FALSE) { HtpMsg(MSG_ERROR, task->infile, "unable to store macro information (out of memory?)"); FreeMemory(name); FreeMemory(param); CloseFile(&blockFile); return MARKUP_ERROR; } /* the name is no longer used, dont free param it will be freed in */ /* the block destructor */ FreeMemory(name); name = NULL; /* start copying the file into the temporary file, looking for the */ /* BLOCK or /BLOCK tag if block macro, DEF or /DEF otherwise ... */ /* just squirrel away all other tags and text */ for(;;) { result = ReadHtmlFile(task->infile, &blockFile, &plaintext, &markupType); if(result == ERROR) { CloseFile(&blockFile); return MARKUP_ERROR; } else if(result == FALSE) { /* end-of-file encountered before end-of-block */ HtpMsg(MSG_ERROR, task->infile, "EOF encountered before %s macro declaration closed", macroTypeName); CloseFile(&blockFile); return MARKUP_ERROR; } /* turn the plain text into HTML structure, but don't destroy */ /* the plaintext, this will be used to copy into output file if */ /* necessary */ if(PlaintextToMarkup(plaintext, &newHtml) == FALSE) { /* memory alloc failed, most likely */ HtpMsg(MSG_ERROR, task->infile, "could not process markup (out of memory?)"); CloseFile(&blockFile); FreeMemory(plaintext); return MARKUP_ERROR; } if(markupType & MARKUP_TYPE_HTP) { /* check for embedded block declarations */ if(IsMarkupTag(&newHtml, openTag)) { /* add to the block macro depth and continue */ blockDepth++; } else if(IsMarkupTag(&newHtml, closeTag) == TRUE) { if(blockDepth > 0) { /* depth has decreased one */ blockDepth--; } else { /* found the end of the macro block */ DestroyMarkupStruct(&newHtml); FreeMemory(plaintext); break; } } } /* if continuing, then the plaintext is put into the output stream */ /* as-is ... there is no case where the processor continues scanning */ /* but discards a markup */ PutFileString(&blockFile, "%c%s%c", MARKUP_OPEN_DELIM(markupType), plaintext, MARKUP_CLOSE_DELIM(markupType)); /* destroy the HTML markup, not needed any longer */ DestroyMarkupStruct(&newHtml); /* destroy the plaintext buffer */ FreeMemory(plaintext); plaintext = NULL; } CloseFile(&blockFile); return DISCARD_MARKUP;} BOOL DiscardConditionalBlock(TEXTFILE *infile){ char *plaintext; HTML_MARKUP htmlMarkup; BOOL result; uint embeddedConditionals; uint markupType; /* discard the block, looking for the matching ELSE or /IF statement */ embeddedConditionals = 0; for(;;) { result = ReadHtmlFile(infile, NULL, &plaintext, &markupType); if(result == ERROR) { return FALSE; } else if(result == FALSE) { /* end-of-file before end-of-conditional ... error */ HtpMsg(MSG_ERROR, infile, "EOF encountered before conditional closed"); return FALSE; } if(PlaintextToMarkup(plaintext, &htmlMarkup) == FALSE) { /* memory alloc error */ HtpMsg(MSG_ERROR, infile, "could not parse markup tag (out of memory?)"); FreeMemory(plaintext); return FALSE; } /* FreeMemory the plaintext buffer, not needed any longer */ FreeMemory(plaintext); plaintext = NULL; /* another conditional started? */ if(IsMarkupTag(&htmlMarkup, "IF")) { embeddedConditionals++; } else if(IsMarkupTag(&htmlMarkup, "/IF")) { /* end of the conditional? */ if(embeddedConditionals == 0) { DestroyMarkupStruct(&htmlMarkup); break; } embeddedConditionals--; } else if(IsMarkupTag(&htmlMarkup, "ELSE")) { /* start of TRUE block? */ if(embeddedConditionals == 0) { DestroyMarkupStruct(&htmlMarkup); break; } } /* destroy and continue */ DestroyMarkupStruct(&htmlMarkup); } return TRUE;} uint BooleanProcessor(TASK *task, HTML_MARKUP *htmlMarkup, char **newPlaintext){ static uint conditionalLevel = 0; const char *value; uint type; BOOL condTrue; HTML_ATTRIBUTE *attrib; BOOL notTagFound; UNREF_PARAM(newPlaintext); condTrue = FALSE; /* conditionalLevel keeps track of boolean depth */ if(conditionalLevel == 0) { if((IsMarkupTag(htmlMarkup, "/IF")) || (IsMarkupTag(htmlMarkup, "ELSE"))) { HtpMsg(MSG_ERROR, task->infile, "conditional block must start with IF tag"); return MARKUP_ERROR; } } if(IsMarkupTag(htmlMarkup, "IF")) { conditionalLevel++; /* this is an ugly way to handle the IF-IF NOT test, but will need */ /* be cleaned up in the future */ /* should either be one or two attributes in markup */ if(htmlMarkup->attribCount == 0) { HtpMsg(MSG_ERROR, task->infile, "no conditional to test"); return MARKUP_ERROR; } if(htmlMarkup->attribCount > 2) { HtpMsg(MSG_ERROR, task->infile, "too many items in conditional expression"); return MARKUP_ERROR; } /* find the attribute to evaluate and search for NOT attribute */ notTagFound = FALSE; attrib = NULL; if(stricmp(htmlMarkup->attrib[0].name, "NOT") == 0) { /* check to make sure the second attribute is present */ if(htmlMarkup->attribCount == 1) { HtpMsg(MSG_ERROR, task->infile, "NOT listed, no conditional to test"); return MARKUP_ERROR; } notTagFound = TRUE; attrib = &htmlMarkup->attrib[1]; } else if(htmlMarkup->attribCount == 2) { if(stricmp(htmlMarkup->attrib[1].name, "NOT") == 0) { notTagFound = TRUE; attrib = &htmlMarkup->attrib[0]; } else { /* this should have been the NOT expression */ HtpMsg(MSG_ERROR, task->infile, "too many conditionals to test"); return MARKUP_ERROR; } } else { attrib = &htmlMarkup->attrib[0]; } /* get the macros asso
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -