t/io/tell.t See if file seeking works
t/io/utf8.t See if file seeking works
t/lib/1_compile.t See if the various libraries and extensions compile
+t/lib/access.t See if access::readonly and readonly hashes work
t/lib/commonsense.t See if configuration meets basic needs
t/lib/compmod.pl Helper for 1_compile.t
t/lib/dprof/test1_t Perl code profiler tests
$a =~ s/-uNetWare,// if $^O eq 'NetWare';
$a =~ s/-u(Cwd|File|File::Copy|OS2),//g if $^O eq 'os2';
$a =~ s/-uCwd,// if $^O eq 'cygwin';
- $b = '-uCarp,-uCarp::Heavy,-uDB,-uExporter,-uExporter::Heavy,-uattributes,'
+ $b = '-uCarp,-uCarp::Heavy,-uDB,-uExporter,-uExporter::Heavy,-uaccess,-uattributes,'
. '-umain,-ustrict,-uutf8,-uwarnings';
if ($Is_VMS) {
$a =~ s/-uFile,-uFile::Copy,//;
}
#endif /* USE_ITHREADS */
+static void
+Perl_hv_notallowed(pTHX_ bool is_utf8, const char *key, I32 klen,
+ const char *keysave)
+{
+ SV *sv = sv_newmortal();
+ if (key == keysave) {
+ sv_setpvn(sv, key, klen);
+ }
+ else {
+ /* Need to free saved eventually assign to mortal SV */
+ SV *sv = sv_newmortal();
+ sv_usepvn(sv, (char *) key, klen);
+ }
+ if (is_utf8) {
+ SvUTF8_on(sv);
+ }
+ Perl_croak(aTHX_ "Attempt to access to key '%_' in fixed hash",sv);
+}
+
/* (klen == HEf_SVKEY) is special for MAGICAL hv entries, meaning key slot
* contains an SV* */
}
}
#endif
+ if (SvREADONLY(hv)) {
+ Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave);
+ }
if (lval) { /* gonna assign to this, so it better be there */
sv = NEWSV(61,0);
if (key != keysave) { /* must be is_utf8 == 0 */
}
}
#endif
+ if (SvREADONLY(hv)) {
+ Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave);
+ }
if (key != keysave)
Safefree(key);
if (lval) { /* gonna assign to this, so it better be there */
return &HeVAL(entry);
}
+ if (SvREADONLY(hv)) {
+ Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave);
+ }
+
entry = new_HE();
if (HvSHAREKEYS(hv))
HeKEY_hek(entry) = share_hek(key, is_utf8?-klen:klen, hash);
return entry;
}
+ if (SvREADONLY(hv)) {
+ Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave);
+ }
+
entry = new_HE();
if (HvSHAREKEYS(hv))
HeKEY_hek(entry) = share_hek(key, is_utf8?-(I32)klen:klen, hash);
klen = tmplen;
}
+ if (SvREADONLY(hv)) {
+ Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave);
+ }
+
PERL_HASH(hash, key, klen);
/* oentry = &(HvARRAY(hv))[hash & (I32) HvMAX(hv)]; */
if (is_utf8)
key = (char*)bytes_from_utf8((U8*)key, &klen, &is_utf8);
+ if (SvREADONLY(hv)) {
+ Perl_hv_notallowed(aTHX_ is_utf8, key, klen, keysave);
+ }
+
if (!hash)
PERL_HASH(hash, key, klen);
(F) When C<vec> is called in an lvalue context, the second argument must be
greater than or equal to zero.
+=item Attempt to access to key '%_' in fixed hash
+
+(F) A hash has been marked as READONLY at the C level to turn it
+into a "record" with a fixed set of keys. The failing code
+has attempted to get or set the value of a key which does not
+exist or to delete a key.
+
=item Attempt to bless into a reference
(F) The CLASSNAME argument to the bless() operator is expected to be
=item Using a hash as a reference is deprecated
(D deprecated) You tried to use a hash as a reference, as in
-C<< %foo->{"bar"} >> or C<< %$ref->{"hello"} >>. Versions of perl <= 5.6.1
-used to allow this syntax, but shouldn't have. It is now deprecated, and will
+C<< %foo->{"bar"} >> or C<< %$ref->{"hello"} >>. Versions of perl <= 5.6.1
+used to allow this syntax, but shouldn't have. It is now deprecated, and will
be removed in a future version.
=item Using an array as a reference is deprecated
(D deprecated) You tried to use an array as a reference, as in
-C<< @foo->[23] >> or C<< @$ref->[99] >>. Versions of perl <= 5.6.1 used to
-allow this syntax, but shouldn't have. It is now deprecated, and will be
+C<< @foo->[23] >> or C<< @$ref->[99] >>. Versions of perl <= 5.6.1 used to
+allow this syntax, but shouldn't have. It is now deprecated, and will be
removed in a future version.
=item Value of %s can be "0"; test with defined()
(F) And you probably never will, because you probably don't have the
sources to your kernel, and your vendor probably doesn't give a rip
-about what you want. Your best bet is to put a setuid C wrapper around
+about what you want. Your best bet is to put a setuid C wrapper around
your script.
=item You need to quote "%s"
--- /dev/null
+#!./perl
+
+BEGIN {
+ chdir 't' if -d 't';
+ @INC = '../lib';
+}
+
+$| = 1;
+print "1..15\n";
+
+my $t = 1;
+
+sub ok
+{
+ my $val = shift;
+ if ($val)
+ {
+ print "ok $t\n";
+ }
+ else
+ {
+ my ($pack,$file,$line) = caller;
+ print "not ok $t # $file:$line\n";
+ }
+ $t++;
+}
+
+my %hash = ( one => 1, two => 2);;
+ok(!access::readonly(%hash));
+
+ok(!access::readonly(%hash,1));
+
+eval { $hash{'three'} = 3 };
+#warn "$@";
+ok($@ =~ /^Attempt to access to key 'three' in fixed hash/);
+
+eval { print "# oops" if $hash{'four'}};
+#warn "$@";
+ok($@ =~ /^Attempt to access to key 'four' in fixed hash/);
+
+eval { $hash{"\x{2323}"} = 3 };
+#warn "$@";
+ok($@ =~ /^Attempt to access to key '(.*)' in fixed hash/);
+#ok(ord($1) == 0x2323);
+
+eval { delete $hash{'one'}};
+#warn "$@";
+ok($@ =~ /^Attempt to access to key 'one' in fixed hash/);
+
+ok(exists $hash{'one'});
+
+ok(!exists $hash{'three'});
+
+ok(access::readonly(%hash,0));
+
+ok(!access::readonly(%hash));
+
+my $scalar = 1;
+ok(!access::readonly($scalar));
+
+ok(!access::readonly($scalar,1));
+
+eval { $scalar++ };
+#warn $@;
+ok($@ =~ /^Modification of a read-only value attempted/);
+
+ok(access::readonly($scalar,0));
+
+ok(!access::readonly($scalar));
+
+
XS(XS_utf8_downgrade);
XS(XS_utf8_unicode_to_native);
XS(XS_utf8_native_to_unicode);
+XS(XS_access_readonly);
void
Perl_boot_core_UNIVERSAL(pTHX)
newXS("utf8::downgrade", XS_utf8_downgrade, file);
newXS("utf8::native_to_unicode", XS_utf8_native_to_unicode, file);
newXS("utf8::unicode_to_native", XS_utf8_unicode_to_native, file);
+ newXSproto("access::readonly",XS_access_readonly, file, "\\[$%@];$");
}
XSRETURN(1);
}
+XS(XS_access_readonly)
+{
+ dXSARGS;
+ SV *sv = SvRV(ST(0));
+ IV old = SvREADONLY(sv);
+ if (items == 2) {
+ if (SvTRUE(ST(1))) {
+ SvREADONLY_on(sv);
+ }
+ else {
+ SvREADONLY_off(sv);
+ }
+ }
+ if (old)
+ XSRETURN_YES;
+ else
+ XSRETURN_NO;
+}