mirror of
https://github.com/arkadiyt/protodump.git
synced 2026-10-23 18:49:38 +02:00
Compare commits
8
Commits
17ad807924
...
e5815840e4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e5815840e4 | ||
|
|
08f630f96e | ||
|
|
8b8af09dcb | ||
|
|
5930c3bfb5 | ||
|
|
e012331a33 | ||
|
|
6667d79d3b | ||
|
|
4d9ac25fb8 | ||
|
|
dcbafdb247 |
No files matched your search
@@ -1,4 +1,6 @@
|
||||
on: [push]
|
||||
on:
|
||||
- push
|
||||
- pull_request_target
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
+54
-5
@@ -6,6 +6,7 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/arkadiyt/protodump/pkg/protodump"
|
||||
@@ -20,6 +21,47 @@ func Debug(str string, a ...any) (int, error) {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
func writeFile(outputDir string, filename string, content []byte) (string, error) {
|
||||
outputDirAbs, err := filepath.Abs(outputDir)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("couldn't get absolute dir for %s: %v", outputDir, err)
|
||||
}
|
||||
|
||||
fileDir, fileBase := filepath.Split(filename)
|
||||
|
||||
parts := strings.Split(path.Clean(fileDir), string(filepath.Separator))
|
||||
var i int
|
||||
for i = 0; i < len(parts); i++ {
|
||||
_, err := os.Stat(filepath.Join(outputDirAbs, filepath.Join(parts[:i+1]...)))
|
||||
if os.IsNotExist(err) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
eval := filepath.Join(outputDirAbs, filepath.Join(parts[:i]...))
|
||||
base, err := filepath.EvalSymlinks(eval)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to evalsymlinks on %s: %v", eval, err)
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(base, outputDirAbs) {
|
||||
return "", fmt.Errorf("invalid filepath: %s", base)
|
||||
}
|
||||
|
||||
rest := filepath.Join(parts[i:]...)
|
||||
err = os.MkdirAll(filepath.Join(base, rest), 0700)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to mkdirall on %s: %v", rest, err)
|
||||
}
|
||||
|
||||
final := filepath.Join(base, rest, fileBase)
|
||||
err = os.WriteFile(final, content, 0700)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to write file %s: %v", final, err)
|
||||
}
|
||||
return final, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
@@ -42,18 +84,25 @@ func main() {
|
||||
log.Fatalf("Got error scanning: %v\n", err)
|
||||
}
|
||||
|
||||
err = os.MkdirAll(*output, 0700)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create output folder %s: %v\n", *output, err)
|
||||
}
|
||||
|
||||
for _, result := range results {
|
||||
definition, err := protodump.NewFromBytes(result)
|
||||
if err != nil {
|
||||
Debug("Got error parsing definition: %v\n", err)
|
||||
} else {
|
||||
|
||||
filename := definition.Filename()
|
||||
if strings.HasSuffix(filename, ".proto") {
|
||||
dir := path.Join(*output, path.Dir(filename))
|
||||
final := path.Join(dir, path.Base(filename))
|
||||
os.MkdirAll(dir, 0700)
|
||||
os.WriteFile(final, []byte(definition.String()), 0700)
|
||||
fmt.Printf("Wrote %s\n", final)
|
||||
final, err := writeFile(*output, filename, []byte(definition.String()))
|
||||
if err != nil {
|
||||
fmt.Printf("Failed to write %s: %v\n", final, err)
|
||||
} else {
|
||||
fmt.Printf("Wrote %s\n", final)
|
||||
}
|
||||
} else {
|
||||
// Need to investigate further
|
||||
}
|
||||
|
||||
+20
-4
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"google.golang.org/protobuf/encoding/protowire"
|
||||
)
|
||||
@@ -15,12 +16,22 @@ func consumeBytes(data []byte, position int) (int, error) {
|
||||
start := position
|
||||
consumedFieldOne := false
|
||||
for {
|
||||
number, _, len := protowire.ConsumeField(data[position:])
|
||||
if len < 0 {
|
||||
err := protowire.ParseError(len)
|
||||
number, _, length := protowire.ConsumeField(data[position:])
|
||||
if length < 0 {
|
||||
err := protowire.ParseError(length)
|
||||
// Treat "invalid field number" as end of data, not an error
|
||||
if strings.Contains(err.Error(), "invalid field number") {
|
||||
return position - start, nil
|
||||
}
|
||||
// Return other parse errors as actual errors
|
||||
return position - start, fmt.Errorf("couldn't consume proto bytes: %w", err)
|
||||
}
|
||||
|
||||
// Prevent infinite loop - if we can't consume any bytes, we're done
|
||||
if length == 0 {
|
||||
return position - start, nil
|
||||
}
|
||||
|
||||
// Only consume Field 1 once (to handle the case where protobuf definitions are adjacent
|
||||
// in program memory)
|
||||
if number == 1 {
|
||||
@@ -30,7 +41,12 @@ func consumeBytes(data []byte, position int) (int, error) {
|
||||
consumedFieldOne = true
|
||||
}
|
||||
|
||||
position += len
|
||||
position += length
|
||||
|
||||
// Additional safety check - don't read beyond data bounds
|
||||
if position-start >= len(data[start:]) {
|
||||
return position - start, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user