Annotation of parser3/src/main/untaint.C, revision 1.4

1.1       paf         1: /*
                      2:        Parser
                      3:        Copyright (c) 2001 ArtLebedev Group (http://www.artlebedev.com)
                      4:        Author: Alexander Petrosyan <paf@design.ru> (http://design.ru/paf)
                      5: 
1.4     ! paf         6:        $Id: untaint.C,v 1.3 2001/03/18 13:22:07 paf Exp $
1.1       paf         7: */
                      8: 
                      9: #include <string.h>
                     10: 
                     11: #include "pa_pool.h"
                     12: #include "pa_string.h"
                     13: #include "pa_hash.h"
                     14: #include "pa_exception.h"
                     15: 
                     16: #define escape(cases) \
                     17:        { \
                     18:                const char *ptr=row->item.ptr; \
1.3       paf        19:                for (int size=row->item.size; size--; ptr++) \
1.1       paf        20:                        switch(*ptr) { \
                     21:                                cases \
                     22:                        } \
                     23:        }
1.4     ! paf        24: #define escape_value(a, c)  case a: *copy_here++=c; break
        !            25: #define escape_default  default: *copy_here++=*ptr; break
1.1       paf        26: #define escape_subst(a, b, bsize)  \
1.4     ! paf        27:                case a: \
1.1       paf        28:                        strncpy(copy_here, b, bsize); \
                     29:                        copy_here+=bsize; \
1.4     ! paf        30:                break
        !            31: 
        !            32: inline bool need_encode(unsigned char c){
        !            33:     if ((c>='0') && (c<='9') || (c>='A') && (c<='Z') || (c>='a') && (c<='z')) 
        !            34:                return false;
        !            35: 
        !            36:     return strchr("_-./", c)==0;
        !            37: }
1.1       paf        38: 
                     39: // String
                     40: 
                     41: char *String::cstr() const {
1.2       paf        42:        char *result=(char *)malloc(size()*UNTAINT_TIMES_BIGGER+1);
1.1       paf        43: 
                     44:        char *copy_here=result;
                     45:        const Chunk *chunk=&head; 
                     46:        // TODO: оптимизировать whitespaces для всех, кроме 'html'
                     47:        do {
                     48:                const Chunk::Row *row=chunk->rows;
                     49:                for(int i=0; i<chunk->count; i++) {
                     50:                        if(row==append_here)
                     51:                                goto break2;
                     52: 
                     53:                        // WARNING:
                     54:                        //      string can grow only UNTAINT_TIMES_BIGGER
                     55:                        switch(row->item.lang) {
                     56:                        case NO:
                     57:                                // clean piece
                     58:                        case YES:
                     59:                                // tainted piece, but undefined untaint language
                     60:                                // for VString.get_double of tainted values
                     61:                                // for ^process{body} evaluation
                     62:                        case AS_IS:
                     63:                                // tainted, untaint language: as-is
                     64:                                memcpy(copy_here, row->item.ptr, row->item.size); 
                     65:                                copy_here+=row->item.size;
                     66:                                break;
1.4     ! paf        67:                        case URI:
        !            68:                                // tainted, untaint language: uri
        !            69:                                escape(
        !            70:                                        escape_value(' ', '+');
        !            71:                                        default: 
        !            72:                                                if(need_encode(*ptr)) {
        !            73:                                                        static const char *hex="0123456789ABCDEF";
        !            74:                                                        char chunk[3]={'%'};
        !            75:                                                        chunk[1]=hex[((unsigned char)*ptr)/0x10];
        !            76:                                                        chunk[2]=hex[((unsigned char)*ptr)%0x10];
        !            77:                                                        strncpy(copy_here, chunk, 3);  copy_here+=3;
        !            78:                                                } else 
        !            79:                                                        *copy_here++=*ptr;
        !            80: 
        !            81:                                                break;
        !            82:                                );
        !            83:                                break;
1.1       paf        84:                        case TABLE: 
                     85:                                escape(
1.4     ! paf        86:                                        escape_value('\t', ' ');
        !            87:                                        escape_value('\n', ' ');
        !            88:                                        escape_default;
1.1       paf        89:                                );
                     90:                                break;
                     91:                        case SQL:
                     92:                                // tainted, untaint language: sql
                     93:                                // TODO: зависимость от sql сервера
                     94:                                memset(copy_here, '?', row->item.size); 
                     95:                                copy_here+=row->item.size;
                     96:                                break;
                     97:                        case JS:
                     98:                                escape(
1.4     ! paf        99:                                        escape_subst('"', "\\\"", 2);
        !           100:                                        escape_subst('\'', "\\'", 2);
        !           101:                                        escape_subst('\n', "\\n", 2);
        !           102:                                        escape_subst('\r', "\\r", 2);
        !           103:                                        escape_subst('\\', "\\\\", 2);
        !           104:                                        escape_subst('я', "\\я", 2);
        !           105:                                        escape_default;
1.1       paf       106:                                );
                    107:                                break;
                    108:                        case HTML:
                    109:                                escape(
1.4     ! paf       110:                                        escape_subst('&', "&amp;", 5); // BEFORE consequent relpaces yelding '&'
        !           111:                                        escape_subst('>', "&gt;", 4);
        !           112:                                        escape_subst('<', "&lt;",4);
        !           113:                                        escape_subst('"', "&quot;",6);
        !           114:                                        escape_value('\t', ' ');
1.1       paf       115:                                        //TODO: XSLT escape_subst('\'', "&apos;", 6)
1.4     ! paf       116:                                        escape_default;
1.1       paf       117:                                );
                    118:                                break;
                    119:                        case HTML_TYPO: 
                    120:                                // tainted, untaint language: html-typo
                    121:                                escape(
1.4     ! paf       122:                                        escape_subst('&', "&amp;", 5); // BEFORE consequent relpaces yelding '&'
        !           123:                                        escape_subst('>', "&gt;", 4);
        !           124:                                        escape_subst('<', "&lt;",4);
        !           125:                                        escape_subst('"', "&quot;",6);
        !           126:                                        escape_value('\t', ' ');
1.1       paf       127:                                        //TODO: $MAIN:html-type table replace, max length(b)==UNTAINT_TIMES_BIGGER*length(a)
1.4     ! paf       128:                                        escape_default;
1.1       paf       129:                                );
                    130:                                break;
                    131:                        default:
                    132:                                THROW(0,0,
                    133:                                        this,
                    134:                                        "unknown untaint language #%d of %d piece", 
                    135:                                                static_cast<int>(row->item.lang),
                    136:                                                i);
                    137:                        }
                    138:                        row++;
                    139:                }
                    140:                chunk=row->link;
                    141:        } while(chunk);
                    142: break2:
                    143:        *copy_here=0;
                    144:        return result;
                    145: }

E-mail: