-
Notifications
You must be signed in to change notification settings - Fork 566
Closed
Labels
Description
First i must say i'm not sure where exactly the error happens.
Maybe it's the adapter or maybe it's ActiveRecord's serializer logic.
I've encountered this error on Rails 4.2 as well as in Rails 5.0.
Having a table with a text/nvarchar(max) column, let's call the column 'data' that's supposed to be serialized.
Migration for replication:
class CreateTestings < ActiveRecord::Migration[5.0]
def change
create_table :testings do |t|
t.text :data
end
end
end
Model
class Testing < ApplicationRecord
serialize :data
end
When having a Hash with a String value that ends in a backslash and at the same time more data after that line in the serialized YAML this will result in an exception making the record pretty much broken.
x = Testing.create(data:{ foo:'foo\\', bar:'bar' })
# SQL (0.0ms) BEGIN TRANSACTION
# SQL (0.0ms) EXEC sp_executesql N'INSERT INTO [testings] ([data]) OUTPUT INSERTED.[id] #VALUES (@0)', N'@0 nvarchar(max)', @0 = N'---
#:foo: foo\
#:bar: bar
#' [["data", "---\n:foo: foo\\\n:bar: bar\n"]]
# SQL (15.7ms) COMMIT TRANSACTION
#=> #<Testing id: 1, data: {:foo=>"foo\\", :bar=>"bar"}>
x.reload
Psych::SyntaxError: (<unknown>): mapping values are not allowed in this context at line 2 column 14
Looking into the database i see this was stored:
---\n:foo: foo:bar: bar\n
but actually there should be this:
---\n:foo: foo\\\n:bar: bar\n
Further tries
# will not trigger an exception will just lose the backslash
x = Testing.create(data:{ foo:'foo\\' })
# will not trigger an exception will just lose the last backslash, the first one will stay
x = Testing.create(data:{ foo:'foo\\\\' })
Any thoughts?