View Issue Details

IDProjectCategoryView StatusLast Update
0000190fileGeneralpublic2020-09-05 14:58
Reporterneal Assigned Tochristos  
PrioritynormalSeverityminorReproducibilityhave not tried
Status resolvedResolutionfixed 
Fixed in Version5.40 
Summary0000190: use always matches
DescriptionConsider the following:

0 byte x 1
>0 use foo
>>0 byte x 2

0 name foo
>0 byte =1 3

I would expect this to print:

$ src/file -m /tmp/use.magic /tmp/byte.bin
/tmp/byte.bin: 1

But, it does the following:

$ src/file -m /tmp/use.magic /tmp/byte.bin
/tmp/byte.bin: 1 2

This is because magiccheck (softmagic.c:2240) always returns 1 when determining whether a USE or NAME matched.

I have some magic code that finds the start of a block of data and then checks whether the data has the required signature. I wanted to use a 'use foo' to check the data. But, that doesn't work, because the 'use foo' doesn't fail.
TagsNo tags attached.

Activities

neal

2020-08-26 13:02

reporter  

use.magic (61 bytes)
byte.bin (256 bytes)

neal

2020-08-26 20:30

reporter   ~0003465

The attached patch fixes the above issue.

It changes 'use' to act like the body of the named continuation were pasted in its place.
0002-Change-use-to-only-return-true-if-its-sub-continuati.patch (4,008 bytes)   
From 781da068d10f28a9f49a3986700730ad057dce1b Mon Sep 17 00:00:00 2001
From: "Neal H. Walfield" <neal@gnu.org>
Date: Wed, 26 Aug 2020 22:10:42 +0200
Subject: [PATCH 2/2] Change use to only return true if its sub-continuations
 match.

  - Consider the following magic:

      0 byte x 1
      >0 use foo
      >>0 byte x 2

      0 name foo
      >0 byte =1 3

  - If foo's body does not match, then one could reasonable expect the
    use's sub-continuations to not be executed.

  - This is currently not the case.  Instead, 'use' is always
    considered to match.

  - This patch changes the behavior of 'use' to match that of any
    sub-continuations.
---
 src/file.h      |  2 +-
 src/softmagic.c | 28 +++++++++++++++++++---------
 2 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/src/file.h b/src/file.h
index 7298b424..d183b159 100644
--- a/src/file.h
+++ b/src/file.h
@@ -404,8 +404,8 @@ struct mlist {
 struct level_info {
 	int32_t off;
 	int got_match;
-#ifdef ENABLE_CONDITIONALS
 	int last_match;
+#ifdef ENABLE_CONDITIONALS
 	int last_cond;	/* used for error checking by parse() */
 #endif
 };
diff --git a/src/softmagic.c b/src/softmagic.c
index c27209ad..f3ad21d0 100644
--- a/src/softmagic.c
+++ b/src/softmagic.c
@@ -52,7 +52,7 @@ private int mget(struct magic_set *, struct magic *, const struct buffer *,
     uint16_t *, int *, int *, int *, int *);
 private int msetoffset(struct magic_set *, struct magic *, struct buffer *,
     const struct buffer *, size_t, unsigned int);
-private int magiccheck(struct magic_set *, struct magic *);
+private int magiccheck(struct magic_set *, struct magic *, int);
 private int32_t mprint(struct magic_set *, struct magic *);
 private int moffset(struct magic_set *, struct magic *, const struct buffer *,
     int32_t *);
@@ -263,7 +263,7 @@ flush:
 				*returnval = 1;
 			}
 
-			switch (magiccheck(ms, m)) {
+			switch (magiccheck(ms, m, cont_level)) {
 			case -1:
 				return -1;
 			case 0:
@@ -376,18 +376,14 @@ flush:
 				break;
 			}
 
-			switch (flush ? 1 : magiccheck(ms, m)) {
+			switch (flush ? 1 : magiccheck(ms, m, cont_level)) {
 			case -1:
 				return -1;
 			case 0:
-#ifdef ENABLE_CONDITIONALS
 				ms->c->li[cont_level].last_match = 0;
-#endif
 				break;
 			default:
-#ifdef ENABLE_CONDITIONALS
 				ms->c->li[cont_level].last_match = 1;
-#endif
 				if (m->type == FILE_CLEAR)
 					ms->c->li[cont_level].got_match = 0;
 				else if (ms->c->li[cont_level].got_match) {
@@ -1577,6 +1573,7 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
 	char *rbuf;
 	union VALUETYPE *p = &ms->ms_value;
 	struct mlist ml;
+	int got_match;
 
 	if (*indir_count >= ms->indir_max) {
 		file_error(ms, 0, "indirect count (%hu) exceeded",
@@ -1891,7 +1888,15 @@ mget(struct magic_set *ms, struct magic *m, const struct buffer *b,
 		rv = match(ms, ml.magic, ml.nmagic, b, offset + o,
 		    mode, text, flip, indir_count, name_count,
 		    printed_something, need_separator, returnval, found_match);
+		// If the named continuation is empty, then return
+		// true.  Otherwise, return the body's 'got_match' value.
+		if (ml.nmagic == 1) {
+			got_match = 1;
+		} else {
+			got_match = ms->c->li[1].got_match;
+		}
 		file_continuation_level_pop(ms);
+		ms->c->li[cont_level].last_match = got_match;
 		(*name_count)--;
 		if (rv != 1)
 		    *need_separator = oneed_separator;
@@ -1999,7 +2004,7 @@ file_strncmp16(const char *a, const char *b, size_t len, size_t maxlen,
 }
 
 private int
-magiccheck(struct magic_set *ms, struct magic *m)
+magiccheck(struct magic_set *ms, struct magic *m, int cont_level)
 {
 	uint64_t l = m->value.q;
 	uint64_t v;
@@ -2239,9 +2244,14 @@ magiccheck(struct magic_set *ms, struct magic *m)
 		break;
 	}
 	case FILE_INDIRECT:
-	case FILE_USE:
 	case FILE_NAME:
 		return 1;
+	case FILE_USE:
+		if (ms->c->li[cont_level].last_match) {
+			return 1;
+		} else {
+			return 0;
+		}
 	case FILE_DER:
 		matched = der_cmp(ms, m);
 		if (matched == -1) {
-- 
2.20.1

neal

2020-08-26 20:31

reporter   ~0003466

The above patch should probably only be applied if https://bugs.astron.com/view.php?id=189 is also applied.

christos

2020-09-05 14:58

manager   ~0003476

Fixed, thanks!

Issue History

Date Modified Username Field Change
2020-08-26 13:02 neal New Issue
2020-08-26 13:02 neal File Added: use.magic
2020-08-26 13:02 neal File Added: byte.bin
2020-08-26 20:30 neal File Added: 0002-Change-use-to-only-return-true-if-its-sub-continuati.patch
2020-08-26 20:30 neal Note Added: 0003465
2020-08-26 20:31 neal Note Added: 0003466
2020-09-05 14:58 christos Assigned To => christos
2020-09-05 14:58 christos Status new => assigned
2020-09-05 14:58 christos Status assigned => resolved
2020-09-05 14:58 christos Resolution open => fixed
2020-09-05 14:58 christos Fixed in Version => 5.40
2020-09-05 14:58 christos Note Added: 0003476