[Libguestfs] [PATCH] df: Correctly quote libvirt domain and filesystem in --csv mode (RHBZ#639986).

Richard W.M. Jones rjones at redhat.com
Mon Oct 18 13:20:46 UTC 2010


-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
libguestfs lets you edit virtual machines.  Supports shell scripting,
bindings from many languages.  http://et.redhat.com/~rjones/libguestfs/
See what it can do: http://et.redhat.com/~rjones/libguestfs/recipes.html
-------------- next part --------------
>From f7475ec577b7ca810185e0fd70a39ac9adaae620 Mon Sep 17 00:00:00 2001
From: Richard W.M. Jones <rjones at redhat.com>
Date: Mon, 18 Oct 2010 14:18:58 +0100
Subject: [PATCH] df: Correctly quote libvirt domain and filesystem in --csv mode (RHBZ#639986).

This fixes virt-df --csv when used with libvirt domains that contain
quotes, spaces, commas and other lesser-used characters.
---
 tools/virt-df |   32 +++++++++++++++++++++++++++++++-
 1 files changed, 31 insertions(+), 1 deletions(-)

diff --git a/tools/virt-df b/tools/virt-df
index 1551221..d9ef8f9 100755
--- a/tools/virt-df
+++ b/tools/virt-df
@@ -473,6 +473,7 @@ sub print_title
         printf "%-36s%10s %10s %10s %5s\n",
           $cols[1], $cols[2], $cols[3], $cols[4], $cols[5];
     } else {
+        # Columns don't need special CSV quoting.
         print (join (",", @cols), "\n");
     }
 }
@@ -491,7 +492,11 @@ sub print_cols
 
         printf ("%10s %10s %10s %5s\n", $_[2], $_[3], $_[4], $percent);
     } else {
-        printf ("\"%s\",\"%s\",%d,%d,%d,%.1f%%\n", @_);
+        # Need to quote libvirt domain and filesystem.
+        my $dom = shift;
+        my $fs = shift;
+        print csv_quote($dom), ",", csv_quote($fs), ",";
+        printf ("%d,%d,%d,%.1f%%\n", @_);
     }
 }
 
@@ -509,6 +514,31 @@ sub human_size
     }
 }
 
+# Quote field for CSV without using an external module.
+sub csv_quote
+{
+    local $_ = shift;
+
+    my $needs_quoting = /[ ",\n\0]/;
+    return $_ unless $needs_quoting;
+
+    my $i;
+    my $out = '"';
+    for ($i = 0; $i < length; ++$i) {
+        my $c = substr $_, $i, 1;
+        if ($c eq '"') {
+            $out .= '""';
+        } elsif ($c eq '\0') {
+            $out .= '"0';
+        } else {
+            $out .= $c;
+        }
+    }
+    $out .= '"';
+
+    return $out;
+}
+
 =head1 NOTE ABOUT CSV FORMAT
 
 Comma-separated values (CSV) is a deceptive format.  It I<seems> like
-- 
1.7.3.1



More information about the Libguestfs mailing list