CVE-2022-41915
Description
Netty project is an event-driven asynchronous network application framework. Starting in version 4.1.83.Final and prior to 4.1.86.Final, when calling DefaultHttpHeadesr.set with an _iterator_ of values, header value validation was not performed, allowing malicious header values in the iterator to perform HTTP Response Splitting. This issue has been patched in version 4.1.86.Final. Integrators can work around the issue by changing the DefaultHttpHeaders.set(CharSequence, Iterator<?>) call, into a remove() call, and call add() in a loop over the iterator of values.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
io.netty:netty-codec-httpMaven | >= 4.1.83.Final, < 4.1.86.Final | 4.1.86.Final |
Affected products
1Patches
2fe18adff1c2bMerge pull request from GHSA-hh82-3pmq-7frp
2 files changed · +30 −3
codec-http/src/test/java/io/netty/handler/codec/http/DefaultHttpHeadersTest.java+24 −1 modified@@ -22,7 +22,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; -import java.util.Arrays; +import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Set; @@ -41,6 +41,7 @@ public class DefaultHttpHeadersTest { private static final CharSequence HEADER_NAME = "testHeader"; + private static final CharSequence ILLEGAL_VALUE = "testHeader\r\nContent-Length:45\r\n\r\n"; @Test public void nullHeaderNameNotAllowed() { @@ -234,6 +235,28 @@ public void setObjectIterable() { assertDefaultValues(headers, HeaderValue.THREE); } + @Test + public void setCharSequenceValidatesValue() { + final DefaultHttpHeaders headers = newDefaultDefaultHttpHeaders(); + assertThrows(IllegalArgumentException.class, new Executable() { + @Override + public void execute() throws Throwable { + headers.set(HEADER_NAME, ILLEGAL_VALUE); + } + }); + } + + @Test + public void setIterableValidatesValue() { + final DefaultHttpHeaders headers = newDefaultDefaultHttpHeaders(); + assertThrows(IllegalArgumentException.class, new Executable() { + @Override + public void execute() throws Throwable { + headers.set(HEADER_NAME, Collections.singleton(ILLEGAL_VALUE)); + } + }); + } + @Test public void toStringOnEmptyHeaders() { assertEquals("DefaultHttpHeaders[]", newDefaultDefaultHttpHeaders().toString());
codec/src/main/java/io/netty/handler/codec/DefaultHeaders.java+6 −2 modified@@ -532,7 +532,9 @@ public T setObject(K name, Iterable<?> values) { if (v == null) { break; } - add0(h, i, name, fromObject(name, v)); + V converted = fromObject(name, v); + validateValue(valueValidator, name, converted); + add0(h, i, name, converted); } return thisT(); @@ -550,7 +552,9 @@ public T setObject(K name, Object... values) { if (v == null) { break; } - add0(h, i, name, fromObject(name, v)); + V converted = fromObject(name, v); + validateValue(valueValidator, name, converted); + add0(h, i, name, converted); } return thisT();
c37c637f096eAvoid including header values in header validation failure exceptions (#12642)
4 files changed · +245 −84
codec-http/src/main/java/io/netty/handler/codec/http/CombinedHttpHeaders.java+33 −24 modified@@ -59,8 +59,15 @@ private CsvValueEscaper<Object> objectEscaper() { if (objectEscaper == null) { objectEscaper = new CsvValueEscaper<Object>() { @Override - public CharSequence escape(Object value) { - return StringUtil.escapeCsv(valueConverter().convertObject(value), true); + public CharSequence escape(CharSequence name, Object value) { + CharSequence converted; + try { + converted = valueConverter().convertObject(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException( + "Failed to convert object value for header '" + name + '\'', e); + } + return StringUtil.escapeCsv(converted, true); } }; } @@ -71,7 +78,7 @@ private CsvValueEscaper<CharSequence> charSequenceEscaper() { if (charSequenceEscaper == null) { charSequenceEscaper = new CsvValueEscaper<CharSequence>() { @Override - public CharSequence escape(CharSequence value) { + public CharSequence escape(CharSequence name, CharSequence value) { return StringUtil.escapeCsv(value, true); } }; @@ -81,7 +88,7 @@ public CharSequence escape(CharSequence value) { CombinedHttpHeadersImpl(HashingStrategy<CharSequence> nameHashingStrategy, ValueConverter<CharSequence> valueConverter, - io.netty.handler.codec.DefaultHeaders.NameValidator<CharSequence> nameValidator) { + DefaultHeaders.NameValidator<CharSequence> nameValidator) { super(nameHashingStrategy, valueConverter, nameValidator); } @@ -156,61 +163,61 @@ public CombinedHttpHeadersImpl setAll(Headers<? extends CharSequence, ? extends @Override public CombinedHttpHeadersImpl add(CharSequence name, CharSequence value) { - return addEscapedValue(name, charSequenceEscaper().escape(value)); + return addEscapedValue(name, charSequenceEscaper().escape(name, value)); } @Override public CombinedHttpHeadersImpl add(CharSequence name, CharSequence... values) { - return addEscapedValue(name, commaSeparate(charSequenceEscaper(), values)); + return addEscapedValue(name, commaSeparate(name, charSequenceEscaper(), values)); } @Override public CombinedHttpHeadersImpl add(CharSequence name, Iterable<? extends CharSequence> values) { - return addEscapedValue(name, commaSeparate(charSequenceEscaper(), values)); + return addEscapedValue(name, commaSeparate(name, charSequenceEscaper(), values)); } @Override public CombinedHttpHeadersImpl addObject(CharSequence name, Object value) { - return addEscapedValue(name, commaSeparate(objectEscaper(), value)); + return addEscapedValue(name, commaSeparate(name, objectEscaper(), value)); } @Override public CombinedHttpHeadersImpl addObject(CharSequence name, Iterable<?> values) { - return addEscapedValue(name, commaSeparate(objectEscaper(), values)); + return addEscapedValue(name, commaSeparate(name, objectEscaper(), values)); } @Override public CombinedHttpHeadersImpl addObject(CharSequence name, Object... values) { - return addEscapedValue(name, commaSeparate(objectEscaper(), values)); + return addEscapedValue(name, commaSeparate(name, objectEscaper(), values)); } @Override public CombinedHttpHeadersImpl set(CharSequence name, CharSequence... values) { - super.set(name, commaSeparate(charSequenceEscaper(), values)); + set(name, commaSeparate(name, charSequenceEscaper(), values)); return this; } @Override public CombinedHttpHeadersImpl set(CharSequence name, Iterable<? extends CharSequence> values) { - super.set(name, commaSeparate(charSequenceEscaper(), values)); + set(name, commaSeparate(name, charSequenceEscaper(), values)); return this; } @Override public CombinedHttpHeadersImpl setObject(CharSequence name, Object value) { - super.set(name, commaSeparate(objectEscaper(), value)); + set(name, commaSeparate(name, objectEscaper(), value)); return this; } @Override public CombinedHttpHeadersImpl setObject(CharSequence name, Object... values) { - super.set(name, commaSeparate(objectEscaper(), values)); + set(name, commaSeparate(name, objectEscaper(), values)); return this; } @Override public CombinedHttpHeadersImpl setObject(CharSequence name, Iterable<?> values) { - super.set(name, commaSeparate(objectEscaper(), values)); + set(name, commaSeparate(name, objectEscaper(), values)); return this; } @@ -219,39 +226,40 @@ private static boolean cannotBeCombined(CharSequence name) { } private CombinedHttpHeadersImpl addEscapedValue(CharSequence name, CharSequence escapedValue) { - CharSequence currentValue = super.get(name); + CharSequence currentValue = get(name); if (currentValue == null || cannotBeCombined(name)) { super.add(name, escapedValue); } else { - super.set(name, commaSeparateEscapedValues(currentValue, escapedValue)); + set(name, commaSeparateEscapedValues(currentValue, escapedValue)); } return this; } - private static <T> CharSequence commaSeparate(CsvValueEscaper<T> escaper, T... values) { + private static <T> CharSequence commaSeparate(CharSequence name, CsvValueEscaper<T> escaper, T... values) { StringBuilder sb = new StringBuilder(values.length * VALUE_LENGTH_ESTIMATE); if (values.length > 0) { int end = values.length - 1; for (int i = 0; i < end; i++) { - sb.append(escaper.escape(values[i])).append(COMMA); + sb.append(escaper.escape(name, values[i])).append(COMMA); } - sb.append(escaper.escape(values[end])); + sb.append(escaper.escape(name, values[end])); } return sb; } - private static <T> CharSequence commaSeparate(CsvValueEscaper<T> escaper, Iterable<? extends T> values) { + private static <T> CharSequence commaSeparate(CharSequence name, CsvValueEscaper<T> escaper, + Iterable<? extends T> values) { @SuppressWarnings("rawtypes") final StringBuilder sb = values instanceof Collection ? new StringBuilder(((Collection) values).size() * VALUE_LENGTH_ESTIMATE) : new StringBuilder(); Iterator<? extends T> iterator = values.iterator(); if (iterator.hasNext()) { T next = iterator.next(); while (iterator.hasNext()) { - sb.append(escaper.escape(next)).append(COMMA); + sb.append(escaper.escape(name, next)).append(COMMA); next = iterator.next(); } - sb.append(escaper.escape(next)); + sb.append(escaper.escape(name, next)); } return sb; } @@ -272,9 +280,10 @@ private interface CsvValueEscaper<T> { /** * Appends the value to the specified {@link StringBuilder}, escaping if necessary. * + * @param name the name of the header for the value being escaped * @param value the value to be appended, escaped if necessary */ - CharSequence escape(T value); + CharSequence escape(CharSequence name, T value); } } }
codec-http/src/main/java/io/netty/handler/codec/http/DefaultHttpHeaders.java+6 −6 modified@@ -462,7 +462,7 @@ public CharSequence convertObject(Object value) { } if (state != 0) { - throw new IllegalArgumentException("a header value must not end with '\\r' or '\\n':" + seq); + throw new IllegalArgumentException("a header value must not end with '\\r' or '\\n'"); } return seq; } @@ -478,11 +478,11 @@ private static int validateValueChar(CharSequence seq, int state, char character // Check the absolutely prohibited characters. switch (character) { case 0x0: // NULL - throw new IllegalArgumentException("a header value contains a prohibited character '\0': " + seq); + throw new IllegalArgumentException("a header value contains a prohibited character '\0'"); case 0x0b: // Vertical tab - throw new IllegalArgumentException("a header value contains a prohibited character '\\v': " + seq); + throw new IllegalArgumentException("a header value contains a prohibited character '\\v'"); case '\f': - throw new IllegalArgumentException("a header value contains a prohibited character '\\f': " + seq); + throw new IllegalArgumentException("a header value contains a prohibited character '\\f'"); default: break; } @@ -504,14 +504,14 @@ private static int validateValueChar(CharSequence seq, int state, char character if (character == '\n') { return 2; } - throw new IllegalArgumentException("only '\\n' is allowed after '\\r': " + seq); + throw new IllegalArgumentException("only '\\n' is allowed after '\\r'"); case 2: switch (character) { case '\t': case ' ': return 0; default: - throw new IllegalArgumentException("only ' ' and '\\t' are allowed after '\\n': " + seq); + throw new IllegalArgumentException("only ' ' and '\\t' are allowed after '\\n'"); } default: break;
codec-http/src/main/java/io/netty/handler/codec/spdy/SpdyCodecUtil.java+1 −1 modified@@ -321,7 +321,7 @@ static void validateHeaderValue(CharSequence value) { char c = value.charAt(i); if (c == 0) { throw new IllegalArgumentException( - "value contains null character: " + value); + "value contains null character"); } } }
codec/src/main/java/io/netty/handler/codec/DefaultHeaders.java+205 −53 modified@@ -105,10 +105,10 @@ public DefaultHeaders(HashingStrategy<K> nameHashingStrategy, ValueConverter<V> valueConverter, NameValidator<K> nameValidator, int arraySizeHint) { this.valueConverter = checkNotNull(valueConverter, "valueConverter"); this.nameValidator = checkNotNull(nameValidator, "nameValidator"); - this.hashingStrategy = checkNotNull(nameHashingStrategy, "nameHashingStrategy"); + hashingStrategy = checkNotNull(nameHashingStrategy, "nameHashingStrategy"); // Enforce a bound of [2, 128] because hashMask is a byte. The max possible value of hashMask is one less // than the length of this array, and we want the mask to be > 0. - entries = new DefaultHeaders.HeaderEntry[findNextPositivePowerOfTwo(max(2, min(arraySizeHint, 128)))]; + entries = new HeaderEntry[findNextPositivePowerOfTwo(max(2, min(arraySizeHint, 128)))]; hashMask = (byte) (entries.length - 1); head = new HeaderEntry<K, V>(); } @@ -197,52 +197,52 @@ public boolean contains(K name) { @Override public boolean containsObject(K name, Object value) { - return contains(name, valueConverter.convertObject(checkNotNull(value, "value"))); + return contains(name, fromObject(name, value)); } @Override public boolean containsBoolean(K name, boolean value) { - return contains(name, valueConverter.convertBoolean(value)); + return contains(name, fromBoolean(name, value)); } @Override public boolean containsByte(K name, byte value) { - return contains(name, valueConverter.convertByte(value)); + return contains(name, fromByte(name, value)); } @Override public boolean containsChar(K name, char value) { - return contains(name, valueConverter.convertChar(value)); + return contains(name, fromChar(name, value)); } @Override public boolean containsShort(K name, short value) { - return contains(name, valueConverter.convertShort(value)); + return contains(name, fromShort(name, value)); } @Override public boolean containsInt(K name, int value) { - return contains(name, valueConverter.convertInt(value)); + return contains(name, fromInt(name, value)); } @Override public boolean containsLong(K name, long value) { - return contains(name, valueConverter.convertLong(value)); + return contains(name, fromLong(name, value)); } @Override public boolean containsFloat(K name, float value) { - return contains(name, valueConverter.convertFloat(value)); + return contains(name, fromFloat(name, value)); } @Override public boolean containsDouble(K name, double value) { - return contains(name, valueConverter.convertDouble(value)); + return contains(name, fromDouble(name, value)); } @Override public boolean containsTimeMillis(K name, long value) { - return contains(name, valueConverter.convertTimeMillis(value)); + return contains(name, fromTimeMillis(name, value)); } @SuppressWarnings("unchecked") @@ -324,7 +324,7 @@ public T add(K name, V... values) { @Override public T addObject(K name, Object value) { - return add(name, valueConverter.convertObject(checkNotNull(value, "value"))); + return add(name, fromObject(name, value)); } @Override @@ -345,47 +345,47 @@ public T addObject(K name, Object... values) { @Override public T addInt(K name, int value) { - return add(name, valueConverter.convertInt(value)); + return add(name, fromInt(name, value)); } @Override public T addLong(K name, long value) { - return add(name, valueConverter.convertLong(value)); + return add(name, fromLong(name, value)); } @Override public T addDouble(K name, double value) { - return add(name, valueConverter.convertDouble(value)); + return add(name, fromDouble(name, value)); } @Override public T addTimeMillis(K name, long value) { - return add(name, valueConverter.convertTimeMillis(value)); + return add(name, fromTimeMillis(name, value)); } @Override public T addChar(K name, char value) { - return add(name, valueConverter.convertChar(value)); + return add(name, fromChar(name, value)); } @Override public T addBoolean(K name, boolean value) { - return add(name, valueConverter.convertBoolean(value)); + return add(name, fromBoolean(name, value)); } @Override public T addFloat(K name, float value) { - return add(name, valueConverter.convertFloat(value)); + return add(name, fromFloat(name, value)); } @Override public T addByte(K name, byte value) { - return add(name, valueConverter.convertByte(value)); + return add(name, fromByte(name, value)); } @Override public T addShort(K name, short value) { - return add(name, valueConverter.convertShort(value)); + return add(name, fromShort(name, value)); } @Override @@ -476,8 +476,7 @@ public T set(K name, V... values) { @Override public T setObject(K name, Object value) { - checkNotNull(value, "value"); - V convertedValue = checkNotNull(valueConverter.convertObject(value), "convertedValue"); + V convertedValue = checkNotNull(fromObject(name, value), "convertedValue"); return set(name, convertedValue); } @@ -493,7 +492,7 @@ public T setObject(K name, Iterable<?> values) { if (v == null) { break; } - add0(h, i, name, valueConverter.convertObject(v)); + add0(h, i, name, fromObject(name, v)); } return thisT(); @@ -511,55 +510,55 @@ public T setObject(K name, Object... values) { if (v == null) { break; } - add0(h, i, name, valueConverter.convertObject(v)); + add0(h, i, name, fromObject(name, v)); } return thisT(); } @Override public T setInt(K name, int value) { - return set(name, valueConverter.convertInt(value)); + return set(name, fromInt(name, value)); } @Override public T setLong(K name, long value) { - return set(name, valueConverter.convertLong(value)); + return set(name, fromLong(name, value)); } @Override public T setDouble(K name, double value) { - return set(name, valueConverter.convertDouble(value)); + return set(name, fromDouble(name, value)); } @Override public T setTimeMillis(K name, long value) { - return set(name, valueConverter.convertTimeMillis(value)); + return set(name, fromTimeMillis(name, value)); } @Override public T setFloat(K name, float value) { - return set(name, valueConverter.convertFloat(value)); + return set(name, fromFloat(name, value)); } @Override public T setChar(K name, char value) { - return set(name, valueConverter.convertChar(value)); + return set(name, fromChar(name, value)); } @Override public T setBoolean(K name, boolean value) { - return set(name, valueConverter.convertBoolean(value)); + return set(name, fromBoolean(name, value)); } @Override public T setByte(K name, byte value) { - return set(name, valueConverter.convertByte(value)); + return set(name, fromByte(name, value)); } @Override public T setShort(K name, short value) { - return set(name, valueConverter.convertShort(value)); + return set(name, fromShort(name, value)); } @Override @@ -604,7 +603,7 @@ public Iterator<Entry<K, V>> iterator() { public Boolean getBoolean(K name) { V v = get(name); try { - return v != null ? valueConverter.convertToBoolean(v) : null; + return v != null ? toBoolean(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -620,7 +619,7 @@ public boolean getBoolean(K name, boolean defaultValue) { public Byte getByte(K name) { V v = get(name); try { - return v != null ? valueConverter.convertToByte(v) : null; + return v != null ? toByte(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -636,7 +635,7 @@ public byte getByte(K name, byte defaultValue) { public Character getChar(K name) { V v = get(name); try { - return v != null ? valueConverter.convertToChar(v) : null; + return v != null ? toChar(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -652,7 +651,7 @@ public char getChar(K name, char defaultValue) { public Short getShort(K name) { V v = get(name); try { - return v != null ? valueConverter.convertToShort(v) : null; + return v != null ? toShort(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -668,7 +667,7 @@ public short getShort(K name, short defaultValue) { public Integer getInt(K name) { V v = get(name); try { - return v != null ? valueConverter.convertToInt(v) : null; + return v != null ? toInt(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -684,7 +683,7 @@ public int getInt(K name, int defaultValue) { public Long getLong(K name) { V v = get(name); try { - return v != null ? valueConverter.convertToLong(v) : null; + return v != null ? toLong(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -700,7 +699,7 @@ public long getLong(K name, long defaultValue) { public Float getFloat(K name) { V v = get(name); try { - return v != null ? valueConverter.convertToFloat(v) : null; + return v != null ? toFloat(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -716,7 +715,7 @@ public float getFloat(K name, float defaultValue) { public Double getDouble(K name) { V v = get(name); try { - return v != null ? valueConverter.convertToDouble(v) : null; + return v != null ? toDouble(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -732,7 +731,7 @@ public double getDouble(K name, double defaultValue) { public Long getTimeMillis(K name) { V v = get(name); try { - return v != null ? valueConverter.convertToTimeMillis(v) : null; + return v != null ? toTimeMillis(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -748,7 +747,7 @@ public long getTimeMillis(K name, long defaultValue) { public Boolean getBooleanAndRemove(K name) { V v = getAndRemove(name); try { - return v != null ? valueConverter.convertToBoolean(v) : null; + return v != null ? toBoolean(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -764,7 +763,7 @@ public boolean getBooleanAndRemove(K name, boolean defaultValue) { public Byte getByteAndRemove(K name) { V v = getAndRemove(name); try { - return v != null ? valueConverter.convertToByte(v) : null; + return v != null ? toByte(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -780,7 +779,7 @@ public byte getByteAndRemove(K name, byte defaultValue) { public Character getCharAndRemove(K name) { V v = getAndRemove(name); try { - return v != null ? valueConverter.convertToChar(v) : null; + return v != null ? toChar(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -796,7 +795,7 @@ public char getCharAndRemove(K name, char defaultValue) { public Short getShortAndRemove(K name) { V v = getAndRemove(name); try { - return v != null ? valueConverter.convertToShort(v) : null; + return v != null ? toShort(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -812,7 +811,7 @@ public short getShortAndRemove(K name, short defaultValue) { public Integer getIntAndRemove(K name) { V v = getAndRemove(name); try { - return v != null ? valueConverter.convertToInt(v) : null; + return v != null ? toInt(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -828,7 +827,7 @@ public int getIntAndRemove(K name, int defaultValue) { public Long getLongAndRemove(K name) { V v = getAndRemove(name); try { - return v != null ? valueConverter.convertToLong(v) : null; + return v != null ? toLong(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -844,7 +843,7 @@ public long getLongAndRemove(K name, long defaultValue) { public Float getFloatAndRemove(K name) { V v = getAndRemove(name); try { - return v != null ? valueConverter.convertToFloat(v) : null; + return v != null ? toFloat(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -860,7 +859,7 @@ public float getFloatAndRemove(K name, float defaultValue) { public Double getDoubleAndRemove(K name) { V v = getAndRemove(name); try { - return v != null ? valueConverter.convertToDouble(v) : null; + return v != null ? toDouble(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -876,7 +875,7 @@ public double getDoubleAndRemove(K name, double defaultValue) { public Long getTimeMillisAndRemove(K name) { V v = getAndRemove(name); try { - return v != null ? valueConverter.convertToTimeMillis(v) : null; + return v != null ? toTimeMillis(name, v) : null; } catch (RuntimeException ignore) { return null; } @@ -1041,6 +1040,159 @@ private T thisT() { return (T) this; } + private V fromObject(K name, Object value) { + try { + return valueConverter.convertObject(checkNotNull(value, "value")); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert object value for header '" + name + '\'', e); + } + } + + private V fromBoolean(K name, boolean value) { + try { + return valueConverter.convertBoolean(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert boolean value for header '" + name + '\'', e); + } + } + + private V fromByte(K name, byte value) { + try { + return valueConverter.convertByte(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert byte value for header '" + name + '\'', e); + } + } + + private V fromChar(K name, char value) { + try { + return valueConverter.convertChar(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert char value for header '" + name + '\'', e); + } + } + + private V fromShort(K name, short value) { + try { + return valueConverter.convertShort(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert short value for header '" + name + '\'', e); + } + } + + private V fromInt(K name, int value) { + try { + return valueConverter.convertInt(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert int value for header '" + name + '\'', e); + } + } + + private V fromLong(K name, long value) { + try { + return valueConverter.convertLong(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert long value for header '" + name + '\'', e); + } + } + + private V fromFloat(K name, float value) { + try { + return valueConverter.convertFloat(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert float value for header '" + name + '\'', e); + } + } + + private V fromDouble(K name, double value) { + try { + return valueConverter.convertDouble(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert double value for header '" + name + '\'', e); + } + } + + private V fromTimeMillis(K name, long value) { + try { + return valueConverter.convertTimeMillis(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert millsecond value for header '" + name + '\'', e); + } + } + + private boolean toBoolean(K name, V value) { + try { + return valueConverter.convertToBoolean(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert header value to boolean for header '" + name + '\''); + } + } + + private byte toByte(K name, V value) { + try { + return valueConverter.convertToByte(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert header value to byte for header '" + name + '\''); + } + } + + private char toChar(K name, V value) { + try { + return valueConverter.convertToChar(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert header value to char for header '" + name + '\''); + } + } + + private short toShort(K name, V value) { + try { + return valueConverter.convertToShort(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert header value to short for header '" + name + '\''); + } + } + + private int toInt(K name, V value) { + try { + return valueConverter.convertToInt(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert header value to int for header '" + name + '\''); + } + } + + private long toLong(K name, V value) { + try { + return valueConverter.convertToLong(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert header value to long for header '" + name + '\''); + } + } + + private float toFloat(K name, V value) { + try { + return valueConverter.convertToFloat(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert header value to float for header '" + name + '\''); + } + } + + private double toDouble(K name, V value) { + try { + return valueConverter.convertToDouble(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("Failed to convert header value to double for header '" + name + '\''); + } + } + + private long toTimeMillis(K name, V value) { + try { + return valueConverter.convertToTimeMillis(value); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException( + "Failed to convert header value to millsecond for header '" + name + '\''); + } + } + /** * Returns a deep copy of this instance. */
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
11- github.com/advisories/GHSA-hh82-3pmq-7frpghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-41915ghsaADVISORY
- www.debian.org/security/2023/dsa-5316ghsavendor-advisoryWEB
- github.com/netty/netty/commit/c37c637f096e7be3dffd36edee3455c8e90cb1b0ghsaWEB
- github.com/netty/netty/commit/fe18adff1c2b333acb135ab779a3b9ba3295a1c4ghsaWEB
- github.com/netty/netty/issues/13084ghsaWEB
- github.com/netty/netty/pull/12760ghsaWEB
- github.com/netty/netty/security/advisories/GHSA-hh82-3pmq-7frpghsaWEB
- lists.debian.org/debian-lts-announce/2023/01/msg00008.htmlghsamailing-listWEB
- security.netapp.com/advisory/ntap-20230113-0004ghsaWEB
- security.netapp.com/advisory/ntap-20230113-0004/mitre
News mentions
0No linked articles in our index yet.