-
Notifications
You must be signed in to change notification settings - Fork 15
/
mysql_codec.rb
131 lines (117 loc) · 3.66 KB
/
mysql_codec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#
# Codec to provide for MySQL string support
# http://mirror.yandex.ru/mirrors/ftp.mysql.com/doc/refman/5.0/en/string-syntax.html for details
module Owasp
module Esapi
module Codec
class MySQLCodec < BaseCodec
MYSQL_MODE = 0 # MySQL standard mode
ANSI_MODE = 1; # ANSI escape mode
# create a mysql codec.
# mode must be either MYSQL_MODE or ANSI_MODE
# The mode sets wether to use ansi mode in mysql or not
# defaults to MYSQL_MODE
def initialize(mode = 0)
if mode < MYSQL_MODE or mode > ANSI_MODE
raise RangeError.new()
end
@mode = mode
end
# Returns quote-encoded *character*
def encode_char(immune,input)
return input if immune.include?(input)
hex = hex(input)
return input if hex.nil?
return to_ansi(input) if @mode == ANSI_MODE
return to_mysql(input) if @mode == MYSQL_MODE
end
# Returns the decoded version of the character starting at index, or
# nil if no decoding is possible.
#
# Formats all are legal (case sensitive)
# In ANSI_MODE '' decodes to '
# In MYSQL_MODE \x decodes to x (or a small list of specials)
def decode_char(input)
return from_ansi(input) if @mode == ANSI_MODE
return from_mysql(input) if @mode == MYSQL_MODE
end
# encode ' only
def to_ansi(input) #:nodoc:
return "\'\'" if input == "\'"
input
end
# encode for NO_BACKLASH_MODE
def to_mysql(input) # :nodoc:
c = input.ord
return "\\0" if c == 0x00
return "\\b" if c == 0x08
return "\\t" if c == 0x09
return "\\n" if c == 0x0a
return "\\r" if c == 0x0d
return "\\Z" if c == 0x1a
return "\\\"" if c == 0x22
return "\\%" if c == 0x25
return "\\'" if c == 0x27
return "\\\\" if c == 0x5c
return "\\_" if c == 0x5f
"\\#{input}"
end
# decode a char with ansi only compliane i.e. apostrohpe only
def from_ansi(input) # :nodoc:
input.mark
first = input.next
# check first char
if first.nil?
input.reset
return nil
end
unless first == "\'"
input.reset
return nil
end
# check second char
second = input.next
if second.nil?
input.reset
return nil
end
# if second isnt an encoded char return nil
unless second == "\'"
input.reset
return nil
end
"\'"
end
# decode a char using mysql NO_BACKSLAH_QUOTE rules
def from_mysql(input) # :nodoc:
input.mark
# check first
first = input.next
if first.nil?
input.reset
return nil
end
# check second
second = input.next
if second.nil?
input.reset
return nil
end
return 0x00.chr if second == "0"
return 0x08.chr if second == "b"
return 0x08.chr if second == "t"
return 0x0a.chr if second == "n"
return 0x0d.chr if second == "r"
return 0x1a.chr if second == "z"
return 0x22.chr if second == "\""
return 0x25.chr if second == "%"
return 0x27.chr if second == "\'"
return 0x5c.chr if second == "\\"
return 0x5f.chr if second == "_"
# not an escape
second
end
end
end
end
end