-
Notifications
You must be signed in to change notification settings - Fork 0
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
logging: Sanitize Journald Field Key Names #48
Conversation
oxzi
commented
Jul 24, 2024
•
edited
Loading
edited
0e88947
to
18bd900
Compare
Based on @julianbrost's comment Icinga/icinga-notifications#254 (comment) at the other PR, I have taken another look. As it turns out, previously I blamed the wrong part, however, I was very self-confident doing so. After some further investigation, which I also commented over there, Icinga/icinga-notifications#254 (comment), I came to the following conclusion:
Thus, i have changed the logic here and introduced a function to ensure that only valid field keys are being set. Please refer to the updated commit message. Using this commit as the icinga-go-library version in icinga-notification seems to work as intended. Take a look at the following (redacted)
|
18bd900
to
a7d3972
Compare
a7d3972
to
5368c18
Compare
logging/journald_core.go
Outdated
isAlpha := func(r rune) bool { return 'A' <= r && r <= 'Z' } | ||
isDigit := func(r rune) bool { return '0' <= r && r <= '9' } | ||
|
||
keyParts := []rune(strcase.ScreamingSnake(key)) | ||
for i, r := range keyParts { | ||
if isAlpha(r) || isDigit(r) || r == '_' { | ||
continue | ||
} | ||
keyParts[i] = '_' | ||
} | ||
key = string(keyParts) | ||
|
||
if !isAlpha(rune(key[0])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm not mistaken, Go already provides utilities for this:
isAlpha := func(r rune) bool { return 'A' <= r && r <= 'Z' } | |
isDigit := func(r rune) bool { return '0' <= r && r <= '9' } | |
keyParts := []rune(strcase.ScreamingSnake(key)) | |
for i, r := range keyParts { | |
if isAlpha(r) || isDigit(r) || r == '_' { | |
continue | |
} | |
keyParts[i] = '_' | |
} | |
key = string(keyParts) | |
if !isAlpha(rune(key[0])) { | |
key := strcase.ScreamingSnake(key) | |
for i, r := range key { | |
if unicode.IsUpper(r) || unicode.IsDigit(r) || r == '_' { | |
continue | |
} | |
key[i] = '_' | |
} | |
if !unicode.IsUpper(rune(key[0])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
journald requires ASCII A-Z, whereas (as the package name already suggests), unicode.IsUpper()
also returns true for non-ASCII uppercase characters like Ä
: https://go.dev/play/p/ayqkoWoCL8E
isUpper
would still be a better name than isAlpha
though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting key[i] = '_'
in a string is not supported. To do so, it needs to be converted to a []rune
or some shenanigans like key[:i] + "_" + key[i+1:]
are necessary. However, the second option messes up some Unicode characters being bigger than a byte. For example: https://go.dev/play/p/qo3nfS83ybc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
journald requires ASCII A-Z, whereas (as the package name already suggests),
unicode.IsUpper()
also returns true for non-ASCII uppercase characters likeÄ
My bad, I didn't expect UTF-8 strings to be supported and overlooked the test for it.
5368c18
to
1cc15bb
Compare
As seen over at Icinga Notifications[0], the use of non-alphanumeric characters for journaldCore causes fields to be silently discarded. This was due to journald's field key validation, which is unfortunately not very well documented. Looking at its implementation[1], this library code could be adapted to ensure that valid field keys are always used. [0]: Icinga/icinga-notifications#254 [1]: https://github.com/systemd/systemd/blob/11d5e2b5fbf9f6bfa5763fd45b56829ad4f0777f/src/libsystemd/sd-journal/journal-file.c#L1703
1cc15bb
to
3f3ec3a
Compare