Diff for /parser3/src/main/untaint.C between versions 1.115.2.12.2.18 and 1.118.2.1

version 1.115.2.12.2.18, 2003/03/27 10:53:01 version 1.118.2.1, 2003/09/23 09:54:28
Line 17  static const char* IDENT_UNTAINT_C="$Dat Line 17  static const char* IDENT_UNTAINT_C="$Dat
 #include "pa_common.h"  #include "pa_common.h"
 #include "pa_charset.h"  #include "pa_charset.h"
 #include "pa_request_charsets.h"  #include "pa_request_charsets.h"
   #include "pa_sapi.h"
   
 extern "C" { // author forgot to do that  extern "C" { // author forgot to do that
 #include "ec.h"  #include "ec.h"
Line 28  extern "C" { // author forgot to do that Line 29  extern "C" { // author forgot to do that
 #include "pa_sql_connection.h"  #include "pa_sql_connection.h"
 #endif  #endif
   
 // forwards  
   
 void CORD_ec_flush_buf_optimize_whitespace(CORD_ec x);  
   
 // defines  // defines
   
   
Line 84  inline bool need_file_encode(unsigned ch Line 81  inline bool need_file_encode(unsigned ch
         return strchr(          return strchr(
                           "*?'\"<>|"                            "*?'\"<>|"
 #ifndef WIN32  #ifndef WIN32
                           ":\\~"                            ":\\"
 #endif  #endif
                           , c)!=0;                            , c)!=0;
 }  }
Line 170  inline bool need_quote_http_header(const Line 167  inline bool need_quote_http_header(const
         return false;          return false;
 }  }
   
   #ifndef DOXYGEN
   struct Append_fragment_info {
           String::Language lang;
           const StringBody dest_body;
           String::Languages* dest_languages;
   };
   #endif
   int append_fragment_optimizing(char alang, size_t asize, Append_fragment_info& info) {
           String::Language lang=(String::Language)alang;
           // main idea here:
           // tainted piece would get OPTIMIZED bit from 'lang'
           // clean piece would be marked OPTIMIZED manually
           // pieces with determined languages [not tainted|clean] would retain theirs langs
           info.dest_languages->append(info.dest_body, 
                   lang==String::Language::L_TAINTED?
                           info.lang
                           :lang==String::Language::L_CLEAN?
                                   (String::Language)(String::Language::L_CLEAN|String::Language::L_OPTIMIZE_BIT) // ORing with OPTIMIZED flag
                                   :lang,
                   asize);
   
           return 0; // 0=continue
   }
   int append_fragment_nonoptimizing(char alang, size_t asize, Append_fragment_info& info) {
           String::Language lang=(String::Language)alang;
           // The core idea: tainted pieces got marked with context's lang
           info.dest_languages->append(info.dest_body, 
                   lang==String::Language::L_TAINTED?
                           info.lang
                           :lang,
                   asize);
   
           return 0; // 0=continue
   }
   
 /**   /** 
         appends to other String,          appends to other String,
Line 181  String& String::append_to(String& dest, Line 212  String& String::append_to(String& dest,
         if(is_empty())          if(is_empty())
                 return dest;                  return dest;
   
         // first: letters          // first: fragment infos
         dest.body<<body;  
   
         // next: fragment infos  
                   
         if(lang==L_PASS_APPENDED) // without language-chage string?          if(lang==L_PASS_APPENDED) // without language-change?
                 dest.fragments.append(fragments);                  dest.langs.append(dest.body, body, langs);
         else if(forced) //forcing passed lang?          else if(forced) //forcing passed lang?
                 dest.fragments+=Fragment(lang, length());                  dest.langs.append(dest.body, lang, length());
         else if(lang&L_OPTIMIZE_BIT) {          else { 
                 Array_iterator<ArrayFragment::element_type> i(fragments);                  Append_fragment_info info={lang, dest.body, &dest.langs};
                 while(i.has_next()) {              langs.for_each(body, lang&L_OPTIMIZE_BIT?
                         const Fragment fragment=i.next();                          append_fragment_optimizing
                         // main idea here:                          :append_fragment_nonoptimizing, info);
                         // tainted piece would get OPTIMIZED bit from 'lang'  
                         // clean piece would be marked OPTIMIZED manually  
                         // pieces with determined languages [not tainted|clean] would retain theirs langs  
                         dest.fragments+=Fragment(static_cast<Language>(  
                                 fragment.lang==L_TAINTED?lang:(  
                                         fragment.lang==L_CLEAN?L_CLEAN|L_OPTIMIZE_BIT: // ORing with OPTIMIZED flag  
                                                 fragment.lang)),  
                                 fragment.length);  
                 }  
         } else { // The core idea: tainted pieces got marked with context's lang  
                 Array_iterator<ArrayFragment::element_type> i(fragments);  
                 while(i.has_next()) {  
                         const Fragment fragment=i.next();  
                         dest.fragments+=Fragment(  
                                 fragment.lang==L_TAINTED?lang:fragment.lang,  
                                 fragment.length);  
                 }  
         }          }
   
           // next: letters
           dest.body<<body;
   
         return dest;          return dest;
 }  }
   
Line 250  inline bool mail_header_char_valid_withi Line 264  inline bool mail_header_char_valid_withi
                 || c>='0' && c<='9'                  || c>='0' && c<='9'
                 || strchr("!*+-/", c);                  || strchr("!*+-/", c);
 }  }
   inline bool addr_spec_soon(const char *src) {
           for(char c; c=*src; src++)
                   if(c=='<')
                           return true;
                   else if(!(c==' ' || c=='\t'))
                           return false;
           return false;
   }
 /**  /**
         RFC           RFC 
         Upper case should be used for hexadecimal digits "A" through "F"          Upper case should be used for hexadecimal digits "A" through "F"
Line 259  inline bool mail_header_char_valid_withi Line 281  inline bool mail_header_char_valid_withi
 inline bool mail_header_nonspace_char(char c) {  inline bool mail_header_nonspace_char(char c) {
         return c != 0x20;          return c != 0x20;
 }  }
 inline void ec_append(CORD_ec& result, bool& optimize, bool& whitespace, CORD_pos& pos, size_t size) {  inline void ec_append(CORD_ec& result, bool& optimize, bool& whitespace, CORD_pos pos, size_t size) {
         while(size--) {          while(size--) {
                 CORD_ec_append(result, CORD_pos_fetch(pos));                  CORD_ec_append(result, CORD_pos_fetch(pos));
                 CORD_next(pos);                  CORD_next(pos);
         }          }
 }  }
   inline void pa_CORD_pos_advance(CORD_pos pos, size_t n) {
           while(true) {
                   size_t avail=CORD_pos_chars_left(pos);
                   if(avail==0) {
                           CORD_next(pos);
                           if(!--n)
                                   break;
                   } else if(avail<n) {
                           CORD_pos_advance(pos, avail);
                           n-=avail;
                   } else { // avail>=n
                           CORD_pos_advance(pos, n);
                           break;
                   }
           }
   }
 StringBody String::cstr_to_string_body(Language lang,   StringBody String::cstr_to_string_body(Language lang, 
                   SQL_Connection* connection,                    SQL_Connection* connection,
                   const Request_charsets *charsets) const {                    const Request_charsets *charsets) const {
Line 285  StringBody String::cstr_to_string_body(L Line 323  StringBody String::cstr_to_string_body(L
                 bool optimize=(to_lang & L_OPTIMIZE_BIT)!=0;                  bool optimize=(to_lang & L_OPTIMIZE_BIT)!=0;
                 if(!optimize)                  if(!optimize)
                         whitespace=false;                          whitespace=false;
                           
                 switch(to_lang & ~L_OPTIMIZE_BIT) {                  switch(to_lang & ~L_OPTIMIZE_BIT) {
                 case L_CLEAN:                  case L_CLEAN:
                 case L_TAINTED:                  case L_TAINTED:
Line 303  StringBody String::cstr_to_string_body(L Line 341  StringBody String::cstr_to_string_body(L
                         // tainted, untaint language: file [name]                          // tainted, untaint language: file [name]
                         escape(                          escape(
                                 // Macintosh has problems with small Russian letter 'r'                                  // Macintosh has problems with small Russian letter 'r'
                                 if( c=='\xF0' && charsets && charsets->source().name()=="windows-1251" ) {                                  if( c=='\xF0' && charsets && charsets->source().NAME()=="WINDOWS-1251" ) {
                                         // fixing that letter for most common charset                                          // fixing that letter for most common charset
                                         to_char('p');                                          to_char('p');
                                 } else // fallback to default                                  } else // fallback to default
Line 315  StringBody String::cstr_to_string_body(L Line 353  StringBody String::cstr_to_string_body(L
                         {                          {
                                 const char *fragment_str=body.mid(fragment_begin, fragment_length).cstr();                                  const char *fragment_str=body.mid(fragment_begin, fragment_length).cstr();
                                 // skip source [we use recoded version]                                  // skip source [we use recoded version]
                                 CORD_pos_advance(pos, fragment_length);                                  pa_CORD_pos_advance(pos, fragment_length);
                                 const void *client_ptr;                                  String::C output(fragment_str, fragment_length);
                                 size_t client_size;  
                                 if(charsets)                                   if(charsets) 
                                         Charset::transcode(                                          output=Charset::transcode(output, 
                                                 charsets->source(), fragment_str, fragment_length,                                                  charsets->source(), 
                                                 charsets->client(), client_ptr, client_size);                                                  charsets->client());
                                 else {  
                                         client_ptr=fragment_str;   
                                         client_size=fragment_length;  
                                 }  
   
                                 char c;                                  char c;
                                 for(const char* src=(const char* )client_ptr; c=*src++; )                                   for(const char* src=output.str; c=*src++; ) 
                                         encode(need_uri_encode, '%', c);                                          encode(need_uri_encode, '%', c);
                         }                          }
                         break;                          break;
Line 346  StringBody String::cstr_to_string_body(L Line 379  StringBody String::cstr_to_string_body(L
                                 const char *mail_ptr=                                  const char *mail_ptr=
                                         body.mid(fragment_begin, mail_size=fragment_length).cstr();                                          body.mid(fragment_begin, mail_size=fragment_length).cstr();
                                 // skip source [we use recoded version]                                  // skip source [we use recoded version]
                                 CORD_pos_advance(pos, mail_size);                                  pa_CORD_pos_advance(pos, mail_size);
   
                                 const char* charset_name=charsets->mail().name().cstr();                                  const char* charset_name=charsets->mail().NAME().cstr();
   
                                 // Subject: Re: parser3: =?koi8-r?Q?=D3=C5=CD=C9=CE=C1=D2?=                                  // Subject: Re: parser3: =?koi8-r?Q?=D3=C5=CD=C9=CE=C1=D2?=
                                 bool to_quoted_printable=false;                                  bool to_quoted_printable=false;
Line 357  StringBody String::cstr_to_string_body(L Line 390  StringBody String::cstr_to_string_body(L
                                 uchar c;                                  uchar c;
                                 for(const char* src=mail_ptr; c=(uchar)*src++; ) {                                  for(const char* src=mail_ptr; c=(uchar)*src++; ) {
                                         //RFC   + An 'encoded-word' MUST NOT appear in any portion of an 'addr-spec'.                                          //RFC   + An 'encoded-word' MUST NOT appear in any portion of an 'addr-spec'.
                                         if(to_quoted_printable && (c==',' || c=='<')) {                                          if(to_quoted_printable && (c==',' || addr_spec_soon(src) || c == '"')) {
                                                 email=c=='<';                                                  email=c=='<';
                                                 to_string("?=");                                                  to_string("?=");
                                                 to_quoted_printable=false;                                                  to_quoted_printable=false;
Line 398  StringBody String::cstr_to_string_body(L Line 431  StringBody String::cstr_to_string_body(L
                         if(connection) {                          if(connection) {
                                 const char *fragment_str=body.mid(fragment_begin, fragment_length).cstr();                                  const char *fragment_str=body.mid(fragment_begin, fragment_length).cstr();
                                 // skip source [we use recoded version]                                  // skip source [we use recoded version]
                                 CORD_pos_advance(pos, fragment_length);                                  pa_CORD_pos_advance(pos, fragment_length);
   
                                 to_string(connection->quote(fragment_str, fragment_length));                                  to_string(connection->quote(fragment_str, fragment_length));
                         } else                          } else
Line 437  StringBody String::cstr_to_string_body(L Line 470  StringBody String::cstr_to_string_body(L
                         });                          });
                         break;                          break;
                 default:                  default:
                         throw Exception(0,                           SAPI::die("unknown untaint language #%d", 
                                 0,                                   static_cast<int>(to_lang)); // should never
                                 "unknown untaint language #%d",   
                                         static_cast<int>(to_lang)); // should never  
                         break; // never                          break; // never
                 }                  }
         }          }

Removed from v.1.115.2.12.2.18  
changed lines
  Added in v.1.118.2.1


E-mail: