fix(config): accept spaces and trailing commas in list option values

MEDIA_PROXY_RESOURCE_TYPES and TRUSTED_REVERSE_PROXY_NETWORKS were
validated by splitting the raw value without trimming, while the parser
trims items and skips empty ones. Values such as "image, video" or
"192.168.0.0/16, 10.0.0.0/8", and lists with a trailing comma, failed
startup even though the parser accepts them.

Validate the parsed list instead, and reject values that contain no
items at all so that a comma-only value cannot silently clear the
default media proxy resource types.
This commit is contained in:
Fred
2026-07-21 21:11:20 -07:00
committed by fguillot
parent 0e26f12426
commit 1d10e7a089
2 changed files with 48 additions and 2 deletions
+11 -2
View File
@@ -4,6 +4,7 @@
package config // import "miniflux.app/v2/internal/config"
import (
"errors"
"maps"
"net"
"net/url"
@@ -383,7 +384,11 @@ func NewConfigOptions() *configOptions {
rawValue: "image",
valueType: stringListType,
validator: func(rawValue string) error {
return validateListChoices(strings.Split(rawValue, ","), []string{"image", "video", "audio"})
resourceTypes := parseStringListValue(rawValue, nil)
if len(resourceTypes) == 0 {
return errors.New("at least one resource type is required")
}
return validateListChoices(resourceTypes, []string{"image", "video", "audio"})
},
},
"METRICS_ALLOWED_NETWORKS": {
@@ -569,7 +574,11 @@ func NewConfigOptions() *configOptions {
rawValue: "",
valueType: stringListType,
validator: func(rawValue string) error {
for ip := range strings.SplitSeq(rawValue, ",") {
networks := parseStringListValue(rawValue, nil)
if len(networks) == 0 {
return errors.New("at least one CIDR notation network is required")
}
for _, ip := range networks {
if _, _, err := net.ParseCIDR(ip); err != nil {
return err
}
+37
View File
@@ -1508,9 +1508,26 @@ func TestMediaProxyResourceTypesOptionParsing(t *testing.T) {
t.Fatalf("Expected MEDIA_PROXY_RESOURCE_TYPES to contain image and video")
}
if err := configParser.parseLines([]string{"MEDIA_PROXY_RESOURCE_TYPES=image, video"}); err != nil {
t.Fatalf("Unexpected error for value with spaces: %v", err)
}
resourceTypes = configParser.options.MediaProxyResourceTypes()
if len(resourceTypes) != 2 || resourceTypes[0] != "image" || resourceTypes[1] != "video" {
t.Fatalf("Expected MEDIA_PROXY_RESOURCE_TYPES to contain image and video")
}
if err := configParser.parseLines([]string{"MEDIA_PROXY_RESOURCE_TYPES=image,video,"}); err != nil {
t.Fatalf("Unexpected error for value with trailing comma: %v", err)
}
if err := configParser.parseLines([]string{"MEDIA_PROXY_RESOURCE_TYPES=image,invalid,video"}); err == nil {
t.Fatal("Expected error due to invalid resource type")
}
if err := configParser.parseLines([]string{"MEDIA_PROXY_RESOURCE_TYPES=,"}); err == nil {
t.Fatal("Expected error for value without any resource type")
}
}
func TestMetricsAllowedNetworksOptionParsing(t *testing.T) {
@@ -1652,10 +1669,30 @@ func TestTrustedReverseProxyNetworksOptionParsing(t *testing.T) {
t.Errorf("Expected 192.168.1.0/24 in allowed networks")
}
// Test value with spaces and trailing comma
if err := configParser.parseLines([]string{"TRUSTED_REVERSE_PROXY_NETWORKS=192.168.0.0/16, 10.0.0.0/8,"}); err != nil {
t.Fatalf("Unexpected error for value with spaces: %v", err)
}
allowedNetworks = configParser.options.TrustedReverseProxyNetworks()
if len(allowedNetworks) != 2 {
t.Fatalf("Expected 2 allowed networks, got %d", len(allowedNetworks))
}
if !slices.Contains(allowedNetworks, "192.168.0.0/16") {
t.Errorf("Expected 192.168.0.0/16 in allowed networks")
}
if !slices.Contains(allowedNetworks, "10.0.0.0/8") {
t.Errorf("Expected 10.0.0.0/8 in allowed networks")
}
// Test invalid value
if err := configParser.parseLines([]string{"TRUSTED_REVERSE_PROXY_NETWORKS=127.0.0.1"}); err == nil {
t.Fatal("Expected error when parsing invalid CIDR notation IP 127.0.0.1, got nil")
}
if err := configParser.parseLines([]string{"TRUSTED_REVERSE_PROXY_NETWORKS=,"}); err == nil {
t.Fatal("Expected error for value without any network")
}
}
func TestYouTubeEmbedDomainOptionParsing(t *testing.T) {