From fa9cf8c758d9dc8b3841edd813be68b8734642ac Mon Sep 17 00:00:00 2001 From: darioleanbit <62099044+darioleanbit@users.noreply.github.com> Date: Wed, 15 Mar 2023 14:33:08 +0100 Subject: [PATCH] SQLite: check for base64 for text content in blob If the SQLite driver returns the value of a blob column a string, don't make the assumption that the value is base64-encoded. Instead, check for actual base64 content by trying to decode the string as base64. See https://github.com/dimitri/pgloader/issues/415 . --- src/sources/sqlite/sqlite.lisp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/sources/sqlite/sqlite.lisp b/src/sources/sqlite/sqlite.lisp index 345dafb3..0798a174 100644 --- a/src/sources/sqlite/sqlite.lisp +++ b/src/sources/sqlite/sqlite.lisp @@ -4,6 +4,17 @@ (in-package :pgloader.source.sqlite) +(in-package :pgloader.source.sqlite) + +(declaim (inline has-base64-sequence-p)) + +;;; Return the decoded value of a base64 string, ignoring errors. +;;; Returns nil if the string doesn't contain a valid base64 string. +;;; +(defun has-base64-value-p (string) + (ignore-errors + (base64:base64-string-to-string string))) + ;;; Map a function to each row extracted from SQLite ;;; (declaim (inline parse-value)) @@ -20,10 +31,16 @@ (babel:octets-to-string value :encoding encoding)) ((and (string-equal "bytea" pgsql-type) + (has-base64-value-p value) (stringp value)) - ;; we expected bytes and got a string instead, must be base64 encoded + ;; we expected bytes and got a be base64 encoded, string instead (base64:base64-string-to-usb8-array value)) + ((and (string-equal "bytea" pgsql-type) + (stringp value)) + ;; we expected bytes and got a string instead, convert it to octets + (babel:string-to-octets value :encoding :utf-8)) + ;; default case, just use what's been given to us (t value)))