[前][次][番号順一覧][スレッド一覧]

ruby-changes:67773

From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Fri, 10 Sep 2021 20:01:51 +0900 (JST)
Subject: [ruby-changes:67773] 72a43d4a4b (master): include/ruby/internal/intern/marshal.h: add doxygen

https://git.ruby-lang.org/ruby.git/commit/?id=72a43d4a4b

From 72a43d4a4b6d4d41d15578b465bb393f6ed051ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?=
 <shyouhei@r...>
Date: Mon, 15 Mar 2021 10:04:43 +0900
Subject: include/ruby/internal/intern/marshal.h: add doxygen

Must not be a bad idea to improve documents. [ci skip]
---
 include/ruby/internal/intern/marshal.h | 81 +++++++++++++++++++++++++++++++++-
 1 file changed, 79 insertions(+), 2 deletions(-)

diff --git a/include/ruby/internal/intern/marshal.h b/include/ruby/internal/intern/marshal.h
index 1da025b..118d78a 100644
--- a/include/ruby/internal/intern/marshal.h
+++ b/include/ruby/internal/intern/marshal.h
@@ -26,8 +26,85 @@ https://github.com/ruby/ruby/blob/trunk/include/ruby/internal/intern/marshal.h#L26
 RBIMPL_SYMBOL_EXPORT_BEGIN()
 
 /* marshal.c */
-VALUE rb_marshal_dump(VALUE, VALUE);
-VALUE rb_marshal_load(VALUE);
+
+/**
+ * Serialises the  given object and  all its  referring objects, to  write them
+ * down to the passed port.
+ *
+ * @param[in]   obj               Target object to dump.
+ * @param[out]  port              IO-like destination buffer.
+ * @exception   rb_eTypeError     `obj` cannot be dumped for some reason.
+ * @exception   rb_eRuntimeError  `obj` was tampered during dumping.
+ * @exception   rb_eArgError      Traversal too deep.
+ * @return      The passed `port` as-is.
+ * @post        Serialised representation of `obj` is written to `port`.
+ * @note        `port` is basically an IO but StringIO is also possible.
+ */
+VALUE rb_marshal_dump(VALUE obj, VALUE port);
+
+/**
+ * Deserialises  a  previous output  of  rb_marshal_dump()  into a  network  of
+ * objects.
+ *
+ * @param[in,out]  port           Either IO or String.
+ * @exception      rb_eTypeError  `port` is in unexpected type.
+ * @exception      rb_eArgError   Contents of `port` is broken.
+ * @return         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.
+ * @warning        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.
+ * @warning        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.
+ */
+VALUE rb_marshal_load(VALUE port);
+
+/**
+ * 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.
+ *
+ * @param[in]  newclass       The class that needs conversion.
+ * @param[in]  oldclass       Old implementation of `newclass`.
+ * @param[in]  dumper         Function that converts `newclass` to `oldclass`.
+ * @param[in]  loader         Function that converts `oldclass` to `newclass`.
+ * @exception  rb_eTypeError  `newclass` has no allocator.
+ */
 void rb_marshal_define_compat(VALUE newclass, VALUE oldclass, VALUE (*dumper)(VALUE), VALUE (*loader)(VALUE, VALUE));
 
 RBIMPL_SYMBOL_EXPORT_END()
-- 
cgit v1.1


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]