diff --git a/.github/dockerhub.png b/.github/dockerhub.png new file mode 100644 index 0000000..a559a38 Binary files /dev/null and b/.github/dockerhub.png differ diff --git a/README.md b/README.md index 7ea38ae..977bd09 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,10 @@ -# nginx-formatter -Nginx Conf Formatter. +# Nginx Formatter + +Nginx configuration formatter under 10MB size. + + +## Docker + + + +- https://hub.docker.com/r/soulteary/nginx-formatter diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..7826e80 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,13 @@ +# Security Policy + +## Supported Versions + +All releases accept security reports, updates. + +| Version | Supported | +| ------- | ------------------ | +| * | :white_check_mark: | + +## Reporting a Vulnerability + +If you find any security issues, welcome to file an issue or submit a PR directly. diff --git a/internal/formatter/beautifier.js b/internal/formatter/beautifier.js index f9f7059..93c3d6a 100644 --- a/internal/formatter/beautifier.js +++ b/internal/formatter/beautifier.js @@ -173,6 +173,16 @@ function add_empty_line_after_nginx_directives(lines) { return output.reverse(); } +function fixDollarVar(lines) { + const placeHolder = `[dollar]`; + return lines.map((line) => { + while (line.indexOf(placeHolder) !== -1) { + line = line.replace(placeHolder, "$"); + } + return line; + }); +} + var options = { INDENTATION: "\t" }; function perform_indentation(lines) { @@ -205,5 +215,6 @@ function FormatNginxConf(text, indentation = " ") { lines = join_opening_bracket(lines); lines = perform_indentation(lines); lines = add_empty_line_after_nginx_directives(lines); + lines = fixDollarVar(lines); return fold_empty_brackets(lines); } diff --git a/internal/updater/updater.go b/internal/updater/updater.go index 3342264..ea504d9 100644 --- a/internal/updater/updater.go +++ b/internal/updater/updater.go @@ -4,9 +4,62 @@ import ( "fmt" "os" "path/filepath" + "regexp" "strings" ) +func EncodeEscapeChars(s string) string { + return strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(s, `\t`, `【\\】t`), `\s`, `【\\】s`), `\r`, `【\\】r`), `\n`, `【\\】n`) +} + +func DecodeEscapeChars(s string) string { + return strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(strings.ReplaceAll(s, `【\】t`, `\t`), `【\】s`, `\s`), `【\】r`, `\r`), `【\】n`, `\n`) +} + +// scenes: +// +// return 200 "1" ; +// return 200 "1"; +// return "1" ; +// return 200; +// return "aaa\naa"; +// return 200 "a\n" ; +// return BACKEND\n; +func FixReturn(s string) string { + var scene1 = regexp.MustCompile(`return\s+(\d+)\s(\S+)\s*;`) + var scene2 = regexp.MustCompile(`return\s+(\d+)\s"(\S+)"\s*;`) + var scene3 = regexp.MustCompile(`return\s+(\S+)\s*;`) + var scene4 = regexp.MustCompile(`return\s+"(\S+)"\s*;`) + var scene5 = regexp.MustCompile(`return\s+(\d+)\s*;`) + + if scene1.MatchString(s) { + if scene2.MatchString(s) { // eg: `return 200 "ok";` + s = scene2.ReplaceAllString(s, "return $1 \"$2\";") + } else { // eg: `return 200 $content;` + s = scene1.ReplaceAllString(s, "return $1 \"$2\";") + } + } else if scene3.MatchString(s) { + if scene5.MatchString(s) { // eg: `return 200;` + s = scene5.ReplaceAllString(s, "return $1;") + } else if scene4.MatchString(s) { // eg: `return "ok";` + s = scene4.ReplaceAllString(s, "return \"$1\";") + } else { // eg: `return BACKEND\n;` + found := scene3.FindString(s) + if !(strings.HasPrefix(found, `"`) && strings.HasSuffix(found, `"`)) { + s = scene3.ReplaceAllString(s, "return $1;") + } else { + s = scene3.ReplaceAllString(s, "return \"$1\";") + } + } + } + return s +} + +func FixVars(s string) string { + s = regexp.MustCompile(`(\$)(\{\S+?\})`).ReplaceAllString(s, "[dollar]$2") + return s +} + func UpdateConfInDir(rootDir string, fn func(s string) (string, error)) error { if rootDir == "" { return fmt.Errorf("scandir is empty") @@ -23,12 +76,12 @@ func UpdateConfInDir(rootDir string, fn func(s string) (string, error)) error { return err } - modifiedData, err := fn(string(data)) + modifiedData, err := fn(FixVars(FixReturn(EncodeEscapeChars(string(data))))) if err != nil { return err } - err = os.WriteFile(path, []byte(modifiedData), info.Mode()) + err = os.WriteFile(path, []byte(DecodeEscapeChars(modifiedData)), info.Mode()) if err != nil { return err }