This is an automated email from the ASF dual-hosted git repository.
rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git
The following commit(s) were added to refs/heads/master by this push:
new 3809734a30 FELIX-6672 - rewrite of detection logic to save previous
char, resolving patterns (esp) start/stop tokens (//, /*, */) spreading across
two reads. (#250)
3809734a30 is described below
commit 3809734a305dd8bbca82c18136f08627861d3054
Author: Dominik Süß <[email protected]>
AuthorDate: Tue Nov 28 11:43:28 2023 +0100
FELIX-6672 - rewrite of detection logic to save previous char, resolving
patterns (esp) start/stop tokens (//, /*, */) spreading across two reads. (#250)
---
.../apache/felix/cm/json/io/impl/JsonSupport.java | 111 +++++++++++++--------
.../felix/cm/json/io/impl/JsonSupportTest.java | 15 +++
2 files changed, 84 insertions(+), 42 deletions(-)
diff --git
a/cm.json/src/main/java/org/apache/felix/cm/json/io/impl/JsonSupport.java
b/cm.json/src/main/java/org/apache/felix/cm/json/io/impl/JsonSupport.java
index 278525e890..4123ea091b 100644
--- a/cm.json/src/main/java/org/apache/felix/cm/json/io/impl/JsonSupport.java
+++ b/cm.json/src/main/java/org/apache/felix/cm/json/io/impl/JsonSupport.java
@@ -244,6 +244,8 @@ public class JsonSupport {
private boolean insideComment = false;
private boolean insideLineComment = false;
private boolean insideString = false;
+ private boolean isSkippedSlash = false;
+ private char oldChar = 0; // priming with 0 as it is not part of
comment or string escaping chars
public CommentRemovingReader(Reader reader) {
super(new BufferedReader(reader));
@@ -268,84 +270,109 @@ public class JsonSupport {
// Detect String start/end if not inside a comment
if (!insideComment && !insideLineComment) {
if (c == '"') {
- // handle escaped quotes inside strings
- if (i > 0 && cbuf[i - 1] == '\\') {
- // escaped quote inside a string, include
both the backslash and the quote
- currentLine.append(c);
- continue;
+ // only flip if not escaped quotes
+ if (oldChar != '\\') {
+ insideString = !insideString;
}
- insideString = !insideString;
+ currentLine.append(c);
+ oldChar = c;
+ continue;
}
}
// Handle comments only if not inside a string
if (!insideString) {
- // Detect start of single-line comment
- if (!insideComment && c == '/' && i < off +
charsRead - 1 && cbuf[i + 1] == '/') {
- insideLineComment = true;
- i++; // Skip '/' character
+ // Detect potential start of a comment by
detecting a slash
+ if(!insideComment && !insideLineComment && c ==
'/') {
+ // If the previous character was also a slash,
we are inside a single-line comment
+ if (oldChar == '/') {
+ insideLineComment = true;
+ isSkippedSlash = false;
+ } else {
+ // skipping slash for verification if this
is comment - will be ammended on next char if non-comment
+ isSkippedSlash = true;
+ }
+ oldChar = c;
continue;
}
-
- // Detect start of multi-line comment
- if (!insideComment && c == '/' && i < off +
charsRead - 1 && cbuf[i + 1] == '*') {
- insideComment = true;
- i++; // Skip '*' character
+ // Detect potential start of a multiline comment
by detecting a star
+ if(!insideComment && !insideLineComment && c ==
'*') {
+ // If the previous character was also a slash,
we are inside a multi-line comment
+ if (oldChar == '/') {
+ insideComment = true;
+ isSkippedSlash = false;
+ } else {
+ // otherwise this is not a comment, just a
star
+ currentLine.append(c);
+ }
+ oldChar = c;
continue;
}
- // Detect end of multi-line comment
- if (insideComment && c == '*' && i < off +
charsRead - 1 && cbuf[i + 1] == '/') {
- insideComment = false;
- i++; // Skip '/' character
- continue;
+ // if if we skipped over a / above and we're not
within a comment, we need to append the oldChar to the currentLine
+ if (!insideComment && !insideLineComment &&
isSkippedSlash) {
+ currentLine.append('/');
+ isSkippedSlash = false;
}
- // Skip characters inside single-line comments
+ // Detect potential end of a linecomment by
detecting a newline
if (insideLineComment && c == '\n') {
insideLineComment = false;
+ currentLine.append(c);
+ oldChar = c;
+ continue;
}
- // Preserve newline characters inside multiline
comments
- if (insideComment && !insideLineComment && c ==
'\n') {
- currentLine.append(c);
+ // Skip over characters inside single-line comments
+ if (insideLineComment) {
+ oldChar = c;
continue;
}
- // Skip characters inside multiline comments
- if (insideComment && c == '*' && i < off +
charsRead - 1 && cbuf[i + 1] == '/') {
+ // Detect potential end of a multiline comment by
detecting a slash that is preceded by a star
+ if (insideComment && c == '/' && oldChar == '*') {
insideComment = false;
- i++; // Skip '/' character
+ oldChar = c;
continue;
}
- // Skip characters inside single-line comments
- if (insideLineComment && c == '\n') {
- insideLineComment = false;
+ // Skip over characters inside multi-line comments
but preserve newlines
+ if (insideComment) {
+ if(c == '\n') {
+ currentLine.append(c);
+ }
+ oldChar = c;
+ continue;
}
}
-
- // Preserve characters outside comments
- if (!insideComment && !insideLineComment) {
- currentLine.append(c);
- }
+ // Preserve characters outside comments
+ if (!insideComment && !insideLineComment) {
+ currentLine.append(c);
}
+ oldChar = c;
+ }
- filteredContent.append(currentLine.toString());
+ filteredContent.append(currentLine.toString());
- char[] filteredChars =
filteredContent.toString().toCharArray();
- int filteredLen = Math.min(filteredChars.length, len);
- System.arraycopy(filteredChars, 0, cbuf, off, filteredLen);
- return filteredLen;
- }
- return charsRead;
+ char[] filteredChars =
filteredContent.toString().toCharArray();
+ int filteredLen = Math.min(filteredChars.length, len);
+ System.arraycopy(filteredChars, 0, cbuf, off, filteredLen);
+ return filteredLen;
+
+ }
+ return charsRead;
}
@Override
public void close() throws IOException {
if (!closed) {
closed = true;
+ closed = false;
+ insideComment = false;
+ insideLineComment = false;
+ insideString = false;
+ isSkippedSlash = false;
in.close();
super.close();
}
diff --git
a/cm.json/src/test/java/org/apache/felix/cm/json/io/impl/JsonSupportTest.java
b/cm.json/src/test/java/org/apache/felix/cm/json/io/impl/JsonSupportTest.java
index 3dfc1d35c1..fcb681caf5 100644
---
a/cm.json/src/test/java/org/apache/felix/cm/json/io/impl/JsonSupportTest.java
+++
b/cm.json/src/test/java/org/apache/felix/cm/json/io/impl/JsonSupportTest.java
@@ -307,4 +307,19 @@ public class JsonSupportTest {
+ "}\n", parse(input));
}
+ @Test
+ public void testSlashAtEndOfRead() throws Exception {
+ String input = "This is a test string // Next string \n"
+ + "next line" ;
+ Reader reader = JsonSupport.createCommentRemovingReader(new
StringReader(input));
+
+ char[] buffer = new char[22];
+ int numRead = reader.read(buffer, 0, 22);
+ assertEquals("This is a test string ", new String(buffer, 0, numRead));
+
+ buffer = new char[30];
+ numRead = reader.read(buffer, 0, 30);
+ assertEquals("\nnext line", new String(buffer, 0, numRead));
+ }
+
}