VYPR
Moderate severityNVD Advisory· Published Dec 13, 2022· Updated Apr 22, 2025

CVE-2022-41915

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.

PackageAffected versionsPatched versions
io.netty:netty-codec-httpMaven
>= 4.1.83.Final, < 4.1.86.Final4.1.86.Final

Affected products

1

Patches

2
fe18adff1c2b

Merge pull request from GHSA-hh82-3pmq-7frp

https://github.com/netty/nettyChris VestDec 12, 2022via ghsa
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();
    
c37c637f096e

Avoid including header values in header validation failure exceptions (#12642)

https://github.com/netty/nettyChris VestJul 27, 2022via ghsa
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

News mentions

0

No linked articles in our index yet.