summaryrefslogtreecommitdiff
blob: b6638adc9b2baebc44ab5ca5fb3bbb98ddabd349 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
From 28e91b48f680a6fab90ee39145123647345f385f Mon Sep 17 00:00:00 2001
From: Sergey Poznyakoff <gray@gnu.org.ua>
Date: Tue, 26 Oct 2010 14:47:16 +0000
Subject: Make sure name matching occurs before name transformation.

The commit 9c194c99 altered that order.

* src/list.c (transform_stat_info): New function.  Split off from
decode_header.
(read_and): Call transform_stat_info right before do_something,
and after deciding if we should proceed with this member name,
so that name matching occurs before name transformation.

* tests/extrac17.at: New file.
* tests/Makefile.am (TESTSUITE_AT): Add extrac17.at
* tests/testsuite.at: Include extrac17.at.
---
diff --git a/src/list.c b/src/list.c
index d15653d..e1e06ca 100644
--- a/src/list.c
+++ b/src/list.c
@@ -75,6 +75,66 @@ base64_init (void)
     base64_map[(int) base_64_digits[i]] = i;
 }
 
+static char *
+decode_xform (char *file_name, void *data)
+{
+  int type = *(int*)data;
+
+  switch (type)
+    {
+    case XFORM_SYMLINK:
+      /* FIXME: It is not quite clear how and to which extent are the symbolic
+	 links subject to filename transformation.  In the absence of another
+	 solution, symbolic links are exempt from component stripping and
+	 name suffix normalization, but subject to filename transformation
+	 proper. */
+      return file_name;
+
+    case XFORM_LINK:
+      file_name = safer_name_suffix (file_name, true, absolute_names_option);
+      break;
+
+    case XFORM_REGFILE:
+      file_name = safer_name_suffix (file_name, false, absolute_names_option);
+      break;
+    }
+
+  if (strip_name_components)
+    {
+      size_t prefix_len = stripped_prefix_len (file_name,
+					       strip_name_components);
+      if (prefix_len == (size_t) -1)
+	prefix_len = strlen (file_name);
+      file_name += prefix_len;
+    }
+  return file_name;
+}
+
+static bool
+transform_member_name (char **pinput, int type)
+{
+  return transform_name_fp (pinput, type, decode_xform, &type);
+}
+
+static void
+transform_stat_info (int typeflag, struct tar_stat_info *stat_info)
+{
+  if (typeflag == GNUTYPE_VOLHDR)
+    /* Name transformations don't apply to volume headers. */
+    return;
+  
+  transform_member_name (&stat_info->file_name, XFORM_REGFILE);
+  switch (typeflag)
+    {
+    case SYMTYPE:
+      transform_member_name (&stat_info->link_name, XFORM_SYMLINK);
+      break;
+
+    case LNKTYPE:
+      transform_member_name (&stat_info->link_name, XFORM_LINK);
+    }
+}
+
 /* Main loop for reading an archive.  */
 void
 read_and (void (*do_something) (void))
@@ -135,7 +195,8 @@ read_and (void (*do_something) (void))
 		  continue;
 		}
 	    }
-
+	  transform_stat_info (current_header->header.typeflag,
+			       &current_stat_info);
 	  (*do_something) ();
 	  continue;
 
@@ -495,47 +556,6 @@ read_header (union block **return_block, struct tar_stat_info *info,
     }
 }
 
-static char *
-decode_xform (char *file_name, void *data)
-{
-  int type = *(int*)data;
-
-  switch (type)
-    {
-    case XFORM_SYMLINK:
-      /* FIXME: It is not quite clear how and to which extent are the symbolic
-	 links subject to filename transformation.  In the absence of another
-	 solution, symbolic links are exempt from component stripping and
-	 name suffix normalization, but subject to filename transformation
-	 proper. */
-      return file_name;
-
-    case XFORM_LINK:
-      file_name = safer_name_suffix (file_name, true, absolute_names_option);
-      break;
-
-    case XFORM_REGFILE:
-      file_name = safer_name_suffix (file_name, false, absolute_names_option);
-      break;
-    }
-
-  if (strip_name_components)
-    {
-      size_t prefix_len = stripped_prefix_len (file_name,
-					       strip_name_components);
-      if (prefix_len == (size_t) -1)
-	prefix_len = strlen (file_name);
-      file_name += prefix_len;
-    }
-  return file_name;
-}
-
-static bool
-transform_member_name (char **pinput, int type)
-{
-  return transform_name_fp (pinput, type, decode_xform, &type);
-}
-
 #define ISOCTAL(c) ((c)>='0'&&(c)<='7')
 
 /* Decode things from a file HEADER block into STAT_INFO, also setting
@@ -655,23 +675,9 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
           || stat_info->dumpdir)
 	stat_info->is_dumpdir = true;
     }
-
-  if (header->header.typeflag == GNUTYPE_VOLHDR)
-    /* Name transformations don't apply to volume headers. */
-    return;
-  
-  transform_member_name (&stat_info->file_name, XFORM_REGFILE);
-  switch (header->header.typeflag)
-    {
-    case SYMTYPE:
-      transform_member_name (&stat_info->link_name, XFORM_SYMLINK);
-      break;
-
-    case LNKTYPE:
-      transform_member_name (&stat_info->link_name, XFORM_LINK);
-    }
 }
 
+
 /* Convert buffer at WHERE0 of size DIGS from external format to
    uintmax_t.  DIGS must be positive.  If TYPE is nonnull, the data
    are of type TYPE.  The buffer must represent a value in the range
--
cgit v0.8.3.2