mirror of
https://github.com/amir20/dozzle.git
synced 2025-12-21 13:23:07 +01:00
fix: fixes searching escaped html and by unescaping before searching (#3838)
This commit is contained in:
@@ -87,7 +87,6 @@ func (g *EventGenerator) consumeReader() {
|
|||||||
logEvent := createEvent(message, streamType)
|
logEvent := createEvent(message, streamType)
|
||||||
logEvent.ContainerID = g.containerID
|
logEvent.ContainerID = g.containerID
|
||||||
logEvent.Level = guessLogLevel(logEvent)
|
logEvent.Level = guessLogLevel(logEvent)
|
||||||
escape(logEvent)
|
|
||||||
g.buffer <- logEvent
|
g.buffer <- logEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,11 @@ import (
|
|||||||
orderedmap "github.com/wk8/go-ordered-map/v2"
|
orderedmap "github.com/wk8/go-ordered-map/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
MarkerStart = "\uE000"
|
||||||
|
MarkerEnd = "\uE001"
|
||||||
|
)
|
||||||
|
|
||||||
func ParseRegex(search string) (*regexp.Regexp, error) {
|
func ParseRegex(search string) (*regexp.Regexp, error) {
|
||||||
flags := ""
|
flags := ""
|
||||||
|
|
||||||
@@ -30,7 +35,7 @@ func Search(re *regexp.Regexp, logEvent *container.LogEvent) bool {
|
|||||||
switch value := logEvent.Message.(type) {
|
switch value := logEvent.Message.(type) {
|
||||||
case string:
|
case string:
|
||||||
if re.MatchString(value) {
|
if re.MatchString(value) {
|
||||||
logEvent.Message = re.ReplaceAllString(value, "<mark>$0</mark>")
|
logEvent.Message = re.ReplaceAllString(value, MarkerStart+"$0"+MarkerEnd)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,9 +61,9 @@ func searchMapAny(re *regexp.Regexp, orderedMap *orderedmap.OrderedMap[string, a
|
|||||||
for pair := orderedMap.Oldest(); pair != nil; pair = pair.Next() {
|
for pair := orderedMap.Oldest(); pair != nil; pair = pair.Next() {
|
||||||
switch value := pair.Value.(type) {
|
switch value := pair.Value.(type) {
|
||||||
case string:
|
case string:
|
||||||
if re.MatchString(value) {
|
if replaced, matched := searchString(re, value); matched {
|
||||||
found = true
|
found = true
|
||||||
orderedMap.Set(pair.Key, re.ReplaceAllString(value, "<mark>$0</mark>"))
|
orderedMap.Set(pair.Key, replaced)
|
||||||
}
|
}
|
||||||
|
|
||||||
case []any:
|
case []any:
|
||||||
@@ -84,7 +89,7 @@ func searchMapAny(re *regexp.Regexp, orderedMap *orderedmap.OrderedMap[string, a
|
|||||||
case int, float64, bool:
|
case int, float64, bool:
|
||||||
formatted := fmt.Sprintf("%v", value)
|
formatted := fmt.Sprintf("%v", value)
|
||||||
if re.MatchString(formatted) {
|
if re.MatchString(formatted) {
|
||||||
orderedMap.Set(pair.Key, re.ReplaceAllString(formatted, "<mark>$0</mark>"))
|
orderedMap.Set(pair.Key, re.ReplaceAllString(formatted, MarkerStart+"$0"+MarkerEnd))
|
||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,11 +106,10 @@ func searchMap(re *regexp.Regexp, data map[string]interface{}) bool {
|
|||||||
for key, value := range data {
|
for key, value := range data {
|
||||||
switch value := value.(type) {
|
switch value := value.(type) {
|
||||||
case string:
|
case string:
|
||||||
if re.MatchString(value) {
|
if replaced, matched := searchString(re, value); matched {
|
||||||
data[key] = re.ReplaceAllString(value, "<mark>$0</mark>")
|
|
||||||
found = true
|
found = true
|
||||||
|
data[key] = replaced
|
||||||
}
|
}
|
||||||
|
|
||||||
case []any:
|
case []any:
|
||||||
if searchArray(re, value) {
|
if searchArray(re, value) {
|
||||||
found = true
|
found = true
|
||||||
@@ -119,7 +123,7 @@ func searchMap(re *regexp.Regexp, data map[string]interface{}) bool {
|
|||||||
case int, float64, bool:
|
case int, float64, bool:
|
||||||
formatted := fmt.Sprintf("%v", value)
|
formatted := fmt.Sprintf("%v", value)
|
||||||
if re.MatchString(formatted) {
|
if re.MatchString(formatted) {
|
||||||
data[key] = re.ReplaceAllString(formatted, "<mark>$0</mark>")
|
data[key] = re.ReplaceAllString(formatted, MarkerStart+"$0"+MarkerEnd)
|
||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@@ -133,9 +137,9 @@ func searchMap(re *regexp.Regexp, data map[string]interface{}) bool {
|
|||||||
func searchMapString(re *regexp.Regexp, orderedMap *orderedmap.OrderedMap[string, string]) bool {
|
func searchMapString(re *regexp.Regexp, orderedMap *orderedmap.OrderedMap[string, string]) bool {
|
||||||
found := false
|
found := false
|
||||||
for pair := orderedMap.Oldest(); pair != nil; pair = pair.Next() {
|
for pair := orderedMap.Oldest(); pair != nil; pair = pair.Next() {
|
||||||
if re.MatchString(pair.Value) {
|
if replaced, matched := searchString(re, pair.Value); matched {
|
||||||
orderedMap.Set(pair.Key, re.ReplaceAllString(pair.Value, "<mark>$0</mark>"))
|
|
||||||
found = true
|
found = true
|
||||||
|
orderedMap.Set(pair.Key, replaced)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return found
|
return found
|
||||||
@@ -146,14 +150,14 @@ func searchArray(re *regexp.Regexp, data []any) bool {
|
|||||||
for i, value := range data {
|
for i, value := range data {
|
||||||
switch value := value.(type) {
|
switch value := value.(type) {
|
||||||
case string:
|
case string:
|
||||||
if re.MatchString(value) {
|
if replaced, matched := searchString(re, value); matched {
|
||||||
data[i] = re.ReplaceAllString(value, "<mark>$0</mark>")
|
|
||||||
found = true
|
found = true
|
||||||
|
data[i] = replaced
|
||||||
}
|
}
|
||||||
case int, float64, bool:
|
case int, float64, bool:
|
||||||
formatted := fmt.Sprintf("%v", value)
|
formatted := fmt.Sprintf("%v", value)
|
||||||
if re.MatchString(formatted) {
|
if re.MatchString(formatted) {
|
||||||
data[i] = re.ReplaceAllString(formatted, "<mark>$0</mark>")
|
data[i] = re.ReplaceAllString(formatted, MarkerStart+"$0"+MarkerEnd)
|
||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
case []any:
|
case []any:
|
||||||
@@ -169,3 +173,12 @@ func searchArray(re *regexp.Regexp, data []any) bool {
|
|||||||
|
|
||||||
return found
|
return found
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func searchString(re *regexp.Regexp, value string) (string, bool) {
|
||||||
|
if re.MatchString(value) {
|
||||||
|
replaced := re.ReplaceAllString(value, MarkerStart+"$0"+MarkerEnd)
|
||||||
|
return replaced, true
|
||||||
|
}
|
||||||
|
|
||||||
|
return value, false
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,16 +1,21 @@
|
|||||||
package container
|
package support_web
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"html"
|
"html"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/amir20/dozzle/internal/container"
|
||||||
|
"github.com/amir20/dozzle/internal/support/search"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
orderedmap "github.com/wk8/go-ordered-map/v2"
|
orderedmap "github.com/wk8/go-ordered-map/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func escape(logEvent *LogEvent) {
|
func EscapeHTMLValues(logEvent *container.LogEvent) {
|
||||||
switch value := logEvent.Message.(type) {
|
switch value := logEvent.Message.(type) {
|
||||||
case string:
|
case string:
|
||||||
logEvent.Message = html.EscapeString(value)
|
value = html.EscapeString(value)
|
||||||
|
value = strings.ReplaceAll(value, search.MarkerStart, "<mark>")
|
||||||
|
logEvent.Message = strings.ReplaceAll(value, search.MarkerEnd, "</mark>")
|
||||||
|
|
||||||
case *orderedmap.OrderedMap[string, any]:
|
case *orderedmap.OrderedMap[string, any]:
|
||||||
escapeAnyMap(value)
|
escapeAnyMap(value)
|
||||||
@@ -33,7 +38,10 @@ func escapeAnyMap(orderedMap *orderedmap.OrderedMap[string, any]) {
|
|||||||
for pair := orderedMap.Oldest(); pair != nil; pair = pair.Next() {
|
for pair := orderedMap.Oldest(); pair != nil; pair = pair.Next() {
|
||||||
switch value := pair.Value.(type) {
|
switch value := pair.Value.(type) {
|
||||||
case string:
|
case string:
|
||||||
orderedMap.Set(pair.Key, html.EscapeString(value))
|
value = html.EscapeString(value)
|
||||||
|
value = strings.ReplaceAll(value, search.MarkerStart, "<mark>")
|
||||||
|
value = strings.ReplaceAll(value, search.MarkerEnd, "</mark>")
|
||||||
|
orderedMap.Set(pair.Key, value)
|
||||||
case *orderedmap.OrderedMap[string, any]:
|
case *orderedmap.OrderedMap[string, any]:
|
||||||
escapeAnyMap(value)
|
escapeAnyMap(value)
|
||||||
case *orderedmap.OrderedMap[string, string]:
|
case *orderedmap.OrderedMap[string, string]:
|
||||||
@@ -45,6 +53,9 @@ func escapeAnyMap(orderedMap *orderedmap.OrderedMap[string, any]) {
|
|||||||
|
|
||||||
func escapeStringMap(orderedMap *orderedmap.OrderedMap[string, string]) {
|
func escapeStringMap(orderedMap *orderedmap.OrderedMap[string, string]) {
|
||||||
for pair := orderedMap.Oldest(); pair != nil; pair = pair.Next() {
|
for pair := orderedMap.Oldest(); pair != nil; pair = pair.Next() {
|
||||||
orderedMap.Set(pair.Key, html.EscapeString(pair.Value))
|
value := html.EscapeString(pair.Value)
|
||||||
|
value = strings.ReplaceAll(value, search.MarkerStart, "<mark>")
|
||||||
|
value = strings.ReplaceAll(value, search.MarkerEnd, "</mark>")
|
||||||
|
orderedMap.Set(pair.Key, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,6 +158,7 @@ func (h *handler) fetchLogsBetweenDates(w http.ResponseWriter, r *http.Request)
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
support_web.EscapeHTMLValues(event) // only escape when not exporting
|
||||||
buffer.Push(event)
|
buffer.Push(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -391,6 +392,8 @@ loop:
|
|||||||
if _, ok := levels[logEvent.Level]; !ok {
|
if _, ok := levels[logEvent.Level]; !ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
support_web.EscapeHTMLValues(logEvent)
|
||||||
sseWriter.Message(logEvent)
|
sseWriter.Message(logEvent)
|
||||||
case c := <-newContainers:
|
case c := <-newContainers:
|
||||||
if _, err := h.hostService.FindContainer(c.Host, c.ID, userLabels); err == nil {
|
if _, err := h.hostService.FindContainer(c.Host, c.ID, userLabels); err == nil {
|
||||||
@@ -405,6 +408,9 @@ loop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
case backfillEvents := <-backfill:
|
case backfillEvents := <-backfill:
|
||||||
|
for _, event := range backfillEvents {
|
||||||
|
support_web.EscapeHTMLValues(event)
|
||||||
|
}
|
||||||
if err := sseWriter.Event("logs-backfill", backfillEvents); err != nil {
|
if err := sseWriter.Event("logs-backfill", backfillEvents); err != nil {
|
||||||
log.Error().Err(err).Msg("error encoding container event")
|
log.Error().Err(err).Msg("error encoding container event")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user