I’m poking around in the 1.8.1 ext/ sources and I notice that there are
very, very few uses of rb_check_frozen. I expected to see the C extensions
calling rb_check_frozen before modifying them. What am I overlooking? Is
it just not necessary?
Tim Hunter wrote:
I’m poking around in the 1.8.1 ext/ sources and I notice that there are
very, very few uses of rb_check_frozen. I expected to see the C extensions
calling rb_check_frozen before modifying them. What am I overlooking? Is
it just not necessary?
Calling a C extension which uses rb_str_modify() and /not/ rb_check_frozen_p()
on a string that’s frozen before the call gives:
D:/ruby/DfB/rb6062.TMP:3:in `call’: can’t modify frozen string (TypeError)
No reason why that should be expected, though.
You could have two exts that do the same job – one causing a TypeError,
but not the other.
As a Ruby String points to a C string, it would easily be possible for
an ext just to overwrite part of the C string even if it had been frozen
but (you made me think) Ruby objects always are/should be modified via
the API rather than directly which allows Ruby to check things such as
/frozen/ status.
That may be a rule which just feels right to my narrow experience.
If I learned it, it was only a few moments ago.
I’d retract it if someone offered the glaring exception(s)
daz
Hi,
···
In message “freeze, frozen? in extensions” on 04/03/07, Tim Hunter cyclists@nc.rr.com writes:
I’m poking around in the 1.8.1 ext/ sources and I notice that there are
very, very few uses of rb_check_frozen. I expected to see the C extensions
calling rb_check_frozen before modifying them. What am I overlooking? Is
it just not necessary?
I encourage extension writers to add frozen/security check to their
extensions.
matz.
As a Ruby String points to a C string, it would easily be possible for
an ext just to overwrite part of the C string even if it had been frozen
but (you made me think) Ruby objects *always* are/should be modified via
the API rather than directly which allows Ruby to check things such as
/frozen/ status.
well, I can give you an exception. In plruby you have
vid = INT2NUM(typoid);
klass = rb_hash_aref(plruby_classes, vid);
if (NIL_P(klass)) {
klass = rb_hash_aref(plruby_conversions, vid);
if (NIL_P(klass)) {
st_insert(RHASH(plruby_classes)->tbl, vid, Qfalse);
}
else {
klass = rb_const_get(rb_cObject, NUM2INT(klass));
st_insert(RHASH(plruby_classes)->tbl, vid, klass);
}
}
It's trying to search if it exist a class associated with a postgres type,
to call a conversion method.
Now there is rb_hash_aref() but it use st_insert() rather than
rb_hash_aset(). The reason is simple, plruby can run with $SAFE >= 4 and
in this case ruby will give an error
svg% ruby -e 'a = {}; $SAFE = 4; a[12] = 24'
-e:1:in `=': Insecure: can't modify hash (SecurityError)
from -e:1
svg%
because I'm *sure* that it don't exist a security problem in this case it
use st_insert() rather than the standard API function to bypass the
security mechanism
Guy Decoux
Thanks, matz! I spent most of yesterday afternoon adding calls to
rb_check_frozen to my extension. Now I’m trying to add meaningful
implementations of dup and clone.
···
On Mon, 8 Mar 2004 13:04:12 +0900, matz@ruby-lang.org (Yukihiro Matsumoto) wrote:
I encourage extension writers to add frozen/security check to their
extensions.matz.
Today I see that I my original post was terse to the point of being
incomprehensible. What I was trying to ask was “How do I support the
freeze method in my C extension? That is, suppose a script calls the
freeze method on one of my objects, and then uses a method that modifies
that object. What should I do?”
I examined the Ruby sources and discovered the “rb_check_frozen” function.
This function tests the frozen state of the object and if the object is
frozen, raises a TypeError exception. So I suppose that every method in my
classes that modifies the object should call rb_check_frozen to make sure
the object isn’t frozen before proceeding. I poked around a bit in the
code that implements the built-in classes (for example, array.c) and see
that this seems to be the case.
To confirm my plan I started looking at the code for the standard
libraries that are written in C, but I saw very few calls to
rb_check_frozen. This makes me wonder, have I misunderstood how to support
frozen objects in C?
···
On Sun, 07 Mar 2004 23:49:09 +0900, ts wrote:
Now there is rb_hash_aref() but it use st_insert() rather than
rb_hash_aset(). The reason is simple, plruby can run with $SAFE >= 4
and in this case ruby will give an errorsvg% ruby -e ‘a = {}; $SAFE = 4; a[12] = 24’ -e:1:in `=': Insecure:
can’t modify hash (SecurityError)
from -e:1
svg%because I’m sure that it don’t exist a security problem in this case
it use st_insert() rather than the standard API function to bypass the
security mechanism
ts wrote:
As a Ruby String points to a C string, it would easily be possible for
an ext just to overwrite part of the C string even if it had been frozen
but (you made me think) Ruby objects always are/should be modified via
the API rather than directly which allows Ruby to check things such as
/frozen/ status.well, I can give you an exception. In plruby you have
vid = INT2NUM(typoid); klass = rb_hash_aref(plruby_classes, vid); if (NIL_P(klass)) { klass = rb_hash_aref(plruby_conversions, vid); if (NIL_P(klass)) { st_insert(RHASH(plruby_classes)->tbl, vid, Qfalse); } else { klass = rb_const_get(rb_cObject, NUM2INT(klass)); st_insert(RHASH(plruby_classes)->tbl, vid, klass); } }
It’s trying to search if it exist a class associated with a postgres type,
to call a conversion method.Now there is rb_hash_aref() but it use st_insert() rather than
rb_hash_aset(). The reason is simple, plruby can run with $SAFE >= 4 and
in this case ruby will give an errorsvg% ruby -e ‘a = {}; $SAFE = 4; a[12] = 24’
-e:1:in `=': Insecure: can’t modify hash (SecurityError)
from -e:1
svg%because I’m sure that it don’t exist a security problem in this case it
use st_insert() rather than the standard API function to bypass the
security mechanismGuy Decoux
I’m checking for holes in my life-boat.
3-)
daz
Today I see that I my original post was terse to the point of being
incomprehensible. What I was trying to ask was "How do I support the
freeze method in my C extension? That is, suppose a script calls the
freeze method on one of my objects, and then uses a method that modifies
that object. What should I do?"
raise an error.
To confirm my plan I started looking at the code for the standard
libraries that are written in C, but I saw very few calls to
rb_check_frozen. This makes me wonder, have I misunderstood how to support
frozen objects in C?
No, but like said previously by "daz" <dooby@d10.karoo.co.uk>, in many
case a C extension will use the standard API function and ruby will make
the test. Uf this is not the case add the test. For example, mmap has
svg% grep frozen mmap-0.2.4/*.c
rb_error_frozen("mmap"); \
if (t_mm->flag & MM_FROZEN) rb_error_frozen("mmap");
if (t_mm->flag & MM_FROZEN) rb_error_frozen("mmap");
rb_error_frozen("mmap");
if (str->flag & MM_FROZEN) rb_error_frozen("mmap");
svg%
Guy Decoux
Tim Hunter wrote:
To confirm my plan I started looking at the code for the standard
libraries that are written in C, but I saw very few calls to
rb_check_frozen. This makes me wonder, have I misunderstood how to support
frozen objects in C?
Did you look for use of the OBJ_FROZEN(obj) macro, also ?
daz
Good suggestion! I see it used in openssl and stringio.
···
On Sun, 07 Mar 2004 16:04:46 +0000, daz wrote:
Did you look for use of the OBJ_FROZEN(obj) macro, also ?
“ts” decoux@moulon.inra.fr schrieb im Newsbeitrag
news:200403071546.i27FkgK20961@moulon.inra.fr…
Today I see that I my original post was terse to the point of being
incomprehensible. What I was trying to ask was “How do I support the
freeze method in my C extension? That is, suppose a script calls the
freeze method on one of my objects, and then uses a method that
modifies
that object. What should I do?”raise an error.
To confirm my plan I started looking at the code for the standard
libraries that are written in C, but I saw very few calls to
rb_check_frozen. This makes me wonder, have I misunderstood how to
support
frozen objects in C?No, but like said previously by “daz” dooby@d10.karoo.co.uk, in many
case a C extension will use the standard API function and ruby will make
the test.
Wouldn’t it be more precise to say that those standard API methods will make
the test? I mean, the interpreter won’t know which methods are “const” and
which aren’t, but those methods will know.
Just my 0.02 EUR…
robert
"ts" <decoux@moulon.inra.fr> schrieb im Newsbeitrag
news:200403071546.i27FkgK20961@moulon.inra.fr...
case a C extension will use the standard API function and ruby will make
the test.
Wouldn't it be more precise to say that those standard API methods will make
the test? I mean, the interpreter won't know which methods are "const" and
which aren't, but those methods will know.
It depend what you call ruby
Guy Decoux