Perl:为标量重新分配新值是否会覆盖 RAM 中的当前内容?

发布于 2024-11-27 14:50:30 字数 166 浏览 8 评论 0原文

我正在使用 Perl 执行与安全相关的任务,并且想知道何时执行诸如

$test = "new value"

之类的语句,是 $test 的旧值> 在 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

几味少女 2024-12-04 14:50:30

如果标量不是神奇的并且它有一个字符串缓冲区并且该字符串适合字符串缓冲区,那么字符串缓冲区的该部分将被覆盖。

请注意,

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

在标量缓冲区中留下“xxx\0ef\0”。您需要缓冲区的长度,而不是缓冲区内字符串的长度。

我的意思是说,两者都

$s = undef;
$s = 123;

不会影响字符串缓冲区。它甚至不会被释放。同样,将字符串分配给标量不会影响标量的其他字段,例如保存数字的字段。


我忘记了,如果分配给标量的字符串是 TEMP,则目标的缓冲区将被替换而不是被覆盖。

>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

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
热情消退 2024-12-04 14:50:30

您可以使用 Devel::Peek 模块来回答此类问题:

use Devel::Peek;

my $test = "value";
Dump($test);
$test = "new value";
Dump($test);

在本例中你会得到:

SV = PV(0x297c04) at 0x187b9ac
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x18751cc "value"\0
  CUR = 5
  LEN = 12
SV = PV(0x297c04) at 0x187b9ac
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x18751cc "new value"\0
  CUR = 9
  LEN = 12

很容易看出在这种情况下地址保持不变。正如其他人指出的,如果您的字符串比缓冲区 LEN 长,数据将被重新分配:

my $test = "value";
Dump($test);
$test = "new value that is much longer";
Dump($test);

收益(请参阅 PV 旁边的指针已更改):

SV = PV(0x297c04) at 0x187b9ac
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x18751cc "value"\0
  CUR = 5
  LEN = 12
SV = PV(0x297c04) at 0x187b9ac
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x187cf74 "new value that is much longer"\0
  CUR = 29
  LEN = 32

You can use Devel::Peek module to answer this kind of questions:

use Devel::Peek;

my $test = "value";
Dump($test);
$test = "new value";
Dump($test);

In this case you get:

SV = PV(0x297c04) at 0x187b9ac
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x18751cc "value"\0
  CUR = 5
  LEN = 12
SV = PV(0x297c04) at 0x187b9ac
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x18751cc "new value"\0
  CUR = 9
  LEN = 12

It can be easily seen that address in this case remained the same. As others noted, if your string is longer than buffers LEN, the data will be reallocated:

my $test = "value";
Dump($test);
$test = "new value that is much longer";
Dump($test);

yields (see that pointer next to PV changed):

SV = PV(0x297c04) at 0x187b9ac
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x18751cc "value"\0
  CUR = 5
  LEN = 12
SV = PV(0x297c04) at 0x187b9ac
  REFCNT = 1
  FLAGS = (PADMY,POK,pPOK)
  PV = 0x187cf74 "new value that is much longer"\0
  CUR = 29
  LEN = 32
毁我热情 2024-12-04 14:50:30

我认为这取决于 $test 之前的值是什么。

例如,如果新值更长,perl 将必须调用 realloc() (或类似的东西),这可以更改字符串的存储位置。

一般来说,perl 字符串操作似乎在可能的情况下使用相同的内存,尽管我认为这不能得到保证。

您可以获取标量 unpack('J', pack('P', $s)) 的字符串缓冲区的地址。如果标量不包含字符串(即使它有字符串缓冲区),则这不起作用。

I think it depends on what the previous value of $test was.

If, for instance, the new value is longer, perl will have to call realloc() (or something similar) which can change where the string is stored.

In general, the perl string operations seem to use the same memory when possible, although I don't think this is guaranteed.

You can get the address of the string buffer of a scalar unpack('J', pack('P', $s)). This doesn't work if the scalar doesn't contain a string (even if it has a string buffer).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文