Commit 2afdf994 authored by Liang Ding's avatar Liang Ding

Fix #12052

parent ece81052
...@@ -56,7 +56,7 @@ import org.json.JSONObject; ...@@ -56,7 +56,7 @@ import org.json.JSONObject;
* Solo Servlet listener. * Solo Servlet listener.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.7.0.11, Dec 13, 2015 * @version 1.7.0.12, Dec 17, 2015
* @since 0.3.1 * @since 0.3.1
*/ */
public final class SoloServletListener extends AbstractServletListener { public final class SoloServletListener extends AbstractServletListener {
...@@ -76,11 +76,6 @@ public final class SoloServletListener extends AbstractServletListener { ...@@ -76,11 +76,6 @@ public final class SoloServletListener extends AbstractServletListener {
*/ */
public static final int JSON_PRINT_INDENT_FACTOR = 4; public static final int JSON_PRINT_INDENT_FACTOR = 4;
/**
* Enter escape.
*/
public static final String ENTER_ESC = "_esc_enter_88250_";
/** /**
* B3log Rhythm address. * B3log Rhythm address.
*/ */
......
...@@ -102,7 +102,7 @@ public final class ArticleCommentReplyNotifier extends AbstractEventListener<JSO ...@@ -102,7 +102,7 @@ public final class ArticleCommentReplyNotifier extends AbstractEventListener<JSO
final String blogTitle = preference.getString(Option.ID_C_BLOG_TITLE); final String blogTitle = preference.getString(Option.ID_C_BLOG_TITLE);
final String adminEmail = preference.getString(Option.ID_C_ADMIN_EMAIL); final String adminEmail = preference.getString(Option.ID_C_ADMIN_EMAIL);
final String commentContent = comment.getString(Comment.COMMENT_CONTENT).replaceAll(SoloServletListener.ENTER_ESC, "<br/>"); final String commentContent = comment.getString(Comment.COMMENT_CONTENT);
final String commentSharpURL = comment.getString(Comment.COMMENT_SHARP_URL); final String commentSharpURL = comment.getString(Comment.COMMENT_SHARP_URL);
final Message message = new Message(); final Message message = new Message();
......
...@@ -97,7 +97,7 @@ public final class PageCommentReplyNotifier extends AbstractEventListener<JSONOb ...@@ -97,7 +97,7 @@ public final class PageCommentReplyNotifier extends AbstractEventListener<JSONOb
final String blogTitle = preference.getString(Option.ID_C_BLOG_TITLE); final String blogTitle = preference.getString(Option.ID_C_BLOG_TITLE);
final String adminEmail = preference.getString(Option.ID_C_ADMIN_EMAIL); final String adminEmail = preference.getString(Option.ID_C_ADMIN_EMAIL);
final String commentContent = comment.getString(Comment.COMMENT_CONTENT).replaceAll(SoloServletListener.ENTER_ESC, "<br/>"); final String commentContent = comment.getString(Comment.COMMENT_CONTENT);
final String commentSharpURL = comment.getString(Comment.COMMENT_SHARP_URL); final String commentSharpURL = comment.getString(Comment.COMMENT_SHARP_URL);
final Message message = new Message(); final Message message = new Message();
......
...@@ -48,7 +48,7 @@ import org.json.JSONObject; ...@@ -48,7 +48,7 @@ import org.json.JSONObject;
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author ArmstrongCN * @author ArmstrongCN
* @version 1.1.1.12, Apr 10, 2014 * @version 1.2.1.12, Dec 17, 2015
* @since 0.3.1 * @since 0.3.1
*/ */
@RequestProcessor @RequestProcessor
...@@ -107,7 +107,8 @@ public class CommentProcessor { ...@@ -107,7 +107,8 @@ public class CommentProcessor {
* "commentEmail": "", * "commentEmail": "",
* "commentURL": "", * "commentURL": "",
* "commentContent": "", * "commentContent": "",
* "commentOriginalCommentId": "" // optional, if exists this key, the comment is an reply * "commentOriginalCommentId": "", // optional, if exists this key, the comment is an reply
* "commentContent": "" // HTML
* } * }
* </pre> * </pre>
* @throws ServletException servlet exception * @throws ServletException servlet exception
...@@ -188,7 +189,8 @@ public class CommentProcessor { ...@@ -188,7 +189,8 @@ public class CommentProcessor {
* "commentDate": "", // yyyy/MM/dd hh:mm:ss * "commentDate": "", // yyyy/MM/dd hh:mm:ss
* "commentSharpURL": "", * "commentSharpURL": "",
* "commentThumbnailURL": "", * "commentThumbnailURL": "",
* "commentOriginalCommentName": "" // if exists this key, the comment is an reply * "commentOriginalCommentName": "", // if exists this key, the comment is an reply
* "commentContent": "" // HTML
* } * }
* </pre> * </pre>
* *
......
...@@ -25,7 +25,6 @@ import java.util.Map; ...@@ -25,7 +25,6 @@ import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.time.DateFormatUtils; import org.apache.commons.lang.time.DateFormatUtils;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.Latkes; import org.b3log.latke.Latkes;
...@@ -71,7 +70,7 @@ import org.json.JSONObject; ...@@ -71,7 +70,7 @@ import org.json.JSONObject;
* Filler utilities. * Filler utilities.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.5.11.12, Nov 20, 2015 * @version 1.5.11.13, Dec 17, 2015
* @since 0.3.1 * @since 0.3.1
*/ */
@Service @Service
...@@ -527,11 +526,10 @@ public class Filler { ...@@ -527,11 +526,10 @@ public class Filler {
final List<JSONObject> recentComments = commentRepository.getRecentComments(recentCommentDisplayCnt); final List<JSONObject> recentComments = commentRepository.getRecentComments(recentCommentDisplayCnt);
for (final JSONObject comment : recentComments) { for (final JSONObject comment : recentComments) {
final String content = comment.getString(Comment.COMMENT_CONTENT).replaceAll(SoloServletListener.ENTER_ESC, "&nbsp;"); final String content = comment.getString(Comment.COMMENT_CONTENT);
comment.put(Comment.COMMENT_CONTENT, content); comment.put(Comment.COMMENT_CONTENT, content);
comment.put(Comment.COMMENT_NAME, StringEscapeUtils.escapeHtml(comment.getString(Comment.COMMENT_NAME))); comment.put(Comment.COMMENT_NAME, comment.getString(Comment.COMMENT_NAME));
comment.put(Comment.COMMENT_URL, StringEscapeUtils.escapeHtml(comment.getString(Comment.COMMENT_URL))); comment.put(Comment.COMMENT_URL, comment.getString(Comment.COMMENT_URL));
comment.remove(Comment.COMMENT_EMAIL); // Erases email for security reason comment.remove(Comment.COMMENT_EMAIL); // Erases email for security reason
} }
......
...@@ -20,7 +20,6 @@ import java.net.URL; ...@@ -20,7 +20,6 @@ import java.net.URL;
import java.util.Date; import java.util.Date;
import javax.inject.Inject; import javax.inject.Inject;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.time.DateFormatUtils; import org.apache.commons.lang.time.DateFormatUtils;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.Latkes; import org.b3log.latke.Latkes;
...@@ -46,15 +45,18 @@ import org.b3log.solo.repository.CommentRepository; ...@@ -46,15 +45,18 @@ import org.b3log.solo.repository.CommentRepository;
import org.b3log.solo.repository.PageRepository; import org.b3log.solo.repository.PageRepository;
import org.b3log.solo.repository.UserRepository; import org.b3log.solo.repository.UserRepository;
import org.b3log.solo.util.Comments; import org.b3log.solo.util.Comments;
import org.b3log.solo.util.Markdowns;
import org.b3log.solo.util.Thumbnails; import org.b3log.solo.util.Thumbnails;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
/** /**
* Comment management service. * Comment management service.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.1.0.8, Nov 20, 2015 * @version 1.2.0.8, Dec 17, 2015
* @since 0.3.5 * @since 0.3.5
*/ */
@Service @Service
...@@ -178,7 +180,7 @@ public class CommentMgmtService { ...@@ -178,7 +180,7 @@ public class CommentMgmtService {
throws IOException, JSONException { throws IOException, JSONException {
final String commentEmail = comment.getString(Comment.COMMENT_EMAIL); final String commentEmail = comment.getString(Comment.COMMENT_EMAIL);
final String commentId = comment.getString(Keys.OBJECT_ID); final String commentId = comment.getString(Keys.OBJECT_ID);
final String commentContent = comment.getString(Comment.COMMENT_CONTENT).replaceAll(SoloServletListener.ENTER_ESC, "<br/>"); final String commentContent = comment.getString(Comment.COMMENT_CONTENT);
final String adminEmail = preference.getString(Option.ID_C_ADMIN_EMAIL); final String adminEmail = preference.getString(Option.ID_C_ADMIN_EMAIL);
...@@ -256,6 +258,10 @@ public class CommentMgmtService { ...@@ -256,6 +258,10 @@ public class CommentMgmtService {
/** /**
* Checks the specified comment adding request. * Checks the specified comment adding request.
* *
* <p>
* XSS process (name, content) in this method.
* </p>
*
* @param requestJSONObject the specified comment adding request, for example, <pre> * @param requestJSONObject the specified comment adding request, for example, <pre>
* { * {
* "type": "", // "article"/"page" * "type": "", // "article"/"page"
...@@ -308,7 +314,7 @@ public class CommentMgmtService { ...@@ -308,7 +314,7 @@ public class CommentMgmtService {
} }
} }
final String commentName = requestJSONObject.getString(Comment.COMMENT_NAME); String commentName = requestJSONObject.getString(Comment.COMMENT_NAME);
if (MAX_COMMENT_NAME_LENGTH < commentName.length() || MIN_COMMENT_NAME_LENGTH > commentName.length()) { if (MAX_COMMENT_NAME_LENGTH < commentName.length() || MIN_COMMENT_NAME_LENGTH > commentName.length()) {
LOGGER.log(Level.WARN, "Comment name is too long[{0}]", commentName); LOGGER.log(Level.WARN, "Comment name is too long[{0}]", commentName);
...@@ -335,8 +341,7 @@ public class CommentMgmtService { ...@@ -335,8 +341,7 @@ public class CommentMgmtService {
return ret; return ret;
} }
final String commentContent = requestJSONObject.optString(Comment.COMMENT_CONTENT).replaceAll("\\n", String commentContent = requestJSONObject.optString(Comment.COMMENT_CONTENT).replaceAll("\\n", "<br/>");
SoloServletListener.ENTER_ESC);
if (MAX_COMMENT_CONTENT_LENGTH < commentContent.length() || MIN_COMMENT_CONTENT_LENGTH > commentContent.length()) { if (MAX_COMMENT_CONTENT_LENGTH < commentContent.length() || MIN_COMMENT_CONTENT_LENGTH > commentContent.length()) {
LOGGER.log(Level.WARN, "Comment conent length is invalid[{0}]", commentContent.length()); LOGGER.log(Level.WARN, "Comment conent length is invalid[{0}]", commentContent.length());
...@@ -347,6 +352,16 @@ public class CommentMgmtService { ...@@ -347,6 +352,16 @@ public class CommentMgmtService {
ret.put(Keys.STATUS_CODE, true); ret.put(Keys.STATUS_CODE, true);
// XSS process
commentName = Jsoup.clean(commentName, Whitelist.none());
requestJSONObject.put(Comment.COMMENT_NAME, commentName);
commentContent = commentContent.replaceAll("\\n", "<br/>\n");
commentContent = Markdowns.toHTML(commentContent);
commentContent = Jsoup.clean(commentContent, Whitelist.relaxed());
requestJSONObject.put(Comment.COMMENT_CONTENT, commentContent);
return ret; return ret;
} catch (final Exception e) { } catch (final Exception e) {
LOGGER.log(Level.WARN, "Checks add comment request[" + requestJSONObject.toString() + "] failed", e); LOGGER.log(Level.WARN, "Checks add comment request[" + requestJSONObject.toString() + "] failed", e);
...@@ -378,7 +393,9 @@ public class CommentMgmtService { ...@@ -378,7 +393,9 @@ public class CommentMgmtService {
* "commentDate": "", // format: yyyy-MM-dd hh:mm:ss * "commentDate": "", // format: yyyy-MM-dd hh:mm:ss
* "commentOriginalCommentName": "" // optional, corresponding to argument "commentOriginalCommentId" * "commentOriginalCommentName": "" // optional, corresponding to argument "commentOriginalCommentId"
* "commentThumbnailURL": "", * "commentThumbnailURL": "",
* "commentSharpURL": "" * "commentSharpURL": "",
* "commentContent": "", // processed XSS HTML
* "commentName": "" // processed XSS
* } * }
* </pre> * </pre>
* *
...@@ -395,9 +412,8 @@ public class CommentMgmtService { ...@@ -395,9 +412,8 @@ public class CommentMgmtService {
final String commentName = requestJSONObject.getString(Comment.COMMENT_NAME); final String commentName = requestJSONObject.getString(Comment.COMMENT_NAME);
final String commentEmail = requestJSONObject.getString(Comment.COMMENT_EMAIL).trim().toLowerCase(); final String commentEmail = requestJSONObject.getString(Comment.COMMENT_EMAIL).trim().toLowerCase();
final String commentURL = requestJSONObject.optString(Comment.COMMENT_URL); final String commentURL = requestJSONObject.optString(Comment.COMMENT_URL);
String commentContent = requestJSONObject.getString(Comment.COMMENT_CONTENT).replaceAll("\\n", SoloServletListener.ENTER_ESC); final String commentContent = requestJSONObject.getString(Comment.COMMENT_CONTENT);
commentContent = StringEscapeUtils.escapeHtml(commentContent);
final String originalCommentId = requestJSONObject.optString(Comment.COMMENT_ORIGINAL_COMMENT_ID); final String originalCommentId = requestJSONObject.optString(Comment.COMMENT_ORIGINAL_COMMENT_ID);
// Step 1: Add comment // Step 1: Add comment
final JSONObject comment = new JSONObject(); final JSONObject comment = new JSONObject();
...@@ -440,6 +456,9 @@ public class CommentMgmtService { ...@@ -440,6 +456,9 @@ public class CommentMgmtService {
// Save comment sharp URL // Save comment sharp URL
final String commentSharpURL = Comments.getCommentSharpURLForPage(page, commentId); final String commentSharpURL = Comments.getCommentSharpURLForPage(page, commentId);
ret.put(Comment.COMMENT_NAME, commentName);
ret.put(Comment.COMMENT_CONTENT, commentContent);
ret.put(Comment.COMMENT_SHARP_URL, commentSharpURL); ret.put(Comment.COMMENT_SHARP_URL, commentSharpURL);
comment.put(Comment.COMMENT_SHARP_URL, commentSharpURL); comment.put(Comment.COMMENT_SHARP_URL, commentSharpURL);
comment.put(Keys.OBJECT_ID, commentId); comment.put(Keys.OBJECT_ID, commentId);
...@@ -494,7 +513,9 @@ public class CommentMgmtService { ...@@ -494,7 +513,9 @@ public class CommentMgmtService {
* "commentDate": "", // format: yyyy-MM-dd hh:mm:ss * "commentDate": "", // format: yyyy-MM-dd hh:mm:ss
* "commentOriginalCommentName": "" // optional, corresponding to argument "commentOriginalCommentId" * "commentOriginalCommentName": "" // optional, corresponding to argument "commentOriginalCommentId"
* "commentThumbnailURL": "", * "commentThumbnailURL": "",
* "commentSharpURL": "" * "commentSharpURL": "",
* "commentContent": "", // processed XSS HTML
* "commentName": "" // processed XSS
* } * }
* </pre> * </pre>
* *
...@@ -511,10 +532,8 @@ public class CommentMgmtService { ...@@ -511,10 +532,8 @@ public class CommentMgmtService {
final String commentName = requestJSONObject.getString(Comment.COMMENT_NAME); final String commentName = requestJSONObject.getString(Comment.COMMENT_NAME);
final String commentEmail = requestJSONObject.getString(Comment.COMMENT_EMAIL).trim().toLowerCase(); final String commentEmail = requestJSONObject.getString(Comment.COMMENT_EMAIL).trim().toLowerCase();
final String commentURL = requestJSONObject.optString(Comment.COMMENT_URL); final String commentURL = requestJSONObject.optString(Comment.COMMENT_URL);
String commentContent = requestJSONObject.getString(Comment.COMMENT_CONTENT).replaceAll("\\n", SoloServletListener.ENTER_ESC); final String commentContent = requestJSONObject.getString(Comment.COMMENT_CONTENT);
final String contentNoEsc = commentContent;
commentContent = StringEscapeUtils.escapeHtml(commentContent);
final String originalCommentId = requestJSONObject.optString(Comment.COMMENT_ORIGINAL_COMMENT_ID); final String originalCommentId = requestJSONObject.optString(Comment.COMMENT_ORIGINAL_COMMENT_ID);
// Step 1: Add comment // Step 1: Add comment
final JSONObject comment = new JSONObject(); final JSONObject comment = new JSONObject();
...@@ -536,6 +555,9 @@ public class CommentMgmtService { ...@@ -536,6 +555,9 @@ public class CommentMgmtService {
comment.put(Comment.COMMENT_DATE, date); comment.put(Comment.COMMENT_DATE, date);
ret.put(Comment.COMMENT_DATE, DateFormatUtils.format(date, "yyyy-MM-dd hh:mm:ss")); ret.put(Comment.COMMENT_DATE, DateFormatUtils.format(date, "yyyy-MM-dd hh:mm:ss"));
ret.put(Comment.COMMENT_NAME, commentName);
ret.put(Comment.COMMENT_CONTENT, commentContent);
if (!Strings.isEmptyOrNull(originalCommentId)) { if (!Strings.isEmptyOrNull(originalCommentId)) {
originalComment = commentRepository.get(originalCommentId); originalComment = commentRepository.get(originalCommentId);
if (null != originalComment) { if (null != originalComment) {
...@@ -579,7 +601,6 @@ public class CommentMgmtService { ...@@ -579,7 +601,6 @@ public class CommentMgmtService {
final JSONObject eventData = new JSONObject(); final JSONObject eventData = new JSONObject();
eventData.put(Comment.COMMENT, comment); eventData.put(Comment.COMMENT, comment);
comment.put(Comment.COMMENT_CONTENT, contentNoEsc);
eventData.put(Article.ARTICLE, article); eventData.put(Article.ARTICLE, article);
eventManager.fireEventSynchronously(new Event<JSONObject>(EventTypes.ADD_COMMENT_TO_ARTICLE, eventData)); eventManager.fireEventSynchronously(new Event<JSONObject>(EventTypes.ADD_COMMENT_TO_ARTICLE, eventData));
......
...@@ -15,13 +15,11 @@ ...@@ -15,13 +15,11 @@
*/ */
package org.b3log.solo.service; package org.b3log.solo.service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringEscapeUtils;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
import org.b3log.latke.logging.Logger; import org.b3log.latke.logging.Logger;
...@@ -33,7 +31,6 @@ import org.b3log.latke.service.ServiceException; ...@@ -33,7 +31,6 @@ import org.b3log.latke.service.ServiceException;
import org.b3log.latke.service.annotation.Service; import org.b3log.latke.service.annotation.Service;
import org.b3log.latke.util.Paginator; import org.b3log.latke.util.Paginator;
import org.b3log.latke.util.Strings; import org.b3log.latke.util.Strings;
import org.b3log.solo.SoloServletListener;
import org.b3log.solo.model.Article; import org.b3log.solo.model.Article;
import org.b3log.solo.model.Comment; import org.b3log.solo.model.Comment;
import org.b3log.solo.model.Common; import org.b3log.solo.model.Common;
...@@ -41,16 +38,18 @@ import org.b3log.solo.model.Page; ...@@ -41,16 +38,18 @@ import org.b3log.solo.model.Page;
import org.b3log.solo.repository.ArticleRepository; import org.b3log.solo.repository.ArticleRepository;
import org.b3log.solo.repository.CommentRepository; import org.b3log.solo.repository.CommentRepository;
import org.b3log.solo.repository.PageRepository; import org.b3log.solo.repository.PageRepository;
import org.b3log.solo.util.Markdowns;
import org.b3log.solo.util.Thumbnails; import org.b3log.solo.util.Thumbnails;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONObject; import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
/** /**
* Comment query service. * Comment query service.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.0.0.6, Nov 5, 2015 * @version 1.1.0.6, Dec 17, 2015
* @since 0.3.5 * @since 0.3.5
*/ */
@Service @Service
...@@ -103,7 +102,6 @@ public class CommentQueryService { ...@@ -103,7 +102,6 @@ public class CommentQueryService {
} }
// Here, you are not admin // Here, you are not admin
final JSONObject comment = commentRepository.get(commentId); final JSONObject comment = commentRepository.get(commentId);
if (null == comment) { if (null == comment) {
...@@ -131,8 +129,7 @@ public class CommentQueryService { ...@@ -131,8 +129,7 @@ public class CommentQueryService {
/** /**
* Gets comments with the specified request json object, request and response. * Gets comments with the specified request json object, request and response.
* *
* @param requestJSONObject the specified request json object, for example, * @param requestJSONObject the specified request json object, for example, <pre>
* <pre>
* { * {
* "paginationCurrentPageNum": 1, * "paginationCurrentPageNum": 1,
* "paginationPageSize": 20, * "paginationPageSize": 20,
...@@ -140,8 +137,7 @@ public class CommentQueryService { ...@@ -140,8 +137,7 @@ public class CommentQueryService {
* }, see {@link Pagination} for more details * }, see {@link Pagination} for more details
* </pre> * </pre>
* *
* @return for example, * @return for example, <pre>
* <pre>
* { * {
* "comments": [{ * "comments": [{
* "oId": "", * "oId": "",
...@@ -199,8 +195,9 @@ public class CommentQueryService { ...@@ -199,8 +195,9 @@ public class CommentQueryService {
comment.put(Comment.COMMENT_TIME, ((Date) comment.get(Comment.COMMENT_DATE)).getTime()); comment.put(Comment.COMMENT_TIME, ((Date) comment.get(Comment.COMMENT_DATE)).getTime());
comment.remove(Comment.COMMENT_DATE); comment.remove(Comment.COMMENT_DATE);
final String content = comment.getString(Comment.COMMENT_CONTENT).replaceAll(SoloServletListener.ENTER_ESC, "<br/>"); String content = comment.getString(Comment.COMMENT_CONTENT);
content = Markdowns.toHTML(content);
content = Jsoup.clean(content, Whitelist.relaxed());
comment.put(Comment.COMMENT_CONTENT, content); comment.put(Comment.COMMENT_CONTENT, content);
} }
...@@ -236,12 +233,14 @@ public class CommentQueryService { ...@@ -236,12 +233,14 @@ public class CommentQueryService {
final List<JSONObject> comments = commentRepository.getComments(onId, 1, Integer.MAX_VALUE); final List<JSONObject> comments = commentRepository.getComments(onId, 1, Integer.MAX_VALUE);
for (final JSONObject comment : comments) { for (final JSONObject comment : comments) {
final String content = comment.getString(Comment.COMMENT_CONTENT).replaceAll(SoloServletListener.ENTER_ESC, "<br/>"); String content = comment.getString(Comment.COMMENT_CONTENT);
content = Markdowns.toHTML(content);
content = Jsoup.clean(content, Whitelist.relaxed());
comment.put(Comment.COMMENT_CONTENT, content); comment.put(Comment.COMMENT_CONTENT, content);
comment.put(Comment.COMMENT_TIME, ((Date) comment.get(Comment.COMMENT_DATE)).getTime()); comment.put(Comment.COMMENT_TIME, ((Date) comment.get(Comment.COMMENT_DATE)).getTime());
comment.put(Comment.COMMENT_NAME, StringEscapeUtils.escapeHtml(comment.getString(Comment.COMMENT_NAME))); comment.put(Comment.COMMENT_NAME, comment.getString(Comment.COMMENT_NAME));
comment.put(Comment.COMMENT_URL, StringEscapeUtils.escapeHtml(comment.getString(Comment.COMMENT_URL))); comment.put(Comment.COMMENT_URL, comment.getString(Comment.COMMENT_URL));
comment.put(Common.IS_REPLY, false); // Assumes this comment is not a reply comment.put(Common.IS_REPLY, false); // Assumes this comment is not a reply
final String email = comment.optString(Comment.COMMENT_EMAIL); final String email = comment.optString(Comment.COMMENT_EMAIL);
......
...@@ -22,7 +22,6 @@ import java.util.List; ...@@ -22,7 +22,6 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import javax.inject.Inject; import javax.inject.Inject;
import javax.servlet.ServletContext; import javax.servlet.ServletContext;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.time.DateFormatUtils; import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils; import org.apache.commons.lang.time.DateUtils;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
...@@ -70,7 +69,7 @@ import org.json.JSONObject; ...@@ -70,7 +69,7 @@ import org.json.JSONObject;
* Solo initialization service. * Solo initialization service.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @version 1.4.2.8, Nov 20, 2015 * @version 1.4.2.9, Dec 17, 2015
* @since 0.4.0 * @since 0.4.0
*/ */
@Service @Service
...@@ -324,7 +323,7 @@ public class InitService { ...@@ -324,7 +323,7 @@ public class InitService {
comment.put(Comment.COMMENT_NAME, "88250"); comment.put(Comment.COMMENT_NAME, "88250");
comment.put(Comment.COMMENT_EMAIL, "dl88250@gmail.com"); comment.put(Comment.COMMENT_EMAIL, "dl88250@gmail.com");
comment.put(Comment.COMMENT_URL, "http://88250.b3log.org"); comment.put(Comment.COMMENT_URL, "http://88250.b3log.org");
comment.put(Comment.COMMENT_CONTENT, StringEscapeUtils.escapeHtml(langPropsService.get("helloWorld.comment.content"))); comment.put(Comment.COMMENT_CONTENT, langPropsService.get("helloWorld.comment.content"));
comment.put(Comment.COMMENT_ORIGINAL_COMMENT_ID, ""); comment.put(Comment.COMMENT_ORIGINAL_COMMENT_ID, "");
comment.put(Comment.COMMENT_ORIGINAL_COMMENT_NAME, ""); comment.put(Comment.COMMENT_ORIGINAL_COMMENT_NAME, "");
comment.put(Comment.COMMENT_THUMBNAIL_URL, Thumbnails.GRAVATAR + "59a5e8209c780307dbe9c9ba728073f5??s=60&r=G"); comment.put(Comment.COMMENT_THUMBNAIL_URL, Thumbnails.GRAVATAR + "59a5e8209c780307dbe9c9ba728073f5??s=60&r=G");
......
...@@ -19,6 +19,7 @@ import java.io.IOException; ...@@ -19,6 +19,7 @@ import java.io.IOException;
import java.sql.Connection; import java.sql.Connection;
import java.sql.Statement; import java.sql.Statement;
import javax.inject.Inject; import javax.inject.Inject;
import org.apache.commons.lang.StringEscapeUtils;
import org.b3log.latke.Keys; import org.b3log.latke.Keys;
import org.b3log.latke.Latkes; import org.b3log.latke.Latkes;
import org.b3log.latke.logging.Level; import org.b3log.latke.logging.Level;
...@@ -34,17 +35,20 @@ import org.b3log.latke.service.annotation.Service; ...@@ -34,17 +35,20 @@ import org.b3log.latke.service.annotation.Service;
import org.b3log.solo.SoloServletListener; import org.b3log.solo.SoloServletListener;
import org.b3log.solo.model.*; import org.b3log.solo.model.*;
import org.b3log.solo.repository.*; import org.b3log.solo.repository.*;
import org.b3log.solo.util.Markdowns;
import org.b3log.solo.util.Thumbnails; import org.b3log.solo.util.Thumbnails;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
import org.jsoup.Jsoup;
import org.jsoup.safety.Whitelist;
/** /**
* Upgrade service. * Upgrade service.
* *
* @author <a href="http://88250.b3log.org">Liang Ding</a> * @author <a href="http://88250.b3log.org">Liang Ding</a>
* @author <a href="mailto:dongxu.wang@acm.org">Dongxu Wang</a> * @author <a href="mailto:dongxu.wang@acm.org">Dongxu Wang</a>
* @version 1.1.0.4, Dec 13, 2015 * @version 1.2.0.4, Dec 17, 2015
* @since 1.2.0 * @since 1.2.0
*/ */
@Service @Service
...@@ -61,6 +65,12 @@ public class UpgradeService { ...@@ -61,6 +65,12 @@ public class UpgradeService {
@Inject @Inject
private ArticleRepository articleRepository; private ArticleRepository articleRepository;
/**
* Comment repository.
*/
@Inject
private CommentRepository commentRepository;
/** /**
* User repository. * User repository.
*/ */
...@@ -174,6 +184,23 @@ public class UpgradeService { ...@@ -174,6 +184,23 @@ public class UpgradeService {
versionOpt.put(Option.OPTION_VALUE, TO_VER); versionOpt.put(Option.OPTION_VALUE, TO_VER);
optionRepository.update(Option.ID_C_VERSION, versionOpt); optionRepository.update(Option.ID_C_VERSION, versionOpt);
final JSONArray comments = commentRepository.get(new Query()).optJSONArray(Keys.RESULTS);
for (int i = 0; i < comments.length(); i++) {
final JSONObject comment = comments.getJSONObject(i);
String name = comment.optString(Comment.COMMENT_NAME);
name = Jsoup.clean(name, Whitelist.none());
comment.put(Comment.COMMENT_NAME, name);
String content = comment.optString(Comment.COMMENT_CONTENT);
content = StringEscapeUtils.unescapeHtml(content).replaceAll("_esc_enter_88250_", "<br/>");
content = Markdowns.toHTML(content);
content = Jsoup.clean(content, Whitelist.relaxed());
comment.put(Comment.COMMENT_CONTENT, content);
commentRepository.update(comment.optString(Keys.OBJECT_ID), comment);
}
transaction.commit(); transaction.commit();
LOGGER.log(Level.INFO, "Updated preference"); LOGGER.log(Level.INFO, "Updated preference");
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
# #
# Description: Solo default language configurations(zh_CN). # Description: Solo default language configurations(zh_CN).
# Version: 2.5.4.15, Nov 20, 2015 # Version: 2.5.4.16, Dec 18, 2015
# Author: Liang Ding # Author: Liang Ding
# Author: Liyuan Li # Author: Liyuan Li
# Author: Dongxu Wang # Author: Dongxu Wang
...@@ -387,6 +387,6 @@ helloWorld.content=<p>\u6b22\u8fce\u4f7f\u7528 \ ...@@ -387,6 +387,6 @@ helloWorld.content=<p>\u6b22\u8fce\u4f7f\u7528 \
\u3002\u8fd9\u662f\u7cfb\u7edf\u81ea\u52a8\u751f\u6210\u7684\u6f14\u793a\u6587\u7ae0\u3002\u7f16\u8f91\u6216\u8005\u5220\u9664\u5b83\uff0c\u7136\u540e\u5f00\u59cb\u60a8\u7684\u535a\u5ba2\uff01</p>\ \u3002\u8fd9\u662f\u7cfb\u7edf\u81ea\u52a8\u751f\u6210\u7684\u6f14\u793a\u6587\u7ae0\u3002\u7f16\u8f91\u6216\u8005\u5220\u9664\u5b83\uff0c\u7136\u540e\u5f00\u59cb\u60a8\u7684\u535a\u5ba2\uff01</p>\
<p>\u53e6\u5916\uff0c\u6b22\u8fce\u60a8\u52a0\u5165<a href="http://hacpai.com" target="_blank">\u9ed1\u5ba2\u4e0e\u753b\u5bb6\u7684\u793e\u533a</a>\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528\u60a8\u7684\u535a\u5ba2\u8d26\u53f7\u76f4\u63a5\u767b\u5f55\uff01\ <p>\u53e6\u5916\uff0c\u6b22\u8fce\u60a8\u52a0\u5165<a href="http://hacpai.com" target="_blank">\u9ed1\u5ba2\u4e0e\u753b\u5bb6\u7684\u793e\u533a</a>\uff0c\u60a8\u53ef\u4ee5\u4f7f\u7528\u60a8\u7684\u535a\u5ba2\u8d26\u53f7\u76f4\u63a5\u767b\u5f55\uff01\
</p> </p>
helloWorld.comment.content=\u60a8\u597d\uff0c\u8fd9\u662f\u4e00\u6761\u8bc4\u8bba\u3002_esc_enter_88250_\u8981\u5220\u9664\u8bc4\u8bba\uff0c\u8bf7\u5148\u767b\u5f55\uff0c\u7136\u540e\u518d\u67e5\u770b\u8fd9\u7bc7\u6587\u7ae0\u7684\u8bc4\u8bba\u3002\u5728\u90a3\u91cc\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u5220\u9664\u8bc4\u8bba\u7684\u9009\u9879\u3002 helloWorld.comment.content=\u60a8\u597d\uff0c\u8fd9\u662f\u4e00\u6761\u8bc4\u8bba\u3002<br/>\u8981\u5220\u9664\u8bc4\u8bba\uff0c\u8bf7\u5148\u767b\u5f55\uff0c\u7136\u540e\u518d\u67e5\u770b\u8fd9\u7bc7\u6587\u7ae0\u7684\u8bc4\u8bba\u3002\u5728\u90a3\u91cc\uff0c\u60a8\u53ef\u4ee5\u770b\u5230\u5220\u9664\u8bc4\u8bba\u7684\u9009\u9879\u3002
articleContentPwd=\u8be5\u6587\u7ae0\u5df2\u7ecf\u52a0\u5bc6\u3002 articleContentPwd=\u8be5\u6587\u7ae0\u5df2\u7ecf\u52a0\u5bc6\u3002
ok=\u786e\u5b9a ok=\u786e\u5b9a
\ No newline at end of file
...@@ -590,9 +590,13 @@ $.extend(Page.prototype, { ...@@ -590,9 +590,13 @@ $.extend(Page.prototype, {
if (!Util.isLoggedIn()) { if (!Util.isLoggedIn()) {
$("#captcha" + state).attr("src", latkeConfig.servePath + "/captcha.do?code=" + Math.random()); $("#captcha" + state).attr("src", latkeConfig.servePath + "/captcha.do?code=" + Math.random());
} }
return; return;
} }
$("#comment" + state).val(result.commentContent); // Server processed XSS
$("#commentName" + state).val(result.commentName); // Server processed XSS
result.replyNameHTML = ""; result.replyNameHTML = "";
if (!Util.isLoggedIn()) { if (!Util.isLoggedIn()) {
$("#captcha" + state).attr("src", latkeConfig.servePath + "/captcha.do?code=" + Math.random()); $("#captcha" + state).attr("src", latkeConfig.servePath + "/captcha.do?code=" + Math.random());
...@@ -602,7 +606,7 @@ $.extend(Page.prototype, { ...@@ -602,7 +606,7 @@ $.extend(Page.prototype, {
result.replyNameHTML = '<a href="' + Util.proessURL($("#commentURL" + state).val()) + result.replyNameHTML = '<a href="' + Util.proessURL($("#commentURL" + state).val()) +
'" target="_blank">' + $("#commentName" + state).val() + '</a>'; '" target="_blank">' + $("#commentName" + state).val() + '</a>';
} }
result.userName = $("#commentName" + state).val(); result.userName = result.commentName;
} else { } else {
result.replyNameHTML = '<a href="' + window.location.host + result.replyNameHTML = '<a href="' + window.location.host +
'" target="_blank">' + Util.getUserName() + '</a>'; '" target="_blank">' + Util.getUserName() + '</a>';
......
This diff is collapsed.
...@@ -131,7 +131,7 @@ ...@@ -131,7 +131,7 @@
commentHTML += '<a class="fn-right" href="javascript:replyTo(\'' + result.oId + '\');">${replyLabel}</a>'; commentHTML += '<a class="fn-right" href="javascript:replyTo(\'' + result.oId + '\');">${replyLabel}</a>';
} }
commentHTML += '</div><div class="comment-content">' + commentHTML += '</div><div class="comment-content">' +
Util.replaceEmString($("#comment" + state).val().replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/\n/g, "<br/>")) Util.replaceEmString($("#comment" + state).val())
+ '</div></div></li>'; + '</div></div></li>';
return commentHTML; return commentHTML;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment