Ruby  3.4.0dev (2024-11-22 revision 0989400a925cd201defdca9eb28eb87200b30785)
Functions
marshal.h File Reference

(0989400a925cd201defdca9eb28eb87200b30785)

Public APIs related to rb_mMarshal. More...

#include "ruby/internal/dllexport.h"
#include "ruby/internal/value.h"
Include dependency graph for marshal.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

VALUE rb_marshal_dump (VALUE obj, VALUE port)
 Serialises the given object and all its referring objects, to write them down to the passed port. More...
 
VALUE rb_marshal_load (VALUE port)
 Deserialises a previous output of rb_marshal_dump() into a network of objects. More...
 
void rb_marshal_define_compat (VALUE newclass, VALUE oldclass, VALUE(*dumper)(VALUE), VALUE(*loader)(VALUE, VALUE))
 Marshal format compatibility layer. More...
 

Detailed Description

Public APIs related to rb_mMarshal.

Author
Ruby developers ruby-.nosp@m.core.nosp@m.@ruby.nosp@m.-lan.nosp@m.g.org
Warning
Symbols prefixed with either RBIMPL or rbimpl are implementation details. Don't take them as canon. They could rapidly appear then vanish. The name (path) of this header file is also an implementation detail. Do not expect it to persist at the place it is now. Developers are free to move it anywhere anytime at will.
Note
To ruby-core: remember that this header can be possibly recursively included from extension libraries written in C++. Do not expect for instance __VA_ARGS__ is always available. We assume C99 for ruby itself but we don't assume languages of extension libraries. They could be written in C++98.

Definition in file marshal.h.

Function Documentation

◆ rb_marshal_define_compat()

void rb_marshal_define_compat ( VALUE  newclass,
VALUE  oldclass,
VALUE(*)(VALUE dumper,
VALUE(*)(VALUE, VALUE loader 
)

Marshal format compatibility layer.

Over time, classes evolve, so that their internal data structure change drastically. For instance an instance of rb_cRange was made of RUBY_T_OBJECT in 1.x., but in 3.x it is a RUBY_T_STRUCT now. In order to keep binary compatibility, we "fake" the marshalled representation to stick to old types. This is the API to enable that manoeuvre. Here is how:

First, because you are going to keep backwards compatibility, you need to retain the old implementation of your class. Rename it, and keep the class somewhere (for instance rb_register_global_address() could help). Next create your new class. Do whatever you want.

Then, this is the key point. Create two new "bridge" functions that convert the structs back and forth:

  • the "dumper" function that takes an instance of the new class, and returns an instance of the old one. This is called from rb_marshal_dump(), to keep it possible for old programs to read your new data.
  • the "loader" function that takes two arguments, new one and old one, in that order. rb_marshal_load() calls this function when it finds a representation of the retained old class. The old one passed to this function is the reconstructed instance of the old class. Reverse-engineer that to modify the new one, to have the identical contents.

Finally, connect all of them using this function.

Parameters
[in]newclassThe class that needs conversion.
[in]oldclassOld implementation of newclass.
[in]dumperFunction that converts newclass to oldclass.
[in]loaderFunction that converts oldclass to newclass.
Exceptions
rb_eTypeErrornewclass has no allocator.

Definition at line 134 of file marshal.c.

◆ rb_marshal_dump()

VALUE rb_marshal_dump ( VALUE  obj,
VALUE  port 
)

Serialises the given object and all its referring objects, to write them down to the passed port.

Parameters
[in]objTarget object to dump.
[out]portIO-like destination buffer.
Exceptions
rb_eTypeErrorobj cannot be dumped for some reason.
rb_eRuntimeErrorobj was tampered during dumping.
rb_eArgErrorTraversal too deep.
Returns
The passed port as-is.
Postcondition
Serialised representation of obj is written to port.
Note
port is basically an IO but StringIO is also possible.

Definition at line 2585 of file marshal.c.

◆ rb_marshal_load()

VALUE rb_marshal_load ( VALUE  port)

Deserialises a previous output of rb_marshal_dump() into a network of objects.

Parameters
[in,out]portEither IO or String.
Exceptions
rb_eTypeErrorport is in unexpected type.
rb_eArgErrorContents of port is broken.
Returns
Object(s) rebuilt using the info from port.

SECURITY CONSIDERATIONS

Warning
By design, rb_marshal_load() can deserialise almost any class loaded into the Ruby process. In many cases this can lead to remote code execution if the Marshal data is loaded from an untrusted source.
As a result, rb_marshal_load() is not suitable as a general purpose serialisation format and you should never unmarshal user supplied input or other untrusted data.
If you need to deserialise untrusted data, use JSON or another serialisation format that is only able to load simple, 'primitive' types such as String, Array, Hash, etc. Never allow user input to specify arbitrary types to deserialise into.

Definition at line 2591 of file marshal.c.