You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by dk...@apache.org on 2019/10/31 14:51:57 UTC
[ws-axiom] 05/11: Merge r1795105 (with changes) to the 1.2 branch.
This is an automated email from the ASF dual-hosted git repository.
dkulp pushed a commit to branch 1.2.x
in repository https://gitbox.apache.org/repos/asf/ws-axiom.git
commit a6235a8968d9298eba5e22ed10826d82ef6fd75f
Author: Andreas Veithen <ve...@apache.org>
AuthorDate: Sat May 4 12:00:00 2019 +0000
Merge r1795105 (with changes) to the 1.2 branch.
---
.../org/apache/axiom/attachments/MIMEMessage.java | 4 +-
.../org/apache/axiom/attachments/PartImpl.java | 9 +-
.../attachments/QuotedPrintableInputStream.java | 321 ---------------------
pom.xml | 3 +-
4 files changed, 4 insertions(+), 333 deletions(-)
diff --git a/axiom-api/src/main/java/org/apache/axiom/attachments/MIMEMessage.java b/axiom-api/src/main/java/org/apache/axiom/attachments/MIMEMessage.java
index 60abdef..f23bf08 100644
--- a/axiom-api/src/main/java/org/apache/axiom/attachments/MIMEMessage.java
+++ b/axiom-api/src/main/java/org/apache/axiom/attachments/MIMEMessage.java
@@ -55,6 +55,8 @@ import org.apache.james.mime4j.stream.RecursionMode;
class MIMEMessage extends AttachmentsDelegate {
private static final Log log = LogFactory.getLog(MIMEMessage.class);
+ private static final MimeConfig config = MimeConfig.custom().setStrictParsing(true).build();
+
private static final WritableBlobFactory rootPartBlobFactory = new WritableBlobFactory() {
public WritableBlob createBlob() {
return Blobs.createMemoryBlob();
@@ -122,8 +124,6 @@ class MIMEMessage extends AttachmentsDelegate {
filterIS = null;
}
- MimeConfig config = new MimeConfig();
- config.setStrictParsing(true);
parser = new MimeTokenStream(config);
parser.setRecursionMode(RecursionMode.M_NO_RECURSE);
parser.parseHeadless(is, contentTypeString);
diff --git a/axiom-api/src/main/java/org/apache/axiom/attachments/PartImpl.java b/axiom-api/src/main/java/org/apache/axiom/attachments/PartImpl.java
index 09ada91..791a924 100644
--- a/axiom-api/src/main/java/org/apache/axiom/attachments/PartImpl.java
+++ b/axiom-api/src/main/java/org/apache/axiom/attachments/PartImpl.java
@@ -166,14 +166,7 @@ final class PartImpl implements Part {
}
private InputStream getDecodedInputStream() {
- InputStream in;
- if ("quoted-printable".equalsIgnoreCase(getHeader("Content-Transfer-Encoding"))) {
- // Temporary workaround for AXIOM-467 while waiting for MIME4J 0.7.3:
- // use a copy of QuotedPrintableInputStream from the 0.7 branch.
- in = new QuotedPrintableInputStream(parser.getInputStream(), true);
- } else {
- in = parser.getDecodedInputStream();
- }
+ InputStream in = parser.getDecodedInputStream();
if (log.isDebugEnabled()) {
in = new DebugInputStream(in, log);
}
diff --git a/axiom-api/src/main/java/org/apache/axiom/attachments/QuotedPrintableInputStream.java b/axiom-api/src/main/java/org/apache/axiom/attachments/QuotedPrintableInputStream.java
deleted file mode 100644
index 6703991..0000000
--- a/axiom-api/src/main/java/org/apache/axiom/attachments/QuotedPrintableInputStream.java
+++ /dev/null
@@ -1,321 +0,0 @@
-/****************************************************************
- * Licensed to the Apache Software Foundation (ASF) under one *
- * or more contributor license agreements. See the NOTICE file *
- * distributed with this work for additional information *
- * regarding copyright ownership. The ASF licenses this file *
- * to you 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.apache.axiom.attachments;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.apache.james.mime4j.codec.DecodeMonitor;
-import org.apache.james.mime4j.util.ByteArrayBuffer;
-
-/**
- * Performs Quoted-Printable decoding on an underlying stream.
- */
-final class QuotedPrintableInputStream extends InputStream {
-
- private static final int DEFAULT_BUFFER_SIZE = 1024 * 2;
-
- private static final byte EQ = 0x3D;
- private static final byte CR = 0x0D;
- private static final byte LF = 0x0A;
-
- private final byte[] singleByte = new byte[1];
-
- private final InputStream in;
- private final ByteArrayBuffer decodedBuf;
- private final ByteArrayBuffer blanks;
-
- private final byte[] encoded;
- private int pos = 0; // current index into encoded buffer
- private int limit = 0; // current size of encoded buffer
-
- private boolean lastWasCR = false;
- private boolean closed;
-
- private final DecodeMonitor monitor;
-
- public QuotedPrintableInputStream(final InputStream in, DecodeMonitor monitor) {
- this(DEFAULT_BUFFER_SIZE, in, monitor);
- }
-
- protected QuotedPrintableInputStream(final int bufsize, final InputStream in, DecodeMonitor monitor) {
- super();
- this.in = in;
- this.encoded = new byte[bufsize];
- this.decodedBuf = new ByteArrayBuffer(512);
- this.blanks = new ByteArrayBuffer(512);
- this.closed = false;
- this.monitor = monitor;
- }
-
- protected QuotedPrintableInputStream(final int bufsize, final InputStream in, boolean strict) {
- this(bufsize, in, strict ? DecodeMonitor.STRICT : DecodeMonitor.SILENT);
- }
-
- public QuotedPrintableInputStream(final InputStream in, boolean strict) {
- this(DEFAULT_BUFFER_SIZE, in, strict);
- }
-
- public QuotedPrintableInputStream(final InputStream in) {
- this(in, false);
- }
-
- /**
- * Terminates Quoted-Printable coded content. This method does NOT close
- * the underlying input stream.
- *
- * @throws IOException on I/O errors.
- */
- @Override
- public void close() throws IOException {
- closed = true;
- }
-
- private int fillBuffer() throws IOException {
- // Compact buffer if needed
- if (pos < limit) {
- System.arraycopy(encoded, pos, encoded, 0, limit - pos);
- limit -= pos;
- pos = 0;
- } else {
- limit = 0;
- pos = 0;
- }
-
- int capacity = encoded.length - limit;
- if (capacity > 0) {
- int bytesRead = in.read(encoded, limit, capacity);
- if (bytesRead > 0) {
- limit += bytesRead;
- }
- return bytesRead;
- } else {
- return 0;
- }
- }
-
- private int getnext() {
- if (pos < limit) {
- byte b = encoded[pos];
- pos++;
- return b & 0xFF;
- } else {
- return -1;
- }
- }
-
- private int peek(int i) {
- if (pos + i < limit) {
- return encoded[pos + i] & 0xFF;
- } else {
- return -1;
- }
- }
-
- private int transfer(
- final int b, final byte[] buffer, final int from, final int to, boolean keepblanks) throws IOException {
- int index = from;
- if (keepblanks && blanks.length() > 0) {
- int chunk = Math.min(blanks.length(), to - index);
- System.arraycopy(blanks.buffer(), 0, buffer, index, chunk);
- index += chunk;
- int remaining = blanks.length() - chunk;
- if (remaining > 0) {
- decodedBuf.append(blanks.buffer(), chunk, remaining);
- }
- blanks.clear();
- } else if (blanks.length() > 0 && !keepblanks) {
- StringBuilder sb = new StringBuilder(blanks.length() * 3);
- for (int i = 0; i < blanks.length(); i++) sb.append(" "+blanks.byteAt(i));
- if (monitor.warn("ignored blanks", sb.toString()))
- throw new IOException("ignored blanks");
- }
- if (b != -1) {
- if (index < to) {
- buffer[index++] = (byte) b;
- } else {
- decodedBuf.append(b);
- }
- }
- return index;
- }
-
- private int read0(final byte[] buffer, final int off, final int len) throws IOException {
- boolean eof = false;
- int from = off;
- int to = off + len;
- int index = off;
-
- // check if a previous invocation left decoded content
- if (decodedBuf.length() > 0) {
- int chunk = Math.min(decodedBuf.length(), to - index);
- System.arraycopy(decodedBuf.buffer(), 0, buffer, index, chunk);
- decodedBuf.remove(0, chunk);
- index += chunk;
- }
-
- while (index < to) {
-
- if (limit - pos < 3) {
- int bytesRead = fillBuffer();
- eof = bytesRead == -1;
- }
-
- // end of stream?
- if (limit - pos == 0 && eof) {
- return index == from ? -1 : index - from;
- }
-
- while (pos < limit && index < to) {
- int b = encoded[pos++] & 0xFF;
-
- if (lastWasCR && b != LF) {
- if (monitor.warn("Found CR without LF", "Leaving it as is")) {
- throw new IOException("Found CR without LF");
- }
- index = transfer(CR, buffer, index, to, false);
- } else if (!lastWasCR && b == LF) {
- if (monitor.warn("Found LF without CR", "Translating to CRLF")) {
- throw new IOException("Found LF without CR");
- }
- }
-
- if (b == CR) {
- lastWasCR = true;
- continue;
- } else {
- lastWasCR = false;
- }
-
- if (b == LF) {
- // at end of line
- if (blanks.length() == 0) {
- index = transfer(CR, buffer, index, to, false);
- index = transfer(LF, buffer, index, to, false);
- } else {
- if (blanks.byteAt(0) != EQ) {
- // hard line break
- index = transfer(CR, buffer, index, to, false);
- index = transfer(LF, buffer, index, to, false);
- }
- }
- blanks.clear();
- } else if (b == EQ) {
- if (limit - pos < 2 && !eof) {
- // not enough buffered data
- pos--;
- break;
- }
-
- // found special char '='
- int b2 = getnext();
- if (b2 == EQ) {
- index = transfer(b2, buffer, index, to, true);
- // deal with '==\r\n' brokenness
- int bb1 = peek(0);
- int bb2 = peek(1);
- if (bb1 == LF || (bb1 == CR && bb2 == LF)) {
- monitor.warn("Unexpected ==EOL encountered", "== 0x"+bb1+" 0x"+bb2);
- blanks.append(b2);
- } else {
- monitor.warn("Unexpected == encountered", "==");
- }
- } else if (Character.isWhitespace((char) b2)) {
- // soft line break
- int b3 = peek(0);
- if (!(b2 == CR && b3 == LF)) {
- if (monitor.warn("Found non-standard soft line break", "Translating to soft line break")) {
- throw new IOException("Non-standard soft line break");
- }
- }
- if (b3 == LF) {
- lastWasCR = b2 == CR;
- }
- index = transfer(-1, buffer, index, to, true);
- if (b2 != LF) {
- blanks.append(b);
- blanks.append(b2);
- }
- } else {
- int b3 = getnext();
- int upper = convert(b2);
- int lower = convert(b3);
- if (upper < 0 || lower < 0) {
- monitor.warn("Malformed encoded value encountered", "leaving "+((char) EQ)+((char) b2)+((char) b3)+" as is");
- // TODO see MIME4J-160
- index = transfer(EQ, buffer, index, to, true);
- index = transfer(b2, buffer, index, to, false);
- index = transfer(b3, buffer, index, to, false);
- } else {
- index = transfer((upper << 4) | lower, buffer, index, to, true);
- }
- }
- } else if (Character.isWhitespace(b)) {
- blanks.append(b);
- } else {
- index = transfer((int) b & 0xFF, buffer, index, to, true);
- }
- }
- }
- return to - from;
- }
-
- /**
- * Converts '0' => 0, 'A' => 10, etc.
- * @param c ASCII character value.
- * @return Numeric value of hexadecimal character.
- */
- private int convert(int c) {
- if (c >= '0' && c <= '9') {
- return (c - '0');
- } else if (c >= 'A' && c <= 'F') {
- return (0xA + (c - 'A'));
- } else if (c >= 'a' && c <= 'f') {
- return (0xA + (c - 'a'));
- } else {
- return -1;
- }
- }
-
- @Override
- public int read() throws IOException {
- if (closed) {
- throw new IOException("Stream has been closed");
- }
- for (;;) {
- int bytes = read(singleByte, 0, 1);
- if (bytes == -1) {
- return -1;
- }
- if (bytes == 1) {
- return singleByte[0] & 0xff;
- }
- }
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- if (closed) {
- throw new IOException("Stream has been closed");
- }
- return read0(b, off, len);
- }
-
-}
diff --git a/pom.xml b/pom.xml
index d779220..78c86b3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -343,8 +343,7 @@
<dependency>
<groupId>org.apache.james</groupId>
<artifactId>apache-mime4j-core</artifactId>
- <!-- Note: snapshot versions are currently not stable because of MIME4J-231 -->
- <version>0.7.2</version>
+ <version>0.8.0</version>
</dependency>
<dependency>
<groupId>org.osgi</groupId>