Skip to content

Commit

Permalink
Fix unicode handling in .env files (fixes #32)
Browse files Browse the repository at this point in the history
  • Loading branch information
ashald committed Oct 7, 2018
1 parent 3b90aab commit 8b91f85
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 22 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Integration with Goland (#67)
- Announce support for `.env` file extension

### Fixed

- Unicode sequences handling in `.env` files (#38)

## 2.1.0 - 2017-03-14

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,34 @@
import net.ashald.envfile.EnvFileErrorException;
import org.jetbrains.annotations.NotNull;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

public class DotEnvFileParser extends AbstractEnvFileParser {

@NotNull
@Override
protected Map<String, String> readFile(@NotNull String path) throws EnvFileErrorException, IOException {
Map<String, String> result = new HashMap<String, String>();
protected Map<String, String> readFile(@NotNull String path) throws EnvFileErrorException {
Map<String, String> result = new HashMap<>();

InputStream input = null;
Properties prop = new Properties();
try {
input = new FileInputStream(path);
prop.load(input);
List<String> lines = Files.readAllLines(Paths.get(path), StandardCharsets.UTF_8);
for (String l: lines) {
String strippedLine = l.trim();
if (!strippedLine.startsWith("#") && strippedLine.contains("=")) {
String[] tokens = strippedLine.split("=", 2);
String key = tokens[0];
String value = trim(tokens[1]);
result.put(key, value);
}
}
} catch (IOException ex) {
throw new EnvFileErrorException(ex);
} finally {
if (input != null) {
input.close();
}
}
Enumeration<?> e = prop.propertyNames();
while (e.hasMoreElements()) {
String key = trim((String) e.nextElement());
String value = trim(prop.getProperty(key));
result.put(key, value);
}

return result;
Expand All @@ -44,10 +40,10 @@ protected Map<String, String> readFile(@NotNull String path) throws EnvFileError
private static String trim(String value) {
String trimmed = value.trim();

if ( (trimmed.startsWith("\"") && trimmed.endsWith("\"")) || (trimmed.startsWith("'") && trimmed.endsWith("'")))
if ((trimmed.startsWith("\"") && trimmed.endsWith("\"")) || (trimmed.startsWith("'") && trimmed.endsWith("'")))
return trimmed.substring(1, trimmed.length() - 1);

return trimmed;
return trimmed.replaceAll("\\s#.*$", "").replaceAll("(\\s)\\\\#", "$1#").trim();
}

@NotNull
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package net.ashald.envfile.parsers;
import net.ashald.envfile.EnvFileErrorException;
import org.junit.Assert;
import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Map;

public class DotEnvFileParserTest {

private DotEnvFileParser parser = new DotEnvFileParser();

private String createFile(String content) throws IOException {
File file = File.createTempFile("test", ".env");
file.deleteOnExit();

String filePath = file.getAbsolutePath();
Files.write(Paths.get(filePath), content.getBytes());
return filePath;
}

@Test
public void testMalformedEncoding() throws IOException, EnvFileErrorException {
parser.readFile(createFile("\\usr")); // should not fail
}

@Test
public void testLinesStartingWithHasAreIgnored() throws IOException, EnvFileErrorException {
StringWriter stringWriter = new StringWriter();
PrintWriter writer = new PrintWriter(stringWriter, true);
writer.println("# ignored");
writer.println(" # also ignored");
writer.println("key=value");

Map<String, String> result = parser.readFile(createFile(stringWriter.toString()));
Assert.assertEquals(1, result.size());
Assert.assertEquals("value", result.get("key"));
}

@Test
public void testInlineComments() throws IOException, EnvFileErrorException {
StringWriter stringWriter = new StringWriter();
PrintWriter writer = new PrintWriter(stringWriter, true);
writer.println("key1=foo#bar"); // not a comment
writer.println("key2=foo #bar"); // a comment
writer.println("key3='foo #bar'"); // a comment
writer.println("key4=\"foo #bar\""); // a comment
writer.println("key5=foo \\#bar"); // a comment

Map<String, String> result = parser.readFile(createFile(stringWriter.toString()));
Assert.assertEquals("foo#bar", result.get("key1"));
Assert.assertEquals("foo", result.get("key2"));
Assert.assertEquals("foo #bar", result.get("key3"));
Assert.assertEquals("foo #bar", result.get("key4"));
Assert.assertEquals("foo #bar", result.get("key5"));
}

}

0 comments on commit 8b91f85

Please sign in to comment.