Repository: apache/kafka
File: clients/src/main/java/org/apache/kafka/common/config/ConfigDef.java (Java)

Code before:

            if (Set.copyOf(values).size() != values.size()) {
                throw new ConfigException("Configuration '" + name + "' values must not be duplicated.");
            }

            validateIndividualValues(name, values);
        }

        private void validateIndividualValues(String name, List<Object> values) {
            boolean hasValidStrings = !validString.validStrings.isEmpty();

            for (Object value : values) {
                if (value instanceof String) {
                    String string = (String) value;
                    if (string.isEmpty()) {
                        throw new ConfigException("Configuration '" + name + "' values must not be empty.");
                    }
                    if (hasValidStrings) {
                        validString.ensureValid(name, value);
                    }
                }
            }
        }

        public String toString() {
            String base = validString.validStrings.isEmpty() ? "any non-duplicate values" : validString.toString();
            String emptyList = isEmptyAllowed ? ", empty list" : "";
            String nullValue = isNullAllowed ? ", null" : "";
            return base + emptyList + nullValue;
        }
    }

    public static class ValidString implements Validator {
        final List<String> validStrings;

        private ValidString(List<String> validStrings) {
            this.validStrings = validStrings;
        }

        public static ValidString in(String... validStrings) {
            return new ValidString(Arrays.asList(validStrings));
        }

        @Override
        public void ensureValid(String name, Object o) {
            String s = (String) o;
            if (!validStrings.contains(s)) {
                throw new ConfigException(name, o, "String must be one of: " + String.join(", ", validStrings));
            }

        }

Review comment (security):
The following configs don't have a validator, but it seems that they shoud.

BrokerSecurityConfigs:
ssl.cipher.suites
sasl.enabled.mechanisms
sasl.kerberos.principal.to.local.rules
sasl.oauthbearer.expected.audience


DefaultConfigPropertyFilter
config.properties.exclude

DefaultTopicFilter
topics
topics.exclude

Code after:

            if (Set.copyOf(values).size() != values.size()) {
                throw new ConfigException("Configuration '" + name + "' values must not be duplicated.");
            }

            validateIndividualValues(name, values);
        }

        private void validateIndividualValues(String name, List<Object> values) {
            boolean hasValidStrings = !validString.validStrings.isEmpty();

            for (Object value : values) {
                if (value instanceof String) {
                    String string = (String) value;
                    if (string.isEmpty()) {
                        throw new ConfigException("Configuration '" + name + "' values must not be empty.");
                    }
                    if (hasValidStrings) {
                        validString.ensureValid(name, value);
                    }
                }
            }
        }

        public String toString() {
            return !validString.validStrings.isEmpty() ? validString.toString() : "";
        }
    }

    public static class ValidString implements Validator {
        final List<String> validStrings;

        private ValidString(List<String> validStrings) {
            this.validStrings = validStrings;
        }

        public static ValidString in(String... validStrings) {
            return new ValidString(Arrays.asList(validStrings));
        }

        @Override
        public void ensureValid(String name, Object o) {
            String s = (String) o;
            if (!validStrings.contains(s)) {
                throw new ConfigException(name, o, "String must be one of: " + String.join(", ", validStrings));
            }

        }

        public String toString() {
            return "[" + String.join(", ", validStrings) + "]";