diff --git a/internal-api/src/main/java/datadog/trace/bootstrap/config/provider/StableConfigParser.java b/internal-api/src/main/java/datadog/trace/bootstrap/config/provider/StableConfigParser.java index 3721528f81f..f0468186e3e 100644 --- a/internal-api/src/main/java/datadog/trace/bootstrap/config/provider/StableConfigParser.java +++ b/internal-api/src/main/java/datadog/trace/bootstrap/config/provider/StableConfigParser.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collections; import java.util.HashMap; @@ -21,6 +22,7 @@ public class StableConfigParser { private static final String ENVIRONMENT_VARIABLES_PREFIX = "environment_variables['"; private static final String PROCESS_ARGUMENTS_PREFIX = "process_arguments['"; + private static final int MAX_FILE_SIZE_BYTES = 256 * 1024; // 256 KB in bytes; private static final String UNDEFINED_VALUE = "UNDEFINED"; /** @@ -39,7 +41,19 @@ public class StableConfigParser { */ public static StableConfigSource.StableConfig parse(String filePath) throws IOException { try { - String content = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8); + Path path = Paths.get(filePath); + + // If file is over size limit, drop + if (Files.size(path) > MAX_FILE_SIZE_BYTES) { + log.warn( + "Configuration file {} exceeds max size {} bytes; dropping.", + filePath, + MAX_FILE_SIZE_BYTES); + return StableConfigSource.StableConfig.EMPTY; + } + + String content = new String(Files.readAllBytes(path), StandardCharsets.UTF_8); + String processedContent = processTemplate(content); StableConfigYaml data = YamlParser.parse(processedContent, StableConfigYaml.class); @@ -268,4 +282,8 @@ private static String processTemplateVar(String templateVar) throws IOException return UNDEFINED_VALUE; } } + + static int getMaxFileSizeBytes() { + return MAX_FILE_SIZE_BYTES; + } } diff --git a/internal-api/src/test/groovy/datadog/trace/bootstrap/config/provider/StableConfigParserTest.groovy b/internal-api/src/test/groovy/datadog/trace/bootstrap/config/provider/StableConfigParserTest.groovy index 686648471a1..cba1ee850f4 100644 --- a/internal-api/src/test/groovy/datadog/trace/bootstrap/config/provider/StableConfigParserTest.groovy +++ b/internal-api/src/test/groovy/datadog/trace/bootstrap/config/provider/StableConfigParserTest.groovy @@ -205,6 +205,50 @@ apm_configuration_rules: Files.delete(filePath) } + def "test file over max size"() { + when: + Path filePath = Files.createTempFile("testFile_", ".yaml") + if (filePath == null) { + throw new AssertionError("Failed to create test file") + } + + // Create a file with valid contents, but bigger than MAX_FILE_SIZE_BYTES + String baseYaml = """ +config_id: 12345 +apm_configuration_default: + KEY_ONE: "value_one" +apm_configuration_rules: +""" + String builderYaml = """ + - selectors: + - origin: language + matches: ["Java"] + operator: equals + configuration: + KEY_TWO: "value_two" +""" + String bigYaml = baseYaml + while(bigYaml.size() < StableConfigParser.getMaxFileSizeBytes()) { + bigYaml += builderYaml + } + + try { + Files.write(filePath, bigYaml.getBytes()) + } catch (IOException e) { + throw new AssertionError("Failed to write to file: ${e.message}") + } + + StableConfigSource.StableConfig cfg + try { + cfg = StableConfigParser.parse(filePath.toString()) + } catch (Exception e) { + throw new AssertionError("Failed to parse the file: ${e.message}") + } + + then: + cfg == StableConfigSource.StableConfig.EMPTY + } + def "test processTemplate valid cases"() { when: if (envKey != null) {