5454import org .apache .hc .core5 .http .HttpEntity ;
5555import org .apache .hc .core5 .http .HttpException ;
5656import org .apache .hc .core5 .http .HttpHeaders ;
57+ import org .apache .hc .core5 .http .ProtocolException ;
5758import org .apache .hc .core5 .http .config .Lookup ;
5859import org .apache .hc .core5 .http .config .RegistryBuilder ;
5960import org .apache .hc .core5 .http .message .BasicHeaderValueParser ;
7778@ Internal
7879public final class ContentCompressionExec implements ExecChainHandler {
7980
81+ public static final int MAX_CODEC_LIST_LEN = 5 ;
82+
8083 private final Header acceptEncoding ;
8184 private final Lookup <InputStreamFactory > decoderRegistry ;
8285 private final boolean ignoreUnknown ;
86+ private final int maxCodecListLen ;
8387
8488 public ContentCompressionExec (
8589 final List <String > acceptEncoding ,
8690 final Lookup <InputStreamFactory > decoderRegistry ,
87- final boolean ignoreUnknown ) {
91+ final boolean ignoreUnknown ,
92+ final int maxCodecListLen ) {
8893
8994 final boolean brotliSupported = decoderRegistry == null && BrotliDecompressingEntity .isAvailable ();
9095 if (acceptEncoding != null ) {
@@ -112,10 +117,22 @@ public ContentCompressionExec(
112117 this .decoderRegistry = builder .build ();
113118 }
114119 this .ignoreUnknown = ignoreUnknown ;
120+ this .maxCodecListLen = maxCodecListLen ;
121+ }
122+
123+ public ContentCompressionExec (
124+ final List <String > acceptEncoding ,
125+ final Lookup <InputStreamFactory > decoderRegistry ,
126+ final boolean ignoreUnknown ) {
127+ this (acceptEncoding , decoderRegistry , ignoreUnknown , MAX_CODEC_LIST_LEN );
115128 }
116129
117130 public ContentCompressionExec (final boolean ignoreUnknown ) {
118- this (null , null , ignoreUnknown );
131+ this (null , null , ignoreUnknown , MAX_CODEC_LIST_LEN );
132+ }
133+
134+ public ContentCompressionExec (final int maxCodecListLen ) {
135+ this (null , null , true , maxCodecListLen );
119136 }
120137
121138 /**
@@ -128,7 +145,7 @@ public ContentCompressionExec(final boolean ignoreUnknown) {
128145 * </ul>
129146 */
130147 public ContentCompressionExec () {
131- this (null , null , true );
148+ this (null , null , true , MAX_CODEC_LIST_LEN );
132149 }
133150
134151
@@ -158,6 +175,9 @@ public ClassicHttpResponse execute(
158175 if (contentEncoding != null ) {
159176 final ParserCursor cursor = new ParserCursor (0 , contentEncoding .length ());
160177 final HeaderElement [] codecs = BasicHeaderValueParser .INSTANCE .parseElements (contentEncoding , cursor );
178+ if (maxCodecListLen > 0 && codecs .length > maxCodecListLen ) {
179+ throw new ProtocolException ("Codec list exceeds maximum of " + maxCodecListLen + " elements" );
180+ }
161181 for (final HeaderElement codec : codecs ) {
162182 final String codecname = codec .getName ().toLowerCase (Locale .ROOT );
163183 final InputStreamFactory decoderFactory = decoderRegistry .lookup (codecname );
0 commit comments