From e2a3c0b59b0b8218dbb6ceaf2694d00c83e115c4 Mon Sep 17 00:00:00 2001
From: Olivier Lamy
Date: Fri, 27 Aug 2021 10:07:22 +1000
Subject: [PATCH 01/28] [maven-release-plugin] prepare for next development
iteration
---
pom.xml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/pom.xml b/pom.xml
index 164b7b15..014f729a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@ limitations under the License.
plexus-utils
- 3.4.1
+ 3.4.2-SNAPSHOT
Plexus Common Utilities
A collection of various utility classes to ease working with strings, files, command lines, XML and
@@ -37,7 +37,7 @@ limitations under the License.
scm:git:git@github.com:codehaus-plexus/plexus-utils.git
scm:git:git@github.com:codehaus-plexus/plexus-utils.git
http://github.com/codehaus-plexus/plexus-utils
- plexus-utils-3.4.1
+ HEAD
github
@@ -51,7 +51,7 @@ limitations under the License.
- 2021-08-27T00:06:38Z
+ 2021-08-27T00:07:22Z
From cbe5a84f604e50c31efce67504c00962b7565841 Mon Sep 17 00:00:00 2001
From: Olivier Lamy
Date: Fri, 27 Aug 2021 13:57:34 +1000
Subject: [PATCH 02/28] cache action not needed anymore
---
.github/workflows/maven.yml | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 10cbc78e..6f98066c 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -35,15 +35,6 @@ jobs:
- name: Checkout
uses: actions/checkout@v2.3.4
- - name: Set up cache for ~./m2/repository
- uses: actions/cache@v2.1.6
- with:
- path: ~/.m2/repository
- key: maven-${{ matrix.os }}-java${{ matrix.java }}-${{ hashFiles('**/pom.xml') }}
- restore-keys: |
- maven-${{ matrix.os }}-java${{ matrix.java }}-
- maven-${{ matrix.os }}-
-
- name: Set up JDK
uses: actions/setup-java@v2.3.0
with:
From 138d57efe3756f2d505f01720747b89af826b851 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Thu, 30 Sep 2021 02:02:09 +0000
Subject: [PATCH 03/28] Bump actions/setup-java from 2.3.0 to 2.3.1
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 2.3.0 to 2.3.1.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/v2.3.0...v2.3.1)
---
updated-dependencies:
- dependency-name: actions/setup-java
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
.github/workflows/maven.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 6f98066c..2ea5498e 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -36,7 +36,7 @@ jobs:
uses: actions/checkout@v2.3.4
- name: Set up JDK
- uses: actions/setup-java@v2.3.0
+ uses: actions/setup-java@v2.3.1
with:
cache: 'maven'
distribution: ${{ matrix.jdk }}
From dd8e9820e5b1291156a6a013b6b34a26e44c58e2 Mon Sep 17 00:00:00 2001
From: Olivier Lamy
Date: Fri, 15 Oct 2021 14:27:59 +1000
Subject: [PATCH 04/28] use github shared actions (#171)
* use shared actions
Signed-off-by: Olivier Lamy
* fix reference
Signed-off-by: Olivier Lamy
---
.github/workflows/maven.yml | 25 ++-----------------------
1 file changed, 2 insertions(+), 23 deletions(-)
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 2ea5498e..776d2439 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -21,26 +21,5 @@ on: [push, pull_request]
jobs:
build:
-
- strategy:
- matrix:
- os: [ubuntu-latest, windows-latest, macOS-latest]
- java: [8, 11, 16, 17-ea]
- jdk: [temurin, zulu, adopt-openj9]
- fail-fast: false
-
- runs-on: ${{ matrix.os }}
-
- steps:
- - name: Checkout
- uses: actions/checkout@v2.3.4
-
- - name: Set up JDK
- uses: actions/setup-java@v2.3.1
- with:
- cache: 'maven'
- distribution: ${{ matrix.jdk }}
- java-version: ${{ matrix.java }}
-
- - name: Build with Maven
- run: mvn verify javadoc:javadoc -e -B -V
+ name: Build it
+ uses: codehaus-plexus/.github/.github/workflows/maven.yml@v0.0.1
From e8a8433894eae9e8f82cbba4b903508362e9322a Mon Sep 17 00:00:00 2001
From: Michael Osipov
Date: Sun, 7 Nov 2021 17:52:50 +0100
Subject: [PATCH 05/28] Don't ignore valid SCM files
This closes #174 and fixes #71
---
.../codehaus/plexus/util/AbstractScanner.java | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/main/java/org/codehaus/plexus/util/AbstractScanner.java b/src/main/java/org/codehaus/plexus/util/AbstractScanner.java
index af3fbc4a..16d64ef9 100644
--- a/src/main/java/org/codehaus/plexus/util/AbstractScanner.java
+++ b/src/main/java/org/codehaus/plexus/util/AbstractScanner.java
@@ -42,8 +42,8 @@ public abstract class AbstractScanner
* SurroundSCM: **/.MySCMServerInfo
* Mac: **/.DS_Store
* Serena Dimension: **/.metadata, **/.metadata/**
- * Mercurial: **/.hg, **/.hg/**, **/.hgignore
- * GIT: **/.git, **/.gitignore, **/.gitattributes, **/.git/**
+ * Mercurial: **/.hg, **/.hg/**
+ * Git: **/.git, **/.git/**
* Bitkeeper: **/BitKeeper, **/BitKeeper/**, **/ChangeSet,
* **/ChangeSet/**
* Darcs: **/_darcs, **/_darcs/**, **/.darcsrepo,
@@ -90,10 +90,10 @@ public abstract class AbstractScanner
"**/.metadata", "**/.metadata/**",
// Mercurial
- "**/.hg", "**/.hgignore", "**/.hg/**",
+ "**/.hg", "**/.hg/**",
// git
- "**/.git", "**/.gitignore", "**/.gitattributes", "**/.git/**",
+ "**/.git", "**/.git/**",
// BitKeeper
"**/BitKeeper", "**/BitKeeper/**", "**/ChangeSet", "**/ChangeSet/**",
@@ -124,7 +124,7 @@ public abstract class AbstractScanner
* @since 3.3.0
*/
protected Comparator filenameComparator;
-
+
/**
* Sets whether or not the file system should be regarded as case sensitive.
*
@@ -137,7 +137,7 @@ public void setCaseSensitive( boolean isCaseSensitive )
/**
* Tests whether or not a given path matches the start of a given pattern up to the first "**".
- *
+ *
* This is not a general purpose test and should only be used if you can live with false positives. For example,
* pattern=**\a and str=b will yield true.
*
@@ -152,7 +152,7 @@ protected static boolean matchPatternStart( String pattern, String str )
/**
* Tests whether or not a given path matches the start of a given pattern up to the first "**".
- *
+ *
* This is not a general purpose test and should only be used if you can live with false positives. For example,
* pattern=**\a and str=b will yield true.
*
@@ -223,7 +223,7 @@ protected static boolean match( String pattern, String str, boolean isCaseSensit
/**
* Sets the list of include patterns to use. All '/' and '\' characters are replaced by
* File.separatorChar, so the separator used need not match File.separatorChar.
- *
+ *
* When a pattern ends with a '/' or '\', "**" is appended.
*
* @param includes A list of include patterns. May be null, indicating that all files should be
@@ -253,7 +253,7 @@ public void setIncludes( String[] includes )
/**
* Sets the list of exclude patterns to use. All '/' and '\' characters are replaced by
* File.separatorChar, so the separator used need not match File.separatorChar.
- *
+ *
* When a pattern ends with a '/' or '\', "**" is appended.
*
* @param excludes A list of exclude patterns. May be null, indicating that no files should be
From 1f93cc8583f872b7bc01bef1dc32979f0a2335bb Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 8 Nov 2021 15:41:08 +1000
Subject: [PATCH 06/28] Bump actions/checkout from 2.3.4 to 2.4.0 (#173)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2.3.4 to 2.4.0.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2.3.4...v2.4.0)
---
updated-dependencies:
- dependency-name: actions/checkout
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
---
.github/workflows/codeql-analysis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index b0dfc833..3f39b7e2 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -32,7 +32,7 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v2.3.4
+ uses: actions/checkout@v2.4.0
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
From f3f41548bed5935b69af3caa56373b461f11068b Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Mon, 7 Feb 2022 02:02:56 +0000
Subject: [PATCH 07/28] Bump release-drafter/release-drafter from 5.15.0 to
5.18.1
Bumps [release-drafter/release-drafter](https://github.com/release-drafter/release-drafter) from 5.15.0 to 5.18.1.
- [Release notes](https://github.com/release-drafter/release-drafter/releases)
- [Commits](https://github.com/release-drafter/release-drafter/compare/v5.15.0...v5.18.1)
---
updated-dependencies:
- dependency-name: release-drafter/release-drafter
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
.github/workflows/release-drafter.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml
index 4e2af995..4ece1c1a 100644
--- a/.github/workflows/release-drafter.yml
+++ b/.github/workflows/release-drafter.yml
@@ -7,6 +7,6 @@ jobs:
update_release_draft:
runs-on: ubuntu-latest
steps:
- - uses: release-drafter/release-drafter@v5.15.0
+ - uses: release-drafter/release-drafter@v5.18.1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
From 9468fd780d9611fb96215f6532da9d62926ebf48 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 24 Dec 2021 02:02:56 +0000
Subject: [PATCH 08/28] Bump jmh-core from 1.33 to 1.34
Bumps jmh-core from 1.33 to 1.34.
---
updated-dependencies:
- dependency-name: org.openjdk.jmh:jmh-core
dependency-type: direct:development
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 014f729a..8166a9f2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,7 +64,7 @@ limitations under the License.
org.openjdk.jmh
jmh-core
- 1.33
+ 1.34
test
From 667ce0ee7ce353a09f38511e91a51c94c2aa7e36 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 24 Dec 2021 02:02:54 +0000
Subject: [PATCH 09/28] Bump jmh-generator-annprocess from 1.33 to 1.34
Bumps jmh-generator-annprocess from 1.33 to 1.34.
---
updated-dependencies:
- dependency-name: org.openjdk.jmh:jmh-generator-annprocess
dependency-type: direct:development
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 8166a9f2..a758c676 100644
--- a/pom.xml
+++ b/pom.xml
@@ -70,7 +70,7 @@ limitations under the License.
org.openjdk.jmh
jmh-generator-annprocess
- 1.33
+ 1.34
test
From 3896620b4fbf031b1b02b4d46b328c5839a231da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotrek=20=C5=BBygie=C5=82o?=
Date: Thu, 24 Feb 2022 12:28:56 +0100
Subject: [PATCH 10/28] Use (already) precalculated value
---
.../org/codehaus/plexus/util/xml/pull/MXSerializer.java | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/main/java/org/codehaus/plexus/util/xml/pull/MXSerializer.java b/src/main/java/org/codehaus/plexus/util/xml/pull/MXSerializer.java
index cd1edc59..c69db3f4 100644
--- a/src/main/java/org/codehaus/plexus/util/xml/pull/MXSerializer.java
+++ b/src/main/java/org/codehaus/plexus/util/xml/pull/MXSerializer.java
@@ -460,15 +460,15 @@ public void startDocument( String encoding, Boolean standalone )
if ( encoding != null )
{
out.write( " encoding=" );
- out.write( attributeUseApostrophe ? '\'' : '"' );
+ out.write( apos );
out.write( encoding );
- out.write( attributeUseApostrophe ? '\'' : '"' );
+ out.write( apos );
// out.write('\'');
}
if ( standalone != null )
{
out.write( " standalone=" );
- out.write( attributeUseApostrophe ? '\'' : '"' );
+ out.write( apos );
if ( standalone )
{
out.write( "yes" );
@@ -477,7 +477,7 @@ public void startDocument( String encoding, Boolean standalone )
{
out.write( "no" );
}
- out.write( attributeUseApostrophe ? '\'' : '"' );
+ out.write( apos );
// if(standalone.booleanValue()) {
// out.write(" standalone='yes'");
// } else {
From b99f7c0e46d8b08d63afa4c2c7d274ebf5ebcc94 Mon Sep 17 00:00:00 2001
From: Gabriel Belingueres
Date: Sat, 2 Apr 2022 12:31:39 -0300
Subject: [PATCH 11/28] Fixed regressions:
* #163 - new case: Don't assume UTF8 as default, to allow parsing from String.
* #194 - Incorrect getText() after parsing the DOCDECL section.
* Added tests exercising other regressions exposed while fixing this issues.
---
.../plexus/util/xml/pull/MXParser.java | 157 ++++--
.../plexus/util/xml/pull/MXParserTest.java | 495 ++++++++++++++++++
src/test/resources/xml/test-entities-dos.xml | 6 +
.../xml/test-entities-in-attr-dos.xml | 9 +
.../resources/xml/test-entities-in-attr.xml | 9 +
src/test/resources/xml/test-entities.xml | 6 +
6 files changed, 637 insertions(+), 45 deletions(-)
create mode 100644 src/test/resources/xml/test-entities-dos.xml
create mode 100644 src/test/resources/xml/test-entities-in-attr-dos.xml
create mode 100644 src/test/resources/xml/test-entities-in-attr.xml
create mode 100644 src/test/resources/xml/test-entities.xml
diff --git a/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java b/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
index 3874f572..e21b66cb 100644
--- a/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
+++ b/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
@@ -124,7 +124,7 @@ private String newStringIntern( char[] cbuf, int off, int len )
// private String elValue[];
private int elNamespaceCount[];
- private String fileEncoding = "UTF8";
+ private String fileEncoding = null;
/**
* Make sure that we have enough space to keep element stack if passed size. It will always create one additional
@@ -587,8 +587,8 @@ else if ( FEATURE_XML_ROUNDTRIP.equals( name ) )
}
}
- /**
- * Unknown properties are always returned as false
+ /**
+ * Unknown properties are always returned as false
*/
@Override
public boolean getFeature( String name )
@@ -1596,11 +1596,11 @@ else if ( ch == '&' )
}
final int oldStart = posStart + bufAbsoluteStart;
final int oldEnd = posEnd + bufAbsoluteStart;
- final char[] resolvedEntity = parseEntityRef();
+ parseEntityRef();
if ( tokenize )
return eventType = ENTITY_REF;
// check if replacement text can be resolved !!!
- if ( resolvedEntity == null )
+ if ( resolvedEntityRefCharBuf == BUF_NOT_RESOLVED )
{
if ( entityRefName == null )
{
@@ -1628,7 +1628,7 @@ else if ( ch == '&' )
}
// assert usePC == true;
// write into PC replacement text - do merge for replacement text!!!!
- for ( char aResolvedEntity : resolvedEntity )
+ for ( char aResolvedEntity : resolvedEntityRefCharBuf )
{
if ( pcEnd >= pc.length )
{
@@ -2675,9 +2675,28 @@ else if ( ch == '\t' || ch == '\n' || ch == '\r' )
return ch;
}
- private char[] charRefOneCharBuf = new char[1];
+ // state representing that no entity ref have been resolved
+ private static final char[] BUF_NOT_RESOLVED = new char[0];
+
+ // predefined entity refs
+ private static final char[] BUF_LT = new char[] { '<' };
+ private static final char[] BUF_AMP = new char[] { '&' };
+ private static final char[] BUF_GT = new char[] { '>' };
+ private static final char[] BUF_APO = new char[] { '\'' };
+ private static final char[] BUF_QUOT = new char[] { '"' };
- private char[] parseEntityRef()
+ private char[] resolvedEntityRefCharBuf = BUF_NOT_RESOLVED;
+
+ /**
+ * parse Entity Ref, either a character entity or one of the predefined name entities.
+ *
+ * @return the length of the valid found character reference, which may be one of the predefined character reference
+ * names (resolvedEntityRefCharBuf contains the replaced chars). Returns the length of the not found entity
+ * name, otherwise.
+ * @throws XmlPullParserException if invalid XML is detected.
+ * @throws IOException if an I/O error is found.
+ */
+ private int parseCharOrPredefinedEntityRef()
throws XmlPullParserException, IOException
{
// entity reference http://www.w3.org/TR/2000/REC-xml-20001006#NT-Reference
@@ -2686,6 +2705,8 @@ private char[] parseEntityRef()
// ASSUMPTION just after &
entityRefName = null;
posStart = pos;
+ int len = 0;
+ resolvedEntityRefCharBuf = BUF_NOT_RESOLVED;
char ch = more();
if ( ch == '#' )
{
@@ -2750,7 +2771,6 @@ else if ( ch >= 'A' && ch <= 'F' )
ch = more();
}
}
- posEnd = pos - 1;
boolean isValidCodePoint = true;
try
@@ -2759,7 +2779,7 @@ else if ( ch >= 'A' && ch <= 'F' )
isValidCodePoint = isValidCodePoint( codePoint );
if ( isValidCodePoint )
{
- charRefOneCharBuf = Character.toChars( codePoint );
+ resolvedEntityRefCharBuf = Character.toChars( codePoint );
}
}
catch ( IllegalArgumentException e )
@@ -2775,14 +2795,14 @@ else if ( ch >= 'A' && ch <= 'F' )
if ( tokenize )
{
- text = newString( charRefOneCharBuf, 0, charRefOneCharBuf.length );
+ text = newString( resolvedEntityRefCharBuf, 0, resolvedEntityRefCharBuf.length );
}
- return charRefOneCharBuf;
+ len = resolvedEntityRefCharBuf.length;
}
else
{
// [68] EntityRef ::= '&' Name ';'
- // scan anem until ;
+ // scan name until ;
if ( !isNameStartChar( ch ) )
{
throw new XmlPullParserException( "entity reference names can not start with character '"
@@ -2801,17 +2821,15 @@ else if ( ch >= 'A' && ch <= 'F' )
+ printable( ch ) + "'", this, null );
}
}
- posEnd = pos - 1;
// determine what name maps to
- final int len = posEnd - posStart;
+ len = ( pos - 1 ) - posStart;
if ( len == 2 && buf[posStart] == 'l' && buf[posStart + 1] == 't' )
{
if ( tokenize )
{
text = "<";
}
- charRefOneCharBuf[0] = '<';
- return charRefOneCharBuf;
+ resolvedEntityRefCharBuf = BUF_LT;
// if(paramPC || isParserTokenizing) {
// if(pcEnd >= pc.length) ensurePC();
// pc[pcEnd++] = '<';
@@ -2823,8 +2841,7 @@ else if ( len == 3 && buf[posStart] == 'a' && buf[posStart + 1] == 'm' && buf[po
{
text = "&";
}
- charRefOneCharBuf[0] = '&';
- return charRefOneCharBuf;
+ resolvedEntityRefCharBuf = BUF_AMP;
}
else if ( len == 2 && buf[posStart] == 'g' && buf[posStart + 1] == 't' )
{
@@ -2832,8 +2849,7 @@ else if ( len == 2 && buf[posStart] == 'g' && buf[posStart + 1] == 't' )
{
text = ">";
}
- charRefOneCharBuf[0] = '>';
- return charRefOneCharBuf;
+ resolvedEntityRefCharBuf = BUF_GT;
}
else if ( len == 4 && buf[posStart] == 'a' && buf[posStart + 1] == 'p' && buf[posStart + 2] == 'o'
&& buf[posStart + 3] == 's' )
@@ -2842,8 +2858,7 @@ else if ( len == 4 && buf[posStart] == 'a' && buf[posStart + 1] == 'p' && buf[po
{
text = "'";
}
- charRefOneCharBuf[0] = '\'';
- return charRefOneCharBuf;
+ resolvedEntityRefCharBuf = BUF_APO;
}
else if ( len == 4 && buf[posStart] == 'q' && buf[posStart + 1] == 'u' && buf[posStart + 2] == 'o'
&& buf[posStart + 3] == 't' )
@@ -2852,25 +2867,65 @@ else if ( len == 4 && buf[posStart] == 'q' && buf[posStart + 1] == 'u' && buf[po
{
text = "\"";
}
- charRefOneCharBuf[0] = '"';
- return charRefOneCharBuf;
- }
- else
- {
- final char[] result = lookuEntityReplacement( len );
- if ( result != null )
- {
- return result;
- }
+ resolvedEntityRefCharBuf = BUF_QUOT;
}
- if ( tokenize )
- text = null;
- return null;
}
+
+ posEnd = pos;
+
+ return len;
+ }
+
+ /**
+ * Parse an entity reference inside the DOCDECL section.
+ *
+ * @throws XmlPullParserException if invalid XML is detected.
+ * @throws IOException if an I/O error is found.
+ */
+ private void parseEntityRefInDocDecl()
+ throws XmlPullParserException, IOException
+ {
+ parseCharOrPredefinedEntityRef();
+ if (usePC) {
+ posStart--; // include in PC the starting '&' of the entity
+ joinPC();
+ }
+
+ if ( resolvedEntityRefCharBuf != BUF_NOT_RESOLVED )
+ return;
+ if ( tokenize )
+ text = null;
+ }
+
+ /**
+ * Parse an entity reference inside a tag or attribute.
+ *
+ * @throws XmlPullParserException if invalid XML is detected.
+ * @throws IOException if an I/O error is found.
+ */
+ private void parseEntityRef()
+ throws XmlPullParserException, IOException
+ {
+ final int len = parseCharOrPredefinedEntityRef();
+
+ posEnd--; // don't involve the final ';' from the entity in the search
+
+ if ( resolvedEntityRefCharBuf != BUF_NOT_RESOLVED ) {
+ return;
+ }
+
+ resolvedEntityRefCharBuf = lookuEntityReplacement( len );
+ if ( resolvedEntityRefCharBuf != BUF_NOT_RESOLVED )
+ {
+ return;
+ }
+ if ( tokenize )
+ text = null;
}
/**
- * Check if the provided parameter is a valid Char, according to: {@link https://www.w3.org/TR/REC-xml/#NT-Char}
+ * Check if the provided parameter is a valid Char. According to
+ * https://www.w3.org/TR/REC-xml/#NT-Char
*
* @param codePoint the numeric value to check
* @return true if it is a valid numeric character reference. False otherwise.
@@ -2883,8 +2938,6 @@ private static boolean isValidCodePoint( int codePoint )
}
private char[] lookuEntityReplacement( int entityNameLen )
- throws XmlPullParserException, IOException
-
{
if ( !allStringsInterned )
{
@@ -2919,7 +2972,7 @@ private char[] lookuEntityReplacement( int entityNameLen )
}
}
}
- return null;
+ return BUF_NOT_RESOLVED;
}
private void parseComment()
@@ -2977,7 +3030,7 @@ else if (isValidCodePoint( ch ))
}
else
{
- throw new XmlPullParserException( "Illegal character 0x" + Integer.toHexString(((int) ch)) + " found in comment", this, null );
+ throw new XmlPullParserException( "Illegal character 0x" + Integer.toHexString(ch) + " found in comment", this, null );
}
if ( normalizeIgnorableWS )
{
@@ -3484,7 +3537,8 @@ else if ( ch == '>' && bracketLevel == 0 )
break;
else if ( ch == '&' )
{
- extractEntityRef();
+ extractEntityRefInDocDecl();
+ continue;
}
if ( normalizeIgnorableWS )
{
@@ -3536,6 +3590,19 @@ else if ( ch == '\n' )
}
posEnd = pos - 1;
+ text = null;
+ }
+
+ private void extractEntityRefInDocDecl()
+ throws XmlPullParserException, IOException
+ {
+ // extractEntityRef
+ posEnd = pos - 1;
+
+ int prevPosStart = posStart;
+ parseEntityRefInDocDecl();
+
+ posStart = prevPosStart;
}
private void extractEntityRef()
@@ -3559,9 +3626,9 @@ private void extractEntityRef()
}
// assert usePC == true;
- final char[] resolvedEntity = parseEntityRef();
+ parseEntityRef();
// check if replacement text can be resolved !!!
- if ( resolvedEntity == null )
+ if ( resolvedEntityRefCharBuf == BUF_NOT_RESOLVED )
{
if ( entityRefName == null )
{
@@ -3571,7 +3638,7 @@ private void extractEntityRef()
+ "'", this, null );
}
// write into PC replacement text - do merge for replacement text!!!!
- for ( char aResolvedEntity : resolvedEntity )
+ for ( char aResolvedEntity : resolvedEntityRefCharBuf )
{
if ( pcEnd >= pc.length )
{
diff --git a/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java b/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
index e0be666a..6fc6e9c6 100644
--- a/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
+++ b/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
@@ -17,6 +17,7 @@
*/
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -29,6 +30,7 @@
import java.nio.file.Files;
import java.nio.file.Paths;
+import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.ReaderFactory;
import org.junit.Test;
@@ -898,4 +900,497 @@ public void testEncodingISO_8859_1_setInputStream()
}
}
+ /**
+ * Issue 163: https://github.com/codehaus-plexus/plexus-utils/issues/163
+ *
+ * Another case of bug #163: File encoding information is lost after the input file is copied to a String.
+ *
+ * @throws IOException if IO error.
+ *
+ * @since 3.4.2
+ */
+ @Test
+ public void testEncodingISO_8859_1setStringReader()
+ throws IOException
+ {
+ try ( Reader reader =
+ ReaderFactory.newXmlReader( new File( "src/test/resources/xml", "test-encoding-ISO-8859-1.xml" ) ) )
+ {
+ MXParser parser = new MXParser();
+ String xmlFileContents = IOUtil.toString( reader );
+ parser.setInput( new StringReader( xmlFileContents ) );
+ while ( parser.nextToken() != XmlPullParser.END_DOCUMENT )
+ ;
+ assertTrue( true );
+ }
+ catch ( XmlPullParserException e )
+ {
+ fail( "should not raise exception: " + e );
+ }
+ }
+
+ /**
+ *
+ * Test custom Entity not found.
+ *
+ *
+ * Regression test: assure same behavior of MXParser from plexus-utils 3.3.0.
+ *
+ * @throws java.lang.Exception if any.
+ *
+ * @since 3.4.2
+ */
+ @Test
+ public void testCustomEntityNotFoundInText()
+ throws Exception
+ {
+ MXParser parser = new MXParser();
+
+ String input = "&otherentity;";
+ parser.setInput( new StringReader( input ) );
+ parser.defineEntityReplacementText( "myentity", "replacement" );
+
+ try
+ {
+ assertEquals( XmlPullParser.START_TAG, parser.next() );
+ assertEquals( XmlPullParser.TEXT, parser.next() );
+ fail( "should raise exception" );
+ }
+ catch ( XmlPullParserException e )
+ {
+ assertTrue( e.getMessage().contains( "could not resolve entity named 'otherentity' (position: START_TAG seen &otherentity;... @1:19)" ) );
+ assertEquals( XmlPullParser.START_TAG, parser.getEventType() ); // not an ENTITY_REF
+ assertEquals( "otherentity", parser.getText() );
+ }
+ }
+
+ /**
+ *
+ * Test custom Entity not found, with tokenize.
+ *
+ *
+ * Regression test: assure same behavior of MXParser from plexus-utils 3.3.0.
+ *
+ * @throws java.lang.Exception if any.
+ *
+ * @since 3.4.2
+ */
+ @Test
+ public void testCustomEntityNotFoundInTextTokenize()
+ throws Exception
+ {
+ MXParser parser = new MXParser();
+
+ String input = "&otherentity;";
+ parser.setInput( new StringReader( input ) );
+ parser.defineEntityReplacementText( "myentity", "replacement" );
+
+ try
+ {
+ assertEquals( XmlPullParser.START_TAG, parser.nextToken() );
+ assertEquals( XmlPullParser.ENTITY_REF, parser.nextToken() );
+ assertNull( parser.getText() );
+ }
+ catch ( XmlPullParserException e )
+ {
+ fail( "should not throw exception if tokenize" );
+ }
+ }
+
+ /**
+ *
+ * Test custom Entity not found in attribute.
+ *
+ *
+ * Regression test: assure same behavior of MXParser from plexus-utils 3.3.0.
+ *
+ * @throws java.lang.Exception if any.
+ *
+ * @since 3.4.2
+ */
+ @Test
+ public void testCustomEntityNotFoundInAttr()
+ throws Exception
+ {
+ MXParser parser = new MXParser();
+
+ String input = "sometext";
+ parser.setInput( new StringReader( input ) );
+ parser.defineEntityReplacementText( "myentity", "replacement" );
+
+ try
+ {
+ assertEquals( XmlPullParser.START_TAG, parser.next() );
+ fail( "should raise exception" );
+ }
+ catch ( XmlPullParserException e )
+ {
+ assertTrue( e.getMessage().contains( "could not resolve entity named 'otherentity' (position: START_DOCUMENT seen
+ * Test custom Entity not found in attribute, with tokenize.
+ *
+ *
+ * Regression test: assure same behavior of MXParser from plexus-utils 3.3.0.
+ * @throws XmlPullParserException
+ *
+ * @throws Exception if any.
+ *
+ * @since 3.4.2
+ */
+ @Test
+ public void testCustomEntityNotFoundInAttrTokenize() throws Exception
+ {
+ MXParser parser = new MXParser();
+
+ String input = "Issue #194: Incorrect getText() after parsing the DOCDECL section>
+ *
+ * test DOCDECL text with myCustomEntity that cannot be resolved, Unix line separator.
+ *
+ * Regression test: assure same behavior of MXParser from plexus-utils 3.3.0.
+ *
+ * @throws IOException if any.
+ *
+ * @since 3.4.2
+ */
+ @Test
+ public void testDocdeclTextWithEntitiesUnix()
+ throws IOException
+ {
+ testDocdeclTextWithEntities( "test-entities.xml" );
+ }
+
+ /**
+ * Issue #194: Incorrect getText() after parsing the DOCDECL section>
+ *
+ *
test DOCDECL text with myCustomEntity that cannot be resolved, DOS line separator.
+ *
+ * Regression test: assure same behavior of MXParser from plexus-utils 3.3.0.
+ *
+ * @throws IOException if any.
+ *
+ * @since 3.4.2
+ */
+ @Test
+ public void testDocdeclTextWithEntitiesDOS()
+ throws IOException
+ {
+ testDocdeclTextWithEntities( "test-entities-dos.xml" );
+ }
+
+ private void testDocdeclTextWithEntities( String filename )
+ throws IOException
+ {
+ try ( Reader reader = ReaderFactory.newXmlReader( new File( "src/test/resources/xml", filename ) ) )
+ {
+ MXParser parser = new MXParser();
+ parser.setInput( reader );
+ assertEquals( XmlPullParser.PROCESSING_INSTRUCTION, parser.nextToken() );
+ assertEquals( XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken() );
+ assertEquals( XmlPullParser.DOCDECL, parser.nextToken() );
+ assertEquals( " document [\n"
+ + "\n"
+ + "\n"
+ + "]", parser.getText() );
+ assertEquals( XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken() );
+ assertEquals( XmlPullParser.START_TAG, parser.nextToken() );
+ assertEquals( "document", parser.getName() );
+ assertEquals( XmlPullParser.TEXT, parser.next() );
+
+ fail( "should fail to resolve 'myCustomEntity' entity");
+ }
+ catch ( XmlPullParserException e )
+ {
+ assertTrue( e.getMessage().contains( "could not resolve entity named 'myCustomEntity'" ));
+ }
+ }
+
+ /**
+ * Issue #194: Incorrect getText() after parsing the DOCDECL section>
+ *
+ *
test DOCDECL text with entities appearing in attributes, Unix line separator.
+ *
+ * Regression test: assure same behavior of MXParser from plexus-utils 3.3.0.
+ *
+ * @throws IOException if any.
+ *
+ * @since 3.4.2
+ */
+ @Test
+ public void testDocdeclTextWithEntitiesInAttributesUnix()
+ throws IOException
+ {
+ testDocdeclTextWithEntitiesInAttributes( "test-entities-in-attr.xml" );
+ }
+
+ /**
+ * Issue #194: Incorrect getText() after parsing the DOCDECL section>
+ *
+ *
test DOCDECL text with entities appearing in attributes, DOS line separator.
+ *
+ * Regression test: assure same behavior of MXParser from plexus-utils 3.3.0.
+ *
+ * @throws IOException if any.
+ *
+ * @since 3.4.2
+ */
+ @Test
+ public void testDocdeclTextWithEntitiesInAttributesDOS()
+ throws IOException
+ {
+ testDocdeclTextWithEntitiesInAttributes( "test-entities-in-attr-dos.xml" );
+ }
+
+ private void testDocdeclTextWithEntitiesInAttributes( String filename )
+ throws IOException
+ {
+ try ( Reader reader = ReaderFactory.newXmlReader( new File( "src/test/resources/xml", filename ) ) )
+ {
+ MXParser parser = new MXParser();
+ parser.setInput( reader );
+ parser.defineEntityReplacementText( "nbsp", " " );
+ parser.defineEntityReplacementText( "Alpha", "Α" );
+ parser.defineEntityReplacementText( "tritPos", "𝟭" );
+ parser.defineEntityReplacementText( "flo", "ř" );
+ parser.defineEntityReplacementText( "myCustomEntity", "&flo;" );
+ assertEquals( XmlPullParser.PROCESSING_INSTRUCTION, parser.nextToken() );
+ assertEquals( XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken() );
+ assertEquals( XmlPullParser.DOCDECL, parser.nextToken() );
+ assertEquals( " document [\n"
+ + " \n"
+ + " \n"
+ + " \n"
+ + "\n"
+ + "\n"
+ + "]", parser.getText() );
+ assertEquals( XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken() );
+ assertEquals( XmlPullParser.START_TAG, parser.nextToken() );
+ assertEquals( "document", parser.getName() );
+ assertEquals( 1, parser.getAttributeCount() );
+ assertEquals( "name", parser.getAttributeName( 0 ) );
+ assertEquals( "section name with entities: '&' 'Α' '<' ' ' '>' '𝟭' ''' 'ř' '\"'",
+ parser.getAttributeValue( 0 ) );
+
+ assertEquals( XmlPullParser.ENTITY_REF, parser.nextToken() );
+ assertEquals( "myCustomEntity", parser.getName() );
+ assertEquals( "ř", parser.getText() );
+
+ assertEquals( XmlPullParser.END_TAG, parser.nextToken() );
+ assertEquals( XmlPullParser.END_DOCUMENT, parser.nextToken() );
+ }
+ catch ( XmlPullParserException e )
+ {
+ fail( "should not raise exception: " + e );
+ }
+ }
+
+ /**
+ * test entity ref with entities appearing in tags, Unix line separator.
+ *
+ * Regression test: assure same behavior of MXParser from plexus-utils 3.3.0.
+ *
+ * @throws IOException if any.
+ *
+ * @since 3.4.2
+ */
+ @Test
+ public void testEntityRefTextUnix()
+ throws IOException
+ {
+ testEntityRefText( "\n" );
+ }
+
+ /**
+ * test entity ref with entities appearing in tags, DOS line separator.
+ *
+ * Regression test: assure same behavior of MXParser from plexus-utils 3.3.0.
+ *
+ * @throws IOException if any.
+ *
+ * @since 3.4.2
+ */
+ @Test
+ public void testEntityRefTextDOS()
+ throws IOException
+ {
+ testEntityRefText( "\r\n" );
+ }
+
+ private void testEntityRefText( String newLine )
+ throws IOException
+ {
+ StringBuilder sb = new StringBuilder();
+ sb.append( "" ).append( newLine );
+ sb.append( "" ).append( newLine );
+ sb.append( "" ).append( newLine );
+ sb.append( "" ).append( newLine );
+ sb.append( "]>" ).append( newLine );
+ sb.append( "&foo;&foo1;&foo2;&tritPos;" );
+
+ try
+ {
+ MXParser parser = new MXParser();
+ parser.setInput( new StringReader( sb.toString() ) );
+ parser.defineEntityReplacementText( "foo", "ř" );
+ parser.defineEntityReplacementText( "nbsp", " " );
+ parser.defineEntityReplacementText( "foo1", " " );
+ parser.defineEntityReplacementText( "foo2", "š" );
+ parser.defineEntityReplacementText( "tritPos", "𝟭" );
+
+ assertEquals( XmlPullParser.DOCDECL, parser.nextToken() );
+ assertEquals( " test [\n"
+ + "\n"
+ + "\n"
+ + "\n"
+ + "\n"
+ + "]", parser.getText() );
+ assertEquals( XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken() );
+ assertEquals( XmlPullParser.START_TAG, parser.nextToken() );
+ assertEquals( "b", parser.getName() );
+ assertEquals( XmlPullParser.ENTITY_REF, parser.nextToken() );
+ assertEquals( "ř", parser.getText() );
+ assertEquals( "foo", parser.getName() );
+ assertEquals( XmlPullParser.ENTITY_REF, parser.nextToken() );
+ assertEquals( " ", parser.getText() );
+ assertEquals( "foo1", parser.getName() );
+ assertEquals( XmlPullParser.ENTITY_REF, parser.nextToken() );
+ assertEquals( "š", parser.getText() );
+ assertEquals( "foo2", parser.getName() );
+ assertEquals( XmlPullParser.ENTITY_REF, parser.nextToken() );
+ assertEquals( "𝟭", parser.getText() );
+ assertEquals( "tritPos", parser.getName() );
+ assertEquals( XmlPullParser.END_TAG, parser.nextToken() );
+ assertEquals( "b", parser.getName() );
+ assertEquals( XmlPullParser.END_DOCUMENT, parser.nextToken() );
+ }
+ catch ( XmlPullParserException e )
+ {
+ fail( "should not raise exception: " + e );
+ }
+ }
+
+ /**
+ * Ensures that entity ref getText() and getName() return the correct value.
+ *
+ * Regression test: assure same behavior of MXParser from plexus-utils 3.3.0.
+ *
+ * @throws IOException if any.
+ *
+ * @since 3.4.2
+ */
+ @Test
+ public void testEntityReplacement() throws IOException {
+ String input = "
";
+
+ try
+ {
+ MXParser parser = new MXParser();
+ parser.setInput( new StringReader( input ) );
+ parser.defineEntityReplacementText( "nbsp", " " );
+
+ assertEquals( XmlPullParser.START_TAG, parser.nextToken() );
+ assertEquals( "p", parser.getName() );
+ assertEquals( XmlPullParser.COMMENT, parser.nextToken() );
+ assertEquals( " a pagebreak: ", parser.getText() );
+ assertEquals( XmlPullParser.COMMENT, parser.nextToken() );
+ assertEquals( " PB ", parser.getText() );
+ assertEquals( XmlPullParser.ENTITY_REF, parser.nextToken() );
+ assertEquals( "\u00A0", parser.getText() );
+ assertEquals( "#160", parser.getName() );
+ assertEquals( XmlPullParser.ENTITY_REF, parser.nextToken() );
+ assertEquals( " ", parser.getText() );
+ assertEquals( "nbsp", parser.getName() );
+ assertEquals( XmlPullParser.START_TAG, parser.nextToken() );
+ assertEquals( "unknown", parser.getName() );
+ assertEquals( XmlPullParser.END_TAG, parser.nextToken() );
+ assertEquals( "unknown", parser.getName() );
+ assertEquals( XmlPullParser.END_TAG, parser.nextToken() );
+ assertEquals( "p", parser.getName() );
+ assertEquals( XmlPullParser.END_DOCUMENT, parser.nextToken() );
+ }
+ catch ( XmlPullParserException e )
+ {
+ fail( "should not raise exception: " + e );
+ }
+ }
+
+ /**
+ * Ensures correct replacements inside the internal PC array when the new copied array size is shorter than
+ * previous ones.
+ *
+ * Regression test: assure same behavior of MXParser from plexus-utils 3.3.0.
+ *
+ * @throws IOException if any.
+ *
+ * @since 3.4.2
+ */
+ @Test
+ public void testReplacementInPCArrayWithShorterCharArray()
+ throws IOException
+ {
+ String input = "]>"
+ + "";
+
+ try
+ {
+ MXParser parser = new MXParser();
+ parser.setInput( new StringReader( new String(input.getBytes(), "ISO-8859-1" ) ) );
+ parser.defineEntityReplacementText( "foo", "ř" );
+ parser.defineEntityReplacementText( "tritPos", "𝟭" );
+
+ assertEquals( XmlPullParser.DOCDECL, parser.nextToken() );
+ assertEquals( " test []", parser.getText() );
+ assertEquals( XmlPullParser.START_TAG, parser.nextToken() );
+ assertEquals( "section", parser.getName() );
+ assertEquals( 1, parser.getAttributeCount() );
+ assertEquals( "name" , parser.getAttributeName( 0 ) );
+ assertEquals( "&ř𝟭" , parser.getAttributeValue( 0 ) );
+ assertEquals( XmlPullParser.START_TAG, parser.nextToken() );
+ assertEquals( "", parser.getText() );
+ assertEquals( "p", parser.getName() );
+ assertEquals( XmlPullParser.ENTITY_REF, parser.nextToken() );
+ assertEquals( "&", parser.getText() );
+ assertEquals( "amp", parser.getName() );
+ assertEquals( XmlPullParser.ENTITY_REF, parser.nextToken() );
+ assertEquals( "ř", parser.getText() );
+ assertEquals( "foo", parser.getName() );
+ assertEquals( XmlPullParser.ENTITY_REF, parser.nextToken() );
+ assertEquals( "𝟭", parser.getText() );
+ assertEquals( "tritPos", parser.getName() );
+ assertEquals( XmlPullParser.END_TAG, parser.nextToken() );
+ assertEquals( "p", parser.getName() );
+ assertEquals( XmlPullParser.END_TAG, parser.nextToken() );
+ assertEquals( "section", parser.getName() );
+ assertEquals( XmlPullParser.END_DOCUMENT, parser.nextToken() );
+ }
+ catch ( XmlPullParserException e )
+ {
+ fail( "should not raise exception: " + e );
+ }
+ }
}
diff --git a/src/test/resources/xml/test-entities-dos.xml b/src/test/resources/xml/test-entities-dos.xml
new file mode 100644
index 00000000..e1d6d17a
--- /dev/null
+++ b/src/test/resources/xml/test-entities-dos.xml
@@ -0,0 +1,6 @@
+
+
+
+]>
+&myCustomEntity;
\ No newline at end of file
diff --git a/src/test/resources/xml/test-entities-in-attr-dos.xml b/src/test/resources/xml/test-entities-in-attr-dos.xml
new file mode 100644
index 00000000..a423c995
--- /dev/null
+++ b/src/test/resources/xml/test-entities-in-attr-dos.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+]>
+&myCustomEntity;
\ No newline at end of file
diff --git a/src/test/resources/xml/test-entities-in-attr.xml b/src/test/resources/xml/test-entities-in-attr.xml
new file mode 100644
index 00000000..a423c995
--- /dev/null
+++ b/src/test/resources/xml/test-entities-in-attr.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+]>
+&myCustomEntity;
\ No newline at end of file
diff --git a/src/test/resources/xml/test-entities.xml b/src/test/resources/xml/test-entities.xml
new file mode 100644
index 00000000..e1d6d17a
--- /dev/null
+++ b/src/test/resources/xml/test-entities.xml
@@ -0,0 +1,6 @@
+
+
+
+]>
+&myCustomEntity;
\ No newline at end of file
From 298fd8d626a7dd1271dcc4ae8e2029a2eba2c1ad Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 15 Apr 2022 02:03:30 +0000
Subject: [PATCH 12/28] Bump actions/checkout from 2.4.0 to 3.0.1
Bumps [actions/checkout](https://github.com/actions/checkout) from 2.4.0 to 3.0.1.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v2.4.0...v3.0.1)
---
updated-dependencies:
- dependency-name: actions/checkout
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
---
.github/workflows/codeql-analysis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 3f39b7e2..9935c621 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -32,7 +32,7 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v2.4.0
+ uses: actions/checkout@v3.0.1
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
From 52d64eadb7d4f8a543d43cc49194cdf74b93f944 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 29 Mar 2022 02:02:37 +0000
Subject: [PATCH 13/28] Bump jmh-core from 1.34 to 1.35
Bumps jmh-core from 1.34 to 1.35.
---
updated-dependencies:
- dependency-name: org.openjdk.jmh:jmh-core
dependency-type: direct:development
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index a758c676..8a9018e9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,7 +64,7 @@ limitations under the License.
org.openjdk.jmh
jmh-core
- 1.34
+ 1.35
test
From 11be3b5bf2a8b9853ab2e7f2e1245233220ca46a Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 29 Mar 2022 02:02:35 +0000
Subject: [PATCH 14/28] Bump jmh-generator-annprocess from 1.34 to 1.35
Bumps jmh-generator-annprocess from 1.34 to 1.35.
---
updated-dependencies:
- dependency-name: org.openjdk.jmh:jmh-generator-annprocess
dependency-type: direct:development
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/pom.xml b/pom.xml
index 8a9018e9..beda14b7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -70,7 +70,7 @@ limitations under the License.
org.openjdk.jmh
jmh-generator-annprocess
- 1.34
+ 1.35
test
From 10f729542509b039a748fc7085826e43137bba35 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 8 Mar 2022 02:02:38 +0000
Subject: [PATCH 15/28] Bump release-drafter/release-drafter from 5.18.1 to
5.19.0
Bumps [release-drafter/release-drafter](https://github.com/release-drafter/release-drafter) from 5.18.1 to 5.19.0.
- [Release notes](https://github.com/release-drafter/release-drafter/releases)
- [Commits](https://github.com/release-drafter/release-drafter/compare/v5.18.1...v5.19.0)
---
updated-dependencies:
- dependency-name: release-drafter/release-drafter
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot]
---
.github/workflows/release-drafter.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml
index 4ece1c1a..96f54b5d 100644
--- a/.github/workflows/release-drafter.yml
+++ b/.github/workflows/release-drafter.yml
@@ -7,6 +7,6 @@ jobs:
update_release_draft:
runs-on: ubuntu-latest
steps:
- - uses: release-drafter/release-drafter@v5.18.1
+ - uses: release-drafter/release-drafter@v5.19.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
From 0d384e75ba5f950d389281226e56515be195b604 Mon Sep 17 00:00:00 2001
From: Gabriel Belingueres
Date: Sun, 17 Apr 2022 04:01:59 -0300
Subject: [PATCH 16/28] Fix some testing XML files checkout with incorrect eol
---
.gitattributes | 4 ++++
.../org/codehaus/plexus/util/xml/pull/MXParserTest.java | 8 ++++----
.../xml/{test-entities-dos.xml => test-entities-DOS.xml} | 0
.../xml/{test-entities.xml => test-entities-UNIX.xml} | 0
...ties-in-attr-dos.xml => test-entities-in-attr-DOS.xml} | 0
...ntities-in-attr.xml => test-entities-in-attr-UNIX.xml} | 0
6 files changed, 8 insertions(+), 4 deletions(-)
rename src/test/resources/xml/{test-entities-dos.xml => test-entities-DOS.xml} (100%)
rename src/test/resources/xml/{test-entities.xml => test-entities-UNIX.xml} (100%)
rename src/test/resources/xml/{test-entities-in-attr-dos.xml => test-entities-in-attr-DOS.xml} (100%)
rename src/test/resources/xml/{test-entities-in-attr.xml => test-entities-in-attr-UNIX.xml} (100%)
diff --git a/.gitattributes b/.gitattributes
index 3bb3b5ea..ccd9f864 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -6,3 +6,7 @@
*.css text
*.js text
*.sql text
+
+# some files require the correct eol for proper testing
+*-DOS.xml text eol=crlf
+*-UNIX.xml text eol=lf
diff --git a/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java b/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
index 6fc6e9c6..27ba5f8c 100644
--- a/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
+++ b/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
@@ -1081,7 +1081,7 @@ public void testCustomEntityNotFoundInAttrTokenize() throws Exception
public void testDocdeclTextWithEntitiesUnix()
throws IOException
{
- testDocdeclTextWithEntities( "test-entities.xml" );
+ testDocdeclTextWithEntities( "test-entities-UNIX.xml" );
}
/**
@@ -1099,7 +1099,7 @@ public void testDocdeclTextWithEntitiesUnix()
public void testDocdeclTextWithEntitiesDOS()
throws IOException
{
- testDocdeclTextWithEntities( "test-entities-dos.xml" );
+ testDocdeclTextWithEntities( "test-entities-DOS.xml" );
}
private void testDocdeclTextWithEntities( String filename )
@@ -1144,7 +1144,7 @@ private void testDocdeclTextWithEntities( String filename )
public void testDocdeclTextWithEntitiesInAttributesUnix()
throws IOException
{
- testDocdeclTextWithEntitiesInAttributes( "test-entities-in-attr.xml" );
+ testDocdeclTextWithEntitiesInAttributes( "test-entities-in-attr-UNIX.xml" );
}
/**
@@ -1162,7 +1162,7 @@ public void testDocdeclTextWithEntitiesInAttributesUnix()
public void testDocdeclTextWithEntitiesInAttributesDOS()
throws IOException
{
- testDocdeclTextWithEntitiesInAttributes( "test-entities-in-attr-dos.xml" );
+ testDocdeclTextWithEntitiesInAttributes( "test-entities-in-attr-DOS.xml" );
}
private void testDocdeclTextWithEntitiesInAttributes( String filename )
diff --git a/src/test/resources/xml/test-entities-dos.xml b/src/test/resources/xml/test-entities-DOS.xml
similarity index 100%
rename from src/test/resources/xml/test-entities-dos.xml
rename to src/test/resources/xml/test-entities-DOS.xml
diff --git a/src/test/resources/xml/test-entities.xml b/src/test/resources/xml/test-entities-UNIX.xml
similarity index 100%
rename from src/test/resources/xml/test-entities.xml
rename to src/test/resources/xml/test-entities-UNIX.xml
diff --git a/src/test/resources/xml/test-entities-in-attr-dos.xml b/src/test/resources/xml/test-entities-in-attr-DOS.xml
similarity index 100%
rename from src/test/resources/xml/test-entities-in-attr-dos.xml
rename to src/test/resources/xml/test-entities-in-attr-DOS.xml
diff --git a/src/test/resources/xml/test-entities-in-attr.xml b/src/test/resources/xml/test-entities-in-attr-UNIX.xml
similarity index 100%
rename from src/test/resources/xml/test-entities-in-attr.xml
rename to src/test/resources/xml/test-entities-in-attr-UNIX.xml
From d3823dc54686cbd268b0cd8f7c6ef6058d163817 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Fri, 22 Apr 2022 02:02:31 +0000
Subject: [PATCH 17/28] Bump actions/checkout from 3.0.1 to 3.0.2
Bumps [actions/checkout](https://github.com/actions/checkout) from 3.0.1 to 3.0.2.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3.0.1...v3.0.2)
---
updated-dependencies:
- dependency-name: actions/checkout
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
.github/workflows/codeql-analysis.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 9935c621..6240fce9 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -32,7 +32,7 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v3.0.1
+ uses: actions/checkout@v3.0.2
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
From 2f68e930054aae96ca8f694774b07fd63741301c Mon Sep 17 00:00:00 2001
From: Sylwester Lachiewicz
Date: Sat, 23 Apr 2022 19:43:51 +0200
Subject: [PATCH 18/28] Fix regression and deprecate: FileUtils.fileAppend
should create file if not exist.
---
src/main/java/org/codehaus/plexus/util/FileUtils.java | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/src/main/java/org/codehaus/plexus/util/FileUtils.java b/src/main/java/org/codehaus/plexus/util/FileUtils.java
index cac82ba3..4dca8b3c 100644
--- a/src/main/java/org/codehaus/plexus/util/FileUtils.java
+++ b/src/main/java/org/codehaus/plexus/util/FileUtils.java
@@ -389,6 +389,8 @@ private static InputStreamReader getInputStreamReader( File file, String encodin
* @param fileName The path of the file to write.
* @param data The content to write to the file.
* @throws IOException if any
+ * @deprecated use {@code java.nio.files.Files.write(filename, data.getBytes(encoding),
+ * StandardOpenOption.APPEND, StandardOpenOption.CREATE)}
*/
public static void fileAppend( String fileName, String data )
throws IOException
@@ -403,11 +405,14 @@ public static void fileAppend( String fileName, String data )
* @param encoding The encoding of the file.
* @param data The content to write to the file.
* @throws IOException if any
+ * @deprecated use {@code java.nio.files.Files.write(filename, data.getBytes(encoding),
+ * StandardOpenOption.APPEND, StandardOpenOption.CREATE)}
*/
public static void fileAppend( String fileName, String encoding, String data )
throws IOException
{
- try ( OutputStream out = Files.newOutputStream( Paths.get(fileName), StandardOpenOption.APPEND ) )
+ try ( OutputStream out = Files.newOutputStream( Paths.get(fileName),
+ StandardOpenOption.APPEND, StandardOpenOption.CREATE ) )
{
if ( encoding != null )
{
From 0808fe36dde238e6824043d5ca597b7cec1bd5c7 Mon Sep 17 00:00:00 2001
From: Sylwester Lachiewicz
Date: Sat, 23 Apr 2022 22:33:48 +0200
Subject: [PATCH 19/28] Added Licence file
Closes #78
---
LICENSE.txt | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 201 insertions(+)
create mode 100644 LICENSE.txt
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 00000000..261eeb9e
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
From 49773f19e43af7d39f441aac06adbc6a4052a063 Mon Sep 17 00:00:00 2001
From: Guillaume Nodet
Date: Tue, 26 Apr 2022 15:42:15 +0200
Subject: [PATCH 20/28] Provides a CachingOuptutStream and a CachingWriter
(#184)
Provides a CachingOuptutStream and a CachingWriter
---
.../plexus/util/io/CachingOutputStream.java | 175 ++++++++++++++++++
.../plexus/util/io/CachingWriter.java | 62 +++++++
.../util/io/CachingOutputStreamTest.java | 145 +++++++++++++++
.../plexus/util/io/CachingWriterTest.java | 143 ++++++++++++++
4 files changed, 525 insertions(+)
create mode 100644 src/main/java/org/codehaus/plexus/util/io/CachingOutputStream.java
create mode 100644 src/main/java/org/codehaus/plexus/util/io/CachingWriter.java
create mode 100644 src/test/java/org/codehaus/plexus/util/io/CachingOutputStreamTest.java
create mode 100644 src/test/java/org/codehaus/plexus/util/io/CachingWriterTest.java
diff --git a/src/main/java/org/codehaus/plexus/util/io/CachingOutputStream.java b/src/main/java/org/codehaus/plexus/util/io/CachingOutputStream.java
new file mode 100644
index 00000000..521d5373
--- /dev/null
+++ b/src/main/java/org/codehaus/plexus/util/io/CachingOutputStream.java
@@ -0,0 +1,175 @@
+package org.codehaus.plexus.util.io;
+
+/*
+ * Copyright The Codehaus Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.Buffer;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.nio.file.attribute.FileTime;
+import java.time.Instant;
+import java.util.Objects;
+
+/**
+ * Caching OutputStream to avoid overwriting a file with
+ * the same content.
+ */
+public class CachingOutputStream extends OutputStream
+{
+ private final Path path;
+ private FileChannel channel;
+ private ByteBuffer readBuffer;
+ private ByteBuffer writeBuffer;
+ private boolean modified;
+
+ public CachingOutputStream( File path ) throws IOException
+ {
+ this( Objects.requireNonNull( path ).toPath() );
+ }
+
+ public CachingOutputStream( Path path ) throws IOException
+ {
+ this( path, 32 * 1024 );
+ }
+
+ public CachingOutputStream( Path path, int bufferSize ) throws IOException
+ {
+ this.path = Objects.requireNonNull( path );
+ this.channel = FileChannel.open( path,
+ StandardOpenOption.READ, StandardOpenOption.WRITE, StandardOpenOption.CREATE );
+ this.readBuffer = ByteBuffer.allocate( bufferSize );
+ this.writeBuffer = ByteBuffer.allocate( bufferSize );
+ }
+
+ @Override
+ public void write( int b ) throws IOException
+ {
+ if ( writeBuffer.remaining() < 1 )
+ {
+ ( ( Buffer ) writeBuffer ).flip();
+ flushBuffer( writeBuffer );
+ ( ( Buffer ) writeBuffer ).clear();
+ }
+ writeBuffer.put( ( byte ) b );
+ }
+
+ @Override
+ public void write( byte[] b ) throws IOException
+ {
+ write( b, 0, b.length );
+ }
+
+ @Override
+ public void write( byte[] b, int off, int len ) throws IOException
+ {
+ if ( writeBuffer.remaining() < len )
+ {
+ ( ( Buffer ) writeBuffer ).flip();
+ flushBuffer( writeBuffer );
+ ( ( Buffer ) writeBuffer ).clear();
+ }
+ int capacity = writeBuffer.capacity();
+ while ( len >= capacity )
+ {
+ flushBuffer( ByteBuffer.wrap( b, off, capacity ) );
+ off += capacity;
+ len -= capacity;
+ }
+ if ( len > 0 )
+ {
+ writeBuffer.put( b, off, len );
+ }
+ }
+
+ @Override
+ public void flush() throws IOException
+ {
+ ( ( Buffer ) writeBuffer ).flip();
+ flushBuffer( writeBuffer );
+ ( ( Buffer ) writeBuffer ).clear();
+ super.flush();
+ }
+
+ private void flushBuffer( ByteBuffer writeBuffer ) throws IOException
+ {
+ if ( modified )
+ {
+ channel.write( writeBuffer );
+ }
+ else
+ {
+ int len = writeBuffer.remaining();
+ ByteBuffer readBuffer;
+ if ( this.readBuffer.capacity() >= len )
+ {
+ readBuffer = this.readBuffer;
+ ( ( Buffer ) readBuffer ).clear();
+ }
+ else
+ {
+ readBuffer = ByteBuffer.allocate( len );
+ }
+ while ( len > 0 )
+ {
+ int read = channel.read( readBuffer );
+ if ( read <= 0 )
+ {
+ modified = true;
+ channel.position( channel.position() - readBuffer.position() );
+ channel.write( writeBuffer );
+ return;
+ }
+ len -= read;
+ }
+ ( ( Buffer ) readBuffer ).flip();
+ if ( readBuffer.compareTo( writeBuffer ) != 0 )
+ {
+ modified = true;
+ channel.position( channel.position() - readBuffer.remaining() );
+ channel.write( writeBuffer );
+ }
+ }
+ }
+
+ @Override
+ public void close() throws IOException
+ {
+ flush();
+ long position = channel.position();
+ if ( position != channel.size() )
+ {
+ if ( !modified )
+ {
+ FileTime now = FileTime.from( Instant.now() );
+ Files.setLastModifiedTime( path, now );
+ modified = true;
+ }
+ channel.truncate( position );
+ }
+ channel.close();
+ }
+
+ public boolean isModified()
+ {
+ return modified;
+ }
+}
diff --git a/src/main/java/org/codehaus/plexus/util/io/CachingWriter.java b/src/main/java/org/codehaus/plexus/util/io/CachingWriter.java
new file mode 100644
index 00000000..23cc4411
--- /dev/null
+++ b/src/main/java/org/codehaus/plexus/util/io/CachingWriter.java
@@ -0,0 +1,62 @@
+package org.codehaus.plexus.util.io;
+
+/*
+ * Copyright The Codehaus Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.StringWriter;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * Caching Writer to avoid overwriting a file with
+ * the same content.
+ */
+public class CachingWriter extends OutputStreamWriter
+{
+ private final CachingOutputStream cos;
+
+ public CachingWriter( File path, Charset charset ) throws IOException
+ {
+ this( Objects.requireNonNull( path ).toPath(), charset );
+ }
+
+ public CachingWriter( Path path, Charset charset ) throws IOException
+ {
+ this( path, charset, 32 * 1024 );
+ }
+
+ public CachingWriter( Path path, Charset charset, int bufferSize ) throws IOException
+ {
+ this( new CachingOutputStream( path, bufferSize ), charset );
+ }
+
+ private CachingWriter( CachingOutputStream outputStream, Charset charset ) throws IOException
+ {
+ super( outputStream, charset );
+ this.cos = outputStream;
+ }
+
+ public boolean isModified()
+ {
+ return cos.isModified();
+ }
+}
diff --git a/src/test/java/org/codehaus/plexus/util/io/CachingOutputStreamTest.java b/src/test/java/org/codehaus/plexus/util/io/CachingOutputStreamTest.java
new file mode 100644
index 00000000..3c329ea9
--- /dev/null
+++ b/src/test/java/org/codehaus/plexus/util/io/CachingOutputStreamTest.java
@@ -0,0 +1,145 @@
+package org.codehaus.plexus.util.io;
+
+/*
+ * Copyright The Codehaus Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.FileTime;
+import java.util.Objects;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+public class CachingOutputStreamTest
+{
+
+ Path tempDir;
+ Path checkLastModified;
+ FileTime lm;
+
+ @Before
+ public void setup() throws IOException
+ {
+ Path dir = Paths.get( "target/io" );
+ Files.createDirectories( dir );
+ tempDir = Files.createTempDirectory( dir, "temp-" );
+ checkLastModified = tempDir.resolve( ".check" );
+ Files.newOutputStream( checkLastModified ).close();
+ lm = Files.getLastModifiedTime( checkLastModified );
+ }
+
+ private void waitLastModified() throws IOException, InterruptedException
+ {
+ while ( true )
+ {
+ Files.newOutputStream( checkLastModified ).close();
+ FileTime nlm = Files.getLastModifiedTime( checkLastModified );
+ if ( !Objects.equals( nlm, lm ) )
+ {
+ lm = nlm;
+ break;
+ }
+ Thread.sleep( 10 );
+ }
+ }
+
+ @Test
+ public void testWriteNoExistingFile() throws IOException, InterruptedException
+ {
+ byte[] data = "Hello world!".getBytes( StandardCharsets.UTF_8 );
+ Path path = tempDir.resolve( "file.txt" );
+ assertFalse( Files.exists( path ) );
+
+ try ( CachingOutputStream cos = new CachingOutputStream( path, 4 ) )
+ {
+ cos.write( data );
+ }
+ assertTrue( Files.exists( path ) );
+ byte[] read = Files.readAllBytes( path );
+ assertArrayEquals( data, read );
+ FileTime modified = Files.getLastModifiedTime( path );
+
+ waitLastModified();
+
+ try ( CachingOutputStream cos = new CachingOutputStream( path, 4 ) )
+ {
+ cos.write( data );
+ }
+ assertTrue( Files.exists( path ) );
+ read = Files.readAllBytes( path );
+ assertArrayEquals( data, read );
+ FileTime newModified = Files.getLastModifiedTime( path );
+ assertEquals( modified, newModified );
+ modified = newModified;
+
+ waitLastModified();
+
+ // write longer data
+ data = "Good morning!".getBytes( StandardCharsets.UTF_8 );
+ try ( CachingOutputStream cos = new CachingOutputStream( path, 4 ) )
+ {
+ cos.write( data );
+ }
+ assertTrue( Files.exists( path ) );
+ read = Files.readAllBytes( path );
+ assertArrayEquals( data, read );
+ newModified = Files.getLastModifiedTime( path );
+ assertNotEquals( modified, newModified );
+ modified = newModified;
+
+ waitLastModified();
+
+ // different data same size
+ data = "Good mornong!".getBytes( StandardCharsets.UTF_8 );
+ try ( CachingOutputStream cos = new CachingOutputStream( path, 4 ) )
+ {
+ cos.write( data );
+ }
+ assertTrue( Files.exists( path ) );
+ read = Files.readAllBytes( path );
+ assertArrayEquals( data, read );
+ newModified = Files.getLastModifiedTime( path );
+ assertNotEquals( modified, newModified );
+ modified = newModified;
+
+ waitLastModified();
+
+ // same data but shorter
+ data = "Good mornon".getBytes( StandardCharsets.UTF_8 );
+ try ( CachingOutputStream cos = new CachingOutputStream( path, 4 ) )
+ {
+ cos.write( data );
+ }
+ assertTrue( Files.exists( path ) );
+ read = Files.readAllBytes( path );
+ assertArrayEquals( data, read );
+ newModified = Files.getLastModifiedTime( path );
+ assertNotEquals( modified, newModified );
+ modified = newModified;
+ }
+
+}
diff --git a/src/test/java/org/codehaus/plexus/util/io/CachingWriterTest.java b/src/test/java/org/codehaus/plexus/util/io/CachingWriterTest.java
new file mode 100644
index 00000000..f5b95903
--- /dev/null
+++ b/src/test/java/org/codehaus/plexus/util/io/CachingWriterTest.java
@@ -0,0 +1,143 @@
+package org.codehaus.plexus.util.io;
+
+/*
+ * Copyright The Codehaus Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.attribute.FileTime;
+import java.util.Objects;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertTrue;
+
+public class CachingWriterTest
+{
+
+ Path tempDir;
+ Path checkLastModified;
+ FileTime lm;
+
+ @Before
+ public void setup() throws IOException
+ {
+ Path dir = Paths.get( "target/io" );
+ Files.createDirectories( dir );
+ tempDir = Files.createTempDirectory( dir, "temp-" );
+ checkLastModified = tempDir.resolve( ".check" );
+ Files.newOutputStream( checkLastModified ).close();
+ lm = Files.getLastModifiedTime( checkLastModified );
+ }
+
+ private void waitLastModified() throws IOException, InterruptedException
+ {
+ while ( true )
+ {
+ Files.newOutputStream( checkLastModified ).close();
+ FileTime nlm = Files.getLastModifiedTime( checkLastModified );
+ if ( !Objects.equals( nlm, lm ) )
+ {
+ lm = nlm;
+ break;
+ }
+ Thread.sleep( 10 );
+ }
+ }
+
+ @Test
+ public void testWriteNoExistingFile() throws IOException, InterruptedException
+ {
+ String data = "Hello world!";
+ Path path = tempDir.resolve( "file.txt" );
+ assertFalse( Files.exists( path ) );
+
+ try ( CachingWriter cos = new CachingWriter( path, StandardCharsets.UTF_8, 4 ) )
+ {
+ cos.write( data );
+ }
+ assertTrue( Files.exists( path ) );
+ String read = new String( Files.readAllBytes( path ), StandardCharsets.UTF_8 );
+ assertEquals( data, read );
+ FileTime modified = Files.getLastModifiedTime( path );
+
+ waitLastModified();
+
+ try ( CachingWriter cos = new CachingWriter( path, StandardCharsets.UTF_8, 4 ) )
+ {
+ cos.write( data );
+ }
+ assertTrue( Files.exists( path ) );
+ read = new String( Files.readAllBytes( path ), StandardCharsets.UTF_8 );
+ assertEquals( data, read );
+ FileTime newModified = Files.getLastModifiedTime( path );
+ assertEquals( modified, newModified );
+ modified = newModified;
+
+ waitLastModified();
+
+ // write longer data
+ data = "Good morning!";
+ try ( CachingWriter cos = new CachingWriter( path, StandardCharsets.UTF_8, 4 ) )
+ {
+ cos.write( data );
+ }
+ assertTrue( Files.exists( path ) );
+ read = new String( Files.readAllBytes( path ), StandardCharsets.UTF_8 );
+ assertEquals( data, read );
+ newModified = Files.getLastModifiedTime( path );
+ assertNotEquals( modified, newModified );
+ modified = newModified;
+
+ waitLastModified();
+
+ // different data same size
+ data = "Good mornong!";
+ try ( CachingWriter cos = new CachingWriter( path, StandardCharsets.UTF_8, 4 ) )
+ {
+ cos.write( data );
+ }
+ assertTrue( Files.exists( path ) );
+ read = new String( Files.readAllBytes( path ), StandardCharsets.UTF_8 );
+ assertEquals( data, read );
+ newModified = Files.getLastModifiedTime( path );
+ assertNotEquals( modified, newModified );
+ modified = newModified;
+
+ waitLastModified();
+
+ // same data but shorter
+ data = "Good mornon";
+ try ( CachingWriter cos = new CachingWriter( path, StandardCharsets.UTF_8, 4 ) )
+ {
+ cos.write( data );
+ }
+ assertTrue( Files.exists( path ) );
+ read = new String( Files.readAllBytes( path ), StandardCharsets.UTF_8 );
+ assertEquals( data, read );
+ newModified = Files.getLastModifiedTime( path );
+ assertNotEquals( modified, newModified );
+ modified = newModified;
+ }
+}
From ee5fe41b032f95f9b39f6ef21256800a6608dfd6 Mon Sep 17 00:00:00 2001
From: Guillaume Nodet
Date: Tue, 26 Apr 2022 17:44:51 +0200
Subject: [PATCH 21/28] Fix last modified time not being updated on linux
(#203)
Fix test, clean things
---
.../plexus/util/io/CachingOutputStream.java | 14 ++++++--------
.../plexus/util/io/CachingOutputStreamTest.java | 7 ++-----
.../codehaus/plexus/util/io/CachingWriterTest.java | 7 ++-----
3 files changed, 10 insertions(+), 18 deletions(-)
diff --git a/src/main/java/org/codehaus/plexus/util/io/CachingOutputStream.java b/src/main/java/org/codehaus/plexus/util/io/CachingOutputStream.java
index 521d5373..744e6f06 100644
--- a/src/main/java/org/codehaus/plexus/util/io/CachingOutputStream.java
+++ b/src/main/java/org/codehaus/plexus/util/io/CachingOutputStream.java
@@ -153,19 +153,17 @@ private void flushBuffer( ByteBuffer writeBuffer ) throws IOException
@Override
public void close() throws IOException
{
- flush();
- long position = channel.position();
- if ( position != channel.size() )
+ if ( channel.isOpen() )
{
- if ( !modified )
+ flush();
+ long position = channel.position();
+ if ( position != channel.size() )
{
- FileTime now = FileTime.from( Instant.now() );
- Files.setLastModifiedTime( path, now );
modified = true;
+ channel.truncate( position );
}
- channel.truncate( position );
+ channel.close();
}
- channel.close();
}
public boolean isModified()
diff --git a/src/test/java/org/codehaus/plexus/util/io/CachingOutputStreamTest.java b/src/test/java/org/codehaus/plexus/util/io/CachingOutputStreamTest.java
index 3c329ea9..e7888ad4 100644
--- a/src/test/java/org/codehaus/plexus/util/io/CachingOutputStreamTest.java
+++ b/src/test/java/org/codehaus/plexus/util/io/CachingOutputStreamTest.java
@@ -17,7 +17,6 @@
*/
import java.io.IOException;
-import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -39,7 +38,6 @@ public class CachingOutputStreamTest
Path tempDir;
Path checkLastModified;
- FileTime lm;
@Before
public void setup() throws IOException
@@ -48,19 +46,18 @@ public void setup() throws IOException
Files.createDirectories( dir );
tempDir = Files.createTempDirectory( dir, "temp-" );
checkLastModified = tempDir.resolve( ".check" );
- Files.newOutputStream( checkLastModified ).close();
- lm = Files.getLastModifiedTime( checkLastModified );
}
private void waitLastModified() throws IOException, InterruptedException
{
+ Files.newOutputStream( checkLastModified ).close();
+ FileTime lm = Files.getLastModifiedTime( checkLastModified );
while ( true )
{
Files.newOutputStream( checkLastModified ).close();
FileTime nlm = Files.getLastModifiedTime( checkLastModified );
if ( !Objects.equals( nlm, lm ) )
{
- lm = nlm;
break;
}
Thread.sleep( 10 );
diff --git a/src/test/java/org/codehaus/plexus/util/io/CachingWriterTest.java b/src/test/java/org/codehaus/plexus/util/io/CachingWriterTest.java
index f5b95903..a4ffec91 100644
--- a/src/test/java/org/codehaus/plexus/util/io/CachingWriterTest.java
+++ b/src/test/java/org/codehaus/plexus/util/io/CachingWriterTest.java
@@ -27,7 +27,6 @@
import org.junit.Before;
import org.junit.Test;
-import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
@@ -38,7 +37,6 @@ public class CachingWriterTest
Path tempDir;
Path checkLastModified;
- FileTime lm;
@Before
public void setup() throws IOException
@@ -47,19 +45,18 @@ public void setup() throws IOException
Files.createDirectories( dir );
tempDir = Files.createTempDirectory( dir, "temp-" );
checkLastModified = tempDir.resolve( ".check" );
- Files.newOutputStream( checkLastModified ).close();
- lm = Files.getLastModifiedTime( checkLastModified );
}
private void waitLastModified() throws IOException, InterruptedException
{
+ Files.newOutputStream( checkLastModified ).close();
+ FileTime lm = Files.getLastModifiedTime( checkLastModified );
while ( true )
{
Files.newOutputStream( checkLastModified ).close();
FileTime nlm = Files.getLastModifiedTime( checkLastModified );
if ( !Objects.equals( nlm, lm ) )
{
- lm = nlm;
break;
}
Thread.sleep( 10 );
From 8dec9319639a4f9772d99264669b63cc3e9c2fe6 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 26 Apr 2022 02:03:21 +0000
Subject: [PATCH 22/28] Bump github/codeql-action from 1 to 2
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v1...v2)
---
updated-dependencies:
- dependency-name: github/codeql-action
dependency-type: direct:production
update-type: version-update:semver-major
...
Signed-off-by: dependabot[bot]
---
.github/workflows/codeql-analysis.yml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 6240fce9..6ede3405 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -36,7 +36,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@v1
+ uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -47,7 +47,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
- uses: github/codeql-action/autobuild@v1
+ uses: github/codeql-action/autobuild@v2
# âšī¸ Command-line programs to run using the OS shell.
# đ https://git.io/JvXDl
@@ -61,4 +61,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v1
+ uses: github/codeql-action/analyze@v2
From 407a93cf5bb2864d35462b3d4a05bb293dafc230 Mon Sep 17 00:00:00 2001
From: Fishermans
Date: Wed, 30 Mar 2022 20:13:37 +0200
Subject: [PATCH 23/28] SelectorUtils.matchPath(): inconsistent behaviour on
POSIX-like and Windows for single Wildcard pattern (#191)
This fixes #191 and closes #192
---
.../codehaus/plexus/util/SelectorUtils.java | 27 +++++++---
.../plexus/util/SelectorUtilsTest.java | 52 ++++++++++++++++++-
2 files changed, 70 insertions(+), 9 deletions(-)
diff --git a/src/main/java/org/codehaus/plexus/util/SelectorUtils.java b/src/main/java/org/codehaus/plexus/util/SelectorUtils.java
index de39f4fe..234a92c5 100644
--- a/src/main/java/org/codehaus/plexus/util/SelectorUtils.java
+++ b/src/main/java/org/codehaus/plexus/util/SelectorUtils.java
@@ -253,21 +253,32 @@ public static boolean matchPath( String pattern, String str, String separator, b
{
if ( isRegexPrefixedPattern( pattern ) )
{
- pattern =
+ String localPattern =
pattern.substring( REGEX_HANDLER_PREFIX.length(), pattern.length() - PATTERN_HANDLER_SUFFIX.length() );
- return str.matches( pattern );
+ return str.matches( localPattern );
}
else
{
- if ( isAntPrefixedPattern( pattern ) )
- {
- pattern = pattern.substring( ANT_HANDLER_PREFIX.length(),
- pattern.length() - PATTERN_HANDLER_SUFFIX.length() );
- }
+ String localPattern = isAntPrefixedPattern( pattern )
+ ? pattern.substring( ANT_HANDLER_PREFIX.length(), pattern.length() - PATTERN_HANDLER_SUFFIX.length() )
+ : pattern;
+ final String osRelatedPath = toOSRelatedPath( str, separator );
+ final String osRelatedPattern = toOSRelatedPath( localPattern, separator );
+ return matchAntPathPattern( osRelatedPattern, osRelatedPath, separator, isCaseSensitive );
+ }
+ }
- return matchAntPathPattern( pattern, str, separator, isCaseSensitive );
+ private static String toOSRelatedPath( String pattern, String separator )
+ {
+ if ( "/".equals( separator ) )
+ {
+ return pattern.replace( "\\", separator );
+ }
+ if ( "\\".equals( separator ) ) {
+ return pattern.replace( "/", separator );
}
+ return pattern;
}
static boolean isRegexPrefixedPattern( String pattern )
diff --git a/src/test/java/org/codehaus/plexus/util/SelectorUtilsTest.java b/src/test/java/org/codehaus/plexus/util/SelectorUtilsTest.java
index ebc2dca0..160aa16d 100644
--- a/src/test/java/org/codehaus/plexus/util/SelectorUtilsTest.java
+++ b/src/test/java/org/codehaus/plexus/util/SelectorUtilsTest.java
@@ -27,7 +27,6 @@
* SelectorUtilsTest class.
*
* @author herve
- * @version $Id: $Id
* @since 3.4.0
*/
public class SelectorUtilsTest
@@ -92,4 +91,55 @@ public void testMatchPath_WindowsFileSeparator()
// Pattern and target don't start with file separator
assertTrue( SelectorUtils.matchPath( "*" + separator + "a.txt", "b" + separator + "a.txt", separator, false ) );
}
+
+ @Test
+ public void testPatternMatchSingleWildcardPosix()
+ {
+ assertFalse(SelectorUtils.matchPath(
+ "/com/test/*",
+ "/com/test/test/hallo"));
+ }
+
+
+ @Test
+ public void testPatternMatchDoubleWildcardCaseInsensitivePosix()
+ {
+ assertTrue(SelectorUtils.matchPath(
+ "/com/test/**",
+ "/com/test/test/hallo"));
+ }
+
+
+ @Test
+ public void testPatternMatchDoubleWildcardPosix()
+ {
+ assertTrue(SelectorUtils.matchPath(
+ "/com/test/**",
+ "/com/test/test/hallo"));
+ }
+
+
+ @Test
+ public void testPatternMatchSingleWildcardWindows()
+ {
+ assertFalse(SelectorUtils.matchPath(
+ "D:\\com\\test\\*",
+ "D:\\com\\test\\test\\hallo"));
+
+ assertFalse(SelectorUtils.matchPath(
+ "D:/com/test/*",
+ "D:/com/test/test/hallo"));
+ }
+
+ @Test
+ public void testPatternMatchDoubleWildcardWindows()
+ {
+ assertTrue(SelectorUtils.matchPath(
+ "D:\\com\\test\\**",
+ "D:\\com\\test\\test\\hallo"));
+
+ assertTrue(SelectorUtils.matchPath(
+ "D:\\com\\test\\**",
+ "D:/com/test/test/hallo"));
+ }
}
From 89b8ef5e9cb4079b2f9cf4f23a6b17370708ad07 Mon Sep 17 00:00:00 2001
From: joehni
Date: Mon, 4 Jan 2021 00:32:48 +0100
Subject: [PATCH 24/28] Fix position on MXParser (#121)
This closes #121
---
.../plexus/util/xml/pull/MXParser.java | 4 +-
.../plexus/util/xml/pull/MXParserTest.java | 45 ++++++++++++++++---
2 files changed, 42 insertions(+), 7 deletions(-)
diff --git a/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java b/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
index e21b66cb..20fdcc8e 100644
--- a/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
+++ b/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
@@ -464,7 +464,7 @@ private void reset()
// System.out.println("reset() called");
location = null;
lineNumber = 1;
- columnNumber = 0;
+ columnNumber = 1;
seenRoot = false;
reachedEnd = false;
eventType = START_DOCUMENT;
@@ -3156,7 +3156,7 @@ else if ( !seenInnerTag )
{
// seenPITarget && !seenQ
throw new XmlPullParserException( "processing instruction started on line " + curLine
- + " and column " + curColumn + " was not closed", this, null );
+ + " and column " + (curColumn -2) + " was not closed", this, null );
}
}
else if ( ch == '<' )
diff --git a/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java b/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
index 27ba5f8c..b1dd6139 100644
--- a/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
+++ b/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
@@ -353,6 +353,35 @@ public void testValidCharacterReferenceDecimal()
*
* @throws java.lang.Exception if any.
*/
+ @Test
+ public void testParserPosition()
+ throws Exception
+ {
+ String input = " \n \tnnn\n";
+
+ MXParser parser = new MXParser();
+ parser.setInput( new StringReader( input ) );
+
+ assertEquals( XmlPullParser.PROCESSING_INSTRUCTION, parser.nextToken() );
+ assertPosition( 1, 39, parser );
+ assertEquals( XmlPullParser.COMMENT, parser.nextToken() );
+ assertPosition( 1, 49, parser );
+ assertEquals( XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken() );
+ assertPosition( 2, 3, parser ); // end when next token starts
+ assertEquals( XmlPullParser.COMMENT, parser.nextToken() );
+ assertPosition( 2, 12, parser );
+ assertEquals( XmlPullParser.START_TAG, parser.nextToken() );
+ assertPosition( 2, 18, parser );
+ assertEquals( XmlPullParser.TEXT, parser.nextToken() );
+ assertPosition( 2, 23, parser ); // end when next token starts
+ assertEquals( XmlPullParser.END_TAG, parser.nextToken() );
+ assertPosition( 2, 29, parser );
+ assertEquals( XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken() );
+ assertPosition( 3, 2, parser ); // end when next token starts
+ assertEquals( XmlPullParser.COMMENT, parser.nextToken() );
+ assertPosition( 4, 6, parser );
+ }
+
@Test
public void testProcessingInstruction()
throws Exception
@@ -624,7 +653,7 @@ public void testMalformedProcessingInstructionNoClosingQuestionMark()
}
catch ( XmlPullParserException ex )
{
- assertTrue( ex.getMessage().contains( "processing instruction started on line 1 and column 2 was not closed" ) );
+ assertTrue( ex.getMessage().contains( "processing instruction started on line 1 and column 1 was not closed" ) );
}
}
@@ -657,7 +686,7 @@ public void testSubsequentMalformedProcessingInstructionNoClosingQuestionMark()
}
catch ( XmlPullParserException ex )
{
- assertTrue( ex.getMessage().contains( "processing instruction started on line 1 and column 13 was not closed" ) );
+ assertTrue( ex.getMessage().contains( "processing instruction started on line 1 and column 12 was not closed" ) );
}
}
@@ -900,6 +929,12 @@ public void testEncodingISO_8859_1_setInputStream()
}
}
+ private static void assertPosition( int row, int col, MXParser parser )
+ {
+ assertEquals( "Current line", row, parser.getLineNumber() );
+ assertEquals( "Current column", col, parser.getColumnNumber() );
+ }
+
/**
* Issue 163: https://github.com/codehaus-plexus/plexus-utils/issues/163
*
@@ -958,7 +993,7 @@ public void testCustomEntityNotFoundInText()
}
catch ( XmlPullParserException e )
{
- assertTrue( e.getMessage().contains( "could not resolve entity named 'otherentity' (position: START_TAG seen &otherentity;... @1:19)" ) );
+ assertTrue( e.getMessage().contains( "could not resolve entity named 'otherentity' (position: START_TAG seen &otherentity;... @1:20)" ) );
assertEquals( XmlPullParser.START_TAG, parser.getEventType() ); // not an ENTITY_REF
assertEquals( "otherentity", parser.getText() );
}
@@ -1025,7 +1060,7 @@ public void testCustomEntityNotFoundInAttr()
}
catch ( XmlPullParserException e )
{
- assertTrue( e.getMessage().contains( "could not resolve entity named 'otherentity' (position: START_DOCUMENT seen
Date: Tue, 5 Jan 2021 00:33:34 +0100
Subject: [PATCH 25/28] Fix start position of PI and comment for all reported
errors (#124)
This closes #124
---
.../java/org/codehaus/plexus/util/xml/pull/MXParser.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java b/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
index 20fdcc8e..d1c6ef18 100644
--- a/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
+++ b/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
@@ -2988,7 +2988,7 @@ private void parseComment()
posStart = pos;
final int curLine = lineNumber;
- final int curColumn = columnNumber;
+ final int curColumn = columnNumber - 4;
try
{
final boolean normalizeIgnorableWS = tokenize && !roundtripSupported;
@@ -3109,7 +3109,7 @@ private boolean parsePI()
if ( tokenize )
posStart = pos;
final int curLine = lineNumber;
- final int curColumn = columnNumber;
+ final int curColumn = columnNumber - 2;
int piTargetStart = pos;
int piTargetEnd = -1;
final boolean normalizeIgnorableWS = tokenize && !roundtripSupported;
@@ -3156,7 +3156,7 @@ else if ( !seenInnerTag )
{
// seenPITarget && !seenQ
throw new XmlPullParserException( "processing instruction started on line " + curLine
- + " and column " + (curColumn -2) + " was not closed", this, null );
+ + " and column " + curColumn + " was not closed", this, null );
}
}
else if ( ch == '<' )
From 11c749d677176b5b04573a1acd37997ec61dcc05 Mon Sep 17 00:00:00 2001
From: joehni
Date: Mon, 4 Jan 2021 00:41:38 +0100
Subject: [PATCH 26/28] Fix endless loop with invalid PI containing XML (#122)
This closes #122
---
.../plexus/util/xml/pull/MXParser.java | 4 +++
.../plexus/util/xml/pull/MXParserTest.java | 31 +++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java b/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
index d1c6ef18..30c30fef 100644
--- a/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
+++ b/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
@@ -3158,6 +3158,10 @@ else if ( !seenInnerTag )
throw new XmlPullParserException( "processing instruction started on line " + curLine
+ " and column " + curColumn + " was not closed", this, null );
}
+ else
+ {
+ seenInnerTag = false;
+ }
}
else if ( ch == '<' )
{
diff --git a/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java b/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
index b1dd6139..8e8dc231 100644
--- a/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
+++ b/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
@@ -432,6 +432,37 @@ public void testProcessingInstructionsContainingXml()
*
* @throws java.lang.Exception if any.
*/
+ @Test
+ public void testMalformedProcessingInstructionsContainingXmlNoClosingQuestionMark()
+ throws Exception
+ {
+ StringBuffer sb = new StringBuffer();
+ sb.append( "\n" );
+ sb.append( "\n" );
+ sb.append( "\n" );
+ sb.append( " >\n" );
+
+ MXParser parser = new MXParser();
+ parser.setInput( new StringReader( sb.toString() ) );
+
+ try
+ {
+ assertEquals( XmlPullParser.PROCESSING_INSTRUCTION, parser.nextToken() );
+ assertEquals( XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken() );
+ assertEquals( XmlPullParser.START_TAG, parser.nextToken() );
+ assertEquals( XmlPullParser.END_TAG, parser.nextToken() );
+ assertEquals( XmlPullParser.IGNORABLE_WHITESPACE, parser.nextToken() );
+ assertEquals( XmlPullParser.PROCESSING_INSTRUCTION, parser.nextToken() );
+
+ fail( "Should fail since it has invalid PI" );
+ }
+ catch ( XmlPullParserException ex )
+ {
+ assertTrue( ex.getMessage().contains( "processing instruction started on line 3 and column 1 was not closed" ) );
+ }
+ }
+
@Test
public void testSubsequentProcessingInstructionShort()
throws Exception
From 0d97c8ba8dfa4663e86c5827555f980fd47c27a9 Mon Sep 17 00:00:00 2001
From: joehni
Date: Tue, 5 Jan 2021 00:38:32 +0100
Subject: [PATCH 27/28] Fix endless loop caused by aborted subsequent PI or
comment (#124)
This closes #124
---
.../plexus/util/xml/pull/MXParser.java | 2 +-
.../plexus/util/xml/pull/MXParserTest.java | 52 +++++++++++++++++++
2 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java b/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
index 30c30fef..d44c9a7f 100644
--- a/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
+++ b/src/main/java/org/codehaus/plexus/util/xml/pull/MXParser.java
@@ -3964,7 +3964,7 @@ private char more()
fillBuf();
// this return value should be ignored as it is used in epilog parsing ...
if ( reachedEnd )
- return (char) -1;
+ throw new EOFException( "no more data available" + getPositionDescription() );
}
final char ch = buf[pos++];
// line/columnNumber
diff --git a/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java b/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
index 8e8dc231..e5e04708 100644
--- a/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
+++ b/src/test/java/org/codehaus/plexus/util/xml/pull/MXParserTest.java
@@ -726,6 +726,58 @@ public void testSubsequentMalformedProcessingInstructionNoClosingQuestionMark()
*
* @throws java.lang.Exception if any.
*/
+ @Test
+ public void testSubsequentAbortedProcessingInstruction()
+ throws Exception
+ {
+ MXParser parser = new MXParser();
+ StringBuilder sb = new StringBuilder();
+ sb.append( "" );
+ sb.append( "" );
+ sb.append( "