001
014
015 package com.liferay.portal.security.xml;
016
017 import com.liferay.portal.kernel.util.ArrayUtil;
018
019 import java.io.IOException;
020 import java.io.InputStream;
021 import java.io.Reader;
022
023
026 public class StripDoctypeFilter {
027
028 public StripDoctypeFilter(InputStream inputStream) {
029 _inputStream = inputStream;
030 }
031
032 public StripDoctypeFilter(Reader reader) {
033 _reader = reader;
034 }
035
036 public int read() throws IOException {
037 if (_bufferLength > 0) {
038 return readFromBuffer();
039 }
040
041 int c = readFromSource();
042
043 if (_documentStarted) {
044 return c;
045 }
046
047 if (c == '<') {
048 int[] buffer = new int[2];
049
050 buffer[0] = readFromSource();
051 buffer[1] = readFromSource();
052
053 if (buffer[0] == '?') {
054 setBuffer(buffer);
055
056 return c;
057 }
058
059 if ((buffer[0] == '!') && (buffer[1] == '-')) {
060 setBuffer(buffer);
061
062 return c;
063 }
064
065 if ((buffer[0] == '!') && (buffer[1] == 'D')) {
066 while (true) {
067 int doctypeContent = readFromSource();
068
069 if (doctypeContent == '[') {
070 entityDeclaration = true;
071 }
072 else if (doctypeContent == ']') {
073 entityDeclaration = false;
074 }
075 else if (doctypeContent == '>') {
076 if (!entityDeclaration) {
077 _documentStarted = true;
078
079 return readFromSource();
080 }
081 }
082 }
083 }
084
085 setBuffer(buffer);
086
087 _documentStarted = true;
088 }
089
090 return c;
091 }
092
093 public int read(byte[] bytes, int offset, int length) throws IOException {
094 if (_documentStarted && (length > _bufferLength)) {
095 int bufferLength = _bufferLength;
096
097 for (int i = 0; i < bufferLength; i++) {
098 bytes[offset++] = (byte) (readFromBuffer() & 0xFF);
099 }
100
101 return _inputStream.read(bytes, offset, length - bufferLength) +
102 bufferLength;
103 }
104
105 int read = 0;
106
107 for (read = 0; read < length; read++) {
108 int c = read();
109
110 if (c == -1) {
111 if (read == 0) {
112 return -1;
113 }
114
115 return read;
116 }
117
118 bytes[offset + read] = (byte) (c & 0xFF);
119 }
120
121 return read;
122 }
123
124 public int read(char[] chars, int offset, int length) throws IOException {
125 if (_documentStarted && (length > _bufferLength)) {
126 int bufferLength = _bufferLength;
127
128 for (int i = 0; i < bufferLength; i++) {
129 chars[offset++] = (char)readFromBuffer();
130 }
131
132 return _reader.read(chars, offset, length - bufferLength) +
133 bufferLength;
134 }
135
136 int read = 0;
137
138 for (read = 0; read < length; read++) {
139 int c = read();
140
141 if (c == -1) {
142 if (read == 0) {
143 return -1;
144 }
145
146 return read;
147 }
148
149 chars[offset + read] = (char)c;
150 }
151
152 return read;
153 }
154
155 protected int readFromBuffer() {
156 _bufferLength--;
157
158 return _buffer[_bufferLength];
159 }
160
161 protected int readFromSource() throws IOException {
162 if (_inputStream != null) {
163 return _inputStream.read();
164 }
165
166 if (_reader != null) {
167 return _reader.read();
168 }
169
170 throw new IllegalStateException("No underlying source available");
171 }
172
173 protected void setBuffer(int[] buffer) {
174 _buffer = buffer;
175
176 ArrayUtil.reverse(_buffer);
177
178 _bufferLength = _buffer.length;
179 }
180
181 private int[] _buffer;
182 private int _bufferLength;
183 private boolean _documentStarted;
184 private InputStream _inputStream;
185 private Reader _reader;
186 private boolean entityDeclaration;
187
188 }