Skip to content

Commit

Permalink
Merge pull request #1651 from fl4via/backport_2.2.x
Browse files Browse the repository at this point in the history
[UNDERTOW-2256][UNDERTOW-2381] Backport fixes to 2.2.x
  • Loading branch information
fl4via authored Aug 20, 2024
2 parents 001ed1d + 4b76773 commit 711110b
Show file tree
Hide file tree
Showing 4 changed files with 188 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,10 @@ public static void decode(ByteBuffer data, int length, StringBuilder target) thr
eosCount = 0;
}
} else {
// we need to check for EOS symbol in the string literal
if (((val >> 16) & LOW_MASK) == 256) {
throw UndertowMessages.MESSAGES.hpackFailed();
}
//bit not set, we want the lower part of the tree
if ((val & HIGH_TERMINAL_BIT) == 0) {
treePos = (val >> 16) & LOW_MASK;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,29 @@ public static StringBuilder renderDirectoryListing(final HttpServerExchange exch
if (!path.endsWith("/")){
path += "/";
}

String relative = null;
if (exchange != null) {
final Map<String, Object> context = exchange.getAttachment(Predicate.PREDICATE_CONTEXT);
if (context != null) {
final PathPrefixPredicate.PathPrefixMatchRecord trans = (PathPrefixMatchRecord) context
.get(PathPrefixPredicate.PREFIX_MATCH_RECORD);
if (trans != null) {
if (trans.isOverWritten()) {
relative = trans.getPrefix();
if (!relative.endsWith("/") && !path.startsWith("/")) {
relative += "/";
}
}
}
}
}

StringBuilder builder = new StringBuilder();
builder.append("<html>\n<head>\n<script src='").append(path).append("?js'></script>\n")
.append("<link rel='stylesheet' type='text/css' href='").append(path).append("?css' />\n</head>\n");
builder.append("<html>\n<head>\n<script src='").append(relative == null ? path : relative + path).append("?js'></script>\n")
.append("<link rel='stylesheet' type='text/css' href='").append(relative == null ? path : relative + path).append("?css' />\n</head>\n");
builder.append("<body onresize='growit()' onload='growit()'>\n<table id='thetable'>\n<thead>\n");
builder.append("<tr><th class='loc' colspan='3'>Directory Listing - ").append(path).append("</th></tr>\n")
builder.append("<tr><th class='loc' colspan='3'>Directory Listing - ").append(relative == null ? path : relative + path).append("</th></tr>\n")
.append("<tr><th class='label offset'>Name</th><th class='label'>Last Modified</th><th class='label'>Size</th></tr>\n</thead>\n")
.append("<tfoot>\n<tr><th class=\"loc footer\" colspan=\"3\">Powered by Undertow</th></tr>\n</tfoot>\n<tbody>\n");

Expand All @@ -137,23 +155,6 @@ public static StringBuilder renderDirectoryListing(final HttpServerExchange exch
}
}

String relative = null;
if (exchange != null) {
final Map<String, Object> context = exchange.getAttachment(Predicate.PREDICATE_CONTEXT);
if (context != null) {
final PathPrefixPredicate.PathPrefixMatchRecord trans = (PathPrefixMatchRecord) context
.get(PathPrefixPredicate.PREFIX_MATCH_RECORD);
if (trans != null) {
if (trans.isOverWritten()) {
relative = trans.getPrefix();
if (!relative.endsWith("/") && !path.startsWith("/")) {
relative += "/";
}
}
}
}
}

SimpleDateFormat format = new SimpleDateFormat("MMM dd, yyyy HH:mm:ss", Locale.US);
int i = 0;
if (parent != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2014 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.undertow.protocols.http2;


import io.undertow.testutils.category.UnitTest;
import org.junit.Assert;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import java.nio.ByteBuffer;




/**
* @author Marek Jusko
*/
@Category(UnitTest.class)
public class HpackHuffmanDecodingStringLiteralRepresentation {

/**
* Sends a Huffman-encoded string literal representation containing the EOS symbol.
* <p>
* Requirement: The endpoint MUST treat this as a decoding error.
*/
@Test
public void testStringLiteralContainingEOS() throws HpackException {
byte[] data = new byte[]{0x00, (byte) 0x85, (byte) 0xf2, (byte) 0xb2, 0x4a, (byte) 0x84, (byte) 0xff, (byte) 0x87, 0x49, (byte) 0x51, (byte) 0xff, (byte) 0xff, (byte) 0xff, (byte) 0xfa, 0x7f};
HpackDecoder decoder = new HpackDecoder(256);

Assert.assertThrows(HpackException.class, () -> decoder.decode(ByteBuffer.wrap(data), false));
}

/**
* Sends a Huffman-encoded string literal representation with padding longer than 7 bits.
* <p>
* Requirement: The endpoint MUST treat this as a decoding error.
*/
@Test
public void testStringLiteralPaddingLongerThan7Bits() throws HpackException {
byte[] data = new byte[]{0x00, (byte) 0x85, (byte) 0xf2, (byte) 0xb2, 0x4a, (byte) 0x84, (byte) 0xff, (byte) 0x84, 0x49, (byte) 0x50, (byte) 0x9f, (byte) 0xff};
HpackDecoder decoder = new HpackDecoder(256);

Assert.assertThrows(HpackException.class, () -> decoder.decode(ByteBuffer.wrap(data), false));
}

/**
* Sends a Huffman-encoded string literal representation padded by zero.
* <p>
* Requirement: The endpoint MUST treat this as a decoding error.
*/
@Test
public void testStringLiteralPaddedByZero() throws HpackException {
byte[] data = new byte[]{0x00, (byte) 0x85, (byte) 0xf2, (byte) 0xb2, 0x4a, (byte) 0x84, (byte) 0xff, (byte) 0x83, 0x49, (byte) 0x50, (byte) 0x90};
HpackDecoder decoder = new HpackDecoder(256);

Assert.assertThrows(HpackException.class, () -> decoder.decode(ByteBuffer.wrap(data), false));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2024 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.undertow.server.handlers.file;

import io.undertow.predicate.PredicatesHandler;
import io.undertow.server.handlers.ResponseCodeHandler;
import io.undertow.server.handlers.builder.PredicatedHandler;
import io.undertow.server.handlers.builder.PredicatedHandlersParser;
import io.undertow.server.handlers.resource.DirectoryUtils;
import io.undertow.testutils.DefaultServer;
import io.undertow.testutils.TestHttpClient;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

@RunWith(DefaultServer.class)
public class FileHandlerWithPredicateTestCase {
@Test
public void testIfHandlerReturnsResourcesWhenItIsInPredicate() throws IOException, URISyntaxException {
TestHttpClient client = new TestHttpClient();
Path rootPath = Paths.get(getClass().getResource("page.html").toURI()).getParent();
try {
List<PredicatedHandler> predicatedHandlers = PredicatedHandlersParser.parse("path-prefix(/subdir)-> { set(attribute=%U,value=${remaining}); resource(location='"+ rootPath +"',allow-listing=true) }", FileHandlerWithPredicateTestCase.class.getClassLoader());
PredicatesHandler predicatesHandler = new PredicatesHandler(new ResponseCodeHandler(200));
for (PredicatedHandler handler : predicatedHandlers) {
predicatesHandler.addPredicatedHandler(handler);
}
DefaultServer.setRootHandler(predicatesHandler);

//Make sure that we receive a body with the js needed to render the page.
CheckResponse(client, "/subdir/?js", true, false);

//Same for css
CheckResponse(client, "/subdir/?css", false, false);

//Make sure that we receive a body with the js needed to render the page.
CheckResponse(client, "/?js", true, true);

//Same for css
CheckResponse(client, "/?css", false, true);

} finally {
client.getConnectionManager().shutdown();
}
}

private void CheckResponse(TestHttpClient client, String path, Boolean isJs, Boolean emptyResponseExpected) throws IOException {
//Make sure that we receive a body with the js needed to render the page.
HttpGet get = new HttpGet(DefaultServer.getDefaultServerURL() + path);
HttpEntity result = client.execute(get).getEntity();

if (emptyResponseExpected){
Assert.assertEquals("The response is not empty", "", EntityUtils.toString(result));
} else {
if (isJs){
Assert.assertEquals("The returned js code is different or empty", DirectoryUtils.Blobs.FILE_JS, EntityUtils.toString(result));
} else {
Assert.assertEquals("The returned css code is different or empty", DirectoryUtils.Blobs.FILE_CSS, EntityUtils.toString(result));
}
}
}
}

0 comments on commit 711110b

Please sign in to comment.