content_rewrite_validation.go 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0
  3. package rewrite // import "miniflux.app/v2/internal/reader/rewrite"
  4. import (
  5. "regexp"
  6. "text/scanner"
  7. "github.com/andybalholm/cascadia"
  8. )
  9. type RuleErrorKind int
  10. const (
  11. RuleErrLexical RuleErrorKind = iota
  12. RuleErrUnquote
  13. RuleErrOrphanArg
  14. RuleErrUnknownName
  15. RuleErrMissingArgs
  16. RuleErrInvalidRegexp
  17. RuleErrInvalidSelector
  18. )
  19. // RuleError describes one problem found while parsing rewrite rules.
  20. type RuleError struct {
  21. Pos scanner.Position
  22. Kind RuleErrorKind
  23. Rule string
  24. Token string
  25. Message string
  26. }
  27. // validateParsedRules checks parsed rules against knownRules for unknown names
  28. // and missing arguments.
  29. func validateParsedRules(rules []rule) (errs []RuleError) {
  30. for _, r := range rules {
  31. spec, ok := knownRules[r.name]
  32. if !ok {
  33. errs = append(errs, RuleError{Kind: RuleErrUnknownName, Rule: r.name,
  34. Message: "unknown rewrite rule name"})
  35. continue
  36. }
  37. if len(r.args) < spec.minArgs {
  38. errs = append(errs, RuleError{Kind: RuleErrMissingArgs, Rule: r.name,
  39. Message: "missing required arguments"})
  40. continue
  41. }
  42. if spec.regexArg && len(r.args) > 0 {
  43. if _, err := regexp.Compile(r.args[0]); err != nil {
  44. errs = append(errs, RuleError{Kind: RuleErrInvalidRegexp, Rule: r.name,
  45. Token: r.args[0], Message: err.Error()})
  46. }
  47. }
  48. // goquery silently matches nothing when a selector does not compile,
  49. // so an invalid selector would turn the rule into a no-op.
  50. if spec.selectorArg && len(r.args) > 0 {
  51. if _, err := cascadia.Compile(r.args[0]); err != nil {
  52. errs = append(errs, RuleError{Kind: RuleErrInvalidSelector, Rule: r.name,
  53. Token: r.args[0], Message: err.Error()})
  54. }
  55. }
  56. }
  57. return errs
  58. }
  59. // ValidateRules parses rules solely to report problems. It returns nil when the
  60. // rules are well-formed.
  61. func ValidateRules(rulesText string) []RuleError {
  62. _, errs := parseRules(rulesText)
  63. return errs
  64. }