#1111 ✓duplicate
robert

Marshal.dump string malformed after database save.

Reported by robert | October 28th, 2009 @ 03:11 AM

Hello,

I've looked into this, and I can only come to the conclusion that DataMapper is malforming the string returned by Marshal.dump() when saved to the database.

I've wrote a test case to reproduce this problem:

require 'dm-core'

class Session

include DataMapper::Resource

property :id, Serial property :dump, String, :length => 10_000

end

DataMapper.setup :default, "sqlite3://#{Dir.getwd}/out.sqlite"
DataMapper.auto_migrate!

class MyClass

def initialize

@foo = {}
@bar = {}

end

def dump

puts (dump = Marshal.dump(self)).inspect
Session.create :dump => dump

end

end

my = MyClass.new

dump() will print the string before it is saved to the database.

At this point, it looks like this:

"\x04\bo:\fMyClass\a:\t@foo{\x00:\t@bar{\x00"

my.dump

Lets see if we can load that dump

Yup, no problem.

Marshal.load "\x04\bo:\fMyClass\a:\t@foo{\x00:\t@bar{\x00"

Lets try to read that string from the database, but we get:

=> "\x04\bo:\fMyClass\a:\t@foo{"

puts (Session.first(:id => 1).dump).inspect

Malformed dump now, we can't load this.

=> Raises ArgumentError, Marshal data too short.

puts Marshal.load Session.first(:id => 1).dump

If @foo, and @bar aren't empty hashes, it works fine.

Comments and changes to this ticket

  • Xavier Shay

    Xavier Shay December 2nd, 2010 @ 11:48 PM

    • State changed from “new” to “confirmed”
    • Milestone order changed from “0” to “0”

    Confirmed. Problem is trying to store \x00 in a String type. (Currently Binary does nothing special, just creates a BLOB but still truncates at the null byte).

    require 'rubygems'
    require 'dm-core'
    require 'dm-migrations'
    
    DataMapper::Logger.new($stdout, :debug)
    DataMapper.setup(:default, 'sqlite3://:memory:') 
    
    class Session
    
      include DataMapper::Resource
    
      property :id, Serial 
      property :dump, Binary, :length => 10_000
    
    end
    Session.auto_migrate!
    
    class MyClass
    
      def initialize
        @foo = {}
        @bar = {}
      end
    
      def dump
        puts (dump = Marshal.dump(self)).inspect
        Session.create :dump => dump
      end
    
    end
    
    my = MyClass.new
    my.dump
    puts Session.first.dump.inspect
    puts Marshal.load( Session.first.dump)
    
  • Xavier Shay

    Xavier Shay December 2nd, 2010 @ 11:49 PM

    • State changed from “confirmed” to “duplicate”

    #1071, scheduled for 1.0.3, will fix this assuming you use the Binary type rather than String.

Please Sign in or create a free account to add a new ticket.

With your very own profile, you can contribute to projects, track your activity, watch tickets, receive and update tickets through your email and much more.

New-ticket Create new ticket

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

Pages