-
-
Notifications
You must be signed in to change notification settings - Fork 6.2k
Markdown: Sanitizier Configuration #9075
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9025a69
5353d15
e582133
45963fc
5ecdfa5
a641266
314330b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,11 +9,14 @@ import ( | |
"strings" | ||
|
||
"code.gitea.io/gitea/modules/log" | ||
|
||
"gopkg.in/ini.v1" | ||
) | ||
|
||
// ExternalMarkupParsers represents the external markup parsers | ||
var ( | ||
ExternalMarkupParsers []MarkupParser | ||
ExternalMarkupParsers []MarkupParser | ||
ExternalSanitizerRules []MarkupSanitizerRule | ||
) | ||
|
||
// MarkupParser defines the external parser configured in ini | ||
|
@@ -25,42 +28,114 @@ type MarkupParser struct { | |
IsInputFile bool | ||
} | ||
|
||
// MarkupSanitizerRule defines the policy for whitelisting attributes on | ||
// certain elements. | ||
type MarkupSanitizerRule struct { | ||
Element string | ||
AllowAttr string | ||
Regexp *regexp.Regexp | ||
} | ||
|
||
func newMarkup() { | ||
extensionReg := regexp.MustCompile(`\.\w`) | ||
for _, sec := range Cfg.Section("markup").ChildSections() { | ||
name := strings.TrimPrefix(sec.Name(), "markup.") | ||
if name == "" { | ||
log.Warn("name is empty, markup " + sec.Name() + "ignored") | ||
continue | ||
} | ||
|
||
extensions := sec.Key("FILE_EXTENSIONS").Strings(",") | ||
var exts = make([]string, 0, len(extensions)) | ||
for _, extension := range extensions { | ||
if !extensionReg.MatchString(extension) { | ||
log.Warn(sec.Name() + " file extension " + extension + " is invalid. Extension ignored") | ||
} else { | ||
exts = append(exts, extension) | ||
} | ||
if name == "sanitizer" { | ||
newMarkupSanitizer(name, sec) | ||
} else { | ||
newMarkupRenderer(name, sec) | ||
} | ||
} | ||
} | ||
|
||
func newMarkupSanitizer(name string, sec *ini.Section) { | ||
haveElement := sec.HasKey("ELEMENT") | ||
haveAttr := sec.HasKey("ALLOW_ATTR") | ||
haveRegexp := sec.HasKey("REGEXP") | ||
|
||
if !haveElement && !haveAttr && !haveRegexp { | ||
log.Warn("Skipping empty section: markup.%s.", name) | ||
return | ||
} | ||
|
||
if !haveElement || !haveAttr || !haveRegexp { | ||
|
||
log.Error("Missing required keys from markup.%s. Must have all three of ELEMENT, ALLOW_ATTR, and REGEXP defined!", name) | ||
return | ||
} | ||
|
||
elements := sec.Key("ELEMENT").ValueWithShadows() | ||
allowAttrs := sec.Key("ALLOW_ATTR").ValueWithShadows() | ||
regexps := sec.Key("REGEXP").ValueWithShadows() | ||
|
||
if len(elements) != len(allowAttrs) || | ||
len(elements) != len(regexps) { | ||
log.Error("All three keys in markup.%s (ELEMENT, ALLOW_ATTR, REGEXP) must be defined the same number of times! Got %d, %d, and %d respectively.", name, len(elements), len(allowAttrs), len(regexps)) | ||
return | ||
} | ||
|
||
if len(exts) == 0 { | ||
log.Warn(sec.Name() + " file extension is empty, markup " + name + " ignored") | ||
ExternalSanitizerRules = make([]MarkupSanitizerRule, 0, len(elements)) | ||
|
||
for index, pattern := range regexps { | ||
if pattern == "" { | ||
rule := MarkupSanitizerRule{ | ||
Element: elements[index], | ||
AllowAttr: allowAttrs[index], | ||
Regexp: nil, | ||
} | ||
ExternalSanitizerRules = append(ExternalSanitizerRules, rule) | ||
continue | ||
} | ||
|
||
command := sec.Key("RENDER_COMMAND").MustString("") | ||
if command == "" { | ||
log.Warn(" RENDER_COMMAND is empty, markup " + name + " ignored") | ||
// Validate when parsing the config that this is a valid regular | ||
// expression. Then we can use regexp.MustCompile(...) later. | ||
compiled, err := regexp.Compile(pattern) | ||
if err != nil { | ||
log.Error("In module.%s: REGEXP at definition %d failed to compile: %v", name, index+1, err) | ||
continue | ||
} | ||
|
||
ExternalMarkupParsers = append(ExternalMarkupParsers, MarkupParser{ | ||
Enabled: sec.Key("ENABLED").MustBool(false), | ||
MarkupName: name, | ||
FileExtensions: exts, | ||
Command: command, | ||
IsInputFile: sec.Key("IS_INPUT_FILE").MustBool(false), | ||
}) | ||
rule := MarkupSanitizerRule{ | ||
Element: elements[index], | ||
AllowAttr: allowAttrs[index], | ||
Regexp: compiled, | ||
} | ||
ExternalSanitizerRules = append(ExternalSanitizerRules, rule) | ||
} | ||
} | ||
|
||
func newMarkupRenderer(name string, sec *ini.Section) { | ||
extensionReg := regexp.MustCompile(`\.\w`) | ||
|
||
extensions := sec.Key("FILE_EXTENSIONS").Strings(",") | ||
var exts = make([]string, 0, len(extensions)) | ||
for _, extension := range extensions { | ||
if !extensionReg.MatchString(extension) { | ||
log.Warn(sec.Name() + " file extension " + extension + " is invalid. Extension ignored") | ||
} else { | ||
exts = append(exts, extension) | ||
} | ||
} | ||
|
||
if len(exts) == 0 { | ||
log.Warn(sec.Name() + " file extension is empty, markup " + name + " ignored") | ||
return | ||
} | ||
|
||
command := sec.Key("RENDER_COMMAND").MustString("") | ||
if command == "" { | ||
log.Warn(" RENDER_COMMAND is empty, markup " + name + " ignored") | ||
return | ||
} | ||
|
||
ExternalMarkupParsers = append(ExternalMarkupParsers, MarkupParser{ | ||
Enabled: sec.Key("ENABLED").MustBool(false), | ||
MarkupName: name, | ||
FileExtensions: exts, | ||
Command: command, | ||
IsInputFile: sec.Key("IS_INPUT_FILE").MustBool(false), | ||
}) | ||
} |
Uh oh!
There was an error while loading. Please reload this page.