Share bounded regular file read mechanics
This commit is contained in:
47
source.go
47
source.go
@@ -125,10 +125,7 @@ func readSource(source Source, sourceID string, limits sourceLimits) (sourceRead
|
||||
}
|
||||
info := &SourceInfo{ID: sourceID, Label: source.label, Layer: LayerBase}
|
||||
|
||||
var (
|
||||
input io.Reader
|
||||
close func() error
|
||||
)
|
||||
var input io.Reader
|
||||
switch source.kind {
|
||||
case sourceFile:
|
||||
absolute, err := filepath.Abs(source.path)
|
||||
@@ -141,32 +138,11 @@ func readSource(source Source, sourceID string, limits sourceLimits) (sourceRead
|
||||
return sourceRead{info: info}, []Diagnostic{classifySourceError(err, sourceID)}
|
||||
}
|
||||
info.Path = canonical
|
||||
preflight, err := os.Stat(canonical)
|
||||
if err != nil {
|
||||
return sourceRead{info: info}, []Diagnostic{classifySourceError(err, sourceID)}
|
||||
data, failure := readRegularFile(canonical, os.Stat, os.Open, limit)
|
||||
if failure != nil {
|
||||
return sourceRead{info: info}, []Diagnostic{sourceReadDiagnostic(failure, sourceID, CodeSourceLimitExceeded, "source exceeds the configured byte limit")}
|
||||
}
|
||||
if !preflight.Mode().IsRegular() {
|
||||
return sourceRead{info: info}, []Diagnostic{sourceDiagnostic(CodeSourceNotRegular, sourceID, "source is not a regular file")}
|
||||
}
|
||||
file, err := os.Open(canonical)
|
||||
if err != nil {
|
||||
return sourceRead{info: info}, []Diagnostic{classifySourceError(err, sourceID)}
|
||||
}
|
||||
close = file.Close
|
||||
stat, err := file.Stat()
|
||||
if err != nil {
|
||||
_ = file.Close()
|
||||
return sourceRead{info: info}, []Diagnostic{classifySourceError(err, sourceID)}
|
||||
}
|
||||
if !stat.Mode().IsRegular() {
|
||||
_ = file.Close()
|
||||
return sourceRead{info: info}, []Diagnostic{sourceDiagnostic(CodeSourceNotRegular, sourceID, "source is not a regular file")}
|
||||
}
|
||||
if stat.Size() > limit {
|
||||
_ = file.Close()
|
||||
return sourceRead{info: info}, []Diagnostic{sourceDiagnostic(CodeSourceLimitExceeded, sourceID, "source exceeds the configured byte limit")}
|
||||
}
|
||||
input = file
|
||||
return sourceRead{data: bytes.Clone(data), info: info}, nil
|
||||
case sourceBytes:
|
||||
input = bytes.NewReader(source.data)
|
||||
case sourceReader:
|
||||
@@ -177,16 +153,9 @@ func readSource(source Source, sourceID string, limits sourceLimits) (sourceRead
|
||||
default:
|
||||
return sourceRead{info: info}, []Diagnostic{sourceDiagnostic(CodeSourceInvalid, sourceID, "source is invalid")}
|
||||
}
|
||||
if close != nil {
|
||||
defer func() { _ = close() }()
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(io.LimitReader(input, limit+1))
|
||||
if err != nil {
|
||||
return sourceRead{info: info}, []Diagnostic{classifySourceError(err, sourceID)}
|
||||
}
|
||||
if int64(len(data)) > limit {
|
||||
return sourceRead{info: info}, []Diagnostic{sourceDiagnostic(CodeSourceLimitExceeded, sourceID, "source exceeds the configured byte limit")}
|
||||
data, failure := readBoundedSource(input, limit)
|
||||
if failure != nil {
|
||||
return sourceRead{info: info}, []Diagnostic{sourceReadDiagnostic(failure, sourceID, CodeSourceLimitExceeded, "source exceeds the configured byte limit")}
|
||||
}
|
||||
return sourceRead{data: bytes.Clone(data), info: info}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user