[PATCH pve-storage v1 07/54] common: prevent autovivification in plugin_get_vtype_subdir helper

Max R. Carrara
2026-04-22T11:14:00Z

When accessing a non-existing (or undefined) value in a hash(ref) and
using this value again for a hash lookup, i.e.
`$hashref->{foo}->{bar}` where `$hashref->{foo}` does not exist or is
`undef`, Perl will (un)conveniently instantiate a new hashref where
one was absent before. This is also called autovivification [0].

This means that if the config hash of directory-based storage plugin
that does *not* declare the 'content-dirs' property in its `options()`
is passed to `plugin_get_vtype_subdir()`, the 'content-dirs' key will
be instantiated as an empty hashref during the
`$scfg->{'content-dirs'}->{$vtype}` lookup.

Note that "directory-based storage plugin" means any storage plugin
that defines the 'path' property in its `options()` method.

While this is a minor issue, the `$scfg` hashref should IMO never be
modified unless necessary, or if the method actually is supposed to
modify it.

Therefore, prevent this autovivification [0] in
`plugin_get_vtype_subdir()`.

Additionally, use string concatenation instead of interpolation for
the returned subdirectory path.

[0]: https://perldoc.perl.org/perlref#Autovivification

Signed-off-by: Max R. Carrara <m.carrara@proxmox.com>
---
src/PVE/Storage/Common.pm | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/PVE/Storage/Common.pm b/src/PVE/Storage/Common.pm
index 52bd627d..abccf52b 100644
--- a/src/PVE/Storage/Common.pm
+++ b/src/PVE/Storage/Common.pm
@@ -330,9 +330,11 @@ sub plugin_get_vtype_subdir : prototype($$) ($scfg, $vtype) {
die "storage definition has no path\n" if !$path;
die "unknown vtype '$vtype'\n" if !exists($DEFAULT_VTYPE_SUBDIRS->{$vtype});

- my $subdir = $scfg->{"content-dirs"}->{$vtype} // $DEFAULT_VTYPE_SUBDIRS->{$vtype};
+ # Intermediate step to prevent autovivification
+ my $content_dirs = $scfg->{'content-dirs'} // {};
+ my $subdir = $content_dirs->{$vtype} // $DEFAULT_VTYPE_SUBDIRS->{$vtype};

- return "$path/$subdir";
+ return $path . '/' . $subdir;
}

1;
--
2.47.3