Skip to content

Commit c2632cc

Browse files
committed
validate header syntax
1 parent 05a79ad commit c2632cc

File tree

3 files changed

+35
-6
lines changed

3 files changed

+35
-6
lines changed

pkl-commons-cli/src/main/kotlin/org/pkl/commons/cli/commands/BaseOptions.kt

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import org.pkl.commons.cli.CliException
3333
import org.pkl.commons.shlex
3434
import org.pkl.core.Pair as PPair
3535
import org.pkl.core.evaluatorSettings.Color
36+
import org.pkl.core.evaluatorSettings.PklEvaluatorSettings
3637
import org.pkl.core.evaluatorSettings.PklEvaluatorSettings.ExternalReader
3738
import org.pkl.core.runtime.VmUtils
3839
import org.pkl.core.util.IoUtils
@@ -293,11 +294,19 @@ class BaseOptions : OptionGroup() {
293294
try {
294295
val uri = URI(uriStr.trim())
295296

297+
val headerRegex = Regex("""^(.+?):[ \t]*(.+)$""")
296298
val headerPairs =
297299
headers.split(',').map { header ->
298-
val headerParts = header.split(":", limit = 2)
299-
require(headerParts.size == 2) { "Header '$header' is not in 'name:value' format. " }
300-
PPair(headerParts[0], headerParts[1])
300+
val (headerName, headerValue) =
301+
headerRegex.find(header)?.destructured
302+
?: fail("Header '$header' is not in 'name:value' format.")
303+
require(PklEvaluatorSettings.HEADER_NAME_REGEX.matcher(headerName).matches()) {
304+
"HTTP header name '$headerName' has invalid syntax."
305+
}
306+
require(PklEvaluatorSettings.HEADER_VALUE_REGEX.matcher(headerValue).matches()) {
307+
"HTTP header value '$headerValue' has invalid syntax"
308+
}
309+
PPair(headerName, headerValue)
301310
}
302311
uri to headerPairs
303312
} catch (e: IllegalArgumentException) {

pkl-core/src/main/java/org/pkl/core/evaluatorSettings/PklEvaluatorSettings.java

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ public record PklEvaluatorSettings(
5353
@Nullable Map<String, ExternalReader> externalModuleReaders,
5454
@Nullable Map<String, ExternalReader> externalResourceReaders) {
5555

56+
public static final Pattern HEADER_NAME_REGEX = Pattern.compile("^[a-zA-Z0-9!#$%&'*+-.^_`|~]+$");
57+
public static final Pattern HEADER_VALUE_REGEX =
58+
Pattern.compile("^[\\t\\u0020-\\u007E\\u0080-\\u00FF]*$");
59+
5660
/** Initializes a {@link PklEvaluatorSettings} from a raw object representation. */
5761
@SuppressWarnings("unchecked")
5862
public static PklEvaluatorSettings parse(
@@ -156,10 +160,20 @@ public record Http(
156160
parsedHeaders = new HashMap<>();
157161
var headersMap = (Map<String, List<Pair<String, String>>>) headers;
158162
for (var entry : headersMap.entrySet()) {
159-
var key = entry.getKey();
160-
var value = entry.getValue();
163+
var uri = entry.getKey();
164+
var pairs = entry.getValue();
165+
for (var pair : pairs) {
166+
if (!HEADER_NAME_REGEX.matcher(pair.getFirst()).matches()) {
167+
throw new PklException(
168+
ErrorMessages.create("invalidHeaderName", pair.getFirst()));
169+
}
170+
if (!HEADER_VALUE_REGEX.matcher(pair.getSecond()).matches()) {
171+
throw new PklException(
172+
ErrorMessages.create("invalidHeaderValue", pair.getSecond()));
173+
}
174+
}
161175
try {
162-
parsedHeaders.put(new URI(key), value);
176+
parsedHeaders.put(new URI(uri), pairs);
163177
} catch (URISyntaxException e) {
164178
throw new PklException(ErrorMessages.create("invalidUri", e.getInput()));
165179
}

pkl-core/src/main/resources/org/pkl/core/errorMessages.properties

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,3 +1070,9 @@ invalidStringBase64=\
10701070

10711071
characterCodingException=\
10721072
Invalid bytes for charset "{0}".
1073+
1074+
invalidHeaderName=\
1075+
HTTP header name `{0}` has invalid syntax.
1076+
1077+
invalidHeaderValue=\
1078+
HTTP header value `{0}` has invalid syntax.

0 commit comments

Comments
 (0)