diff --git a/ChangeLog.md b/ChangeLog.md index eed4cd10ef..6100e2cf85 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -17,6 +17,13 @@ specific language governing permissions and limitations under the License. --> +*2024-02-20 Arturo Bernal (abernal AT apache DOT org)** + +* _2.12.2-git-12_ + +Avoid method that assume default platform encoding is suitable. #232 + + **2023-12-04 Juan Pablo Santos (juanpablo AT apache DOT org)** * _2.12.2-git-11_ diff --git a/jspwiki-api/src/main/java/org/apache/wiki/api/Release.java b/jspwiki-api/src/main/java/org/apache/wiki/api/Release.java index b3699e53a1..1c6bef6af2 100644 --- a/jspwiki-api/src/main/java/org/apache/wiki/api/Release.java +++ b/jspwiki-api/src/main/java/org/apache/wiki/api/Release.java @@ -69,7 +69,7 @@ public final class Release { *
* If the build identifier is empty, it is not added.
*/
- public static final String BUILD = "11";
+ public static final String BUILD = "12";
/**
* This is the generic version string you should use when printing out the version. It is of
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/JDBCUserDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/JDBCUserDatabase.java
index 9dd48be064..6bb29fc19b 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/JDBCUserDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/JDBCUserDatabase.java
@@ -32,6 +32,7 @@ Licensed to the Apache Software Foundation (ASF) under one
import javax.sql.DataSource;
import java.io.IOException;
import java.io.Serializable;
+import java.nio.charset.Charset;
import java.security.Principal;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
@@ -298,6 +299,12 @@ public class JDBCUserDatabase extends AbstractUserDatabase {
private boolean m_supportsCommits;
+ /**
+ * The character set encoding used by this object. This is obtained from {@link org.apache.wiki.WikiEngine#getContentEncoding()},
+ * which returns the content encoding of the engine, either UTF-8 or ISO-8859-1.
+ */
+ private Charset m_encoding;
+
/**
* Looks up and deletes the first {@link UserProfile} in the user database
* that matches a profile having a given login name. If the user database
@@ -415,6 +422,7 @@ public Principal[] getWikiNames() throws WikiSecurityException {
@Override
public void initialize( final Engine engine, final Properties props ) throws NoRequiredPropertyException, WikiSecurityException {
final String jndiName = props.getProperty( PROP_DB_DATASOURCE, DEFAULT_DB_JNDI_NAME );
+ m_encoding = engine != null ? engine.getContentEncoding() : Charset.defaultCharset();
try {
final Context initCtx = new InitialContext();
final Context ctx = (Context) initCtx.lookup( "java:comp/env" );
@@ -615,7 +623,7 @@ public void save( final UserProfile profile ) throws WikiSecurityException {
ps1.setTimestamp( 6, ts );
ps1.setString( 7, profile.getLoginName() );
try {
- ps1.setString( 8, Serializer.serializeToBase64( profile.getAttributes() ) );
+ ps1.setString( 8, Serializer.serializeToBase64( profile.getAttributes(), m_encoding != null ? m_encoding : Charset.defaultCharset() ) );
} catch ( final IOException e ) {
throw new WikiSecurityException( "Could not save user profile attribute. Reason: " + e.getMessage(), e );
}
@@ -649,7 +657,7 @@ public void save( final UserProfile profile ) throws WikiSecurityException {
ps4.setTimestamp( 6, ts );
ps4.setString( 7, profile.getLoginName() );
try {
- ps4.setString( 8, Serializer.serializeToBase64( profile.getAttributes() ) );
+ ps4.setString( 8, Serializer.serializeToBase64( profile.getAttributes(), m_encoding != null ? m_encoding : Charset.defaultCharset() ) );
} catch ( final IOException e ) {
throw new WikiSecurityException( "Could not save user profile attribute. Reason: " + e.getMessage(), e );
}
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/XMLUserDatabase.java b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/XMLUserDatabase.java
index dd7c6ee582..6e50f3d2b8 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/auth/user/XMLUserDatabase.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/auth/user/XMLUserDatabase.java
@@ -41,6 +41,7 @@ Licensed to the Apache Software Foundation (ASF) under one
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Serializable;
+import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.Principal;
@@ -91,6 +92,12 @@ public class XMLUserDatabase extends AbstractUserDatabase {
private Document c_dom;
private File c_file;
+ /**
+ * The character set encoding used by this object. This is obtained from {@link org.apache.wiki.WikiEngine#getContentEncoding()},
+ * which returns the content encoding of the engine, either UTF-8 or ISO-8859-1.
+ */
+ private Charset m_encoding;
+
/** {@inheritDoc} */
@Override
public synchronized void deleteByLoginName( final String loginName ) throws WikiSecurityException {
@@ -182,6 +189,8 @@ public void initialize( final Engine engine, final Properties props ) throws NoR
defaultFile = new File( engine.getRootPath() + "/WEB-INF/" + DEFAULT_USERDATABASE );
}
+ m_encoding = engine.getContentEncoding();
+
// Get database file location
final String file = TextUtil.getStringProperty( props, PROP_USERDATABASE, defaultFile.getAbsolutePath() );
if( file == null ) {
@@ -416,7 +425,7 @@ public synchronized void save( final UserProfile profile ) throws WikiSecurityEx
// Save the attributes as Base64 string
if(!profile.getAttributes().isEmpty()) {
try {
- final String encodedAttributes = Serializer.serializeToBase64( profile.getAttributes() );
+ final String encodedAttributes = Serializer.serializeToBase64( profile.getAttributes(), m_encoding != null ? m_encoding : Charset.defaultCharset() );
final Element attributes = c_dom.createElement( ATTRIBUTES_TAG );
user.appendChild( attributes );
final Text value = c_dom.createTextNode( encodedAttributes );
diff --git a/jspwiki-main/src/main/java/org/apache/wiki/diff/ExternalDiffProvider.java b/jspwiki-main/src/main/java/org/apache/wiki/diff/ExternalDiffProvider.java
index d1ae915eed..39f548c768 100644
--- a/jspwiki-main/src/main/java/org/apache/wiki/diff/ExternalDiffProvider.java
+++ b/jspwiki-main/src/main/java/org/apache/wiki/diff/ExternalDiffProvider.java
@@ -49,6 +49,11 @@ public class ExternalDiffProvider implements DiffProvider {
public static final String PROP_DIFFCOMMAND = "jspwiki.diffCommand";
private String m_diffCommand;
+
+ /**
+ * The character set encoding used by this object. This is obtained from {@link org.apache.wiki.WikiEngine#getContentEncoding()},
+ * which returns the content encoding of the engine, either UTF-8 or ISO-8859-1.
+ */
private Charset m_encoding;
private static final char DIFF_ADDED_SYMBOL = '+';
@@ -113,7 +118,7 @@ public String makeDiffHtml( final Context ctx, final String p1, final String p2
String cmd = TextUtil.replaceString(m_diffCommand, "%s1", f1.getPath());
cmd = TextUtil.replaceString(cmd, "%s2", f2.getPath());
- final String output = FileUtil.runSimpleCommand(cmd, f1.getParent());
+ final String output = FileUtil.runSimpleCommand(cmd, f1.getParent(), m_encoding != null ? m_encoding : Charset.defaultCharset());
// FIXME: Should this rely on the system default encoding?
final String rawWikiDiff = new String( output.getBytes( StandardCharsets.ISO_8859_1 ), m_encoding );
diff --git a/jspwiki-util/src/main/java/org/apache/wiki/util/FileUtil.java b/jspwiki-util/src/main/java/org/apache/wiki/util/FileUtil.java
index b8205c04c5..1591736a7d 100644
--- a/jspwiki-util/src/main/java/org/apache/wiki/util/FileUtil.java
+++ b/jspwiki-util/src/main/java/org/apache/wiki/util/FileUtil.java
@@ -100,16 +100,17 @@ public static File newTmpFile( final String content ) throws IOException {
* @return Standard output from the command.
* @param command The command to run
* @param directory The working directory to run the command in
+ * @param charset The character set encoding to use for the input streams
* @throws IOException If the command failed
* @throws InterruptedException If the command was halted
*/
- public static String runSimpleCommand( final String command, final String directory ) throws IOException, InterruptedException {
+ public static String runSimpleCommand( final String command, final String directory , final Charset charset) throws IOException, InterruptedException {
LOG.info( "Running simple command " + command + " in " + directory );
final StringBuilder result = new StringBuilder();
final Process process = Runtime.getRuntime().exec( command, null, new File( directory ) );
- try( final BufferedReader stdout = new BufferedReader( new InputStreamReader( process.getInputStream() ) );
- final BufferedReader stderr = new BufferedReader( new InputStreamReader( process.getErrorStream() ) ) ) {
+ try( final BufferedReader stdout = new BufferedReader( new InputStreamReader( process.getInputStream(), charset ) );
+ final BufferedReader stderr = new BufferedReader( new InputStreamReader( process.getErrorStream(), charset ) ) ) {
String line;
while( (line = stdout.readLine()) != null ) {
diff --git a/jspwiki-util/src/main/java/org/apache/wiki/util/Serializer.java b/jspwiki-util/src/main/java/org/apache/wiki/util/Serializer.java
index 78ca48a7f7..3bb13f476f 100644
--- a/jspwiki-util/src/main/java/org/apache/wiki/util/Serializer.java
+++ b/jspwiki-util/src/main/java/org/apache/wiki/util/Serializer.java
@@ -25,6 +25,7 @@ Licensed to the Apache Software Foundation (ASF) under one
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
+import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.HashMap;
@@ -74,10 +75,11 @@ private Serializer()
* Serializes a Map and formats it into a Base64-encoded String. For ease of serialization, the Map contents
* are first copied into a HashMap, then serialized into a byte array that is encoded as a Base64 String.
* @param map the Map to serialize
+ * @param charset the character set encoding to use for the Base64-encoded String
* @return a String representing the serialized form of the Map
* @throws IOException If serialization cannot be done
*/
- public static String serializeToBase64(final Map< String, Serializable > map ) throws IOException {
+ public static String serializeToBase64(final Map< String, Serializable > map, final Charset charset) throws IOException {
// Load the Map contents into a defensive HashMap
final Map