Subject: | $r->pnotes stores aliases not copies so is subject to action at a distance |
This code:
$x = 42;
$r->pnotes( 'foo', $x );
++$x;
warn $r->pnotes( 'foo', $x );
should print the value that was stored, 42, but it actually prints 43!
The value stored has been modified by action at a distance. *Not good*
This can cause some very hard to debug problems, where values stored in pnotes change for
no readily apparent reason. I know, I've spent way too long doing just that before I identified
this as the cause.
A workaround for affected code is to assign to a temporary variable so the alias taken by
pnotes isn't an alias for the orginal value:
$r->pnotes( 'foo', my $tmp = $x )
The minimal fix is to change:
hv_store(cfg->pnotes, key, len, SvREFCNT_inc(val), FALSE);
in pnotes in src/modules/perl/Apache.xs to something more like
SV **svp = hv_fetch(cfg->pnotes, key, len, TRUE);
sv_setsv(*svp, val);
with a little more work you could eliminate the earlier hv_exists and hv_fetch by doing
SV **svp = hv_fetch(cfg->pnotes, key, len, (val) ? TRUE : FALSE);
and working with svp.
Tim Bunce.