Skip to content

Commit

Permalink
zfs, libzfs: diff: accept -h/ZFS_DIFF_NO_MANGLE, disabling path escaping
Browse files Browse the repository at this point in the history
Reviewed-by: Brian Behlendorf <[email protected]>
Reviewed-by: Rich Ercolani <[email protected]>
Signed-off-by: Ahelenia Ziemiańska <[email protected]>
Upstream-commit: 344bbc8
Closes openzfs#12829
  • Loading branch information
nabijaczleweli authored and behlendorf committed Apr 1, 2022
1 parent 52bad4f commit 5a21214
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 10 deletions.
5 changes: 4 additions & 1 deletion cmd/zfs/zfs_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7672,7 +7672,7 @@ zfs_do_diff(int argc, char **argv)
int c;
struct sigaction sa;

while ((c = getopt(argc, argv, "FHt")) != -1) {
while ((c = getopt(argc, argv, "FHth")) != -1) {
switch (c) {
case 'F':
flags |= ZFS_DIFF_CLASSIFY;
Expand All @@ -7683,6 +7683,9 @@ zfs_do_diff(int argc, char **argv)
case 't':
flags |= ZFS_DIFF_TIMESTAMP;
break;
case 'h':
flags |= ZFS_DIFF_NO_MANGLE;
break;
default:
(void) fprintf(stderr,
gettext("invalid option '%c'\n"), optopt);
Expand Down
7 changes: 4 additions & 3 deletions include/libzfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -795,9 +795,10 @@ extern int zfs_receive(libzfs_handle_t *, const char *, nvlist_t *,
recvflags_t *, int, avl_tree_t *);

typedef enum diff_flags {
ZFS_DIFF_PARSEABLE = 0x1,
ZFS_DIFF_TIMESTAMP = 0x2,
ZFS_DIFF_CLASSIFY = 0x4
ZFS_DIFF_PARSEABLE = 1 << 0,
ZFS_DIFF_TIMESTAMP = 1 << 1,
ZFS_DIFF_CLASSIFY = 1 << 2,
ZFS_DIFF_NO_MANGLE = 1 << 3
} diff_flags_t;

extern int zfs_show_diffs(zfs_handle_t *, int, const char *, const char *,
Expand Down
1 change: 1 addition & 0 deletions include/libzfs_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ typedef struct differ_info {
boolean_t scripted;
boolean_t classify;
boolean_t timestamped;
boolean_t no_mangle;
uint64_t shares;
int zerr;
int cleanupfd;
Expand Down
10 changes: 8 additions & 2 deletions lib/libzfs/libzfs_diff.c
Original file line number Diff line number Diff line change
Expand Up @@ -176,8 +176,13 @@ print_what(FILE *fp, mode_t what)
static void
print_cmn(FILE *fp, differ_info_t *di, const char *file)
{
stream_bytes(fp, di->dsmnt);
stream_bytes(fp, file);
if (!di->no_mangle) {
stream_bytes(fp, di->dsmnt);
stream_bytes(fp, file);
} else {
(void) fputs(di->dsmnt, fp);
(void) fputs(file, fp);
}
}

static void
Expand Down Expand Up @@ -752,6 +757,7 @@ zfs_show_diffs(zfs_handle_t *zhp, int outfd, const char *fromsnap,
di.scripted = (flags & ZFS_DIFF_PARSEABLE);
di.classify = (flags & ZFS_DIFF_CLASSIFY);
di.timestamped = (flags & ZFS_DIFF_TIMESTAMP);
di.no_mangle = (flags & ZFS_DIFF_NO_MANGLE);

di.outputfd = outfd;
di.datafd = pipefd[0];
Expand Down
6 changes: 5 additions & 1 deletion man/man8/zfs-diff.8
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
.Sh SYNOPSIS
.Nm zfs
.Cm diff
.Op Fl FHt
.Op Fl FHth
.Ar snapshot Ar snapshot Ns | Ns Ar filesystem
.
.Sh DESCRIPTION
Expand Down Expand Up @@ -92,6 +92,10 @@ Give more parsable tab-separated output, without header lines and without
arrows.
.It Fl t
Display the path's inode change time as the first column of output.
.It Fl h
Do not
.Sy \e0 Ns Ar ooo Ns -escape
non-ASCII paths.
.El
.
.Sh SEE ALSO
Expand Down
2 changes: 1 addition & 1 deletion tests/runfiles/common.run
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ tags = ['functional', 'cli_root', 'zfs_destroy']

[tests/functional/cli_root/zfs_diff]
tests = ['zfs_diff_changes', 'zfs_diff_cliargs', 'zfs_diff_timestamp',
'zfs_diff_types', 'zfs_diff_encrypted']
'zfs_diff_types', 'zfs_diff_encrypted', 'zfs_diff_mangle']
tags = ['functional', 'cli_root', 'zfs_diff']

[tests/functional/cli_root/zfs_get]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dist_pkgdata_SCRIPTS = \
zfs_diff_changes.ksh \
zfs_diff_cliargs.ksh \
zfs_diff_encrypted.ksh \
zfs_diff_mangle.ksh \
zfs_diff_timestamp.ksh \
zfs_diff_types.ksh

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ function cleanup
log_assert "'zfs diff' should only work with supported options."
log_onexit cleanup

typeset goodopts=("" "-F" "-H" "-t" "-FH" "-Ft" "-Ht" "-FHt")
typeset badopts=("-f" "-h" "-h" "-T" "-Fx" "-Ho" "-tT" "-")
typeset goodopts=("" "-h" "-t" "-th" "-H" "-Hh" "-Ht" "-Hth" "-F" "-Fh" "-Ft" "-Fth" "-FH" "-FHh" "-FHt" "-FHth")
typeset badopts=("-f" "-T" "-Fx" "-Ho" "-tT" "-")

DATASET="$TESTPOOL/$TESTFS"
TESTSNAP1="$DATASET@snap1"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#!/bin/ksh -p
#
# This file and its contents are supplied under the terms of the
# Common Development and Distribution License ("CDDL"), version 1.0.
# You may only use this file in accordance with the terms of version
# 1.0 of the CDDL.
#
# A full copy of the text of the CDDL should have accompanied this
# source. A copy of the CDDL is also available via the Internet at
# http://www.illumos.org/license/CDDL.
#

. $STF_SUITE/include/libtest.shlib

#
# DESCRIPTION:
# 'zfs diff' escapes filenames as expected, 'zfs diff -h' doesn't
#
# STRATEGY:
# 1. Prepare a dataset
# 2. Create some files
# 3. verify 'zfs diff' mangles them and 'zfs diff -h' doesn't
#

verify_runnable "both"

function cleanup
{
log_must zfs destroy -r "$DATASET"
}

log_assert "'zfs diff' mangles filenames, 'zfs diff -h' doesn't"
log_onexit cleanup

DATASET="$TESTPOOL/$TESTFS/fs"
TESTSNAP1="$DATASET@snap1"

# 1. Prepare a dataset
log_must zfs create "$DATASET"
MNTPOINT="$(get_prop mountpoint "$DATASET")"
log_must zfs snapshot "$TESTSNAP1"

printf '%c\t'"$MNTPOINT/"'%s\n' M '' + 'śmieszny żupan' + 'достопримечательности' | sort > "$MNTPOINT/śmieszny żupan"
printf '%c\t'"$MNTPOINT/"'%s\n' M '' + '\0305\0233mieszny\0040\0305\0274upan' + '\0320\0264\0320\0276\0321\0201\0321\0202\0320\0276\0320\0277\0321\0200\0320\0270\0320\0274\0320\0265\0321\0207\0320\0260\0321\0202\0320\0265\0320\0273\0321\0214\0320\0275\0320\0276\0321\0201\0321\0202\0320\0270' | sort > "$MNTPOINT/достопримечательности"
log_must diff -u <(zfs diff -h "$TESTSNAP1" | grep -vF '<xattrdir>' | sort) "$MNTPOINT/śmieszny żupan"
log_must diff -u <(zfs diff "$TESTSNAP1" | grep -vF '<xattrdir>' | sort) "$MNTPOINT/достопримечательности"

log_pass "'zfs diff' mangles filenames, 'zfs diff -h' doesn't"

0 comments on commit 5a21214

Please sign in to comment.