View Issue Details

IDProjectCategoryView StatusLast Update
0000195fileGeneralpublic2020-09-05 17:39
Reporterneal Assigned Tochristos  
PrioritynormalSeverityminorReproducibilityhave not tried
Status resolvedResolutionfixed 
Fixed in Version5.40 
Summary0000195: Different execution depending on whether or not --mime-type is given
DescriptionConsider the following magic file:

0 byte x
>0 use foo
>>0 byte x 1
>>0 use bar

0 name foo
>0 byte x 2

0 name bar
>0 byte x 3
!:mime application/3


When I run it (using file 5.35 from Debian or the latest from github.com/file/file), I see the following:

$ file -m /tmp/mime.magic /tmp/byte.bin
/tmp/byte.bin: 2 1 3
us@grit:~/neal/src/file$ file --mime-type -m /tmp/mime.magic /tmp/byte.bin
/tmp/byte.bin: application/octet-stream

What I'd expect is the following:

$ src/file --mime-type -m /tmp/mime.magic /tmp/byte.bin
/tmp/byte.bin: application/3
$ src/file -m /tmp/mime.magic /tmp/byte.bin
/tmp/byte.bin: 2 1 3

The problem is that after executing foo, match sets *returnval to 0 when --mime-type is specified and 1 when it is not. AIUI, *returnval basically means: "we printed something." When --mime-type is specified, the magic entries in foo don't have any mime information, so nothing is printed and *returnvalue is 0. When --mime-type is not specified, the descriptions are printed, so something is printed and *returnval is 1. This causes mget to behave differently: for FILE_USE, it returns *return_value.
TagsNo tags attached.

Activities

neal

2020-09-01 10:19

reporter  

mime.magic (116 bytes)
byte.bin (256 bytes)

neal

2020-09-01 11:53

reporter   ~0003471

I've spent some time studying the code and I think the correct solution is to change mget so that FILE_USE behaves like the other entry types.

Reading mget, it appears that -1 is returned if there is an error, 0 is returned if the accessed data is not buffered, and 1 is returned if the data could be read.

I've tried to figure out what match's return type means, but it seems to depend on many conditions. I think it does the following: If match returns -1, then an error occured. If an annotation was handled, it returns 1. If cont_level is 0 and an offset is used (OFFADD), it returns 0. Otherwise, it returns *returnval. *returnval can be set by mget or set directly. When set directly, it is set to 1. This is done if mget returns 1 and type is FILE_INDIRECT, if handle_annotation returns an error (-1) or success (1), or if something is displayed. mget only changes returnval insofar as it passes returnval to match when the magic entry's type is FILE_USE.

As a first approximation, it seems that mget with FILE_USE is returning whether the procedure matched whereas in other cases, mget is only returning whether the data could be loaded. The match case should actually be handled by magiccheck, and, to align FILE_USE's behavior with other types, this should only return whether the use "executed." My attached patch changes the behavior of mget. In issue 0000190 (https://bugs.astron.com/view.php?id=190), I fixed magiccheck.

neal

2020-09-01 12:19

reporter  

0005-Change-mget-to-return-whether-a-USE-execute-not-whet.patch (1,716 bytes)   
From 70fbb8bf04f8d2221c88b41cf4387f9ef94554d1 Mon Sep 17 00:00:00 2001
From: "Neal H. Walfield" <neal@gnu.org>
Date: Tue, 1 Sep 2020 13:53:27 +0200
Subject: [PATCH 5/5] Change mget to return whether a USE execute, not whether
 it matched.

  - Consider the following magic:

      0 byte x
      >0 use foo
      >>0 byte x 1
      >>0 use bar

      0 name foo
      >0 byte x 2

      0 name bar
      >0 byte x 3
      !:mime application/3

    Executing normally and getting the mime type result in different
    control flows:

      $ file -m /tmp/mime.magic /tmp/byte.bin
      /tmp/byte.bin: 2 1 3
      $ file --mime-type -m /tmp/mime.magic /tmp/byte.bin
      /tmp/byte.bin: application/octet-stream

    'bar' is executed in the first case, because 'foo' output '2', but
    not in the second case, because no lines in 'foo' have a mime
    annotation.

    This happens, because mget's handling of FILE_USE returns whether
    a match occured, not whether the required data was loaded, which
    is what it returns.

  - Change mget to return whether the use executed.  Let magiccheck
    handle whether the entry matched anything.

    See https://bugs.astron.com/view.php?id=195 for more details.
---
 src/softmagic.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/softmagic.c b/src/softmagic.c
index 5ecdd0b4..3681c75c 100644
--- a/src/softmagic.c
+++ b/src/softmagic.c
@@ -1907,7 +1907,10 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
 		(*name_count)--;
 		if (rv != 1)
 		    *need_separator = oneed_separator;
-		return rv;
+		if (rv == -1)
+			return -1;
+		else
+			return 1;
 
 	case FILE_NAME:
 		if (ms->flags & MAGIC_NODESC)
-- 
2.20.1

christos

2020-09-05 17:39

manager   ~0003480

Fixed, thanks!

Issue History

Date Modified Username Field Change
2020-09-01 10:19 neal New Issue
2020-09-01 10:19 neal File Added: mime.magic
2020-09-01 10:19 neal File Added: byte.bin
2020-09-01 11:53 neal Note Added: 0003471
2020-09-01 12:19 neal File Added: 0005-Change-mget-to-return-whether-a-USE-execute-not-whet.patch
2020-09-05 17:39 christos Assigned To => christos
2020-09-05 17:39 christos Status new => assigned
2020-09-05 17:39 christos Status assigned => resolved
2020-09-05 17:39 christos Resolution open => fixed
2020-09-05 17:39 christos Fixed in Version => 5.40
2020-09-05 17:39 christos Note Added: 0003480