(
toolName string,
store media.MediaStore,
channel string,
chatID string,
dataURL string,
seen map[string]struct{},
)
| 176 | } |
| 177 | |
| 178 | func storeInlineDataURL( |
| 179 | toolName string, |
| 180 | store media.MediaStore, |
| 181 | channel string, |
| 182 | chatID string, |
| 183 | dataURL string, |
| 184 | seen map[string]struct{}, |
| 185 | ) (ref string, note string) { |
| 186 | dataURL = strings.TrimSpace(dataURL) |
| 187 | if _, ok := seen[dataURL]; ok { |
| 188 | return "", "" |
| 189 | } |
| 190 | seen[dataURL] = struct{}{} |
| 191 | |
| 192 | if !strings.HasPrefix(strings.ToLower(dataURL), "data:") { |
| 193 | return "", "" |
| 194 | } |
| 195 | |
| 196 | comma := strings.IndexByte(dataURL, ',') |
| 197 | if comma <= 5 { |
| 198 | return "", "[Tool returned inline media content that could not be parsed.]" |
| 199 | } |
| 200 | |
| 201 | metaPart := dataURL[:comma] |
| 202 | payload := dataURL[comma+1:] |
| 203 | if !strings.Contains(strings.ToLower(metaPart), ";base64") { |
| 204 | return "", "[Tool returned inline media content that was not base64-encoded.]" |
| 205 | } |
| 206 | |
| 207 | mimeType := strings.TrimSpace(strings.TrimPrefix(metaPart, "data:")) |
| 208 | if semi := strings.IndexByte(mimeType, ';'); semi >= 0 { |
| 209 | mimeType = mimeType[:semi] |
| 210 | } |
| 211 | if mimeType == "" { |
| 212 | mimeType = "application/octet-stream" |
| 213 | } |
| 214 | |
| 215 | payload = strings.NewReplacer("\n", "", "\r", "", "\t", "", " ", "").Replace(payload) |
| 216 | decoded, err := base64.StdEncoding.DecodeString(payload) |
| 217 | if err != nil { |
| 218 | return "", fmt.Sprintf("[Tool returned inline media content (%s) that could not be decoded.]", mimeType) |
| 219 | } |
| 220 | |
| 221 | dir := media.TempDir() |
| 222 | if err = os.MkdirAll(dir, 0o700); err != nil { |
| 223 | return "", fmt.Sprintf("[Tool returned inline media content (%s) but it could not be stored.]", mimeType) |
| 224 | } |
| 225 | |
| 226 | ext := extensionForMIMEType(mimeType) |
| 227 | tmpFile, err := os.CreateTemp(dir, "tool-inline-*"+ext) |
| 228 | if err != nil { |
| 229 | return "", fmt.Sprintf("[Tool returned inline media content (%s) but it could not be stored.]", mimeType) |
| 230 | } |
| 231 | tmpPath := tmpFile.Name() |
| 232 | if _, err = tmpFile.Write(decoded); err != nil { |
| 233 | _ = tmpFile.Close() |
| 234 | _ = os.Remove(tmpPath) |
| 235 | return "", fmt.Sprintf("[Tool returned inline media content (%s) but it could not be stored.]", mimeType) |
no test coverage detected