2019-03-16 06:12:44 +03:00
// Copyright 2019 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package setting
import (
"regexp"
"strings"
"code.gitea.io/gitea/modules/log"
2019-12-07 22:49:04 +03:00
"gopkg.in/ini.v1"
2019-03-16 06:12:44 +03:00
)
// ExternalMarkupParsers represents the external markup parsers
var (
2019-12-07 22:49:04 +03:00
ExternalMarkupParsers [ ] MarkupParser
ExternalSanitizerRules [ ] MarkupSanitizerRule
2019-03-16 06:12:44 +03:00
)
// MarkupParser defines the external parser configured in ini
type MarkupParser struct {
Enabled bool
MarkupName string
Command string
FileExtensions [ ] string
IsInputFile bool
}
2019-12-07 22:49:04 +03:00
// MarkupSanitizerRule defines the policy for whitelisting attributes on
// certain elements.
type MarkupSanitizerRule struct {
Element string
AllowAttr string
Regexp * regexp . Regexp
}
2019-03-16 06:12:44 +03:00
func newMarkup ( ) {
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
}
2020-04-29 14:34:59 +03:00
if name == "sanitizer" || strings . HasPrefix ( name , "sanitizer." ) {
2019-12-07 22:49:04 +03:00
newMarkupSanitizer ( name , sec )
} else {
newMarkupRenderer ( name , sec )
2019-03-16 06:12:44 +03:00
}
2019-12-07 22:49:04 +03:00
}
}
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
}
2020-04-29 14:34:59 +03:00
elements := sec . Key ( "ELEMENT" ) . Value ( )
allowAttrs := sec . Key ( "ALLOW_ATTR" ) . Value ( )
regexpStr := sec . Key ( "REGEXP" ) . Value ( )
2019-12-07 22:49:04 +03:00
2020-04-29 14:34:59 +03:00
if regexpStr == "" {
rule := MarkupSanitizerRule {
Element : elements ,
AllowAttr : allowAttrs ,
Regexp : nil ,
}
ExternalSanitizerRules = append ( ExternalSanitizerRules , rule )
2019-12-07 22:49:04 +03:00
return
}
2019-03-16 06:12:44 +03:00
2020-04-29 14:34:59 +03:00
// Validate when parsing the config that this is a valid regular
// expression. Then we can use regexp.MustCompile(...) later.
compiled , err := regexp . Compile ( regexpStr )
if err != nil {
log . Error ( "In module.%s: REGEXP (%s) at definition %d failed to compile: %v" , regexpStr , name , err )
return
}
2019-03-16 06:12:44 +03:00
2020-04-29 14:34:59 +03:00
rule := MarkupSanitizerRule {
Element : elements ,
AllowAttr : allowAttrs ,
Regexp : compiled ,
2019-12-07 22:49:04 +03:00
}
2020-04-29 14:34:59 +03:00
ExternalSanitizerRules = append ( ExternalSanitizerRules , rule )
2019-12-07 22:49:04 +03:00
}
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
2019-03-16 06:12:44 +03:00
}
2019-12-07 22:49:04 +03:00
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 ) ,
} )
2019-03-16 06:12:44 +03:00
}