Change 27028 by [EMAIL PROTECTED] on 2006/01/31 22:59:27

        Make Perl_gv_fetchpvn_flags actually heed the passed in length.
        This means that \0 bytes in symbolic references now work.

Affected files ...

... //depot/perl/doio.c#315 edit
... //depot/perl/gv.c#290 edit
... //depot/perl/perl.c#711 edit
... //depot/perl/t/op/ref.t#29 edit
... //depot/perl/toke.c#638 edit

Differences ...

==== //depot/perl/doio.c#315 (text) ====
Index: perl/doio.c
--- perl/doio.c#314~26989~      2006-01-28 09:46:56.000000000 -0800
+++ perl/doio.c 2006-01-31 14:59:27.000000000 -0800
@@ -336,7 +336,7 @@
                        }
                        else {
                            GV *thatgv;
-                           thatgv = gv_fetchpvn_flags(type, type-tend,
+                           thatgv = gv_fetchpvn_flags(type, tend - type,
                                                       0, SVt_PVIO);
                            thatio = GvIO(thatgv);
                        }

==== //depot/perl/gv.c#290 (text) ====
Index: perl/gv.c
--- perl/gv.c#289~26980~        2006-01-28 06:02:10.000000000 -0800
+++ perl/gv.c   2006-01-31 14:59:27.000000000 -0800
@@ -758,27 +758,28 @@
     register GV *gv = NULL;
     GV**gvp;
     I32 len;
-    register const char *namend;
+    register const char *name_cursor;
     HV *stash = NULL;
     const I32 no_init = flags & (GV_NOADD_NOINIT | GV_NOINIT);
     const I32 no_expand = flags & GV_NOEXPAND;
     const I32 add = flags & ~SVf_UTF8 & ~GV_NOADD_NOINIT & ~GV_NOEXPAND;
-
-    PERL_UNUSED_ARG(full_len);
+    const char *const name_end = nambeg + full_len;
+    const char *const name_em1 = name_end - 1;
 
     if (*name == '*' && isALPHA(name[1])) /* accidental stringify on a GV? */
        name++;
 
-    for (namend = name; *namend; namend++) {
-       if ((*namend == ':' && namend[1] == ':')
-           || (*namend == '\'' && namend[1]))
+    for (name_cursor = name; name_cursor < name_end; name_cursor++) {
+       if ((*name_cursor == ':' && name_cursor < name_em1
+            && name_cursor[1] == ':')
+           || (*name_cursor == '\'' && name_cursor[1]))
        {
            if (!stash)
                stash = PL_defstash;
            if (!stash || !SvREFCNT(stash)) /* symbol table under destruction */
                return Nullgv;
 
-           len = namend - name;
+           len = name_cursor - name;
            if (len > 0) {
                char smallbuf[128];
                char *tmpbuf;
@@ -808,18 +809,18 @@
                    stash = GvHV(gv) = newHV();
 
                if (!HvNAME_get(stash))
-                   hv_name_set(stash, nambeg, namend - nambeg, 0);
+                   hv_name_set(stash, nambeg, name_cursor - nambeg, 0);
            }
 
-           if (*namend == ':')
-               namend++;
-           namend++;
-           name = namend;
+           if (*name_cursor == ':')
+               name_cursor++;
+           name_cursor++;
+           name = name_cursor;
            if (!*name)
                return gv ? gv : (GV*)*hv_fetchs(PL_defstash, "main::", TRUE);
        }
     }
-    len = namend - name;
+    len = name_cursor - name;
 
     /* No stash in name, so see how we can default */
 

==== //depot/perl/perl.c#711 (text) ====
Index: perl/perl.c
--- perl/perl.c#710~27000~      2006-01-30 04:59:12.000000000 -0800
+++ perl/perl.c 2006-01-31 14:59:27.000000000 -0800
@@ -4539,9 +4539,9 @@
                break;
            }
            if ((s = strchr(argv[0], '='))) {
-               *s = '\0';
-               sv_setpv(GvSV(gv_fetchpv(argv[0] + 1, TRUE, SVt_PV)), s + 1);
-               *s = '=';
+               const char *const start_name = argv[0] + 1;
+               sv_setpv(GvSV(gv_fetchpvn_flags(start_name, s - start_name,
+                                               TRUE, SVt_PV)), s + 1);
            }
            else
                sv_setiv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),1);

==== //depot/perl/t/op/ref.t#29 (xtext) ====
Index: perl/t/op/ref.t
--- perl/t/op/ref.t#28~26280~   2005-12-06 08:53:46.000000000 -0800
+++ perl/t/op/ref.t     2006-01-31 14:59:27.000000000 -0800
@@ -423,9 +423,8 @@
 
     is ($$name1, undef, 'Nothing before we start');
     is ($$name2, undef, 'Nothing before we start');
-    $$name2 = "Yummy";
+    $$name1 = "Yummy";
     is ($$name1, "Yummy", 'Accessing via the correct name works');
-    local $TODO = "NUL bytes truncate in symrefs";
     is ($$name2, undef,
        'Accessing via a different NUL-containing name gives nothing');
 }

==== //depot/perl/toke.c#638 (text) ====
Index: perl/toke.c
--- perl/toke.c#637~27006~      2006-01-30 08:50:38.000000000 -0800
+++ perl/toke.c 2006-01-31 14:59:27.000000000 -0800
@@ -4296,7 +4296,6 @@
                    gvp = 0;
                }
                else {
-                   len = 0;
                    if (!gv) {
                        /* Mustn't actually add anything to a symbol table.
                           But also don't want to "initialise" any placeholder
@@ -4305,6 +4304,7 @@
                        gv = gv_fetchpvn_flags(PL_tokenbuf, len,
                                               GV_NOADD_NOINIT, SVt_PVCV);
                    }
+                   len = 0;
                }
 
                /* if we saw a global override before, get the right name */
@@ -4450,7 +4450,7 @@
 
                    /* Resolve to GV now. */
                    if (SvTYPE(gv) != SVt_PVGV) {
-                       gv = gv_fetchpvn_flags(PL_tokenbuf, len, 0, SVt_PVCV);
+                       gv = gv_fetchpv(PL_tokenbuf, 0, SVt_PVCV);
                        assert (SvTYPE(gv) == SVt_PVGV);
                        /* cv must have been some sort of placeholder, so
                           now needs replacing with a real code reference.  */
End of Patch.

Reply via email to