Search code examples
perlvariablesscalardata-persistence

Perl: does reassigning a new value to a scalar overwrite its current contents in RAM?


I'm using Perl for a security-related task and am wondering when a statement such as:

$test = "new value"

is executed, is the old value that $test created overwritten in RAM?

If not, is there a way to force that to happen?


Solution

  • If the scalar isn't magical and it has a string buffer and the string fits in the string buffer, then that portion of the string buffer will be overwritten.

    Note that

    $s = "abcdef";
    $s =~ s/...//;
    $s = "x" x length($s);
    

    leaves "xxx\0ef\0" in the scalar's buffer. You want the buffer's length, and not the length of the string inside the buffer.

    I meant to say that neither of

    $s = undef;
    $s = 123;
    

    will affect the string buffer whatsoever. It won't even be deallocated. Similarly, assigning a string to a scalar will not affect the other fields of the scalar, such as fields to hold numbers.


    I forgot that if string being assigned to the scalar is a TEMP, the buffer of the target is replaced instead of being overwritten.

    >perl -MDevel::Peek -e"my $s = 'abc'; Dump($s); $s = 'X' x length($s); Dump($s);"
    SV = PV(0x348d54) at 0x1d3927c
      REFCNT = 1
      FLAGS = (PADMY,POK,pPOK)
      PV = 0x349fac "abc"\0
      CUR = 3
      LEN = 12
    SV = PV(0x348d54) at 0x1d3927c
      REFCNT = 1
      FLAGS = (PADMY,POK,pPOK)
      PV = 0x349fac "XXX"\0     <-- same address
      CUR = 3
      LEN = 12
    
    >perl -MDevel::Peek -e"my $s = 'abc'; Dump($s); $s = sub { 'X' x length($s); }->(); Dump($s);"
    SV = PV(0x38d54) at 0x1c3930c
      REFCNT = 1
      FLAGS = (PADMY,POK,pPOK)
      PV = 0x39fac "abc"\0
      CUR = 3
      LEN = 12
    SV = PV(0x38d54) at 0x1c3930c
      REFCNT = 1
      FLAGS = (PADMY,POK,pPOK)
      PV = 0x1c603fc "XXX"\0     <-- different address
      CUR = 3                        No overwriting.
      LEN = 12