diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rwxr-xr-x | bootstrap | 3 | ||||
-rw-r--r-- | fish/guestfish.pod | 19 | ||||
-rw-r--r-- | m4/.gitignore | 13 | ||||
-rw-r--r-- | regressions/Makefile.am | 4 | ||||
-rw-r--r-- | regressions/rhbz557655-expected.out | 22 | ||||
-rwxr-xr-x | regressions/rhbz557655.sh | 83 | ||||
-rwxr-xr-x | src/generator.ml | 54 |
8 files changed, 194 insertions, 5 deletions
@@ -204,6 +204,7 @@ python/guestfs.py python/guestfs-py.c python/guestfs.pyc regressions/test1.img +regressions/test.out ruby/bindtests.rb ruby/ext/guestfs/extconf.h ruby/ext/guestfs/_guestfs.c @@ -60,6 +60,7 @@ modules=' arpa_inet c-ctype closeout +full-write gitlog-to-changelog gnu-make gnumakefile @@ -77,6 +78,8 @@ strndup vasprintf vc-list-files warnings +xstrtol +xstrtoll ' $gnulib_tool \ diff --git a/fish/guestfish.pod b/fish/guestfish.pod index 13a9fa7d..13645456 100644 --- a/fish/guestfish.pod +++ b/fish/guestfish.pod @@ -296,6 +296,25 @@ must be escaped with a backslash. command "/bin/echo 'foo bar'" command "/bin/echo \'foo\'" +=head1 NUMBERS + +Commands which take integers as parameters use the C convention which +is to use C<0> to prefix an octal number or C<0x> to prefix a +hexadecimal number. For example: + + 1234 decimal number 1234 + 02322 octal number, equivalent to decimal 1234 + 0x4d2 hexadecimal number, equivalent to decimal 1234 + +When using the C<chmod> command, you almost always want to specify an +octal number for the mode, and you must prefix it with C<0> (unlike +the Unix L<chmod(1)> program): + + chmod 0777 /public # OK + chmod 777 /public # WRONG! This is mode 777 decimal = 01411 octal. + +Commands that return numbers currently always print them in decimal. + =head1 WILDCARDS AND GLOBBING Neither guestfish nor the underlying guestfs API performs diff --git a/m4/.gitignore b/m4/.gitignore index 788ec877..01c8e2d6 100644 --- a/m4/.gitignore +++ b/m4/.gitignore @@ -130,3 +130,16 @@ xsize.m4 /yield.m4 /fcntl-o.m4 /warn-on-use.m4 +/getopt.m4 +/stat.m4 +/symlink.m4 +/time_h.m4 +/xstrtol.m4 +/safe-read.m4 +/safe-write.m4 +/ssize_t.m4 +/write.m4 +/strtol.m4 +/strtoll.m4 +/strtoul.m4 +/strtoull.m4 diff --git a/regressions/Makefile.am b/regressions/Makefile.am index 7ceb0cee..3ce4b8d5 100644 --- a/regressions/Makefile.am +++ b/regressions/Makefile.am @@ -26,6 +26,7 @@ include $(top_srcdir)/subdir-rules.mk TESTS = \ rhbz503169c10.sh \ rhbz503169c13.sh \ + rhbz557655.sh \ test-cancellation-download-librarycancels.sh \ test-cancellation-upload-daemoncancels.sh \ test-find0.sh \ @@ -55,4 +56,5 @@ TESTS_ENVIRONMENT = \ EXTRA_DIST = \ $(FAILING_TESTS) \ $(SKIPPED_TESTS) \ - $(TESTS) + $(TESTS) \ + rhbz557655-expected.out diff --git a/regressions/rhbz557655-expected.out b/regressions/rhbz557655-expected.out new file mode 100644 index 00000000..7d37e842 --- /dev/null +++ b/regressions/rhbz557655-expected.out @@ -0,0 +1,22 @@ +0 +16 +8 +-1073741824 +1073741823 +set-memsize: memsize: integer out of range +set-memsize: memsize: integer out of range +set-memsize: memsize: integer out of range +set-memsize: memsize: integer out of range +set-memsize: memsize: invalid integer parameter (xstrtol returned 4) +set-memsize: memsize: invalid integer parameter (xstrtol returned 2) +set-memsize: memsize: invalid integer parameter (xstrtol returned 2) +set-memsize: memsize: invalid integer parameter (xstrtol returned 2) +1234 +1234 +1234 +libguestfs: error: truncate_size: ftruncate: /test: File too large +truncate-size: size: invalid integer parameter (xstrtoll returned 1) +truncate-size: size: invalid integer parameter (xstrtoll returned 4) +truncate-size: size: invalid integer parameter (xstrtoll returned 2) +truncate-size: size: invalid integer parameter (xstrtoll returned 2) +truncate-size: size: invalid integer parameter (xstrtoll returned 2) diff --git a/regressions/rhbz557655.sh b/regressions/rhbz557655.sh new file mode 100755 index 00000000..6ef0b70d --- /dev/null +++ b/regressions/rhbz557655.sh @@ -0,0 +1,83 @@ +#!/bin/bash - +# libguestfs +# Copyright (C) 2009 Red Hat Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +# Regression test for: +# https://bugzilla.redhat.com/show_bug.cgi?id=557655 +# "guestfish number parsing should not use atoi, should support '0...' for octal and '0x...' for hexadecimal" + +set -e +rm -f test.out +export LANG=C + +../fish/guestfish >> test.out 2>&1 <<EOF +# set-memsize is just a convenient non-daemon function that +# takes a single integer argument. +set-memsize 0 +get-memsize +set-memsize 0x10 +get-memsize +set-memsize 010 +get-memsize +set-memsize -1073741824 +get-memsize +set-memsize 1073741823 +get-memsize + +# the following should all provoke error messages: +-set-memsize -9000000000000000 +-set-memsize 9000000000000000 +-set-memsize 0x900000000000 +-set-memsize 07777770000000000000 +-set-memsize ABC +-set-memsize 09 +-set-memsize 123K +-set-memsize 123L +EOF + +../fish/guestfish >> test.out 2>&1 <<EOF +alloc test1.img 10M +run +part-disk /dev/sda mbr +mkfs ext2 /dev/sda1 +mount /dev/sda1 / + +touch /test + +# truncate-size takes an Int64 argument +truncate-size /test 1234 +filesize /test +truncate-size /test 0x4d2 +filesize /test +truncate-size /test 02322 +filesize /test + +# should parse OK, but underlying filesystem will reject it: +-truncate-size /test 0x7fffffffffffffff + +# larger than 64 bits, should be an error: +-truncate-size /test 0x10000000000000000 + +# these should all provoke parse errors: +-truncate-size /test ABC +-truncate-size /test 09 +-truncate-size /test 123K +-truncate-size /test 123L +EOF + +diff -u test.out rhbz557655-expected.out +rm test.out test1.img diff --git a/src/generator.ml b/src/generator.ml index e55b2b5a..58c39e61 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -1326,7 +1326,11 @@ as necessary. This is like the C<mkdir -p> shell command."); "change file mode", "\ Change the mode (permissions) of C<path> to C<mode>. Only -numeric modes are supported."); +numeric modes are supported. + +I<Note>: When using this command from guestfish, C<mode> +by default would be decimal, unless you prefix it with +C<0> to get octal, ie. use C<0700> not C<700>."); ("chown", (RErr, [Int "owner"; Int "group"; Pathname "path"]), 35, [], [], (* XXX Need stat command to test *) @@ -6861,6 +6865,8 @@ and generate_fish_cmds () = fun (_, _, _, flags, _, _, _) -> not (List.mem NotInFish flags) ) all_functions_sorted in + pr "#include <config.h>\n"; + pr "\n"; pr "#include <stdio.h>\n"; pr "#include <stdlib.h>\n"; pr "#include <string.h>\n"; @@ -6868,6 +6874,8 @@ and generate_fish_cmds () = pr "\n"; pr "#include <guestfs.h>\n"; pr "#include \"c-ctype.h\"\n"; + pr "#include \"full-write.h\"\n"; + pr "#include \"xstrtol.h\"\n"; pr "#include \"fish.h\"\n"; pr "\n"; @@ -7079,6 +7087,34 @@ and generate_fish_cmds () = pr " fprintf (stderr, _(\"type 'help %%s' for help on %%s\\n\"), cmd, cmd);\n"; pr " return -1;\n"; pr " }\n"; + + let parse_integer fn fntyp rtyp range name i = + pr " {\n"; + pr " strtol_error xerr;\n"; + pr " %s r;\n" fntyp; + pr "\n"; + pr " xerr = %s (argv[%d], NULL, 0, &r, \"\");\n" fn i; + pr " if (xerr != LONGINT_OK) {\n"; + pr " fprintf (stderr,\n"; + pr " _(\"%%s: %%s: invalid integer parameter (%%s returned %%d)\\n\"),\n"; + pr " cmd, \"%s\", \"%s\", xerr);\n" name fn; + pr " return -1;\n"; + pr " }\n"; + (match range with + | None -> () + | Some (min, max, comment) -> + pr " /* %s */\n" comment; + pr " if (r < %s || r > %s) {\n" min max; + pr " fprintf (stderr, _(\"%%s: %%s: integer out of range\\n\"), cmd, \"%s\");\n" + name; + pr " return -1;\n"; + pr " }\n"; + pr " /* The check above should ensure this assignment does not overflow. */\n"; + ); + pr " %s = r;\n" name; + pr " }\n"; + in + iteri ( fun i -> function @@ -7104,9 +7140,15 @@ and generate_fish_cmds () = | Bool name -> pr " %s = is_true (argv[%d]) ? 1 : 0;\n" name i | Int name -> - pr " %s = atoi (argv[%d]);\n" name i + let range = + let min = "(-(2LL<<30))" + and max = "((2LL<<30)-1)" + and comment = + "The Int type in the generator is a signed 31 bit int." in + Some (min, max, comment) in + parse_integer "xstrtol" "long" "int" range name i | Int64 name -> - pr " %s = atoll (argv[%d]);\n" name i + parse_integer "xstrtoll" "long long" "int64_t" None name i ) (snd style); (* Call C API function. *) @@ -7177,7 +7219,11 @@ and generate_fish_cmds () = pr " return 0;\n" | RBufferOut _ -> pr " if (r == NULL) return -1;\n"; - pr " fwrite (r, size, 1, stdout);\n"; + pr " if (full_write (1, r, size) != size) {\n"; + pr " perror (\"write\");\n"; + pr " free (r);\n"; + pr " return -1;\n"; + pr " }\n"; pr " free (r);\n"; pr " return 0;\n" ); |