2

I want to replace "\\" from a bytestring sequence (Data.ByteString) with "\", but due to the internal escaping of "\" it won't work. Consider following example:

The original bytestring:

"\159\DEL*\150\222/\129vr\205\241=mA\192\184"

After storing in and re-reading from a database I obtain following bytestring:

 "\"\\159\\DEL*\\150\\222/\\129vr\\205\\241=mA\\192\\184\""

Imagine that the bytestring is used as a cryptographic key, which is now a wrong key due to the invalid characters in the sequence. This problem actually arises from the wrong database representation (varchar instead of bytea) because it's otherwise considered as an invalid utf-8 sequence. I have tried to replace the invalid characters using some sort of split-modify-concat approach, but all I get is something without any backslash inside the sequence, because I can't insert a single backslash into a bytestring.

I really ask for your help.

auermich
  • 130
  • 10
  • You want to replace a character by itself? I can't understand. Anyway, double check you are not using some escaping functions inadvertently, like `show`, which add unwanted escapes. – chi Jun 11 '16 at 12:20
  • How are you storing the string to the database? I think that's where your problem is. – ErikR Jun 11 '16 at 12:29
  • @ErikR True, but I think part of the purpose of this question is to repair the damage to strings already stored in the database. – chepner Jun 11 '16 at 12:50
  • Please edit your question. StackOverflow uses [markdown](https://en.wikipedia.org/wiki/Markdown), not plaintext, hence your backslash-containing strings aren't shown as intended. – leftaroundabout Jun 11 '16 at 12:58
  • strip of the start-end quotes and cast them to bytea – Jasen Jun 11 '16 at 13:02
  • The formatting is still wrong. – leftaroundabout Jun 11 '16 at 13:08
  • I have edited the question @leftaroundabout. I can't store it as bytea due to the invalid encoding. Moreover, it seems that storing it as SqlString and retrieving it - wich comes back as SqlByteString - achieves the "best" result, namely the aboved mentioned. – auermich Jun 11 '16 at 14:18
  • 1
    @chi, I am using show in order to obtain a string out of the bytestring. I have also tried to use the unpack function, but no different result. – auermich Jun 11 '16 at 14:23
  • show is meant to escape funny chars, unpack should keep the string as it is – chi Jun 11 '16 at 14:54
  • Actually the data is stored correctly in the database, but reading from the database doesn't work properly. There must be some bug in the 'fromSql' conversion function. It's even worse when you need to handle both lazy and strict bytestrings as strict bytestrings are only supported. – auermich Jun 11 '16 at 15:09

2 Answers2

0

possibly you want the postgresql expression

substring(ByteString from e'^\\"(.*)\\"$')::bytea

that will give a bytea result that can be used in queries or in an alter table-using DDL

Jasen
  • 11,837
  • 2
  • 30
  • 48
0

Perhaps using read will work for you:

import Data.ByteString.Char8 as BS

bad =  BS.pack "\"\\159\\DEL*\\150\\222/\\129vr\\205\\241=mA\\192\\184\""

good = read (BS.unpack bad) :: BS.ByteString

-- returns: "\159\DEL*\150\222/\129vr\205\241=mA\192\184"

You can also use readMaybe instead for safer parsing.

ErikR
  • 51,541
  • 9
  • 73
  • 124