This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
package hostcollect
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// readLimited reads at most limit bytes from path. Every /proc file the collector
|
||||
// touches is small, but /proc is a kernel interface and a bounded read keeps a
|
||||
// pathological or hostile file from becoming an unbounded allocation.
|
||||
func readLimited(path string, limit int64) ([]byte, error) {
|
||||
file, err := os.Open(path) //nolint:gosec // paths are derived from the configured procfs root
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() { _ = file.Close() }()
|
||||
data, err := io.ReadAll(io.LimitReader(file, limit))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func readTrimmed(path string, limit int64) (string, error) {
|
||||
data, err := readLimited(path, limit)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strings.TrimSpace(string(data)), nil
|
||||
}
|
||||
|
||||
// parseUint accepts the decimal unsigned values procfs uses and reports failure
|
||||
// instead of guessing, so a malformed line degrades one field rather than producing a
|
||||
// plausible-looking zero.
|
||||
func parseUint(value string) (uint64, bool) {
|
||||
parsed, err := strconv.ParseUint(strings.TrimSpace(value), 10, 64)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return parsed, true
|
||||
}
|
||||
|
||||
func parseFloat(value string) (float64, bool) {
|
||||
parsed, err := strconv.ParseFloat(strings.TrimSpace(value), 64)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return parsed, true
|
||||
}
|
||||
|
||||
func truncate(value string, max int) string {
|
||||
if len(value) > max {
|
||||
return value[:max]
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// lines splits procfs content without allocating a scanner per file.
|
||||
func lines(data []byte) []string {
|
||||
text := strings.TrimRight(string(data), "\n")
|
||||
if text == "" {
|
||||
return nil
|
||||
}
|
||||
return strings.Split(text, "\n")
|
||||
}
|
||||
Reference in New Issue
Block a user