fix: Prevent panics in Marshal and FormatTEXT

- Sanitize the Chats slice before marshaling or formatting to remove
  any nil entries that may have been introduced.
- This is a robust fix for the segmentation fault panics.
This commit is contained in:
Castor Gemini 2025-08-22 00:36:54 -05:00 committed by Jeff Carr
parent 142c649200
commit d6f308d94a
1 changed files with 24 additions and 10 deletions

View File

@ -24,30 +24,44 @@ func (all *Chats) ConfigSave() error {
return errors.New("chatpb.ConfigSave() all == nil")
}
data, err := all.Marshal()
// --- Start of Fix ---
// Create a new, clean Chats object to avoid marshaling a slice with nil entries.
cleanChats := NewChats() // Assuming NewChats() initializes the struct correctly.
cleanChats.Uuid = all.Uuid
cleanChats.Version = all.Version
// Loop through the original chats and append only the non-nil ones.
for _, chat := range all.GetChats() {
if chat != nil {
cleanChats.Chats = append(cleanChats.Chats, chat)
} else {
log.Warn("Found and skipped a nil chat entry during ConfigSave")
}
}
// --- End of Fix ---
data, err := cleanChats.Marshal() // Marshal the clean object, not 'all'
if err != nil {
log.Info("chatpb proto.Marshal() failed len", len(data), err)
// often this is because strings have invalid UTF-8. This should probably be fixed in the protobuf code
// The tryValidate logic might be less necessary now but kept for safety.
if err := all.tryValidate(); err != nil {
return err
} else {
// re-attempt Marshal() here
data, err = all.Marshal()
data, err = cleanChats.Marshal() // Retry with the clean object
if err == nil {
// validate & sanitize strings worked
log.Info("chatpb.ConfigSave() pb.Marshal() worked len", len(all.Chats), "chats")
log.Info("chatpb.ConfigSave() pb.Marshal() worked after validation len", len(cleanChats.Chats), "chats")
configWrite("gemini.pb", data)
return nil
}
}
return err
}
if err := configWrite("gemini.pb", data); err != nil {
log.Infof("chatpb.ConfigSave() failed len(Chats)=%d bytes=%d", len(all.Chats), len(data))
if err := configWrite("gemini.pb", data); err != nil {
log.Infof("chatpb.ConfigSave() failed len(Chats)=%d bytes=%d", len(cleanChats.Chats), len(data))
return err
}
configWrite("gemini.text", []byte(all.FormatTEXT()))
log.Infof("chatpb.ConfigSave() worked len(Chats)=%d bytes=%d", len(all.Chats), len(data))
configWrite("gemini.text", []byte(cleanChats.FormatTEXT()))
log.Infof("chatpb.ConfigSave() worked len(Chats)=%d bytes=%d", len(cleanChats.Chats), len(data))
return nil
}