Projects
openEuler:24.03:SP1:Everything
jetty
_service:tar_scm:CVE-2020-27223.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:CVE-2020-27223.patch of Package jetty
From: Markus Koschany <apo@debian.org> Date: Sat, 31 Jul 2021 17:21:57 +0200 Subject: CVE-2020-27223 --- .../java/org/eclipse/jetty/http/QuotedCSV.java | 280 ++----------------- .../org/eclipse/jetty/http/QuotedCSVParser.java | 303 +++++++++++++++++++++ .../org/eclipse/jetty/http/QuotedQualityCSV.java | 140 ++++++---- .../eclipse/jetty/http/QuotedQualityCSVTest.java | 143 +++++----- 4 files changed, 479 insertions(+), 387 deletions(-) create mode 100644 jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSVParser.java diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSV.java b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSV.java index 9ca7dbe..a356213 100644 --- a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSV.java +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSV.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 @@ -22,236 +22,36 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import org.eclipse.jetty.util.QuotedStringTokenizer; - -/* ------------------------------------------------------------ */ /** * Implements a quoted comma separated list of values * in accordance with RFC7230. * OWS is removed and quoted characters ignored for parsing. + * * @see "https://tools.ietf.org/html/rfc7230#section-3.2.6" * @see "https://tools.ietf.org/html/rfc7230#section-7" */ -public class QuotedCSV implements Iterable<String> -{ - private enum State { VALUE, PARAM_NAME, PARAM_VALUE}; - +public class QuotedCSV extends QuotedCSVParser implements Iterable<String> +{ protected final List<String> _values = new ArrayList<>(); - protected final boolean _keepQuotes; - - /* ------------------------------------------------------------ */ + public QuotedCSV(String... values) { - this(true,values); + this(true, values); } - - /* ------------------------------------------------------------ */ - public QuotedCSV(boolean keepQuotes,String... values) - { - _keepQuotes=keepQuotes; - for (String v:values) - addValue(v); - } - - /* ------------------------------------------------------------ */ - /** Add and parse a value string(s) - * @param value A value that may contain one or more Quoted CSV items. - */ - public void addValue(String value) + + public QuotedCSV(boolean keepQuotes, String... values) { - if (value == null) - return; - - StringBuffer buffer = new StringBuffer(); - - int l=value.length(); - State state=State.VALUE; - boolean quoted=false; - boolean sloshed=false; - int nws_length=0; - int last_length=0; - int value_length=-1; - int param_name=-1; - int param_value=-1; - - for (int i=0;i<=l;i++) + super(keepQuotes); + for (String v : values) { - char c=i==l?0:value.charAt(i); - - // Handle quoting https://tools.ietf.org/html/rfc7230#section-3.2.6 - if (quoted && c!=0) - { - if (sloshed) - sloshed=false; - else - { - switch(c) - { - case '\\': - sloshed=true; - if (!_keepQuotes) - continue; - break; - case '"': - quoted=false; - if (!_keepQuotes) - continue; - break; - } - } - - buffer.append(c); - nws_length=buffer.length(); - continue; - } - - // Handle common cases - switch(c) - { - case ' ': - case '\t': - if (buffer.length()>last_length) // not leading OWS - buffer.append(c); - continue; - - case '"': - quoted=true; - if (_keepQuotes) - { - if (state==State.PARAM_VALUE && param_value<0) - param_value=nws_length; - buffer.append(c); - } - else if (state==State.PARAM_VALUE && param_value<0) - param_value=nws_length; - nws_length=buffer.length(); - continue; - - case ';': - buffer.setLength(nws_length); // trim following OWS - if (state==State.VALUE) - { - parsedValue(buffer); - value_length=buffer.length(); - } - else - parsedParam(buffer,value_length,param_name,param_value); - nws_length=buffer.length(); - param_name=param_value=-1; - buffer.append(c); - last_length=++nws_length; - state=State.PARAM_NAME; - continue; - - case ',': - case 0: - if (nws_length>0) - { - buffer.setLength(nws_length); // trim following OWS - switch(state) - { - case VALUE: - parsedValue(buffer); - value_length=buffer.length(); - break; - case PARAM_NAME: - case PARAM_VALUE: - parsedParam(buffer,value_length,param_name,param_value); - break; - } - _values.add(buffer.toString()); - } - buffer.setLength(0); - last_length=0; - nws_length=0; - value_length=param_name=param_value=-1; - state=State.VALUE; - continue; - - case '=': - switch (state) - { - case VALUE: - // It wasn't really a value, it was a param name - value_length=param_name=0; - buffer.setLength(nws_length); // trim following OWS - String param = buffer.toString(); - buffer.setLength(0); - parsedValue(buffer); - value_length=buffer.length(); - buffer.append(param); - buffer.append(c); - last_length=++nws_length; - state=State.PARAM_VALUE; - continue; - - case PARAM_NAME: - buffer.setLength(nws_length); // trim following OWS - buffer.append(c); - last_length=++nws_length; - state=State.PARAM_VALUE; - continue; - - case PARAM_VALUE: - if (param_value<0) - param_value=nws_length; - buffer.append(c); - nws_length=buffer.length(); - continue; - } - continue; - - default: - { - switch (state) - { - case VALUE: - { - buffer.append(c); - nws_length=buffer.length(); - continue; - } - - case PARAM_NAME: - { - if (param_name<0) - param_name=nws_length; - buffer.append(c); - nws_length=buffer.length(); - continue; - } - - case PARAM_VALUE: - { - if (param_value<0) - param_value=nws_length; - buffer.append(c); - nws_length=buffer.length(); - continue; - } - } - } - } + addValue(v); } } - /** - * Called when a value has been parsed - * @param buffer Containing the trimmed value, which may be mutated - */ - protected void parsedValue(StringBuffer buffer) - { - } - - /** - * Called when a parameter has been parsed - * @param buffer Containing the trimmed value and all parameters, which may be mutated - * @param valueLength The length of the value - * @param paramName The index of the start of the parameter just parsed - * @param paramValue The index of the start of the parameter value just parsed, or -1 - */ - protected void parsedParam(StringBuffer buffer, int valueLength, int paramName, int paramValue) + @Override + protected void parsedValueAndParams(StringBuffer buffer) { + _values.add(buffer.toString()); } public int size() @@ -268,67 +68,21 @@ public class QuotedCSV implements Iterable<String> { return _values; } - + @Override public Iterator<String> iterator() { return _values.iterator(); } - - public static String unquote(String s) - { - // handle trivial cases - int l=s.length(); - if (s==null || l==0) - return s; - - // Look for any quotes - int i=0; - for (;i<l;i++) - { - char c=s.charAt(i); - if (c=='"') - break; - } - if (i==l) - return s; - boolean quoted=true; - boolean sloshed=false; - StringBuffer buffer = new StringBuffer(); - buffer.append(s,0,i); - i++; - for (;i<l;i++) - { - char c=s.charAt(i); - if (quoted) - { - if (sloshed) - { - buffer.append(c); - sloshed=false; - } - else if (c=='"') - quoted=false; - else if (c=='\\') - sloshed=true; - else - buffer.append(c); - } - else if (c=='"') - quoted=true; - else - buffer.append(c); - } - return buffer.toString(); - } - @Override public String toString() { List<String> list = new ArrayList<>(); for (String s : this) + { list.add(s); + } return list.toString(); } } diff --git a/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSVParser.java b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSVParser.java new file mode 100644 index 0000000..7aefcf7 --- /dev/null +++ b/jetty-http/src/main/java/org/eclipse/jetty/http/QuotedCSVParser.java @@ -0,0 +1,303 @@ +// +// ======================================================================== +// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.http; + +/** + * Implements a quoted comma separated list parser + * in accordance with RFC7230. + * OWS is removed and quoted characters ignored for parsing. + * + * @see "https://tools.ietf.org/html/rfc7230#section-3.2.6" + * @see "https://tools.ietf.org/html/rfc7230#section-7" + */ +public abstract class QuotedCSVParser +{ + private enum State + { + VALUE, PARAM_NAME, PARAM_VALUE + } + + protected final boolean _keepQuotes; + + public QuotedCSVParser(boolean keepQuotes) + { + _keepQuotes = keepQuotes; + } + + public static String unquote(String s) + { + // handle trivial cases + int l = s.length(); + if (s == null || l == 0) + return s; + + // Look for any quotes + int i = 0; + for (; i < l; i++) + { + char c = s.charAt(i); + if (c == '"') + break; + } + if (i == l) + return s; + + boolean quoted = true; + boolean sloshed = false; + StringBuffer buffer = new StringBuffer(); + buffer.append(s, 0, i); + i++; + for (; i < l; i++) + { + char c = s.charAt(i); + if (quoted) + { + if (sloshed) + { + buffer.append(c); + sloshed = false; + } + else if (c == '"') + quoted = false; + else if (c == '\\') + sloshed = true; + else + buffer.append(c); + } + else if (c == '"') + quoted = true; + else + buffer.append(c); + } + return buffer.toString(); + } + + /** + * Add and parse a value string(s) + * + * @param value A value that may contain one or more Quoted CSV items. + */ + public void addValue(String value) + { + if (value == null) + return; + + StringBuffer buffer = new StringBuffer(); + + int l = value.length(); + State state = State.VALUE; + boolean quoted = false; + boolean sloshed = false; + int nwsLength = 0; + int lastLength = 0; + int valueLength = -1; + int paramName = -1; + int paramValue = -1; + + for (int i = 0; i <= l; i++) + { + char c = i == l ? 0 : value.charAt(i); + + // Handle quoting https://tools.ietf.org/html/rfc7230#section-3.2.6 + if (quoted && c != 0) + { + if (sloshed) + sloshed = false; + else + { + switch (c) + { + case '\\': + sloshed = true; + if (!_keepQuotes) + continue; + break; + case '"': + quoted = false; + if (!_keepQuotes) + continue; + break; + } + } + + buffer.append(c); + nwsLength = buffer.length(); + continue; + } + + // Handle common cases + switch (c) + { + case ' ': + case '\t': + if (buffer.length() > lastLength) // not leading OWS + buffer.append(c); + continue; + + case '"': + quoted = true; + if (_keepQuotes) + { + if (state == State.PARAM_VALUE && paramValue < 0) + paramValue = nwsLength; + buffer.append(c); + } + else if (state == State.PARAM_VALUE && paramValue < 0) + paramValue = nwsLength; + nwsLength = buffer.length(); + continue; + + case ';': + buffer.setLength(nwsLength); // trim following OWS + if (state == State.VALUE) + { + parsedValue(buffer); + valueLength = buffer.length(); + } + else + parsedParam(buffer, valueLength, paramName, paramValue); + nwsLength = buffer.length(); + paramName = paramValue = -1; + buffer.append(c); + lastLength = ++nwsLength; + state = State.PARAM_NAME; + continue; + + case ',': + case 0: + if (nwsLength > 0) + { + buffer.setLength(nwsLength); // trim following OWS + switch (state) + { + case VALUE: + parsedValue(buffer); + valueLength = buffer.length(); + break; + case PARAM_NAME: + case PARAM_VALUE: + parsedParam(buffer, valueLength, paramName, paramValue); + break; + } + parsedValueAndParams(buffer); + } + buffer.setLength(0); + lastLength = 0; + nwsLength = 0; + valueLength = paramName = paramValue = -1; + state = State.VALUE; + continue; + + case '=': + switch (state) + { + case VALUE: + // It wasn't really a value, it was a param name + valueLength = paramName = 0; + buffer.setLength(nwsLength); // trim following OWS + String param = buffer.toString(); + buffer.setLength(0); + parsedValue(buffer); + valueLength = buffer.length(); + buffer.append(param); + buffer.append(c); + lastLength = ++nwsLength; + state = State.PARAM_VALUE; + continue; + + case PARAM_NAME: + buffer.setLength(nwsLength); // trim following OWS + buffer.append(c); + lastLength = ++nwsLength; + state = State.PARAM_VALUE; + continue; + + case PARAM_VALUE: + if (paramValue < 0) + paramValue = nwsLength; + buffer.append(c); + nwsLength = buffer.length(); + continue; + } + continue; + + default: + { + switch (state) + { + case VALUE: + { + buffer.append(c); + nwsLength = buffer.length(); + continue; + } + + case PARAM_NAME: + { + if (paramName < 0) + paramName = nwsLength; + buffer.append(c); + nwsLength = buffer.length(); + continue; + } + + case PARAM_VALUE: + { + if (paramValue < 0) + paramValue = nwsLength; + buffer.append(c); + nwsLength = buffer.length(); + continue; + } + } + } + } + } + } + + /** + * Called when a value and it's parameters has been parsed + * + * @param buffer Containing the trimmed value and parameters + */ + protected void parsedValueAndParams(StringBuffer buffer) + { + } + + /** + * Called when a value has been parsed (prior to any parameters) + * + * @param buffer Containing the trimmed value, which may be mutated + */ + protected void parsedValue(StringBuffer buffer) + { + } + + /** + * Called when a parameter has been parsed + * + * @param buffer Containing the trimmed value and all parameters, which may be mutated + * @param valueLength The length of the value + * @param paramName The index of the start of the parameter just parsed + * @param paramValue The index of the start of the parameter value just parsed, or -1 + */ + protected void parsedParam(StringBuffer buffer, int valueLength, int paramName, int paramValue) + { + } +} 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 d148d9e..5bc9985 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 @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 @@ -21,14 +21,12 @@ package org.eclipse.jetty.http; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Objects; import java.util.function.ToIntFunction; +import java.util.stream.Collectors; 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. @@ -57,22 +55,19 @@ public class QuotedQualityCSV extends QuotedCSV implements Iterable<String> return 3; }; - private final List<Double> _quality = new ArrayList<>(); + private final List<QualityValue> _qualities = new ArrayList<>(); + private QualityValue _lastQuality; private boolean _sorted = false; private final ToIntFunction<String> _secondaryOrdering; - /* ------------------------------------------------------------ */ - /** * Sorts values with equal quality according to the length of the value String. */ public QuotedQualityCSV() { - this((ToIntFunction)null); + this((ToIntFunction<String>)null); } - /* ------------------------------------------------------------ */ - /** * Sorts values with equal quality according to given order. * @@ -83,57 +78,71 @@ public class QuotedQualityCSV extends QuotedCSV implements Iterable<String> this((s) -> { for (int i = 0; i < preferredOrder.length; ++i) + { if (preferredOrder[i].equals(s)) return preferredOrder.length - i; + } if ("*".equals(s)) return preferredOrder.length; - return MIN_VALUE; + return 0; }); } - /* ------------------------------------------------------------ */ - /** * Orders values with equal quality with the given function. * - * @param secondaryOrdering Function to apply an ordering other than specified by quality + * @param secondaryOrdering Function to apply an ordering other than specified by quality, highest values are sorted first. */ public QuotedQualityCSV(ToIntFunction<String> secondaryOrdering) { this._secondaryOrdering = secondaryOrdering == null ? s -> 0 : secondaryOrdering; } - /* ------------------------------------------------------------ */ + @Override + protected void parsedValueAndParams(StringBuffer buffer) + { + super.parsedValueAndParams(buffer); + + // Collect full value with parameters + _lastQuality = new QualityValue(_lastQuality._quality, buffer.toString(), _lastQuality._index); + _qualities.set(_lastQuality._index, _lastQuality); + } + @Override protected void parsedValue(StringBuffer buffer) { super.parsedValue(buffer); + _sorted = false; + + // This is the just the value, without parameters. // Assume a quality of ONE - _quality.add(1.0D); + _lastQuality = new QualityValue(1.0D, buffer.toString(), _qualities.size()); + _qualities.add(_lastQuality); } - /* ------------------------------------------------------------ */ @Override protected void parsedParam(StringBuffer buffer, int valueLength, int paramName, int paramValue) { + _sorted = false; + if (paramName < 0) { 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) == '=') + buffer.charAt(paramName) == 'q' && paramValue > paramName && + buffer.length() >= paramName && buffer.charAt(paramName + 1) == '=') { - Double q; + double q; try { q = (_keepQuotes && buffer.charAt(paramValue) == '"') - ? Double.valueOf(buffer.substring(paramValue + 1, buffer.length() - 1)) - : Double.valueOf(buffer.substring(paramValue)); + ? Double.valueOf(buffer.substring(paramValue + 1, buffer.length() - 1)) + : Double.valueOf(buffer.substring(paramValue)); } catch (Exception e) { @@ -143,8 +152,10 @@ public class QuotedQualityCSV extends QuotedCSV implements Iterable<String> buffer.setLength(Math.max(0, paramName - 1)); if (q != 1.0D) - // replace assumed quality - _quality.set(_quality.size() - 1, q); + { + _lastQuality = new QualityValue(q, buffer.toString(), _lastQuality._index); + _qualities.set(_lastQuality._index, _lastQuality); + } } } @@ -166,38 +177,73 @@ public class QuotedQualityCSV extends QuotedCSV implements Iterable<String> protected void sort() { + _values.clear(); + _qualities.stream() + .filter((qv) -> qv._quality != 0.0D) + .sorted() + .map(QualityValue::getValue) + .collect(Collectors.toCollection(() -> _values)); _sorted = true; + } + + private class QualityValue implements Comparable<QualityValue> + { + private final double _quality; + private final String _value; + private final int _index; - Double last = 0.0D; - int lastSecondaryOrder = Integer.MIN_VALUE; + private QualityValue(double quality, String value, int index) + { + _quality = quality; + _value = value; + _index = index; + } - for (int i = _values.size(); i-- > 0; ) + @Override + public int hashCode() { - String v = _values.get(i); - Double q = _quality.get(i); + return Double.hashCode(_quality) ^ Objects.hash(_value, _index); + } - int compare = last.compareTo(q); - if (compare > 0 || (compare == 0 && _secondaryOrdering.applyAsInt(v) < lastSecondaryOrder)) + @Override + public boolean equals(Object obj) + { + if (!(obj instanceof QualityValue)) + return false; + QualityValue qv = (QualityValue)obj; + return _quality == qv._quality && Objects.equals(_value, qv._value) && Objects.equals(_index, qv._index); + } + + private String getValue() + { + return _value; + } + + @Override + public int compareTo(QualityValue o) + { + // sort highest quality first + int compare = Double.compare(o._quality, _quality); + if (compare == 0) { - _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; - i = _values.size(); - continue; + // then sort secondary order highest first + compare = Integer.compare(_secondaryOrdering.applyAsInt(o._value), _secondaryOrdering.applyAsInt(_value)); + if (compare == 0) + // then sort index lowest first + compare = -Integer.compare(o._index, _index); } - - last = q; - lastSecondaryOrder = _secondaryOrdering.applyAsInt(v); + return compare; } - int last_element = _quality.size(); - while (last_element > 0 && _quality.get(--last_element).equals(0.0D)) + @Override + public String toString() { - _quality.remove(last_element); - _values.remove(last_element); + return String.format("%s@%x[%s,q=%f,i=%d]", + getClass().getSimpleName(), + hashCode(), + _value, + _quality, + _index); } } } 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 f03657b..b941e95 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 @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2019 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 @@ -18,13 +18,12 @@ package org.eclipse.jetty.http; +import java.util.ArrayList; +import java.util.List; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; -import java.util.ArrayList; -import java.util.List; - import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; @@ -32,58 +31,58 @@ public class QuotedQualityCSVTest { @Test - public void test7231_5_3_2_example1() + public void test7231Sec532Example1() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue(" audio/*; q=0.2, audio/basic"); - assertThat(values,Matchers.contains("audio/basic","audio/*")); + assertThat(values, Matchers.contains("audio/basic", "audio/*")); } @Test - public void test7231_5_3_2_example2() + public void test7231Sec532Example2() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue("text/plain; q=0.5, text/html,"); values.addValue("text/x-dvi; q=0.8, text/x-c"); - assertThat(values,Matchers.contains("text/html","text/x-c","text/x-dvi","text/plain")); + assertThat(values, Matchers.contains("text/html", "text/x-c", "text/x-dvi", "text/plain")); } - + @Test - public void test7231_5_3_2_example3() + public void test7231Sec532Example3() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue("text/*, text/plain, text/plain;format=flowed, */*"); - + // Note this sort is only on quality and not the most specific type as per 5.3.2 - assertThat(values,Matchers.contains("text/*","text/plain","text/plain;format=flowed","*/*")); + assertThat(values, Matchers.contains("text/*", "text/plain", "text/plain;format=flowed", "*/*")); } - + @Test - public void test7231_5_3_2_example3_most_specific() + public void test7231532Example3MostSpecific() { 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/*","*/*")); + + assertThat(values, Matchers.contains("text/plain;format=flowed", "text/plain", "text/*", "*/*")); } - + @Test - public void test7231_5_3_2_example4() + public void test7231Sec532Example4() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue("text/*;q=0.3, text/html;q=0.7, text/html;level=1,"); values.addValue("text/html;level=2;q=0.4, */*;q=0.5"); - assertThat(values,Matchers.contains( - "text/html;level=1", - "text/html", - "*/*", - "text/html;level=2", - "text/*" - )); + assertThat(values, Matchers.contains( + "text/html;level=1", + "text/html", + "*/*", + "text/html;level=2", + "text/*" + )); } - + @Test - public void test7231_5_3_4_example1() + public void test7231Sec534Example1() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue("compress, gzip"); @@ -91,16 +90,16 @@ public class QuotedQualityCSVTest values.addValue("*"); values.addValue("compress;q=0.5, gzip;q=1.0"); values.addValue("gzip;q=1.0, identity; q=0.5, *;q=0"); - - assertThat(values,Matchers.contains( - "compress", - "gzip", - "*", - "gzip", - "gzip", - "compress", - "identity" - )); + + assertThat(values, Matchers.contains( + "compress", + "gzip", + "*", + "gzip", + "gzip", + "compress", + "identity" + )); } @Test @@ -108,66 +107,65 @@ public class QuotedQualityCSVTest { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue(" value 0.5 ; p = v ; q =0.5 , value 1.0 "); - assertThat(values,Matchers.contains( - "value 1.0", - "value 0.5;p=v")); + assertThat(values, Matchers.contains( + "value 1.0", + "value 0.5;p=v")); } - + @Test public void testEmpty() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue(",aaaa, , bbbb ,,cccc,"); - assertThat(values,Matchers.contains( - "aaaa", - "bbbb", - "cccc")); + assertThat(values, Matchers.contains( + "aaaa", + "bbbb", + "cccc")); } - + @Test public void testQuoted() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue(" value 0.5 ; p = \"v ; q = \\\"0.5\\\" , value 1.0 \" "); - assertThat(values,Matchers.contains( - "value 0.5;p=\"v ; q = \\\"0.5\\\" , value 1.0 \"")); + assertThat(values, Matchers.contains( + "value 0.5;p=\"v ; q = \\\"0.5\\\" , value 1.0 \"")); } - + @Test public void testOpenQuote() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue("value;p=\"v"); - assertThat(values,Matchers.contains( - "value;p=\"v")); + assertThat(values, Matchers.contains( + "value;p=\"v")); } - + @Test public void testQuotedQuality() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue(" value 0.5 ; p = v ; q = \"0.5\" , value 1.0 "); - assertThat(values,Matchers.contains( - "value 1.0", - "value 0.5;p=v")); + assertThat(values, Matchers.contains( + "value 1.0", + "value 0.5;p=v")); } - + @Test public void testBadQuality() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue("value0.5;p=v;q=0.5,value1.0,valueBad;q=X"); - assertThat(values,Matchers.contains( - "value1.0", - "value0.5;p=v")); + assertThat(values, Matchers.contains( + "value1.0", + "value0.5;p=v")); } - + @Test public void testBad() { QuotedQualityCSV values = new QuotedQualityCSV(); - // None of these should throw exceptions values.addValue(null); values.addValue(""); @@ -223,13 +221,10 @@ public class QuotedQualityCSVTest values.addValue("q="); values.addValue("q=,"); values.addValue("q=;"); - } - /* ------------------------------------------------------------ */ - - private static final String[] preferBrotli = {"br","gzip"}; - private static final String[] preferGzip = {"gzip","br"}; + private static final String[] preferBrotli = {"br", "gzip"}; + private static final String[] preferGzip = {"gzip", "br"}; private static final String[] noFormats = {}; @Test @@ -295,14 +290,13 @@ public class QuotedQualityCSVTest values.addValue("gzip, *"); assertThat(values, contains("*", "gzip")); } - @Test public void testSameQuality() { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue("one;q=0.5,two;q=0.5,three;q=0.5"); - assertThat(values.getValues(),Matchers.contains("one","two","three")); + assertThat(values.getValues(), Matchers.contains("one", "two", "three")); } @Test @@ -310,10 +304,9 @@ public class QuotedQualityCSVTest { QuotedQualityCSV values = new QuotedQualityCSV(); values.addValue("one,two;,three;x=y"); - assertThat(values.getValues(),Matchers.contains("one","two","three;x=y")); + assertThat(values.getValues(), Matchers.contains("one", "two", "three;x=y")); } - @Test public void testQuality() { @@ -339,19 +332,15 @@ public class QuotedQualityCSVTest } }; - // The provided string is not legal according to some RFCs ( not a token because of = and not a parameter because not preceded by ; ) // The string is legal according to RFC7239 which allows for just parameters (called forwarded-pairs) values.addValue("p=0.5,q=0.5"); - // The QuotedCSV implementation is lenient and adopts the later interpretation and thus sees q=0.5 and p=0.5 both as parameters - assertThat(results,contains("parsedValue: ", "parsedParam: p=0.5", - "parsedValue: ", "parsedParam: q=0.5")); - + assertThat(results, contains("parsedValue: ", "parsedParam: p=0.5", + "parsedValue: ", "parsedParam: q=0.5")); // However the QuotedQualityCSV only handles the q parameter and that is consumed from the parameter string. - assertThat(values,contains("p=0.5", "")); - + assertThat(values, contains("p=0.5", "")); } }
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2