Skip to content
Snippets Groups Projects
Verified Commit 92038302 authored by Timm Fitschen's avatar Timm Fitschen
Browse files

BUG: issue #30

parent b9ccc09e
Branches
Tags
No related merge requests found
...@@ -36,6 +36,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ...@@ -36,6 +36,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed ### Fixed
* #27 - star matches slashes (e.g. for `FIND ... STORED AT /*.dat`).
* #30 - file path cannot be in quotes
- #46 - Server-side scripting failed as an unprivileged user because the was no - #46 - Server-side scripting failed as an unprivileged user because the was no
writable home directory. writable home directory.
......
...@@ -444,7 +444,7 @@ value returns [String str] ...@@ -444,7 +444,7 @@ value returns [String str]
: :
number {$str = $text;} number {$str = $text;}
| datetime {$str = $text;} | datetime {$str = $text;}
| atom {$str = $atom.str;} | atom {$str = $atom.ep.toString();}
; ;
number number
...@@ -454,20 +454,17 @@ number ...@@ -454,20 +454,17 @@ number
location returns [String str] location returns [String str]
: :
atom {$str = $atom.str;} atom {$str = $atom.ep.str;}
| |
SLASHES ? SLASHES ?
((WHICH | WITH)+ SLASHES |( TXT | COLON | HYPHEN | NUM | DOT | ESC_STAR | ESC_BS | ESC_REGEXP_END | STAR )+ SLASHES ?)* {$str = $text; } ((WHICH | WITH)+ SLASHES |( TXT | COLON | HYPHEN | NUM | DOT | ESC_STAR | ESC_BS | ESC_REGEXP_END | STAR )+ SLASHES ?)* {$str = $text; }
; ;
atom returns [String str] atom returns [Query.Pattern ep]
@init {
$str = null;
}
: :
double_quoted {$str = $double_quoted.ep.toString();} double_quoted {$ep = $double_quoted.ep;}
| single_quoted {$str = $single_quoted.ep.toString();} | single_quoted {$ep = $single_quoted.ep;}
| (TXT | NUM | REGEXP_MARKER | STAR | A )+ {$str = $text;} | (TXT | NUM | REGEXP_MARKER | STAR | A )+ {$ep = new Query.Pattern($text, Query.Pattern.TYPE_NORMAL);}
; ;
single_quoted returns [Query.Pattern ep] locals [StringBuffer sb, int patternType] single_quoted returns [Query.Pattern ep] locals [StringBuffer sb, int patternType]
......
...@@ -126,7 +126,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac ...@@ -126,7 +126,7 @@ public class Query implements QueryInterface, ToElementable, TransactionInterfac
public static final int TYPE_LIKE = 1; public static final int TYPE_LIKE = 1;
public static final int TYPE_REGEXP = 2; public static final int TYPE_REGEXP = 2;
public final int type; public final int type;
private final String str; public final String str;
public Pattern(final String str, final int type) { public Pattern(final String str, final int type) {
this.type = type; this.type = type;
......
...@@ -45,8 +45,7 @@ public class StoredAt implements EntityFilterInterface { ...@@ -45,8 +45,7 @@ public class StoredAt implements EntityFilterInterface {
public StoredAt(final String loc) { public StoredAt(final String loc) {
Path locPath = Paths.get(loc); Path locPath = Paths.get(loc);
this.location = this.location = locPath.normalize().toString() + (loc.endsWith("/") ? "/" : "");
locPath.normalize().toString().replaceFirst("^/", "") + (loc.endsWith("/") ? "/" : "");
this.pattern_matching = requiresPatternMatching(this.location); this.pattern_matching = requiresPatternMatching(this.location);
if (this.pattern_matching) { if (this.pattern_matching) {
...@@ -87,7 +86,7 @@ public class StoredAt implements EntityFilterInterface { ...@@ -87,7 +86,7 @@ public class StoredAt implements EntityFilterInterface {
java.util.regex.Pattern multiplePat = Pattern.compile(findMultipleAst); java.util.regex.Pattern multiplePat = Pattern.compile(findMultipleAst);
// Simple SQL escape replacements // Simple SQL escape replacements
String converted = location.replace("%", "\\%").replace("_", "\\_"); String converted = location.replaceFirst("^/", "").replace("%", "\\%").replace("_", "\\_");
// * -> %%, has to run mutliple times, because otherwise the separation between patterns would // * -> %%, has to run mutliple times, because otherwise the separation between patterns would
// need to be larger than one character // need to be larger than one character
while (singlePat.matcher(converted).find()) { while (singlePat.matcher(converted).find()) {
...@@ -101,7 +100,11 @@ public class StoredAt implements EntityFilterInterface { ...@@ -101,7 +100,11 @@ public class StoredAt implements EntityFilterInterface {
converted = converted.replaceAll(singleEscapedAst.replace("b", "\\\\"), "*"); converted = converted.replaceAll(singleEscapedAst.replace("b", "\\\\"), "*");
// Final exceptions // Final exceptions
converted = converted.replaceFirst("^%{2,}", "%"); // .replaceFirst("^/", ""); if (location.startsWith("/*") && !location.startsWith("/**")) {
converted = converted.replaceFirst("^/", "");
} else {
converted = converted.replaceFirst("^%{2,}", "%"); // .replaceFirst("^/", "");
}
return converted; return converted;
} }
...@@ -128,7 +131,8 @@ public class StoredAt implements EntityFilterInterface { ...@@ -128,7 +131,8 @@ public class StoredAt implements EntityFilterInterface {
if (this.location == null) { // location if (this.location == null) { // location
callSAT.setNull(3, VARCHAR); callSAT.setNull(3, VARCHAR);
} else { } else {
callSAT.setString(3, (this.pattern_matching ? this.likeLocation : this.location)); callSAT.setString(
3, (this.pattern_matching ? this.likeLocation : this.location.replaceFirst("^/", "")));
} }
callSAT.setString(4, (this.pattern_matching ? "LIKE" : "=")); callSAT.setString(4, (this.pattern_matching ? "LIKE" : "="));
......
...@@ -28,15 +28,6 @@ import static org.junit.Assert.assertNotNull; ...@@ -28,15 +28,6 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull; import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
import caosdb.server.CaosDBServer;
import caosdb.server.database.access.Access;
import caosdb.server.database.backend.implementation.MySQL.ConnectionException;
import caosdb.server.database.exceptions.TransactionException;
import caosdb.server.query.CQLParser.CqContext;
import caosdb.server.query.Query.Pattern;
import caosdb.server.query.Query.QueryException;
import caosdb.server.utils.Initialization;
import java.io.IOException; import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.LinkedList; import java.util.LinkedList;
...@@ -47,6 +38,14 @@ import org.antlr.v4.runtime.Token; ...@@ -47,6 +38,14 @@ import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.ParseTree; import org.antlr.v4.runtime.tree.ParseTree;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import caosdb.server.CaosDBServer;
import caosdb.server.database.access.Access;
import caosdb.server.database.backend.implementation.MySQL.ConnectionException;
import caosdb.server.database.exceptions.TransactionException;
import caosdb.server.query.CQLParser.CqContext;
import caosdb.server.query.Query.Pattern;
import caosdb.server.query.Query.QueryException;
import caosdb.server.utils.Initialization;
public class TestCQL { public class TestCQL {
...@@ -229,6 +228,10 @@ public class TestCQL { ...@@ -229,6 +228,10 @@ public class TestCQL {
String filepath_pat02 = "/foo\\\\*/"; // -> \\* (2) String filepath_pat02 = "/foo\\\\*/"; // -> \\* (2)
String filepath_pat03 = "/foo\\\\\\\\*/"; // -> \\\\* (4) String filepath_pat03 = "/foo\\\\\\\\*/"; // -> \\\\* (4)
String filepath_pat04 = "/foo**/"; String filepath_pat04 = "/foo**/";
String query_filepath_quotes =
"FIND FILE WHICH IS STORED AT '/SimulationData/2016_single/2018-01-10/**'";
String query_filepath_quotes_2 =
"FIND FILE WHICH IS STORED AT /SimulationData/2016_single/2018-01-10/**";
String referenceByLikePattern = "FIND ENTITY WHICH IS REFERENCED BY *name*"; String referenceByLikePattern = "FIND ENTITY WHICH IS REFERENCED BY *name*";
...@@ -1596,7 +1599,7 @@ public class TestCQL { ...@@ -1596,7 +1599,7 @@ public class TestCQL {
assertNotNull(sfq.filter); assertNotNull(sfq.filter);
assertEquals(StoredAt.class.getName(), sfq.filter.getClass().getName()); assertEquals(StoredAt.class.getName(), sfq.filter.getClass().getName());
assertEquals("SAT(bla/bla/bla)", ((StoredAt) sfq.filter).toString()); assertEquals("SAT(/bla/bla/bla)", ((StoredAt) sfq.filter).toString());
} }
@Test @Test
...@@ -1642,7 +1645,7 @@ public class TestCQL { ...@@ -1642,7 +1645,7 @@ public class TestCQL {
assertNotNull(sfq.filter); assertNotNull(sfq.filter);
assertEquals(StoredAt.class.getName(), sfq.filter.getClass().getName()); assertEquals(StoredAt.class.getName(), sfq.filter.getClass().getName());
assertEquals("SAT(bla/bla/bla)", ((StoredAt) sfq.filter).toString()); assertEquals("SAT(/bla/bla/bla)", ((StoredAt) sfq.filter).toString());
} }
@Test @Test
...@@ -1687,7 +1690,7 @@ public class TestCQL { ...@@ -1687,7 +1690,7 @@ public class TestCQL {
assertEquals(Query.Role.FILE, sfq.r); assertEquals(Query.Role.FILE, sfq.r);
assertEquals(StoredAt.class.getName(), sfq.filter.getClass().getName()); assertEquals(StoredAt.class.getName(), sfq.filter.getClass().getName());
assertEquals("SAT(bla/bla/bla/)", ((StoredAt) sfq.filter).toString()); assertEquals("SAT(/bla/bla/bla/)", ((StoredAt) sfq.filter).toString());
} }
/** /**
...@@ -1738,7 +1741,7 @@ public class TestCQL { ...@@ -1738,7 +1741,7 @@ public class TestCQL {
assertNotNull(sfq.filter); assertNotNull(sfq.filter);
assertEquals(StoredAt.class.getName(), sfq.filter.getClass().getName()); assertEquals(StoredAt.class.getName(), sfq.filter.getClass().getName());
assertEquals("SAT(bla/bla/bla.html)", ((StoredAt) sfq.filter).toString()); assertEquals("SAT(/bla/bla/bla.html)", ((StoredAt) sfq.filter).toString());
} }
/** /**
...@@ -1789,7 +1792,7 @@ public class TestCQL { ...@@ -1789,7 +1792,7 @@ public class TestCQL {
assertNotNull(sfq.filter); assertNotNull(sfq.filter);
assertEquals(StoredAt.class.getName(), sfq.filter.getClass().getName()); assertEquals(StoredAt.class.getName(), sfq.filter.getClass().getName());
assertEquals("SAT(bla/bla.html)", ((StoredAt) sfq.filter).toString()); assertEquals("SAT(/bla/bla.html)", ((StoredAt) sfq.filter).toString());
} }
/** /**
...@@ -1840,7 +1843,7 @@ public class TestCQL { ...@@ -1840,7 +1843,7 @@ public class TestCQL {
assertNotNull(sfq.filter); assertNotNull(sfq.filter);
assertEquals(StoredAt.class.getName(), sfq.filter.getClass().getName()); assertEquals(StoredAt.class.getName(), sfq.filter.getClass().getName());
assertEquals("SAT(bla/bla_bla.html)", ((StoredAt) sfq.filter).toString()); assertEquals("SAT(/bla/bla_bla.html)", ((StoredAt) sfq.filter).toString());
} }
/** /**
...@@ -1894,9 +1897,9 @@ public class TestCQL { ...@@ -1894,9 +1897,9 @@ public class TestCQL {
assertEquals(StoredAt.class.getName(), sfq.filter.getClass().getName()); assertEquals(StoredAt.class.getName(), sfq.filter.getClass().getName());
final StoredAt storedAt = (StoredAt) sfq.filter; final StoredAt storedAt = (StoredAt) sfq.filter;
assertFalse(storedAt.requiresPatternMatching(storedAt.location)); assertFalse(StoredAt.requiresPatternMatching(storedAt.location));
assertEquals( assertEquals(
"SAT(" + absPath.toString().replaceFirst("^/", "") + ")", "SAT(/" + absPath.toString().replaceFirst("^/", "") + ")",
((StoredAt) sfq.filter).toString()); ((StoredAt) sfq.filter).toString());
} }
...@@ -1955,7 +1958,7 @@ public class TestCQL { ...@@ -1955,7 +1958,7 @@ public class TestCQL {
assertFalse(c.getFilters().isEmpty()); assertFalse(c.getFilters().isEmpty());
assertNotNull(c.getFilters().get(0)); assertNotNull(c.getFilters().get(0));
assertEquals(StoredAt.class.getName(), c.getFilters().get(0).getClass().getName()); assertEquals(StoredAt.class.getName(), c.getFilters().get(0).getClass().getName());
assertEquals("SAT(bla/bla/bla)", ((StoredAt) c.getFilters().get(0)).toString()); assertEquals("SAT(/bla/bla/bla)", ((StoredAt) c.getFilters().get(0)).toString());
assertNotNull(c.getFilters().get(1)); assertNotNull(c.getFilters().get(1));
assertEquals(POV.class.getName(), c.getFilters().get(1).getClass().getName()); assertEquals(POV.class.getName(), c.getFilters().get(1).getClass().getName());
assertEquals("POV(pname2,=,val2)", ((POV) c.getFilters().get(1)).toString()); assertEquals("POV(pname2,=,val2)", ((POV) c.getFilters().get(1)).toString());
...@@ -2022,7 +2025,7 @@ public class TestCQL { ...@@ -2022,7 +2025,7 @@ public class TestCQL {
assertFalse(c.getFilters().isEmpty()); assertFalse(c.getFilters().isEmpty());
assertNotNull(c.getFilters().get(1)); assertNotNull(c.getFilters().get(1));
assertEquals(StoredAt.class.getName(), c.getFilters().get(1).getClass().getName()); assertEquals(StoredAt.class.getName(), c.getFilters().get(1).getClass().getName());
assertEquals("SAT(bla/bla/bla)", ((StoredAt) c.getFilters().get(1)).toString()); assertEquals("SAT(/bla/bla/bla)", ((StoredAt) c.getFilters().get(1)).toString());
assertNotNull(c.getFilters().get(0)); assertNotNull(c.getFilters().get(0));
assertEquals(POV.class.getName(), c.getFilters().get(0).getClass().getName()); assertEquals(POV.class.getName(), c.getFilters().get(0).getClass().getName());
assertEquals("POV(pname2,=,val2)", ((POV) c.getFilters().get(0)).toString()); assertEquals("POV(pname2,=,val2)", ((POV) c.getFilters().get(0)).toString());
...@@ -4972,7 +4975,7 @@ public class TestCQL { ...@@ -4972,7 +4975,7 @@ public class TestCQL {
assertTrue(sfq.filter instanceof StoredAt); assertTrue(sfq.filter instanceof StoredAt);
final StoredAt storedAt = (StoredAt) sfq.filter; final StoredAt storedAt = (StoredAt) sfq.filter;
assertEquals("SAT(data/bla.acq)", storedAt.toString()); assertEquals("SAT(/data/bla.acq)", storedAt.toString());
} }
/** String query42 = "FIND FILE WHICH IS STORED AT /*"; */ /** String query42 = "FIND FILE WHICH IS STORED AT /*"; */
...@@ -5010,7 +5013,7 @@ public class TestCQL { ...@@ -5010,7 +5013,7 @@ public class TestCQL {
assertTrue(sfq.filter instanceof StoredAt); assertTrue(sfq.filter instanceof StoredAt);
final StoredAt storedAt = (StoredAt) sfq.filter; final StoredAt storedAt = (StoredAt) sfq.filter;
assertTrue(storedAt.requiresPatternMatching(storedAt.location)); assertTrue(storedAt.requiresPatternMatching(storedAt.location));
assertEquals("SAT(%)", storedAt.toString()); assertEquals("SAT(%%)", storedAt.toString());
} }
/** String query43 = "FIND FILE WHICH IS STORED AT /* /" (without the space); */ /** String query43 = "FIND FILE WHICH IS STORED AT /* /" (without the space); */
...@@ -5048,7 +5051,7 @@ public class TestCQL { ...@@ -5048,7 +5051,7 @@ public class TestCQL {
assertTrue(sfq.filter instanceof StoredAt); assertTrue(sfq.filter instanceof StoredAt);
final StoredAt storedAt = (StoredAt) sfq.filter; final StoredAt storedAt = (StoredAt) sfq.filter;
assertTrue(storedAt.requiresPatternMatching(storedAt.location)); assertTrue(storedAt.requiresPatternMatching(storedAt.location));
assertEquals("SAT(%/)", storedAt.toString()); assertEquals("SAT(%%/)", storedAt.toString());
} }
/** String query44 = "FIND FILE WHICH IS STORED AT /** /"; */ /** String query44 = "FIND FILE WHICH IS STORED AT /** /"; */
...@@ -5159,7 +5162,7 @@ public class TestCQL { ...@@ -5159,7 +5162,7 @@ public class TestCQL {
assertTrue(sfq.filter instanceof StoredAt); assertTrue(sfq.filter instanceof StoredAt);
final StoredAt storedAt = (StoredAt) sfq.filter; final StoredAt storedAt = (StoredAt) sfq.filter;
assertEquals("SAT(%/%%)", storedAt.toString()); assertEquals("SAT(%%/%%)", storedAt.toString());
} }
/** String query47 = "FIND FILE WHICH IS STORED AT /* /*.acq"; */ /** String query47 = "FIND FILE WHICH IS STORED AT /* /*.acq"; */
...@@ -5196,7 +5199,7 @@ public class TestCQL { ...@@ -5196,7 +5199,7 @@ public class TestCQL {
assertTrue(sfq.filter instanceof StoredAt); assertTrue(sfq.filter instanceof StoredAt);
final StoredAt storedAt = (StoredAt) sfq.filter; final StoredAt storedAt = (StoredAt) sfq.filter;
assertEquals("SAT(%/%%.acq)", storedAt.toString()); assertEquals("SAT(%%/%%.acq)", storedAt.toString());
} }
/** String query48 = "FIND FILE WHICH IS STORED AT /** /*.acq"; */ /** String query48 = "FIND FILE WHICH IS STORED AT /** /*.acq"; */
...@@ -5270,7 +5273,7 @@ public class TestCQL { ...@@ -5270,7 +5273,7 @@ public class TestCQL {
assertTrue(sfq.filter instanceof StoredAt); assertTrue(sfq.filter instanceof StoredAt);
final StoredAt storedAt = (StoredAt) sfq.filter; final StoredAt storedAt = (StoredAt) sfq.filter;
assertEquals("SAT(%.acq)", storedAt.toString()); assertEquals("SAT(%%.acq)", storedAt.toString());
} }
/** String query50 = "FIND FILE WHICH IS STORED AT *.acq"; */ /** String query50 = "FIND FILE WHICH IS STORED AT *.acq"; */
...@@ -6016,7 +6019,7 @@ public class TestCQL { ...@@ -6016,7 +6019,7 @@ public class TestCQL {
assertTrue(sfq.filter instanceof StoredAt); assertTrue(sfq.filter instanceof StoredAt);
final StoredAt storedAt = (StoredAt) sfq.filter; final StoredAt storedAt = (StoredAt) sfq.filter;
assertEquals("SAT(dir/with/date/2016-05-15)", storedAt.toString()); assertEquals("SAT(/dir/with/date/2016-05-15)", storedAt.toString());
} }
/** String query55b = "FIND ename WHICH IS STORED AT /dir/with/date/2016-05-15/**"; */ /** String query55b = "FIND ename WHICH IS STORED AT /dir/with/date/2016-05-15/**"; */
...@@ -6178,4 +6181,76 @@ public class TestCQL { ...@@ -6178,4 +6181,76 @@ public class TestCQL {
assertTrue(f instanceof Backreference); assertTrue(f instanceof Backreference);
assertEquals("%name%", ((Backreference) f).getEntity()); assertEquals("%name%", ((Backreference) f).getEntity());
} }
@Test
public void testFilePathInQuotes() {
CQLLexer lexer = new CQLLexer(CharStreams.fromString(query_filepath_quotes));
final CommonTokenStream tokens = new CommonTokenStream(lexer);
final CQLParser parser = new CQLParser(tokens);
final CqContext sfq = parser.cq();
// 4 children: FIND, role, WHICHCLAUSE, EOF
assertEquals(4, sfq.getChildCount());
assertEquals("FIND", sfq.getChild(0).getText());
assertEquals("FILE", sfq.getChild(1).getText());
assertEquals(
"WHICHIS STORED AT'/SimulationData/2016_single/2018-01-10/**'", sfq.getChild(2).getText());
assertEquals("FILE", sfq.r.toString());
assertNull(sfq.e);
assertEquals("StoredAt", sfq.filter.getClass().getSimpleName());
final ParseTree whichclause = sfq.getChild(2);
// 2 children: WHICH, POV
assertEquals(2, whichclause.getChildCount());
assertEquals("WHICH", whichclause.getChild(0).getText());
assertEquals(
"IS STORED AT'/SimulationData/2016_single/2018-01-10/**'",
whichclause.getChild(1).getText());
final ParseTree satFilter = whichclause.getChild(1).getChild(0);
assertEquals(2, satFilter.getChildCount());
assertEquals("IS STORED AT", satFilter.getChild(0).getText());
assertEquals("'/SimulationData/2016_single/2018-01-10/**'", satFilter.getChild(1).getText());
assertTrue(sfq.filter instanceof StoredAt);
final StoredAt storedAt = (StoredAt) sfq.filter;
assertTrue(storedAt.pattern_matching);
assertEquals("SAT(SimulationData/2016\\_single/2018-01-10/%)", storedAt.toString());
}
public void testFilePathInQuotes2() {
CQLLexer lexer = new CQLLexer(CharStreams.fromString(query_filepath_quotes_2));
final CommonTokenStream tokens = new CommonTokenStream(lexer);
final CQLParser parser = new CQLParser(tokens);
final CqContext sfq = parser.cq();
// 4 children: FIND, role, WHICHCLAUSE, EOF
assertEquals(4, sfq.getChildCount());
assertEquals("FIND", sfq.getChild(0).getText());
assertEquals("FILE", sfq.getChild(1).getText());
assertEquals(
"WHICHIS STORED AT/SimulationData/2016_single/2018-01-10/**", sfq.getChild(2).getText());
assertEquals("FILE", sfq.r.toString());
assertNull(sfq.e);
assertEquals("StoredAt", sfq.filter.getClass().getSimpleName());
final ParseTree whichclause = sfq.getChild(2);
// 2 children: WHICH, POV
assertEquals(2, whichclause.getChildCount());
assertEquals("WHICH", whichclause.getChild(0).getText());
assertEquals(
"IS STORED AT/SimulationData/2016_single/2018-01-10/**", whichclause.getChild(1).getText());
final ParseTree satFilter = whichclause.getChild(1).getChild(0);
assertEquals(2, satFilter.getChildCount());
assertEquals("IS STORED AT", satFilter.getChild(0).getText());
assertEquals("'/SimulationData/2016_single/2018-01-10/**'", satFilter.getChild(1).getText());
assertTrue(sfq.filter instanceof StoredAt);
final StoredAt storedAt = (StoredAt) sfq.filter;
assertTrue(storedAt.pattern_matching);
assertEquals("SAT(SimulationData/2016\\_single/2018-01-10/%%)", storedAt.toString());
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment