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