]> git.proxmox.com Git - pve-storage.git/commitdiff
storage plugins: en/decode volume notes as UTF-8
authorDominik Csapak <d.csapak@proxmox.com>
Wed, 9 Mar 2022 08:21:28 +0000 (09:21 +0100)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Tue, 26 Apr 2022 13:33:13 +0000 (15:33 +0200)
When writing into the file, explicitly utf8 encode it, and then try
to utf8 decode it on read.

If the notes are not valid utf8, we assume they were iso-8859 encoded
and return as is.

Technically this is a breaking change, since there are iso-8859
comments that would successfully decode as utf8, for example: the
byte sequence "C2 A9" would be "£" in iso, but would decode to "£".

From what i can tell though, this is rather unlikely to happen for
"real world" notes, because the first byte would be in the range of
C0-F7 (which are mostly language dependent characters like "Â") and
the following bytes would have to be in the range of 80-BF, which are
only special characters like "£" (or undefined)

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
PVE/Storage/DirPlugin.pm
PVE/Storage/Plugin.pm

index 1baad63aa8550032d738f6300ef4f5b8b5d2e150..53eb6423c32320691a833231538c0dd1b942a8d9 100644 (file)
@@ -4,6 +4,7 @@ use strict;
 use warnings;
 
 use Cwd;
+use Encode qw(decode encode);
 use File::Path;
 use IO::File;
 use POSIX;
@@ -104,7 +105,10 @@ sub get_volume_notes {
     my $path = $class->filesystem_path($scfg, $volname);
     $path .= $class->SUPER::NOTES_EXT;
 
-    return PVE::Tools::file_get_contents($path) if -f $path;
+    if (-f $path) {
+       my $data = PVE::Tools::file_get_contents($path);
+       return eval { decode('UTF-8', $data, 1) } // $data;
+    }
 
     return '';
 }
@@ -121,7 +125,8 @@ sub update_volume_notes {
     $path .= $class->SUPER::NOTES_EXT;
 
     if (defined($notes) && $notes ne '') {
-       PVE::Tools::file_set_contents($path, $notes);
+       my $encoded = encode('UTF-8', $notes);
+       PVE::Tools::file_set_contents($path, $encoded);
     } else {
        unlink $path or $! == ENOENT or die "could not delete notes - $!\n";
     }
index d2974ee0fea1282eda449c5876f592275caf2c98..0a100b7b05a257afa0aab65ae5f9260e9ad0a09a 100644 (file)
@@ -3,6 +3,7 @@ package PVE::Storage::Plugin;
 use strict;
 use warnings;
 
+use Encode qw(decode);
 use Fcntl ':mode';
 use File::chdir;
 use File::Path;
@@ -1197,7 +1198,7 @@ my $get_subdir_files = sub {
            my $notes_fn = $original.NOTES_EXT;
            if (-f $notes_fn) {
                my $notes = PVE::Tools::file_read_firstline($notes_fn);
-               $info->{notes} = $notes if defined($notes);
+               $info->{notes} = eval { decode('UTF-8', $notes, 1) } // $notes if defined($notes);
            }
 
            $info->{protected} = 1 if -e PVE::Storage::protection_file_path($original);