强化文件api,添加FilePond

This commit is contained in:
AlanScipio
2024-02-22 11:19:57 +08:00
parent da8d9f2fed
commit 7b71fd28e4
57 changed files with 1798 additions and 1542 deletions

View File

@@ -20,4 +20,9 @@ public class ServiceNameConstants {
* 文件服务的serviceId
*/
public static final String FILE_SERVICE = "ruoyi-file";
/**
* WMS服务的serviceId
*/
public static final String WMS_SERVICE = "ruoyi-wms";
}

View File

@@ -10,20 +10,31 @@ import java.nio.charset.StandardCharsets;
*
* @author ruoyi
*/
public class CharsetKit
{
/** ISO-8859-1 */
public class CharsetKit {
/**
* ISO-8859-1
*/
public static final String ISO_8859_1 = "ISO-8859-1";
/** UTF-8 */
/**
* UTF-8
*/
public static final String UTF_8 = "UTF-8";
/** GBK */
/**
* GBK
*/
public static final String GBK = "GBK";
/** ISO-8859-1 */
/**
* ISO-8859-1
*/
public static final Charset CHARSET_ISO_8859_1 = StandardCharsets.ISO_8859_1;
/** UTF-8 */
/**
* UTF-8
*/
public static final Charset CHARSET_UTF_8 = StandardCharsets.UTF_8;
/** GBK */
/**
* GBK
*/
public static final Charset CHARSET_GBK = Charset.forName(GBK);
/**
@@ -32,46 +43,40 @@ public class CharsetKit
* @param charset 字符集,为空则返回默认字符集
* @return Charset
*/
public static Charset charset(String charset)
{
public static Charset charset(String charset) {
return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
}
/**
* 转换字符串的字符集编码
*
* @param source 字符串
* @param srcCharset 源字符集默认ISO-8859-1
* @param source 字符串
* @param srcCharset 源字符集默认ISO-8859-1
* @param destCharset 目标字符集默认UTF-8
* @return 转换后的字符集
*/
public static String convert(String source, String srcCharset, String destCharset)
{
public static String convert(String source, String srcCharset, String destCharset) {
return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
}
/**
* 转换字符串的字符集编码
*
* @param source 字符串
* @param srcCharset 源字符集默认ISO-8859-1
* @param source 字符串
* @param srcCharset 源字符集默认ISO-8859-1
* @param destCharset 目标字符集默认UTF-8
* @return 转换后的字符集
*/
public static String convert(String source, Charset srcCharset, Charset destCharset)
{
if (null == srcCharset)
{
public static String convert(String source, Charset srcCharset, Charset destCharset) {
if (null == srcCharset) {
srcCharset = StandardCharsets.ISO_8859_1;
}
if (null == destCharset)
{
if (null == destCharset) {
destCharset = StandardCharsets.UTF_8;
}
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
{
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset)) {
return source;
}
return new String(source.getBytes(srcCharset), destCharset);
@@ -80,8 +85,7 @@ public class CharsetKit
/**
* @return 系统字符集编码
*/
public static String systemCharset()
{
public static String systemCharset() {
return Charset.defaultCharset().name();
}
}

View File

@@ -8,59 +8,57 @@ import java.util.regex.Pattern;
/**
* Bean 工具类
*
*
* @author ruoyi
*/
public class BeanUtils extends org.springframework.beans.BeanUtils
{
/** Bean方法名中属性名开始的下标 */
public class BeanUtils extends org.springframework.beans.BeanUtils {
/**
* Bean方法名中属性名开始的下标
*/
private static final int BEAN_METHOD_PROP_INDEX = 3;
/** * 匹配getter方法的正则表达式 */
/**
* 匹配getter方法的正则表达式
*/
private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)");
/** * 匹配setter方法的正则表达式 */
/**
* 匹配setter方法的正则表达式
*/
private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)");
/**
* Bean属性复制工具方法。
*
*
* @param dest 目标对象
* @param src 源对象
* @param src 源对象
*/
public static void copyBeanProp(Object dest, Object src)
{
try
{
public static void copyBeanProp(Object dest, Object src) {
try {
copyProperties(src, dest);
}
catch (Exception e)
{
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取对象的setter方法。
*
*
* @param obj 对象
* @return 对象的setter方法列表
*/
public static List<Method> getSetterMethods(Object obj)
{
public static List<Method> getSetterMethods(Object obj) {
// setter方法列表
List<Method> setterMethods = new ArrayList<Method>();
List<Method> setterMethods = new ArrayList<>();
// 获取所有方法
Method[] methods = obj.getClass().getMethods();
// 查找setter方法
for (Method method : methods)
{
for (Method method : methods) {
Matcher m = SET_PATTERN.matcher(method.getName());
if (m.matches() && (method.getParameterTypes().length == 1))
{
if (m.matches() && (method.getParameterTypes().length == 1)) {
setterMethods.add(method);
}
}
@@ -70,23 +68,20 @@ public class BeanUtils extends org.springframework.beans.BeanUtils
/**
* 获取对象的getter方法。
*
*
* @param obj 对象
* @return 对象的getter方法列表
*/
public static List<Method> getGetterMethods(Object obj)
{
public static List<Method> getGetterMethods(Object obj) {
// getter方法列表
List<Method> getterMethods = new ArrayList<Method>();
List<Method> getterMethods = new ArrayList<>();
// 获取所有方法
Method[] methods = obj.getClass().getMethods();
// 查找getter方法
for (Method method : methods)
{
for (Method method : methods) {
Matcher m = GET_PATTERN.matcher(method.getName());
if (m.matches() && (method.getParameterTypes().length == 0))
{
if (m.matches() && (method.getParameterTypes().length == 0)) {
getterMethods.add(method);
}
}
@@ -97,14 +92,13 @@ public class BeanUtils extends org.springframework.beans.BeanUtils
/**
* 检查Bean方法名中的属性名是否相等。<br>
* 如getName()和setName()属性名一样getName()和setAge()属性名不一样。
*
*
* @param m1 方法名1
* @param m2 方法名2
* @return 属性名一样返回true否则返回false
*/
public static boolean isMethodPropEquals(String m1, String m2)
{
public static boolean isMethodPropEquals(String m1, String m2) {
return m1.substring(BEAN_METHOD_PROP_INDEX).equals(m2.substring(BEAN_METHOD_PROP_INDEX));
}
}

View File

@@ -8,18 +8,17 @@ import java.util.Set;
/**
* bean对象属性验证
*
*
* @author ruoyi
*/
public class BeanValidators
{
public class BeanValidators {
public static void validateWithException(Validator validator, Object object, Class<?>... groups)
throws ConstraintViolationException
{
throws ConstraintViolationException {
Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
if (!constraintViolations.isEmpty())
{
if (!constraintViolations.isEmpty()) {
throw new ConstraintViolationException(constraintViolations);
}
}
}

View File

@@ -1,30 +1,28 @@
package com.ruoyi.common.core.utils.file;
import java.io.File;
import java.util.Objects;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.Objects;
/**
* 文件类型工具类
*
* @author ruoyi
*/
public class FileTypeUtils
{
public class FileTypeUtils {
/**
* 获取文件类型
* <p>
* 例如: ruoyi.txt, 返回: txt
*
*
* @param file 文件名
* @return 后缀(不含".")
*/
public static String getFileType(File file)
{
if (null == file)
{
public static String getFileType(File file) {
if (null == file) {
return StringUtils.EMPTY;
}
return getFileType(file.getName());
@@ -38,11 +36,9 @@ public class FileTypeUtils
* @param fileName 文件名
* @return 后缀(不含".")
*/
public static String getFileType(String fileName)
{
public static String getFileType(String fileName) {
int separatorIndex = fileName.lastIndexOf(".");
if (separatorIndex < 0)
{
if (separatorIndex < 0) {
return "";
}
return fileName.substring(separatorIndex + 1).toLowerCase();
@@ -50,15 +46,13 @@ public class FileTypeUtils
/**
* 获取文件名的后缀
*
*
* @param file 表单文件
* @return 后缀名
*/
public static final String getExtension(MultipartFile file)
{
public static String getExtension(MultipartFile file) {
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
if (StringUtils.isEmpty(extension))
{
if (StringUtils.isEmpty(extension)) {
extension = MimeTypeUtils.getExtension(Objects.requireNonNull(file.getContentType()));
}
return extension;
@@ -66,28 +60,20 @@ public class FileTypeUtils
/**
* 获取文件类型
*
*
* @param photoByte 文件字节码
* @return 后缀(不含".")
*/
public static String getFileExtendName(byte[] photoByte)
{
public static String getFileExtendName(byte[] photoByte) {
String strFileExtendName = "JPG";
if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
&& ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97))
{
&& ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) {
strFileExtendName = "GIF";
}
else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70))
{
} else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) {
strFileExtendName = "JPG";
}
else if ((photoByte[0] == 66) && (photoByte[1] == 77))
{
} else if ((photoByte[0] == 66) && (photoByte[1] == 77)) {
strFileExtendName = "BMP";
}
else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71))
{
} else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) {
strFileExtendName = "PNG";
}
return strFileExtendName;

View File

@@ -1,5 +1,9 @@
package com.ruoyi.common.core.utils.file;
import org.apache.poi.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.URI;
@@ -7,10 +11,6 @@ import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import org.apache.poi.util.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 图片处理工具类
*
@@ -22,6 +22,7 @@ public class ImageUtils {
public static byte[] getImage(String imagePath) {
InputStream is = getFile(imagePath);
try {
assert is != null;
return IOUtils.toByteArray(is);
} catch (Exception e) {
log.error("图片加载异常", e);
@@ -34,6 +35,7 @@ public class ImageUtils {
public static InputStream getFile(String imagePath) {
try {
byte[] result = readFile(imagePath);
assert result != null;
result = Arrays.copyOf(result, result.length);
return new ByteArrayInputStream(result);
} catch (Exception e) {

View File

@@ -4,20 +4,17 @@ import com.ruoyi.common.core.utils.StringUtils;
/**
* 转义和反转义工具类
*
*
* @author ruoyi
*/
public class EscapeUtil
{
public class EscapeUtil {
public static final String RE_HTML_MARK = "(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)";
private static final char[][] TEXT = new char[64][];
static
{
for (int i = 0; i < 64; i++)
{
TEXT[i] = new char[] { (char) i };
static {
for (int i = 0; i < 64; i++) {
TEXT[i] = new char[]{(char) i};
}
// special HTML characters
@@ -30,69 +27,58 @@ public class EscapeUtil
/**
* 转义文本中的HTML字符为安全的字符
*
*
* @param text 被转义的文本
* @return 转义后的文本
*/
public static String escape(String text)
{
public static String escape(String text) {
return encode(text);
}
/**
* 还原被转义的HTML特殊字符
*
*
* @param content 包含转义符的HTML内容
* @return 转换后的字符串
*/
public static String unescape(String content)
{
public static String unescape(String content) {
return decode(content);
}
/**
* 清除所有HTML标签但是不删除标签内的内容
*
*
* @param content 文本
* @return 清除标签后的文本
*/
public static String clean(String content)
{
public static String clean(String content) {
return new HTMLFilter().filter(content);
}
/**
* Escape编码
*
*
* @param text 被编码的文本
* @return 编码后的字符
*/
private static String encode(String text)
{
if (StringUtils.isEmpty(text))
{
private static String encode(String text) {
if (StringUtils.isEmpty(text)) {
return StringUtils.EMPTY;
}
final StringBuilder tmp = new StringBuilder(text.length() * 6);
char c;
for (int i = 0; i < text.length(); i++)
{
for (int i = 0; i < text.length(); i++) {
c = text.charAt(i);
if (c < 256)
{
if (c < 256) {
tmp.append("%");
if (c < 16)
{
if (c < 16) {
tmp.append("0");
}
tmp.append(Integer.toString(c, 16));
}
else
{
} else {
tmp.append("%u");
if (c <= 0xfff)
{
if (c <= 0xfff) {
// issue#I49JU8@Gitee
tmp.append("0");
}
@@ -104,48 +90,36 @@ public class EscapeUtil
/**
* Escape解码
*
*
* @param content 被转义的内容
* @return 解码后的字符串
*/
public static String decode(String content)
{
if (StringUtils.isEmpty(content))
{
public static String decode(String content) {
if (StringUtils.isEmpty(content)) {
return content;
}
StringBuilder tmp = new StringBuilder(content.length());
int lastPos = 0, pos = 0;
char ch;
while (lastPos < content.length())
{
while (lastPos < content.length()) {
pos = content.indexOf("%", lastPos);
if (pos == lastPos)
{
if (content.charAt(pos + 1) == 'u')
{
if (pos == lastPos) {
if (content.charAt(pos + 1) == 'u') {
ch = (char) Integer.parseInt(content.substring(pos + 2, pos + 6), 16);
tmp.append(ch);
lastPos = pos + 6;
}
else
{
} else {
ch = (char) Integer.parseInt(content.substring(pos + 1, pos + 3), 16);
tmp.append(ch);
lastPos = pos + 3;
}
}
else
{
if (pos == -1)
{
} else {
if (pos == -1) {
tmp.append(content.substring(lastPos));
lastPos = content.length();
}
else
{
tmp.append(content.substring(lastPos, pos));
} else {
tmp.append(content, lastPos, pos);
lastPos = pos;
}
}
@@ -153,8 +127,7 @@ public class EscapeUtil
return tmp.toString();
}
public static void main(String[] args)
{
public static void main(String[] args) {
String html = "<script>alert(1);</script>";
String escape = EscapeUtil.escape(html);
// String html = "<scr<script>ipt>alert(\"XSS\")</scr<script>ipt>";

View File

@@ -15,8 +15,7 @@ import java.util.regex.Pattern;
*
* @author ruoyi
*/
public final class HTMLFilter
{
public final class HTMLFilter {
/**
* regex flag union representing /si modifiers in php
**/
@@ -100,8 +99,7 @@ public final class HTMLFilter
/**
* Default constructor.
*/
public HTMLFilter()
{
public HTMLFilter() {
vAllowed = new HashMap<>();
final ArrayList<String> a_atts = new ArrayList<>();
@@ -122,13 +120,13 @@ public final class HTMLFilter
vAllowed.put("i", no_atts);
vAllowed.put("em", no_atts);
vSelfClosingTags = new String[] { "img" };
vNeedClosingTags = new String[] { "a", "b", "strong", "i", "em" };
vDisallowed = new String[] {};
vAllowedProtocols = new String[] { "http", "mailto", "https" }; // no ftp.
vProtocolAtts = new String[] { "src", "href" };
vRemoveBlanks = new String[] { "a", "b", "strong", "i", "em" };
vAllowedEntities = new String[] { "amp", "gt", "lt", "quot" };
vSelfClosingTags = new String[]{"img"};
vNeedClosingTags = new String[]{"a", "b", "strong", "i", "em"};
vDisallowed = new String[]{};
vAllowedProtocols = new String[]{"http", "mailto", "https"}; // no ftp.
vProtocolAtts = new String[]{"src", "href"};
vRemoveBlanks = new String[]{"a", "b", "strong", "i", "em"};
vAllowedEntities = new String[]{"amp", "gt", "lt", "quot"};
stripComment = true;
encodeQuotes = true;
alwaysMakeTags = false;
@@ -140,8 +138,7 @@ public final class HTMLFilter
* @param conf map containing configuration. keys match field names.
*/
@SuppressWarnings("unchecked")
public HTMLFilter(final Map<String, Object> conf)
{
public HTMLFilter(final Map<String, Object> conf) {
assert conf.containsKey("vAllowed") : "configuration requires vAllowed";
assert conf.containsKey("vSelfClosingTags") : "configuration requires vSelfClosingTags";
@@ -165,20 +162,17 @@ public final class HTMLFilter
alwaysMakeTags = conf.containsKey("alwaysMakeTags") ? (Boolean) conf.get("alwaysMakeTags") : true;
}
private void reset()
{
private void reset() {
vTagCounts.clear();
}
// ---------------------------------------------------------------
// my versions of some PHP library functions
public static String chr(final int decimal)
{
public static String chr(final int decimal) {
return String.valueOf((char) decimal);
}
public static String htmlSpecialChars(final String s)
{
public static String htmlSpecialChars(final String s) {
String result = s;
result = regexReplace(P_AMP, "&amp;", result);
result = regexReplace(P_QUOTE, "&quot;", result);
@@ -195,8 +189,7 @@ public final class HTMLFilter
* @param input text (i.e. submitted by a user) than may contain html
* @return "clean" version of input, with only valid, whitelisted html elements allowed
*/
public String filter(final String input)
{
public String filter(final String input) {
reset();
String s = input;
@@ -213,22 +206,18 @@ public final class HTMLFilter
return s;
}
public boolean isAlwaysMakeTags()
{
public boolean isAlwaysMakeTags() {
return alwaysMakeTags;
}
public boolean isStripComments()
{
public boolean isStripComments() {
return stripComment;
}
private String escapeComments(final String s)
{
private String escapeComments(final String s) {
final Matcher m = P_COMMENTS.matcher(s);
final StringBuffer buf = new StringBuffer();
if (m.find())
{
if (m.find()) {
final String match = m.group(1); // (.*?)
m.appendReplacement(buf, Matcher.quoteReplacement("<!--" + htmlSpecialChars(match) + "-->"));
}
@@ -237,10 +226,8 @@ public final class HTMLFilter
return buf.toString();
}
private String balanceHTML(String s)
{
if (alwaysMakeTags)
{
private String balanceHTML(String s) {
if (alwaysMakeTags) {
//
// try and form html
//
@@ -249,9 +236,7 @@ public final class HTMLFilter
s = regexReplace(P_BODY_TO_END, "<$1>", s);
s = regexReplace(P_XML_CONTENT, "$1<$2", s);
}
else
{
} else {
//
// escape stray brackets
//
@@ -269,13 +254,11 @@ public final class HTMLFilter
return s;
}
private String checkTags(String s)
{
private String checkTags(String s) {
Matcher m = P_TAGS.matcher(s);
final StringBuffer buf = new StringBuffer();
while (m.find())
{
while (m.find()) {
String replaceStr = m.group(1);
replaceStr = processTag(replaceStr);
m.appendReplacement(buf, Matcher.quoteReplacement(replaceStr));
@@ -285,10 +268,8 @@ public final class HTMLFilter
// these get tallied in processTag
// (remember to reset before subsequent calls to filter method)
final StringBuilder sBuilder = new StringBuilder(buf.toString());
for (String key : vTagCounts.keySet())
{
for (int ii = 0; ii < vTagCounts.get(key); ii++)
{
for (String key : vTagCounts.keySet()) {
for (int ii = 0; ii < vTagCounts.get(key); ii++) {
sBuilder.append("</").append(key).append(">");
}
}
@@ -297,18 +278,14 @@ public final class HTMLFilter
return s;
}
private String processRemoveBlanks(final String s)
{
private String processRemoveBlanks(final String s) {
String result = s;
for (String tag : vRemoveBlanks)
{
if (!P_REMOVE_PAIR_BLANKS.containsKey(tag))
{
for (String tag : vRemoveBlanks) {
if (!P_REMOVE_PAIR_BLANKS.containsKey(tag)) {
P_REMOVE_PAIR_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?></" + tag + ">"));
}
result = regexReplace(P_REMOVE_PAIR_BLANKS.get(tag), "", result);
if (!P_REMOVE_SELF_BLANKS.containsKey(tag))
{
if (!P_REMOVE_SELF_BLANKS.containsKey(tag)) {
P_REMOVE_SELF_BLANKS.putIfAbsent(tag, Pattern.compile("<" + tag + "(\\s[^>]*)?/>"));
}
result = regexReplace(P_REMOVE_SELF_BLANKS.get(tag), "", result);
@@ -317,25 +294,19 @@ public final class HTMLFilter
return result;
}
private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s)
{
private static String regexReplace(final Pattern regex_pattern, final String replacement, final String s) {
Matcher m = regex_pattern.matcher(s);
return m.replaceAll(replacement);
}
private String processTag(final String s)
{
private String processTag(final String s) {
// ending tags
Matcher m = P_END_TAG.matcher(s);
if (m.find())
{
if (m.find()) {
final String name = m.group(1).toLowerCase();
if (allowed(name))
{
if (!inArray(name, vSelfClosingTags))
{
if (vTagCounts.containsKey(name))
{
if (allowed(name)) {
if (!inArray(name, vSelfClosingTags)) {
if (vTagCounts.containsKey(name)) {
vTagCounts.put(name, vTagCounts.get(name) - 1);
return "</" + name + ">";
}
@@ -345,35 +316,30 @@ public final class HTMLFilter
// starting tags
m = P_START_TAG.matcher(s);
if (m.find())
{
if (m.find()) {
final String name = m.group(1).toLowerCase();
final String body = m.group(2);
String ending = m.group(3);
// debug( "in a starting tag, name='" + name + "'; body='" + body + "'; ending='" + ending + "'" );
if (allowed(name))
{
if (allowed(name)) {
final StringBuilder params = new StringBuilder();
final Matcher m2 = P_QUOTED_ATTRIBUTES.matcher(body);
final Matcher m3 = P_UNQUOTED_ATTRIBUTES.matcher(body);
final List<String> paramNames = new ArrayList<>();
final List<String> paramValues = new ArrayList<>();
while (m2.find())
{
while (m2.find()) {
paramNames.add(m2.group(1)); // ([a-z0-9]+)
paramValues.add(m2.group(3)); // (.*?)
}
while (m3.find())
{
while (m3.find()) {
paramNames.add(m3.group(1)); // ([a-z0-9]+)
paramValues.add(m3.group(3)); // ([^\"\\s']+)
}
String paramName, paramValue;
for (int ii = 0; ii < paramNames.size(); ii++)
{
for (int ii = 0; ii < paramNames.size(); ii++) {
paramName = paramNames.get(ii).toLowerCase();
paramValue = paramValues.get(ii);
@@ -381,72 +347,55 @@ public final class HTMLFilter
// debug( "paramValue='" + paramValue + "'" );
// debug( "allowed? " + vAllowed.get( name ).contains( paramName ) );
if (allowedAttribute(name, paramName))
{
if (inArray(paramName, vProtocolAtts))
{
if (allowedAttribute(name, paramName)) {
if (inArray(paramName, vProtocolAtts)) {
paramValue = processParamProtocol(paramValue);
}
params.append(' ').append(paramName).append("=\\\"").append(paramValue).append("\\\"");
}
}
if (inArray(name, vSelfClosingTags))
{
if (inArray(name, vSelfClosingTags)) {
ending = " /";
}
if (inArray(name, vNeedClosingTags))
{
if (inArray(name, vNeedClosingTags)) {
ending = "";
}
if (ending == null || ending.length() < 1)
{
if (vTagCounts.containsKey(name))
{
if (ending == null || ending.length() < 1) {
if (vTagCounts.containsKey(name)) {
vTagCounts.put(name, vTagCounts.get(name) + 1);
}
else
{
} else {
vTagCounts.put(name, 1);
}
}
else
{
} else {
ending = " /";
}
return "<" + name + params + ending + ">";
}
else
{
} else {
return "";
}
}
// comments
m = P_COMMENT.matcher(s);
if (!stripComment && m.find())
{
if (!stripComment && m.find()) {
return "<" + m.group() + ">";
}
return "";
}
private String processParamProtocol(String s)
{
private String processParamProtocol(String s) {
s = decodeEntities(s);
final Matcher m = P_PROTOCOL.matcher(s);
if (m.find())
{
if (m.find()) {
final String protocol = m.group(1);
if (!inArray(protocol, vAllowedProtocols))
{
if (!inArray(protocol, vAllowedProtocols)) {
// bad protocol, turn into local anchor link instead
s = "#" + s.substring(protocol.length() + 1);
if (s.startsWith("#//"))
{
if (s.startsWith("#//")) {
s = "#" + s.substring(3);
}
}
@@ -455,13 +404,11 @@ public final class HTMLFilter
return s;
}
private String decodeEntities(String s)
{
private String decodeEntities(String s) {
StringBuffer buf = new StringBuffer();
Matcher m = P_ENTITY.matcher(s);
while (m.find())
{
while (m.find()) {
final String match = m.group(1);
final int decimal = Integer.decode(match).intValue();
m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
@@ -471,8 +418,7 @@ public final class HTMLFilter
buf = new StringBuffer();
m = P_ENTITY_UNICODE.matcher(s);
while (m.find())
{
while (m.find()) {
final String match = m.group(1);
final int decimal = Integer.valueOf(match, 16).intValue();
m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
@@ -482,8 +428,7 @@ public final class HTMLFilter
buf = new StringBuffer();
m = P_ENCODE.matcher(s);
while (m.find())
{
while (m.find()) {
final String match = m.group(1);
final int decimal = Integer.valueOf(match, 16).intValue();
m.appendReplacement(buf, Matcher.quoteReplacement(chr(decimal)));
@@ -495,14 +440,12 @@ public final class HTMLFilter
return s;
}
private String validateEntities(final String s)
{
private String validateEntities(final String s) {
StringBuffer buf = new StringBuffer();
// validate entities throughout the string
Matcher m = P_VALID_ENTITIES.matcher(s);
while (m.find())
{
while (m.find()) {
final String one = m.group(1); // ([^&;]*)
final String two = m.group(2); // (?=(;|&|$))
m.appendReplacement(buf, Matcher.quoteReplacement(checkEntity(one, two)));
@@ -512,14 +455,11 @@ public final class HTMLFilter
return encodeQuotes(buf.toString());
}
private String encodeQuotes(final String s)
{
if (encodeQuotes)
{
private String encodeQuotes(final String s) {
if (encodeQuotes) {
StringBuffer buf = new StringBuffer();
Matcher m = P_VALID_QUOTES.matcher(s);
while (m.find())
{
while (m.find()) {
final String one = m.group(1); // (>|^)
final String two = m.group(2); // ([^<]+?)
final String three = m.group(3); // (<|$)
@@ -528,43 +468,34 @@ public final class HTMLFilter
}
m.appendTail(buf);
return buf.toString();
}
else
{
} else {
return s;
}
}
private String checkEntity(final String preamble, final String term)
{
private String checkEntity(final String preamble, final String term) {
return ";".equals(term) && isValidEntity(preamble) ? '&' + preamble : "&amp;" + preamble;
}
private boolean isValidEntity(final String entity)
{
private boolean isValidEntity(final String entity) {
return inArray(entity, vAllowedEntities);
}
private static boolean inArray(final String s, final String[] array)
{
for (String item : array)
{
if (item != null && item.equals(s))
{
private static boolean inArray(final String s, final String[] array) {
for (String item : array) {
if (item != null && item.equals(s)) {
return true;
}
}
return false;
}
private boolean allowed(final String name)
{
private boolean allowed(final String name) {
return (vAllowed.isEmpty() || vAllowed.containsKey(name)) && !inArray(name, vDisallowed);
}
private boolean allowedAttribute(final String name, final String paramName)
{
private boolean allowedAttribute(final String name, final String paramName) {
return allowed(name) && (vAllowed.isEmpty() || vAllowed.get(name).contains(paramName));
}
}

View File

@@ -1,67 +1,59 @@
package com.ruoyi.common.core.utils.ip;
import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.StringUtils;
import jakarta.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
import jakarta.servlet.http.HttpServletRequest;
import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.StringUtils;
/**
* 获取IP方法
*
*
* @author ruoyi
*/
public class IpUtils
{
public class IpUtils {
public final static String REGX_0_255 = "(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)";
// 匹配 ip
public final static String REGX_IP = "((" + REGX_0_255 + "\\.){3}" + REGX_0_255 + ")";
public final static String REGX_IP_WILDCARD = "(((\\*\\.){3}\\*)|(" + REGX_0_255 + "(\\.\\*){3})|(" + REGX_0_255 + "\\." + REGX_0_255 + ")(\\.\\*){2}" + "|((" + REGX_0_255 + "\\.){3}\\*))";
// 匹配网段
public final static String REGX_IP_SEG = "(" + REGX_IP + "\\-" + REGX_IP + ")";
public final static String REGX_IP_SEG = "(" + REGX_IP + "-" + REGX_IP + ")";
/**
* 获取客户端IP
*
*
* @return IP地址
*/
public static String getIpAddr()
{
public static String getIpAddr() {
return getIpAddr(ServletUtils.getRequest());
}
/**
* 获取客户端IP
*
*
* @param request 请求对象
* @return IP地址
*/
public static String getIpAddr(HttpServletRequest request)
{
if (request == null)
{
public static String getIpAddr(HttpServletRequest request) {
if (request == null) {
return "unknown";
}
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Forwarded-For");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
{
if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
@@ -70,26 +62,23 @@ public class IpUtils
/**
* 检查是否为内部IP地址
*
*
* @param ip IP地址
* @return 结果
*/
public static boolean internalIp(String ip)
{
public static boolean internalIp(String ip) {
byte[] addr = textToNumericFormatV4(ip);
return internalIp(addr) || "127.0.0.1".equals(ip);
}
/**
* 检查是否为内部IP地址
*
*
* @param addr byte地址
* @return 结果
*/
private static boolean internalIp(byte[] addr)
{
if (StringUtils.isNull(addr) || addr.length < 2)
{
private static boolean internalIp(byte[] addr) {
if (StringUtils.isNull(addr) || addr.length < 2) {
return true;
}
final byte b0 = addr[0];
@@ -103,18 +92,15 @@ public class IpUtils
// 192.168.x.x/16
final byte SECTION_5 = (byte) 0xC0;
final byte SECTION_6 = (byte) 0xA8;
switch (b0)
{
switch (b0) {
case SECTION_1:
return true;
case SECTION_2:
if (b1 >= SECTION_3 && b1 <= SECTION_4)
{
if (b1 >= SECTION_3 && b1 <= SECTION_4) {
return true;
}
case SECTION_5:
switch (b1)
{
switch (b1) {
case SECTION_6:
return true;
}
@@ -125,29 +111,24 @@ public class IpUtils
/**
* 将IPv4地址转换成字节
*
*
* @param text IPv4地址
* @return byte 字节
*/
public static byte[] textToNumericFormatV4(String text)
{
if (text.length() == 0)
{
public static byte[] textToNumericFormatV4(String text) {
if (text.isEmpty()) {
return null;
}
byte[] bytes = new byte[4];
String[] elements = text.split("\\.", -1);
try
{
try {
long l;
int i;
switch (elements.length)
{
switch (elements.length) {
case 1:
l = Long.parseLong(elements[0]);
if ((l < 0L) || (l > 4294967295L))
{
if ((l < 0L) || (l > 4294967295L)) {
return null;
}
bytes[0] = (byte) (int) (l >> 24 & 0xFF);
@@ -157,14 +138,12 @@ public class IpUtils
break;
case 2:
l = Integer.parseInt(elements[0]);
if ((l < 0L) || (l > 255L))
{
if ((l < 0L) || (l > 255L)) {
return null;
}
bytes[0] = (byte) (int) (l & 0xFF);
l = Integer.parseInt(elements[1]);
if ((l < 0L) || (l > 16777215L))
{
if ((l < 0L) || (l > 16777215L)) {
return null;
}
bytes[1] = (byte) (int) (l >> 16 & 0xFF);
@@ -172,29 +151,24 @@ public class IpUtils
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 3:
for (i = 0; i < 2; ++i)
{
for (i = 0; i < 2; ++i) {
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L))
{
if ((l < 0L) || (l > 255L)) {
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
}
l = Integer.parseInt(elements[2]);
if ((l < 0L) || (l > 65535L))
{
if ((l < 0L) || (l > 65535L)) {
return null;
}
bytes[2] = (byte) (int) (l >> 8 & 0xFF);
bytes[3] = (byte) (int) (l & 0xFF);
break;
case 4:
for (i = 0; i < 4; ++i)
{
for (i = 0; i < 4; ++i) {
l = Integer.parseInt(elements[i]);
if ((l < 0L) || (l > 255L))
{
if ((l < 0L) || (l > 255L)) {
return null;
}
bytes[i] = (byte) (int) (l & 0xFF);
@@ -203,9 +177,7 @@ public class IpUtils
default:
return null;
}
}
catch (NumberFormatException e)
{
} catch (NumberFormatException e) {
return null;
}
return bytes;
@@ -213,34 +185,26 @@ public class IpUtils
/**
* 获取IP地址
*
*
* @return 本地IP地址
*/
public static String getHostIp()
{
try
{
public static String getHostIp() {
try {
return InetAddress.getLocalHost().getHostAddress();
}
catch (UnknownHostException e)
{
} catch (UnknownHostException ignored) {
}
return "127.0.0.1";
}
/**
* 获取主机名
*
*
* @return 本地主机名
*/
public static String getHostName()
{
try
{
public static String getHostName() {
try {
return InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException e)
{
} catch (UnknownHostException ignored) {
}
return "未知";
}
@@ -251,16 +215,12 @@ public class IpUtils
* @param ip 获得的IP地址
* @return 第一个非unknown IP地址
*/
public static String getMultistageReverseProxyIp(String ip)
{
public static String getMultistageReverseProxyIp(String ip) {
// 多级反向代理检测
if (ip != null && ip.indexOf(",") > 0)
{
if (ip != null && ip.indexOf(",") > 0) {
final String[] ips = ip.trim().split(",");
for (String subIp : ips)
{
if (false == isUnknown(subIp))
{
for (String subIp : ips) {
if (!isUnknown(subIp)) {
ip = subIp;
break;
}
@@ -275,39 +235,33 @@ public class IpUtils
* @param checkString 被检测的字符串
* @return 是否未知
*/
public static boolean isUnknown(String checkString)
{
public static boolean isUnknown(String checkString) {
return StringUtils.isBlank(checkString) || "unknown".equalsIgnoreCase(checkString);
}
/**
* 是否为IP
*/
public static boolean isIP(String ip)
{
public static boolean isIP(String ip) {
return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP);
}
/**
* 是否为IP或 *为间隔的通配符地址
*/
public static boolean isIpWildCard(String ip)
{
public static boolean isIpWildCard(String ip) {
return StringUtils.isNotBlank(ip) && ip.matches(REGX_IP_WILDCARD);
}
/**
* 检测参数是否在ip通配符里
*/
public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip)
{
public static boolean ipIsInWildCardNoCheck(String ipWildCard, String ip) {
String[] s1 = ipWildCard.split("\\.");
String[] s2 = ip.split("\\.");
boolean isMatchedSeg = true;
for (int i = 0; i < s1.length && !s1[i].equals("*"); i++)
{
if (!s1[i].equals(s2[i]))
{
for (int i = 0; i < s1.length && !s1[i].equals("*"); i++) {
if (!s1[i].equals(s2[i])) {
isMatchedSeg = false;
break;
}
@@ -318,29 +272,25 @@ public class IpUtils
/**
* 是否为特定格式如:“10.10.10.1-10.10.10.99”的ip段字符串
*/
public static boolean isIPSegment(String ipSeg)
{
public static boolean isIPSegment(String ipSeg) {
return StringUtils.isNotBlank(ipSeg) && ipSeg.matches(REGX_IP_SEG);
}
/**
* 判断ip是否在指定网段中
*/
public static boolean ipIsInNetNoCheck(String iparea, String ip)
{
public static boolean ipIsInNetNoCheck(String iparea, String ip) {
int idx = iparea.indexOf('-');
String[] sips = iparea.substring(0, idx).split("\\.");
String[] sipe = iparea.substring(idx + 1).split("\\.");
String[] sipt = ip.split("\\.");
long ips = 0L, ipe = 0L, ipt = 0L;
for (int i = 0; i < 4; ++i)
{
for (int i = 0; i < 4; ++i) {
ips = ips << 8 | Integer.parseInt(sips[i]);
ipe = ipe << 8 | Integer.parseInt(sipe[i]);
ipt = ipt << 8 | Integer.parseInt(sipt[i]);
}
if (ips > ipe)
{
if (ips > ipe) {
long t = ips;
ips = ipe;
ipe = t;
@@ -350,30 +300,22 @@ public class IpUtils
/**
* 校验ip是否符合过滤串规则
*
*
* @param filter 过滤IP列表,支持后缀'*'通配,支持网段如:`10.10.10.1-10.10.10.99`
* @param ip 校验IP地址
* @param ip 校验IP地址
* @return boolean 结果
*/
public static boolean isMatchedIp(String filter, String ip)
{
if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip))
{
public static boolean isMatchedIp(String filter, String ip) {
if (StringUtils.isEmpty(filter) || StringUtils.isEmpty(ip)) {
return false;
}
String[] ips = filter.split(";");
for (String iStr : ips)
{
if (isIP(iStr) && iStr.equals(ip))
{
for (String iStr : ips) {
if (isIP(iStr) && iStr.equals(ip)) {
return true;
}
else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip))
{
} else if (isIpWildCard(iStr) && ipIsInWildCardNoCheck(iStr, ip)) {
return true;
}
else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip))
{
} else if (isIPSegment(iStr) && ipIsInNetNoCheck(iStr, ip)) {
return true;
}
}

View File

@@ -5,19 +5,17 @@ import org.apache.poi.ss.usermodel.Workbook;
/**
* Excel数据格式处理适配器
*
*
* @author ruoyi
*/
public interface ExcelHandlerAdapter
{
public interface ExcelHandlerAdapter {
/**
* 格式化
*
* @param value 单元格数据值
* @param args excel注解args参数组
* @param cell 单元格对象
* @param wb 工作簿对象
*
* @param value 单元格数据值
* @param args excel注解args参数组
* @param cell 单元格对象
* @param wb 工作簿对象
* @return 处理后的值
*/
Object format(Object value, String[] args, Cell cell, Workbook wb);

View File

@@ -2,75 +2,63 @@ package com.ruoyi.common.core.utils.sign;
/**
* Base64工具类
*
*
* @author ruoyi
*/
public final class Base64
{
static private final int BASELENGTH = 128;
static private final int LOOKUPLENGTH = 64;
static private final int TWENTYFOURBITGROUP = 24;
static private final int EIGHTBIT = 8;
static private final int SIXTEENBIT = 16;
static private final int FOURBYTE = 4;
static private final int SIGN = -128;
static private final char PAD = '=';
static final private byte[] base64Alphabet = new byte[BASELENGTH];
static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
public final class Base64 {
static private final int BASELENGTH = 128;
static private final int LOOKUPLENGTH = 64;
static private final int TWENTYFOURBITGROUP = 24;
static private final int EIGHTBIT = 8;
static private final int SIXTEENBIT = 16;
static private final int FOURBYTE = 4;
static private final int SIGN = -128;
static private final char PAD = '=';
static final private byte[] base64Alphabet = new byte[BASELENGTH];
static final private char[] lookUpBase64Alphabet = new char[LOOKUPLENGTH];
static
{
for (int i = 0; i < BASELENGTH; ++i)
{
static {
for (int i = 0; i < BASELENGTH; ++i) {
base64Alphabet[i] = -1;
}
for (int i = 'Z'; i >= 'A'; i--)
{
for (int i = 'Z'; i >= 'A'; i--) {
base64Alphabet[i] = (byte) (i - 'A');
}
for (int i = 'z'; i >= 'a'; i--)
{
for (int i = 'z'; i >= 'a'; i--) {
base64Alphabet[i] = (byte) (i - 'a' + 26);
}
for (int i = '9'; i >= '0'; i--)
{
for (int i = '9'; i >= '0'; i--) {
base64Alphabet[i] = (byte) (i - '0' + 52);
}
base64Alphabet['+'] = 62;
base64Alphabet['/'] = 63;
for (int i = 0; i <= 25; i++)
{
for (int i = 0; i <= 25; i++) {
lookUpBase64Alphabet[i] = (char) ('A' + i);
}
for (int i = 26, j = 0; i <= 51; i++, j++)
{
for (int i = 26, j = 0; i <= 51; i++, j++) {
lookUpBase64Alphabet[i] = (char) ('a' + j);
}
for (int i = 52, j = 0; i <= 61; i++, j++)
{
for (int i = 52, j = 0; i <= 61; i++, j++) {
lookUpBase64Alphabet[i] = (char) ('0' + j);
}
lookUpBase64Alphabet[62] = (char) '+';
lookUpBase64Alphabet[63] = (char) '/';
}
private static boolean isWhiteSpace(char octect)
{
private static boolean isWhiteSpace(char octect) {
return (octect == 0x20 || octect == 0xd || octect == 0xa || octect == 0x9);
}
private static boolean isPad(char octect)
{
private static boolean isPad(char octect) {
return (octect == PAD);
}
private static boolean isData(char octect)
{
private static boolean isData(char octect) {
return (octect < BASELENGTH && base64Alphabet[octect] != -1);
}
@@ -80,23 +68,20 @@ public final class Base64
* @param binaryData Array containing binaryData
* @return Encoded Base64 array
*/
public static String encode(byte[] binaryData)
{
if (binaryData == null)
{
public static String encode(byte[] binaryData) {
if (binaryData == null) {
return null;
}
int lengthDataBits = binaryData.length * EIGHTBIT;
if (lengthDataBits == 0)
{
if (lengthDataBits == 0) {
return "";
}
int fewerThan24bits = lengthDataBits % TWENTYFOURBITGROUP;
int numberTriplets = lengthDataBits / TWENTYFOURBITGROUP;
int numberQuartet = fewerThan24bits != 0 ? numberTriplets + 1 : numberTriplets;
char encodedData[] = null;
char[] encodedData;
encodedData = new char[numberQuartet * 4];
@@ -105,8 +90,7 @@ public final class Base64
int encodedIndex = 0;
int dataIndex = 0;
for (int i = 0; i < numberTriplets; i++)
{
for (int i = 0; i < numberTriplets; i++) {
b1 = binaryData[dataIndex++];
b2 = binaryData[dataIndex++];
b3 = binaryData[dataIndex++];
@@ -125,8 +109,7 @@ public final class Base64
}
// form integral number of 6-bit groups
if (fewerThan24bits == EIGHTBIT)
{
if (fewerThan24bits == EIGHTBIT) {
b1 = binaryData[dataIndex];
k = (byte) (b1 & 0x03);
byte val1 = ((b1 & SIGN) == 0) ? (byte) (b1 >> 2) : (byte) ((b1) >> 2 ^ 0xc0);
@@ -134,9 +117,7 @@ public final class Base64
encodedData[encodedIndex++] = lookUpBase64Alphabet[k << 4];
encodedData[encodedIndex++] = PAD;
encodedData[encodedIndex++] = PAD;
}
else if (fewerThan24bits == SIXTEENBIT)
{
} else if (fewerThan24bits == SIXTEENBIT) {
b1 = binaryData[dataIndex];
b2 = binaryData[dataIndex + 1];
l = (byte) (b2 & 0x0f);
@@ -159,10 +140,8 @@ public final class Base64
* @param encoded string containing Base64 data
* @return Array containind decoded data.
*/
public static byte[] decode(String encoded)
{
if (encoded == null)
{
public static byte[] decode(String encoded) {
if (encoded == null) {
return null;
}
@@ -170,15 +149,13 @@ public final class Base64
// remove white spaces
int len = removeWhiteSpace(base64Data);
if (len % FOURBYTE != 0)
{
if (len % FOURBYTE != 0) {
return null;// should be divisible by four
}
int numberQuadruple = (len / FOURBYTE);
if (numberQuadruple == 0)
{
if (numberQuadruple == 0) {
return new byte[0];
}
@@ -191,12 +168,10 @@ public final class Base64
int dataIndex = 0;
decodedData = new byte[(numberQuadruple) * 3];
for (; i < numberQuadruple - 1; i++)
{
for (; i < numberQuadruple - 1; i++) {
if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))
|| !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++])))
{
|| !isData((d3 = base64Data[dataIndex++])) || !isData((d4 = base64Data[dataIndex++]))) {
return null;
} // if found "no data" just return null
@@ -210,8 +185,7 @@ public final class Base64
decodedData[encodedIndex++] = (byte) (b3 << 6 | b4);
}
if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++])))
{
if (!isData((d1 = base64Data[dataIndex++])) || !isData((d2 = base64Data[dataIndex++]))) {
return null;// if found "no data" just return null
}
@@ -220,10 +194,8 @@ public final class Base64
d3 = base64Data[dataIndex++];
d4 = base64Data[dataIndex++];
if (!isData((d3)) || !isData((d4)))
{// Check if they are PAD characters
if (isPad(d3) && isPad(d4))
{
if (!isData((d3)) || !isData((d4))) {// Check if they are PAD characters
if (isPad(d3) && isPad(d4)) {
if ((b2 & 0xf) != 0)// last 4 bits should be zero
{
return null;
@@ -232,9 +204,7 @@ public final class Base64
System.arraycopy(decodedData, 0, tmp, 0, i * 3);
tmp[encodedIndex] = (byte) (b1 << 2 | b2 >> 4);
return tmp;
}
else if (!isPad(d3) && isPad(d4))
{
} else if (!isPad(d3) && isPad(d4)) {
b3 = base64Alphabet[d3];
if ((b3 & 0x3) != 0)// last 2 bits should be zero
{
@@ -245,14 +215,10 @@ public final class Base64
tmp[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
tmp[encodedIndex] = (byte) (((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf));
return tmp;
}
else
{
} else {
return null;
}
}
else
{ // No PAD e.g 3cQl
} else { // No PAD e.g 3cQl
b3 = base64Alphabet[d3];
b4 = base64Alphabet[d4];
decodedData[encodedIndex++] = (byte) (b1 << 2 | b2 >> 4);
@@ -269,20 +235,16 @@ public final class Base64
* @param data the byte array of base64 data (with WS)
* @return the new length
*/
private static int removeWhiteSpace(char[] data)
{
if (data == null)
{
private static int removeWhiteSpace(char[] data) {
if (data == null) {
return 0;
}
// count characters that's not whitespace
int newSize = 0;
int len = data.length;
for (int i = 0; i < len; i++)
{
if (!isWhiteSpace(data[i]))
{
for (int i = 0; i < len; i++) {
if (!isWhiteSpace(data[i])) {
data[newSize++] = data[i];
}
}

View File

@@ -5,11 +5,10 @@ import com.ruoyi.common.core.utils.StringUtils;
/**
* sql操作工具类
*
*
* @author ruoyi
*/
public class SqlUtil
{
public class SqlUtil {
/**
* 定义常用的 sql关键字
*/
@@ -18,7 +17,7 @@ public class SqlUtil
/**
* 仅支持字母、数字、下划线、空格、逗号、小数点(支持多个字段排序)
*/
public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
public static String SQL_PATTERN = "[a-zA-Z0-9_ ,.]+";
/**
* 限制orderBy最大长度
@@ -28,14 +27,11 @@ public class SqlUtil
/**
* 检查字符,防止注入绕过
*/
public static String escapeOrderBySql(String value)
{
if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value))
{
public static String escapeOrderBySql(String value) {
if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) {
throw new UtilException("参数不符合规范,不能进行查询");
}
if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH)
{
if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH) {
throw new UtilException("参数已超过最大限制,不能进行查询");
}
return value;
@@ -44,25 +40,20 @@ public class SqlUtil
/**
* 验证 order by 语法是否符合规范
*/
public static boolean isValidOrderBySql(String value)
{
public static boolean isValidOrderBySql(String value) {
return value.matches(SQL_PATTERN);
}
/**
* SQL关键字检查
*/
public static void filterKeyword(String value)
{
if (StringUtils.isEmpty(value))
{
public static void filterKeyword(String value) {
if (StringUtils.isEmpty(value)) {
return;
}
String[] sqlKeywords = StringUtils.split(SQL_REGEX, "\\|");
for (String sqlKeyword : sqlKeywords)
{
if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1)
{
for (String sqlKeyword : sqlKeywords) {
if (StringUtils.indexOfIgnoreCase(value, sqlKeyword) > -1) {
throw new UtilException("参数存在SQL注入风险");
}
}

View File

@@ -10,13 +10,13 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-common-datascope</artifactId>
<description>
ruoyi-common-datascope权限范围
</description>
<dependencies>
<!-- RuoYi Common Security -->
<dependency>
<groupId>com.ruoyi</groupId>

View File

@@ -152,4 +152,12 @@ public class GlobalExceptionHandler {
public AjaxResult handleLoginExpiredException(LoginExpiredException e) {
return AjaxResult.error(e.getMessage());
}
/**
* 参数校验异常
*/
@ExceptionHandler(IllegalArgumentException.class)
public AjaxResult handleIllegalArgumentException(IllegalArgumentException e) {
return AjaxResult.error("参数校验失败: " + e.getMessage());
}
}

View File

@@ -16,10 +16,10 @@
</description>
<dependencies>
<!-- RuoYi Common Security -->
<!-- RuoYi Common Log -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common-security</artifactId>
<artifactId>ruoyi-common-log</artifactId>
</dependency>
</dependencies>

View File

@@ -10,12 +10,12 @@
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-common-swagger</artifactId>
<description>
ruoyi-common-swagger系统接口
</description>
<dependencies>
<dependencies>
<!-- SpringBoot Web -->
<dependency>
@@ -34,5 +34,5 @@
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
</dependencies>
</dependencies>
</project>