|
|
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.3 ! paf 6: $Id: untaint.C,v 1.2 2001/03/12 21:54:20 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: default: *copy_here++=*ptr; break; \
23: } \
24: }
25: #define escape_value(a, c) case a: *copy_here++=c; break;
26: #define escape_subst(a, b, bsize) \
27: case a: \
28: { \
29: strncpy(copy_here, b, bsize); \
30: copy_here+=bsize; \
31: } \
32: break;
33:
34: // String
35:
36: char *String::cstr() const {
1.2 paf 37: char *result=(char *)malloc(size()*UNTAINT_TIMES_BIGGER+1);
1.1 paf 38:
39: char *copy_here=result;
40: const Chunk *chunk=&head;
41: // TODO: оптимизировать whitespaces для всех, кроме 'html'
42: do {
43: const Chunk::Row *row=chunk->rows;
44: for(int i=0; i<chunk->count; i++) {
45: if(row==append_here)
46: goto break2;
47:
48: // WARNING:
49: // string can grow only UNTAINT_TIMES_BIGGER
50: switch(row->item.lang) {
51: case NO:
52: // clean piece
53: case YES:
54: // tainted piece, but undefined untaint language
55: // for VString.get_double of tainted values
56: // for ^process{body} evaluation
57: case AS_IS:
58: // tainted, untaint language: as-is
59: memcpy(copy_here, row->item.ptr, row->item.size);
60: copy_here+=row->item.size;
61: break;
62: case TABLE:
63: escape(
64: escape_value('\t', ' ')
65: escape_value('\n', ' ')
66: );
67: break;
68: case SQL:
69: // tainted, untaint language: sql
70: // TODO: зависимость от sql сервера
71: memset(copy_here, '?', row->item.size);
72: copy_here+=row->item.size;
73: break;
74: case JS:
75: escape(
76: escape_subst('"', "\\\"", 2)
77: escape_subst('\'', "\\'", 2)
78: escape_subst('\n', "\\n", 2)
79: escape_subst('\r', "\\r", 2)
80: escape_subst('\\', "\\\\", 2)
81: escape_subst('я', "\\я", 2)
82: );
83: break;
84: case HTML:
85: escape(
86: escape_subst('&', "&", 5) // BEFORE consequent relpaces yelding '&'
87: escape_subst('>', ">", 4)
88: escape_subst('<', "<",4)
89: escape_subst('"', """,6)
90: escape_value('\t', ' ')
91: //TODO: XSLT escape_subst('\'', "'", 6)
92: );
93: break;
94: case HTML_TYPO:
95: // tainted, untaint language: html-typo
96: escape(
97: escape_subst('&', "&", 5) // BEFORE consequent relpaces yelding '&'
98: escape_subst('>', ">", 4)
99: escape_subst('<', "<",4)
100: escape_subst('"', """,6)
101: escape_value('\t', ' ')
102: //TODO: $MAIN:html-type table replace, max length(b)==UNTAINT_TIMES_BIGGER*length(a)
103: );
104: break;
105: default:
106: THROW(0,0,
107: this,
108: "unknown untaint language #%d of %d piece",
109: static_cast<int>(row->item.lang),
110: i);
111: }
112: row++;
113: }
114: chunk=row->link;
115: } while(chunk);
116: break2:
117: *copy_here=0;
118: return result;
119: }