jetty/CVE-2020-27223-pre-1.patch
2021-03-18 16:09:03 +08:00

546 lines
21 KiB
Diff

From 8011c48685e78850a88e7cc06650f678a375037d Mon Sep 17 00:00:00 2001
From: Greg Wilkins <gregw@webtide.com>
Date: Thu, 28 Feb 2019 18:37:02 +1100
Subject: [PATCH 1/4] Issue #3404 Updated QCSV Double usage
Signed-off-by: Greg Wilkins <gregw@webtide.com>
---
.../eclipse/jetty/http/QuotedQualityCSV.java | 58 ++++++++++---------
1 file changed, 30 insertions(+), 28 deletions(-)
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java
index 61cee88bfd5..c7047c57a4b 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java
@@ -25,6 +25,8 @@
import java.util.List;
import java.util.function.Function;
+import org.eclipse.jetty.util.log.Log;
+
/* ------------------------------------------------------------ */
/**
* Implements a quoted comma separated list of quality values
@@ -37,21 +39,16 @@
*/
public class QuotedQualityCSV extends QuotedCSV implements Iterable<String>
{
- private final static Double ZERO=new Double(0.0);
- private final static Double ONE=new Double(1.0);
-
+ private final static Double ZERO = 0.0D;
+ private final static Double ONE = 1.0D;
/**
- * Function to apply a most specific MIME encoding secondary ordering
+ * Lambda to apply a most specific MIME encoding secondary ordering
*/
- public static Function<String, Integer> MOST_SPECIFIC = new Function<String, Integer>()
+ public static Function<String, Integer> MOST_SPECIFIC = s ->
{
- @Override
- public Integer apply(String s)
- {
- String[] elements = s.split("/");
- return 1000000*elements.length+1000*elements[0].length()+elements[elements.length-1].length();
- }
+ String[] elements = s.split("/");
+ return 1000000*elements.length+1000*elements[0].length()+elements[elements.length-1].length();
};
private final List<Double> _quality = new ArrayList<>();
@@ -74,7 +71,8 @@ public QuotedQualityCSV()
*/
public QuotedQualityCSV(String[] preferredOrder)
{
- this((s) -> {
+ this((s) ->
+ {
for (int i=0;i<preferredOrder.length;++i)
if (preferredOrder[i].equals(s))
return preferredOrder.length-i;
@@ -101,6 +99,8 @@ public QuotedQualityCSV(Function<String, Integer> secondaryOrdering)
protected void parsedValue(StringBuffer buffer)
{
super.parsedValue(buffer);
+
+ // Assume a quality of ONE
_quality.add(ONE);
}
@@ -108,30 +108,32 @@ protected void parsedValue(StringBuffer buffer)
@Override
protected void parsedParam(StringBuffer buffer, int valueLength, int paramName, int paramValue)
{
- if (paramName<0)
+ if (paramName < 0)
{
- if (buffer.charAt(buffer.length()-1)==';')
- buffer.setLength(buffer.length()-1);
+ if (buffer.charAt(buffer.length() - 1) == ';')
+ buffer.setLength(buffer.length() - 1);
}
- else if (paramValue>=0 &&
- buffer.charAt(paramName)=='q' && paramValue>paramName &&
- buffer.length()>=paramName && buffer.charAt(paramName+1)=='=')
+ else if (paramValue >= 0 &&
+ buffer.charAt(paramName) == 'q' && paramValue > paramName &&
+ buffer.length() >= paramName && buffer.charAt(paramName + 1) == '=')
{
Double q;
try
{
- q=(_keepQuotes && buffer.charAt(paramValue)=='"')
- ?new Double(buffer.substring(paramValue+1,buffer.length()-1))
- :new Double(buffer.substring(paramValue));
+ q = (_keepQuotes && buffer.charAt(paramValue) == '"')
+ ? Double.valueOf(buffer.substring(paramValue + 1, buffer.length() - 1))
+ : Double.valueOf(buffer.substring(paramValue));
}
- catch(Exception e)
+ catch (Exception e)
{
- q=ZERO;
- }
- buffer.setLength(Math.max(0,paramName-1));
-
- if (!ONE.equals(q))
- _quality.set(_quality.size()-1,q);
+ Log.getLogger(QuotedQualityCSV.class).ignore(e);
+ q = ZERO;
+ }
+ buffer.setLength(Math.max(0, paramName - 1));
+
+ if (!ONE.equals(q))
+ // replace assumed quality
+ _quality.set(_quality.size() - 1, q);
}
}
From ca8a10a9d5a50e7d814c65134144f776bff1c07a Mon Sep 17 00:00:00 2001
From: Greg Wilkins <gregw@webtide.com>
Date: Fri, 1 Mar 2019 10:17:02 +1100
Subject: [PATCH 2/4] Issue #3404 Cleanup QCSV mime ordering
Signed-off-by: Greg Wilkins <gregw@webtide.com>
---
.../org/eclipse/jetty/http/HttpFields.java | 16 ++++++++-
.../eclipse/jetty/http/QuotedQualityCSV.java | 35 ++++++++++---------
.../jetty/http/QuotedQualityCSVTest.java | 2 +-
.../jetty/server/handler/ErrorHandler.java | 3 +-
4 files changed, 37 insertions(+), 19 deletions(-)
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
index 14c4335eb5a..5a8b53013a7 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
@@ -31,6 +31,7 @@
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.StringTokenizer;
+import java.util.function.Function;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
@@ -437,6 +438,19 @@ protected String addCSV(QuotedCSV existing,String... values)
* @param header The header
*/
public List<String> getQualityCSV(HttpHeader header)
+ {
+ return getQualityCSV(header,null);
+ }
+
+ /**
+ * Get multiple field values of the same name, split and
+ * sorted as a {@link QuotedQualityCSV}
+ *
+ * @param header The header
+ * @param secondaryOrdering Function to apply an ordering other than specified by quality
+ * @return List the values in quality order with the q param and OWS stripped
+ */
+ public List<String> getQualityCSV(HttpHeader header, Function<String, Integer> secondaryOrdering)
{
QuotedQualityCSV values = null;
for (HttpField f : this)
@@ -444,7 +458,7 @@ protected String addCSV(QuotedCSV existing,String... values)
if (f.getHeader()==header)
{
if (values==null)
- values = new QuotedQualityCSV();
+ values = new QuotedQualityCSV(secondaryOrdering);
values.addValue(f.getValue());
}
}
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java
index c7047c57a4b..498d4e01491 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java
@@ -38,17 +38,20 @@
* @see "https://tools.ietf.org/html/rfc7231#section-5.3.1"
*/
public class QuotedQualityCSV extends QuotedCSV implements Iterable<String>
-{
- private final static Double ZERO = 0.0D;
- private final static Double ONE = 1.0D;
-
+{
/**
- * Lambda to apply a most specific MIME encoding secondary ordering
+ * Lambda to apply a most specific MIME encoding secondary ordering.
+ * @see "https://tools.ietf.org/html/rfc7231#section-5.3.2"
*/
- public static Function<String, Integer> MOST_SPECIFIC = s ->
+ public static Function<String, Integer> MOST_SPECIFIC_MIME_ORDERING = s ->
{
- String[] elements = s.split("/");
- return 1000000*elements.length+1000*elements[0].length()+elements[elements.length-1].length();
+ if ("*/*".equals(s))
+ return 0;
+ if (s.endsWith("/*"))
+ return 1;
+ if (s.indexOf(';')<0)
+ return 2;
+ return 3;
};
private final List<Double> _quality = new ArrayList<>();
@@ -61,7 +64,7 @@
*/
public QuotedQualityCSV()
{
- this((s) -> 0);
+ this((Function)null);
}
/* ------------------------------------------------------------ */
@@ -91,7 +94,7 @@ public QuotedQualityCSV(String[] preferredOrder)
*/
public QuotedQualityCSV(Function<String, Integer> secondaryOrdering)
{
- this._secondaryOrdering = secondaryOrdering;
+ this._secondaryOrdering = secondaryOrdering == null ? s->0 : secondaryOrdering;
}
/* ------------------------------------------------------------ */
@@ -101,7 +104,7 @@ protected void parsedValue(StringBuffer buffer)
super.parsedValue(buffer);
// Assume a quality of ONE
- _quality.add(ONE);
+ _quality.add(1.0D);
}
/* ------------------------------------------------------------ */
@@ -127,11 +130,11 @@ else if (paramValue >= 0 &&
catch (Exception e)
{
Log.getLogger(QuotedQualityCSV.class).ignore(e);
- q = ZERO;
+ q = 0.0D;
}
buffer.setLength(Math.max(0, paramName - 1));
- if (!ONE.equals(q))
+ if (!((Double)1.0D).equals(q))
// replace assumed quality
_quality.set(_quality.size() - 1, q);
}
@@ -157,7 +160,7 @@ protected void sort()
{
_sorted=true;
- Double last = ZERO;
+ Double last = 0.0D;
int lastSecondaryOrder = Integer.MIN_VALUE;
for (int i = _values.size(); i-- > 0;)
@@ -172,7 +175,7 @@ protected void sort()
_values.set(i + 1, v);
_quality.set(i, _quality.get(i + 1));
_quality.set(i + 1, q);
- last = ZERO;
+ last = 0.0D;
lastSecondaryOrder=0;
i = _values.size();
continue;
@@ -183,7 +186,7 @@ protected void sort()
}
int last_element=_quality.size();
- while(last_element>0 && _quality.get(--last_element).equals(ZERO))
+ while(last_element>0 && _quality.get(--last_element).equals(0.0D))
{
_quality.remove(last_element);
_values.remove(last_element);
diff --git a/jetty-http/src/test/java/org/eclipse/jetty/http/QuotedQualityCSVTest.java b/jetty-http/src/test/java/org/eclipse/jetty/http/QuotedQualityCSVTest.java
index ba0db4a8972..f03657ba3e5 100644
--- a/jetty-http/src/test/java/org/eclipse/jetty/http/QuotedQualityCSVTest.java
+++ b/jetty-http/src/test/java/org/eclipse/jetty/http/QuotedQualityCSVTest.java
@@ -61,7 +61,7 @@ public void test7231_5_3_2_example3()
@Test
public void test7231_5_3_2_example3_most_specific()
{
- QuotedQualityCSV values = new QuotedQualityCSV(QuotedQualityCSV.MOST_SPECIFIC);
+ QuotedQualityCSV values = new QuotedQualityCSV(QuotedQualityCSV.MOST_SPECIFIC_MIME_ORDERING);
values.addValue("text/*, text/plain, text/plain;format=flowed, */*");
assertThat(values,Matchers.contains("text/plain;format=flowed","text/plain","text/*","*/*"));
diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java
index 84088146cd3..2820dca3a0c 100644
--- a/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java
+++ b/jetty-server/src/main/java/org/eclipse/jetty/server/handler/ErrorHandler.java
@@ -38,6 +38,7 @@
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.MimeTypes;
+import org.eclipse.jetty.http.QuotedQualityCSV;
import org.eclipse.jetty.server.Dispatcher;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
@@ -159,7 +160,7 @@ else if (old_error_page!=null && old_error_page.equals(error_page))
protected void generateAcceptableResponse(Request baseRequest, HttpServletRequest request, HttpServletResponse response, int code, String message)
throws IOException
{
- List<String> acceptable=baseRequest.getHttpFields().getQualityCSV(HttpHeader.ACCEPT);
+ List<String> acceptable=baseRequest.getHttpFields().getQualityCSV(HttpHeader.ACCEPT, QuotedQualityCSV.MOST_SPECIFIC_MIME_ORDERING);
if (acceptable.isEmpty() && !baseRequest.getHttpFields().contains(HttpHeader.ACCEPT))
{
From b925380ede948ab7d8757e95a0ce384b2441625b Mon Sep 17 00:00:00 2001
From: Greg Wilkins <gregw@webtide.com>
Date: Fri, 1 Mar 2019 10:20:10 +1100
Subject: [PATCH 3/4] Issue #3404 Updated QCSV Double usage
Signed-off-by: Greg Wilkins <gregw@webtide.com>
---
.../src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java
index 498d4e01491..a7407d34199 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java
@@ -134,7 +134,7 @@ else if (paramValue >= 0 &&
}
buffer.setLength(Math.max(0, paramName - 1));
- if (!((Double)1.0D).equals(q))
+ if (q!=1.0D)
// replace assumed quality
_quality.set(_quality.size() - 1, q);
}
From 69f6b3b6164228485744918a28ab6a0d4c3facae Mon Sep 17 00:00:00 2001
From: Greg Wilkins <gregw@webtide.com>
Date: Tue, 5 Mar 2019 08:59:55 +1100
Subject: [PATCH 4/4] Issue #3404
updates after review:
+ use ToIntFunction
+ reformat
Signed-off-by: Greg Wilkins <gregw@webtide.com>
---
.../org/eclipse/jetty/http/HttpFields.java | 4 +-
.../eclipse/jetty/http/QuotedQualityCSV.java | 62 +++++++++++--------
2 files changed, 37 insertions(+), 29 deletions(-)
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
index 5a8b53013a7..395b87bde35 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/HttpFields.java
@@ -31,7 +31,7 @@
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.StringTokenizer;
-import java.util.function.Function;
+import java.util.function.ToIntFunction;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
@@ -450,7 +450,7 @@ protected String addCSV(QuotedCSV existing,String... values)
* @param secondaryOrdering Function to apply an ordering other than specified by quality
* @return List the values in quality order with the q param and OWS stripped
*/
- public List<String> getQualityCSV(HttpHeader header, Function<String, Integer> secondaryOrdering)
+ public List<String> getQualityCSV(HttpHeader header, ToIntFunction<String> secondaryOrdering)
{
QuotedQualityCSV values = null;
for (HttpField f : this)
diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java
index a7407d34199..d148d9e65e1 100644
--- a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java
+++ b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java
@@ -18,21 +18,23 @@
package org.eclipse.jetty.http;
-import static java.lang.Integer.MIN_VALUE;
-
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
-import java.util.function.Function;
+import java.util.function.ToIntFunction;
import org.eclipse.jetty.util.log.Log;
+import static java.lang.Integer.MIN_VALUE;
+
/* ------------------------------------------------------------ */
+
/**
* Implements a quoted comma separated list of quality values
* in accordance with RFC7230 and RFC7231.
- * Values are returned sorted in quality order, with OWS and the
+ * Values are returned sorted in quality order, with OWS and the
* quality parameters removed.
+ *
* @see "https://tools.ietf.org/html/rfc7230#section-3.2.6"
* @see "https://tools.ietf.org/html/rfc7230#section-7"
* @see "https://tools.ietf.org/html/rfc7231#section-5.3.1"
@@ -41,44 +43,48 @@
{
/**
* Lambda to apply a most specific MIME encoding secondary ordering.
+ *
* @see "https://tools.ietf.org/html/rfc7231#section-5.3.2"
*/
- public static Function<String, Integer> MOST_SPECIFIC_MIME_ORDERING = s ->
+ public static ToIntFunction<String> MOST_SPECIFIC_MIME_ORDERING = s ->
{
if ("*/*".equals(s))
return 0;
if (s.endsWith("/*"))
return 1;
- if (s.indexOf(';')<0)
+ if (s.indexOf(';') < 0)
return 2;
return 3;
};
-
+
private final List<Double> _quality = new ArrayList<>();
private boolean _sorted = false;
- private final Function<String, Integer> _secondaryOrdering;
-
+ private final ToIntFunction<String> _secondaryOrdering;
+
/* ------------------------------------------------------------ */
+
/**
* Sorts values with equal quality according to the length of the value String.
*/
public QuotedQualityCSV()
{
- this((Function)null);
+ this((ToIntFunction)null);
}
/* ------------------------------------------------------------ */
+
/**
* Sorts values with equal quality according to given order.
+ *
* @param preferredOrder Array indicating the preferred order of known values
*/
public QuotedQualityCSV(String[] preferredOrder)
{
this((s) ->
{
- for (int i=0;i<preferredOrder.length;++i)
+ for (int i = 0; i < preferredOrder.length; ++i)
if (preferredOrder[i].equals(s))
- return preferredOrder.length-i;
+ return preferredOrder.length - i;
if ("*".equals(s))
return preferredOrder.length;
@@ -88,15 +94,17 @@ public QuotedQualityCSV(String[] preferredOrder)
}
/* ------------------------------------------------------------ */
+
/**
* Orders values with equal quality with the given function.
+ *
* @param secondaryOrdering Function to apply an ordering other than specified by quality
*/
- public QuotedQualityCSV(Function<String, Integer> secondaryOrdering)
+ public QuotedQualityCSV(ToIntFunction<String> secondaryOrdering)
{
- this._secondaryOrdering = secondaryOrdering == null ? s->0 : secondaryOrdering;
+ this._secondaryOrdering = secondaryOrdering == null ? s -> 0 : secondaryOrdering;
}
-
+
/* ------------------------------------------------------------ */
@Override
protected void parsedValue(StringBuffer buffer)
@@ -134,7 +142,7 @@ else if (paramValue >= 0 &&
}
buffer.setLength(Math.max(0, paramName - 1));
- if (q!=1.0D)
+ if (q != 1.0D)
// replace assumed quality
_quality.set(_quality.size() - 1, q);
}
@@ -147,7 +155,7 @@ else if (paramValue >= 0 &&
sort();
return _values;
}
-
+
@Override
public Iterator<String> iterator()
{
@@ -158,35 +166,35 @@ else if (paramValue >= 0 &&
protected void sort()
{
- _sorted=true;
+ _sorted = true;
Double last = 0.0D;
int lastSecondaryOrder = Integer.MIN_VALUE;
- for (int i = _values.size(); i-- > 0;)
+ for (int i = _values.size(); i-- > 0; )
{
String v = _values.get(i);
Double q = _quality.get(i);
- int compare=last.compareTo(q);
- if (compare>0 || (compare==0 && _secondaryOrdering.apply(v)<lastSecondaryOrder))
+ int compare = last.compareTo(q);
+ if (compare > 0 || (compare == 0 && _secondaryOrdering.applyAsInt(v) < lastSecondaryOrder))
{
_values.set(i, _values.get(i + 1));
_values.set(i + 1, v);
_quality.set(i, _quality.get(i + 1));
_quality.set(i + 1, q);
last = 0.0D;
- lastSecondaryOrder=0;
+ lastSecondaryOrder = 0;
i = _values.size();
continue;
}
- last=q;
- lastSecondaryOrder=_secondaryOrdering.apply(v);
+ last = q;
+ lastSecondaryOrder = _secondaryOrdering.applyAsInt(v);
}
-
- int last_element=_quality.size();
- while(last_element>0 && _quality.get(--last_element).equals(0.0D))
+
+ int last_element = _quality.size();
+ while (last_element > 0 && _quality.get(--last_element).equals(0.0D))
{
_quality.remove(last_element);
_values.remove(last_element);