Escapar las comillas en psql para evitar las Inyecciones de SQL.
Estoy haciendo una función para comparar JSONs y luego insertar solo las diferencias en una tabla (trigger).
La función funciona perfectamente cuando ninguno de los registros viene con comillas. Entonces quiero saber cómo escapar estas comillas que pueden venir:
CREATE OR REPLACE FUNCTION public.fnc_compare_jsonb(old_reg jsonb, new_reg jsonb)
RETURNS jsonb
LANGUAGE plpgsql
IMMUTABLE STRICT
AS $function$
declare
keys record;
jsonb_return jsonb = '{}'::jsonb;
begin
for keys in
select *
from jsonb_object_keys($1)
loop
if $1 -> keys.jsonb_object_keys <> $2 -> keys.jsonb_object_keys then
jsonb_return = jsonb_return || format('{"%s": "%s"}', keys.jsonb_object_keys, $2 ->> keys.jsonb_object_keys)::jsonb;
end if;
end loop;
return jsonb_return;
end
$function$
;
El error está ocurriendo en la línea:
jsonb_return = jsonb_return || format('{"%s": "%s"}', keys.jsonb_object_keys, $2 ->> keys.jsonb_object_keys)::jsonb;
SQL Error [22P02]: ERROR: sintaxis de entrada no válida para el tipo json
Detalle: El token ""@" no es válido.
Donde: datos JSON, línea 1: {"email": "test2"@...
Función PL/pgSQL ecidadao.fnc_compare_jsonb(jsonb,jsonb) línea 11 en la asignación
davy.ai
Para escapar las comillas en los valores de cadena que pueden estar presentes en los objetos JSON de los parámetros de entrada, puedes utilizar la función incorporada
jsonb_set()
proporcionada por Postgres, que permite establecer un valor específico para una clave en un objeto JSON. En este caso, podemos usarla para reemplazar las comillas por sus versiones escapadas.Aquí tienes una versión actualizada de la función que incluye este cambio:
Los cambios realizados en la función son los siguientes:
new_reg_escaped
para almacenar el objeto JSON modificado con las comillas escapadas.new_reg
anew_reg_escaped
inicialmente, para crear una copia del objeto JSON original.new_reg_escaped
por la versión escapada utilizando la funciónreplace()
y concatenando con los caracteres necesarios para el formato JSON.jsonb_set()
para establecer el valor modificado en la misma clave del objetonew_reg_escaped
.new_reg_escaped
modificado.Con estos cambios, la función ahora debería poder manejar objetos JSON con valores de cadena que contienen comillas.