diff --git a/src/java/org/jivesoftware/multiplexer/net/MXParser.java b/src/java/org/jivesoftware/multiplexer/net/MXParser.java index 7fa746c..63b9283 100644 --- a/src/java/org/jivesoftware/multiplexer/net/MXParser.java +++ b/src/java/org/jivesoftware/multiplexer/net/MXParser.java @@ -354,4 +354,27 @@ reader = oldReader; inputEncoding = oldEncoding; } + + /** + * Makes sure that each individual character is a valid XML character. + * + * Note that when MXParser is being modified to handle multibyte chars correctly, this method needs to change (as + * then, there are more codepoints to check). + */ + @Override + protected char more() throws IOException, XmlPullParserException { + final char codePoint = super.more(); // note - this does NOT return a codepoint now, but simply a (single byte) character! + if ((codePoint == 0x0) || // 0x0 is not allowed, but flash clients insist on sending this as the very first character of a stream. We should stop allowing this codepoint after the first byte has been parsed. + (codePoint == 0x9) || + (codePoint == 0xA) || + (codePoint == 0xD) || + ((codePoint >= 0x20) && (codePoint <= 0xD7FF)) || + ((codePoint >= 0xE000) && (codePoint <= 0xFFFD)) || + ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF))) { + return codePoint; + } + + throw new XmlPullParserException("Illegal XML character: " + Integer.parseInt(codePoint+"", 16)); + } + } diff --git a/src/java/org/jivesoftware/multiplexer/net/XMLLightweightParser.java b/src/java/org/jivesoftware/multiplexer/net/XMLLightweightParser.java index 9599059..251c24c 100644 --- a/src/java/org/jivesoftware/multiplexer/net/XMLLightweightParser.java +++ b/src/java/org/jivesoftware/multiplexer/net/XMLLightweightParser.java @@ -2,26 +2,38 @@ * $Revision: $ * $Date: $ * - * Copyright (C) 2008 Jive Software. All rights reserved. + * Copyright (C) 2005-2008 Jive Software. All rights reserved. * - * This software is published under the terms of the GNU Public License (GPL), - * a copy of which is included in this distribution. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ package org.jivesoftware.multiplexer.net; -import org.apache.mina.common.ByteBuffer; -import org.jivesoftware.util.JiveGlobals; -import org.jivesoftware.util.Log; -import org.jivesoftware.util.PropertyEventDispatcher; -import org.jivesoftware.util.PropertyEventListener; - import java.nio.CharBuffer; import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CodingErrorAction; import java.util.ArrayList; import java.util.List; import java.util.Map; +import org.apache.mina.common.ByteBuffer; +import org.jivesoftware.util.JiveGlobals; +import org.jivesoftware.util.PropertyEventDispatcher; +import org.jivesoftware.util.PropertyEventListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * This is a Light-Weight XML Parser. * It read data from a channel and collect data until data are available in @@ -34,6 +46,9 @@ * @author Gaston Dombiak */ class XMLLightweightParser { + + private static final Logger Log = LoggerFactory.getLogger(XMLLightweightParser.class); + private static final String MAX_PROPERTY_NAME = "xmpp.parser.buffer.size"; private static int maxBufferSize; // Chars that rappresent CDATA section start @@ -88,7 +103,7 @@ protected boolean insideChildrenTag = false; - Charset encoder; + CharsetDecoder encoder; static { // Set default max buffer size to 1MB. If limit is reached then close connection @@ -97,9 +112,11 @@ PropertyEventDispatcher.addListener(new PropertyListener()); } - public XMLLightweightParser(String charset) { - encoder = Charset.forName(charset); - } + public XMLLightweightParser(String charset) { + encoder = Charset.forName(charset).newDecoder() + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); + } /* * true if the parser has found some complete xml message. @@ -176,7 +193,7 @@ char lastChar = buf[readByte-1]; if (lastChar >= 0xfff0) { if (Log.isDebugEnabled()) { - Log.debug("Waiting to get complete char: " + String.valueOf(buf)); + Log.debug("Waiting to get complete char: " + String.valueOf(buf)); } // Rewind the position one place so the last byte stays in the buffer // The missing byte should arrive in the next iteration. Once we have both @@ -184,21 +201,14 @@ byteBuffer.position(byteBuffer.position()-1); // Decrease the number of bytes read by one readByte--; - // Just return if nothing was read + // Just return if nothing was read if (readByte == 0) { return; } } buffer.append(buf, 0, readByte); - // Do nothing if the buffer only contains white spaces - if (buffer.charAt(0) <= ' ' && buffer.charAt(buffer.length()-1) <= ' ') { - if ("".equals(buffer.toString().trim())) { - // Empty the buffer so there is no memory leak - buffer.delete(0, buffer.length()); - return; - } - } + // Robot. char ch; boolean isHighSurrogate = false;