--- parser3/src/main/untaint.C 2001/05/19 19:52:38 1.51 +++ parser3/src/main/untaint.C 2001/07/28 12:01:50 1.57 @@ -4,9 +4,8 @@ Copyright(c) 2001 ArtLebedev Group(http://www.artlebedev.com) Author: Alexander Petrosyan (http://design.ru/paf) - - $Id: untaint.C,v 1.51 2001/05/19 19:52:38 parser Exp $ */ +static const char *RCSId="$Id: untaint.C,v 1.57 2001/07/28 12:01:50 parser Exp $"; #include "pa_pool.h" #include "pa_string.h" @@ -62,6 +61,31 @@ inline bool need_http_header_encode(unsi return need_uri_encode(c); } +// + +static const char * String_Untaint_lang_name[]={ + "U", ///< zero value handy for hash lookup @see untaint_lang_name2enum + "C", ///< clean + "T", ///< tainted, untaint language as assigned later + // untaint languages. assigned by ^untaint[lang]{...} + "P", + /**< + leave language built into string being appended. + just a flag, that value not stored + */ + "A", ///< leave all characters intact + "F", ///< filename + "H", ///< text in HTTP response header + "M", ///< text in mail header + "URI", ///< text in uri + "T", ///< ^table:set body + "SQL", ///< ^table:sql body + "JS", ///< JavaScript code + "HTML", ///< HTML code (for editing) + "UHTML", ///< HTML code with USER chars +}; + + // String static bool typo_present(Array::Item *value, const void *info) { @@ -117,12 +141,16 @@ inline bool need_quote_http_header(const return false; } -/// @todo maybe additional check "are all pieces are clean?" would be profitable? +/** @todo maybe additional check "are all pieces are clean?" would be profitable? + @todo fix potential forigins_mode buf overrun +*/ size_t String::cstr_bufsize(Untaint_lang lang) const { - return (lang==UL_AS_IS?size():size()*UNTAINT_TIMES_BIGGER) +1; + return (lang==UL_AS_IS?size():size()*UNTAINT_TIMES_BIGGER*(forigins_mode?10:1)) +1; } -/// @todo fix theoretical \n mem overrun in TYPO replacements +/** @todo fix theoretical \n mem overrun in TYPO replacements +@todo rename base_64 to quoted_printable [invalid name now] +*/ char *String::store_to(char *dest, Untaint_lang lang, SQL_Connection *connection, const char *charset) const { @@ -138,9 +166,27 @@ char *String::store_to(char *dest, Untai if(row==append_here) goto break2; + Untaint_lang to_lang=lang==UL_UNSPECIFIED?row->item.lang:lang; + + char *dest_before_origins=dest; + + if(forigins_mode) { +#ifndef NO_STRING_ORIGIN + if(row->item.origin.file) + dest+=sprintf(dest, "%s(%d)", + row->item.origin.file, + 1+row->item.origin.line); + else + dest+=sprintf(dest, "unknown"); +#endif + dest+=sprintf(dest, "#%s: ", + String_Untaint_lang_name[to_lang]); + } + char *dest_after_origins=dest; + // WARNING: // string can grow only UNTAINT_TIMES_BIGGER - switch(lang==UL_UNSPECIFIED?row->item.lang:lang) { + switch(to_lang) { case UL_CLEAN: // clean piece { // optimizing whitespace @@ -260,6 +306,11 @@ char *String::store_to(char *dest, Untai break; case UL_USER_HTML: { // tainted, untaint language: html-typo + if(!typo_table) // never, always has default + THROW(0, 0, + this, + "untaint to user-html lang failed, no typo table"); + char *html_for_typo= (char *)malloc(row->item.size*2/* '\n' -> '\' 'n' */+1); // note: @@ -274,16 +325,13 @@ char *String::store_to(char *dest, Untai escape(switch(*src) { // convinient name for typo match "\n" case '\r': - if(typo_table) { - *dest++='\\'; *dest++='n'; // \r -> \n - if(src[1]=='\n') { // \r\n -> remove \n - size--; src++; - } + to_string("\\n", 2); // \r -> "\n" + if(size && src[1]=='\n') { // \r\n -> remove \n + size--; src++; } break; case '\n': - if(typo_table) - to_string("\\n", 2); + to_string("\\n", 2); break; //TODO: XSLT case '\'': to_string("'", 6); break; _default; @@ -340,6 +388,17 @@ char *String::store_to(char *dest, Untai if((lang==UL_UNSPECIFIED?row->item.lang:lang)!=UL_CLEAN) whitespace=false; + + if(forigins_mode) + if(dest==dest_after_origins) // never moved==optimized space + dest=dest_before_origins; + else { + for(char *p=dest_after_origins; plink; } while(chunk);