Skip to content

Commit 1f6194a

Browse files
committed
avoid java Date class for reading root files as it has timezone issues, see GH #289
1 parent ecef972 commit 1f6194a

File tree

5 files changed

+42
-38
lines changed

5 files changed

+42
-38
lines changed

pftpd-pojo-lib/src/main/java/org/primftpd/pojo/LsOutputBean.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package org.primftpd.pojo;
22

3-
import java.util.Date;
4-
53
public class LsOutputBean {
64
private final boolean exists;
75

@@ -26,7 +24,7 @@ public class LsOutputBean {
2624
private final long linkCount;
2725
private final long size;
2826

29-
private final Date date;
27+
private final long timestamp;
3028

3129
private final String user;
3230
private final String group;
@@ -54,7 +52,7 @@ public LsOutputBean(String name) {
5452
this.hasAcl = false;
5553
this.linkCount = 0;
5654
this.size = 0;
57-
this.date = null;
55+
this.timestamp = 0;
5856
this.user = null;
5957
this.group = null;
6058
this.linkTarget = null;
@@ -77,7 +75,7 @@ public LsOutputBean(
7775
boolean hasAcl,
7876
long linkCount,
7977
long size,
80-
Date date,
78+
long timestamp,
8179
String user,
8280
String group,
8381
String name,
@@ -99,7 +97,7 @@ public LsOutputBean(
9997
this.hasAcl = hasAcl;
10098
this.linkCount = linkCount;
10199
this.size = size;
102-
this.date = date;
100+
this.timestamp = timestamp;
103101
this.user = user;
104102
this.group = group;
105103
this.name = name;
@@ -171,8 +169,8 @@ public long getSize() {
171169
return size;
172170
}
173171

174-
public Date getDate() {
175-
return date;
172+
public long getTimestamp() {
173+
return timestamp;
176174
}
177175

178176
public String getUser() {

pftpd-pojo-lib/src/main/java/org/primftpd/pojo/LsOutputBuilder.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package org.primftpd.pojo;
22

3-
import java.util.Date;
4-
53
class LsOutputBuilder {
64

75
private boolean isFile;
@@ -25,7 +23,7 @@ class LsOutputBuilder {
2523
private long linkCount;
2624
private long size;
2725

28-
private Date date;
26+
private long timestamp;
2927

3028
private String user;
3129
private String group;
@@ -154,12 +152,12 @@ public void setSize(long size) {
154152
this.size = size;
155153
}
156154

157-
public Date getDate() {
158-
return date;
155+
public long getTimestamp() {
156+
return timestamp;
159157
}
160158

161-
public void setDate(Date date) {
162-
this.date = date;
159+
public void setTimestamp(long timestamp) {
160+
this.timestamp = timestamp;
163161
}
164162

165163
public String getUser() {
@@ -219,7 +217,7 @@ LsOutputBean build() {
219217
hasAcl,
220218
linkCount,
221219
size,
222-
date,
220+
timestamp,
223221
user,
224222
group,
225223
name,

pftpd-pojo-lib/src/main/java/org/primftpd/pojo/LsOutputParser.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import java.util.Calendar;
1414
import java.util.Date;
1515
import java.util.List;
16+
import java.util.SimpleTimeZone;
1617
import java.util.StringTokenizer;
1718
import java.util.TimeZone;
1819

@@ -123,7 +124,8 @@ public LsOutputBean parseLine(String line) {
123124
// date
124125
String dateStr;
125126
DateFormat dateFormat;
126-
Date date;
127+
Date date = null;
128+
long timestamp = 0;
127129
long offset = 0;
128130
String firstDateCol = parts.get(4 + linkCountOffset);
129131
int dateEndIndex;
@@ -143,15 +145,19 @@ public LsOutputBean parseLine(String line) {
143145
dateEndIndex = 6 + linkCountOffset;
144146
}
145147
try {
146-
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
148+
SimpleTimeZone timeZone = new SimpleTimeZone(0, "No-TZ");
149+
dateFormat.setTimeZone(timeZone);
147150
date = dateFormat.parse(dateStr);
148151
if (offset > 0) {
149152
date = new Date(date.getTime() + offset);
150153
}
151154
} catch (Exception e) {
152-
date = new Date(0);
155+
// never mind
153156
}
154-
builder.setDate(date);
157+
if (date != null) {
158+
timestamp = date.getTime();
159+
}
160+
builder.setTimestamp(timestamp);
155161

156162
// name
157163
int nameEndIndex = 0;

pftpd-pojo-lib/src/test/java/org/primftpd/pojo/LsOutputParserTests.java

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
public class LsOutputParserTests {
1111

12-
private InputStream stream(String filename) throws IOException {
12+
private InputStream stream(String filename) {
1313
return getClass().getResourceAsStream("/ls-output/" + filename);
1414
}
1515

@@ -51,27 +51,24 @@ public void good() throws IOException {
5151
Assert.assertEquals(1234, dir.getSize());
5252
Assert.assertEquals("dir_name", dir.getName());
5353
Assert.assertNull(dir.getLinkTarget());
54-
Assert.assertNotNull(dir.getDate());
55-
Assert.assertEquals(88200000, dir.getDate().getTime());
54+
Assert.assertEquals(88200000, dir.getTimestamp());
5655

5756
LsOutputBean file1 = beans.get(1);
5857
Assert.assertTrue(file1.isFile());
5958
Assert.assertFalse(file1.isDir());
6059
Assert.assertFalse(file1.isLink());
6160
Assert.assertEquals("file_name", file1.getName());
62-
Assert.assertNotNull(file1.getDate());
63-
Assert.assertEquals(86400000, file1.getDate().getTime());
61+
Assert.assertEquals(86400000, file1.getTimestamp());
6462

6563
LsOutputBean file2 = beans.get(2);
6664
Assert.assertTrue(file2.isFile());
6765
Assert.assertTrue(file2.isHasAcl());
6866
Assert.assertEquals("file_2", file2.getName());
69-
Assert.assertNotNull(file2.getDate());
7067
long expectedTime =
7168
LsOutputParser.CURRENT_YEAR_MILLIS +
7269
(24 * 60 * 60 * 1000) +
7370
(30 * 60 * 1000);
74-
Assert.assertEquals(expectedTime, file2.getDate().getTime());
71+
Assert.assertEquals(expectedTime, file2.getTimestamp());
7572
}
7673

7774
@Test
@@ -85,8 +82,7 @@ public void symLink() throws IOException {
8582
Assert.assertTrue(link.isLink());
8683
Assert.assertEquals("link_name", link.getName());
8784
Assert.assertEquals("/absolute/link/target", link.getLinkTarget());
88-
Assert.assertNotNull(link.getDate());
89-
Assert.assertTrue(link.getDate().getTime() > 0);
85+
Assert.assertTrue(link.getTimestamp() > 0);
9086
}
9187

9288
@Test
@@ -127,28 +123,25 @@ public void noLinkCount() throws IOException {
127123
Assert.assertEquals(1234, dir.getSize());
128124
Assert.assertEquals("dir_name", dir.getName());
129125
Assert.assertNull(dir.getLinkTarget());
130-
Assert.assertNotNull(dir.getDate());
131-
Assert.assertEquals(88200000, dir.getDate().getTime());
126+
Assert.assertEquals(88200000, dir.getTimestamp());
132127

133128
LsOutputBean file1 = beans.get(1);
134129
Assert.assertTrue(file1.isFile());
135130
Assert.assertFalse(file1.isDir());
136131
Assert.assertFalse(file1.isLink());
137132
Assert.assertEquals("file_name", file1.getName());
138-
Assert.assertNotNull(file1.getDate());
139-
Assert.assertEquals(86400000, file1.getDate().getTime());
133+
Assert.assertEquals(86400000, file1.getTimestamp());
140134
Assert.assertEquals(0, file1.getLinkCount());
141135

142136
LsOutputBean file2 = beans.get(2);
143137
Assert.assertTrue(file2.isFile());
144138
Assert.assertTrue(file2.isHasAcl());
145139
Assert.assertEquals("file_2", file2.getName());
146-
Assert.assertNotNull(file2.getDate());
147140
long expectedTime =
148141
LsOutputParser.CURRENT_YEAR_MILLIS +
149142
(24 * 60 * 60 * 1000) +
150143
(30 * 60 * 1000);
151-
Assert.assertEquals(expectedTime, file2.getDate().getTime());
144+
Assert.assertEquals(expectedTime, file2.getTimestamp());
152145
Assert.assertEquals(0, file2.getLinkCount());
153146

154147
}

primitiveFTPd/src/org/primftpd/filesystem/RootFile.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
import java.io.IOException;
2020
import java.io.InputStream;
2121
import java.io.OutputStream;
22+
import java.text.SimpleDateFormat;
2223
import java.util.ArrayList;
2324
import java.util.List;
25+
import java.util.TimeZone;
2426

2527
import eu.chainfire.libsuperuser.Shell;
2628

@@ -40,7 +42,7 @@ public RootFile(Shell.Interactive shell, LsOutputBean bean, String absPath, Pftp
4042
super(
4143
absPath,
4244
bean.getName(),
43-
bean.getDate() != null ? bean.getDate().getTime() : 0,
45+
bean.getTimestamp(),
4446
bean.getSize(),
4547
true,
4648
bean.isExists(),
@@ -79,10 +81,17 @@ public boolean setLastModified(long time) {
7981
return runCommand("touch -m -t " + dateStr + " " + escapePath(absPath));
8082
}
8183

84+
private static final SimpleDateFormat DEBUG_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm");
85+
static {
86+
DEBUG_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
87+
}
88+
8289
@Override
8390
public long getLastModified() {
84-
logger.trace("[{}] getLastModified()", name);
85-
logger.trace(" original ls-output line: {}", bean.getOriginalLine());
91+
logger.trace("[{}] RootFile getLastModified()", name);
92+
logger.trace(" returning date '{}', original ls-output line: {}",
93+
DEBUG_DATE_FORMAT.format(bean.getTimestamp()),
94+
bean.getOriginalLine());
8695
return super.getLastModified();
8796
}
8897

0 commit comments

Comments
 (0)