From 308dc8108de9dabf0571bfe6b4f424288509ef5f Mon Sep 17 00:00:00 2001 From: "chengfei.jin" Date: Wed, 24 Sep 2025 17:03:56 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=87=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0=E5=9F=BA=E6=9C=AC=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E5=92=8C=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- simple_utils.py | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 simple_utils.py diff --git a/simple_utils.py b/simple_utils.py new file mode 100644 index 0000000..6de0ca6 --- /dev/null +++ b/simple_utils.py @@ -0,0 +1,11 @@ +# simple_utils.py - A tiny utility library + +def reverse_string(text): + """Reverses the characters in a string.""" + return text[::-1] + +def count_words(sentence): + return len(sentence.split()) + +def celsius_to_fahrenheit(celsius): + return (celsius * 9/5) + 32 \ No newline at end of file From 291a233c2da5b4b80107fb2559ee404da2269ad1 Mon Sep 17 00:00:00 2001 From: "chengfei.jin" Date: Wed, 24 Sep 2025 17:25:31 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E5=88=A0=E9=99=A4=E7=AE=80=E5=8D=95?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E5=BA=93=E6=96=87=E4=BB=B6=20simple=5Futils.?= =?UTF-8?q?py?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .coderabbit.yaml | 9 ++ Calculator.java | 120 +++++++++++++++++ ConcurrentTask.java | 179 +++++++++++++++++++++++++ DataProcessor.java | 285 ++++++++++++++++++++++++++++++++++++++++ DatabaseConnection.java | 110 ++++++++++++++++ FileProcessor.java | 159 ++++++++++++++++++++++ RestController.java | 209 +++++++++++++++++++++++++++++ StringUtils.java | 155 ++++++++++++++++++++++ Test.java | 10 ++ UserService.java | 91 +++++++++++++ simple_utils.py | 11 -- 11 files changed, 1327 insertions(+), 11 deletions(-) create mode 100644 .coderabbit.yaml create mode 100644 Calculator.java create mode 100644 ConcurrentTask.java create mode 100644 DataProcessor.java create mode 100644 DatabaseConnection.java create mode 100644 FileProcessor.java create mode 100644 RestController.java create mode 100644 StringUtils.java create mode 100644 Test.java create mode 100644 UserService.java delete mode 100644 simple_utils.py diff --git a/.coderabbit.yaml b/.coderabbit.yaml new file mode 100644 index 0000000..67f1c86 --- /dev/null +++ b/.coderabbit.yaml @@ -0,0 +1,9 @@ +# Minimal configuration for getting started +language: "zh-CN" + +reviews: + profile: "chill" + high_level_summary: true + auto_review: + enabled: true + drafts: false diff --git a/Calculator.java b/Calculator.java new file mode 100644 index 0000000..289eb68 --- /dev/null +++ b/Calculator.java @@ -0,0 +1,120 @@ +/** + * 计算器类 - 包含数值计算和逻辑错误 + */ +public class Calculator { + + public static final double PI = 3.14; // 精度不够 + private static int lastResult; // 应该用long或BigDecimal + + // 除零问题 + public double divide(double a, double b) { + return a / b; // 没有检查b是否为0 + } + + // 整数除法精度丢失 + public double percentage(int value, int total) { + return (value / total) * 100; // 整数除法会丢失精度 + } + + // 数值溢出风险 + public int factorial(int n) { + if (n == 0) + return 1; + return n * factorial(n - 1); // 可能栈溢出,int溢出 + } + + // 浮点数比较问题 + public boolean isEqual(double a, double b) { + return a == b; // 不应该直接比较浮点数 + } + + // 复杂的方法,职责不单一 + public String calculateAndFormat(double num1, double num2, String operation) { + double result = 0; + String symbol = ""; + + // 应该使用switch或策略模式 + if (operation.equals("add")) { + result = num1 + num2; + symbol = "+"; + } else if (operation.equals("subtract")) { + result = num1 - num2; + symbol = "-"; + } else if (operation.equals("multiply")) { + result = num1 * num2; + symbol = "*"; + } else if (operation.equals("divide")) { + if (num2 != 0) { + result = num1 / num2; + symbol = "/"; + } else { + return "Error: Division by zero"; + } + } else { + return "Invalid operation"; + } + + // 格式化逻辑也在这里 + String formatted; + if (result == (int) result) { + formatted = String.valueOf((int) result); + } else { + formatted = String.format("%.2f", result); + } + + lastResult = (int) result; // 可能丢失精度 + + return num1 + " " + symbol + " " + num2 + " = " + formatted; + } + + // 无限循环风险 + public double sqrt(double number) { + if (number < 0) + return Double.NaN; + + double guess = number / 2; + double previous; + + do { + previous = guess; + guess = (guess + number / guess) / 2; + } while (Math.abs(guess - previous) > 0.0001); // 可能无限循环 + + return guess; + } + + // 静态方法访问实例变量 + public static int getLastResult() { + return lastResult; // 线程安全问题 + } + + // 缺少输入验证 + public double power(double base, int exponent) { + double result = 1; + for (int i = 0; i < exponent; i++) { // 没有处理负指数 + result *= base; + } + return result; + } + + // 魔法数字 + public double calculateCircleArea(double radius) { + return 3.14159 * radius * radius; // 应该使用常量 + } + + // 不一致的返回类型处理 + public Object calculate(String expression) { + try { + if (expression.contains("+")) { + String[] parts = expression.split("\\+"); + return Double.parseDouble(parts[0]) + Double.parseDouble(parts[1]); + } else if (expression.contains("-")) { + String[] parts = expression.split("-"); + return Double.parseDouble(parts[0]) - Double.parseDouble(parts[1]); + } + return "Unsupported operation"; + } catch (Exception e) { + return null; // 不一致的错误处理 + } + } +} diff --git a/ConcurrentTask.java b/ConcurrentTask.java new file mode 100644 index 0000000..1bc8b71 --- /dev/null +++ b/ConcurrentTask.java @@ -0,0 +1,179 @@ +import java.util.*; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * 并发任务处理类 - 包含线程安全和并发问题 + */ +public class ConcurrentTask { + + private static int counter = 0; // 线程不安全的计数器 + private List results = new ArrayList<>(); // 非线程安全集合 + private Map cache = new HashMap<>(); // 非线程安全缓存 + + // 竞态条件 + public void incrementCounter() { + counter++; // 非原子操作 + } + + public int getCounter() { + return counter; + } + + // 双重检查锁定的错误实现 + private static volatile ConcurrentTask instance; + + public static ConcurrentTask getInstance() { + if (instance == null) { + synchronized (ConcurrentTask.class) { + if (instance == null) { + instance = new ConcurrentTask(); // 正确,但有其他问题 + } + } + } + return instance; + } + + // 死锁风险 + private final Object lock1 = new Object(); + private final Object lock2 = new Object(); + + public void method1() { + synchronized (lock1) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + synchronized (lock2) { + // 一些操作 + } + } + } + + public void method2() { + synchronized (lock2) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + synchronized (lock1) { + // 一些操作 + } + } + } + + // 不正确的线程池使用 + public void processItems(List items) { + ExecutorService executor = Executors.newFixedThreadPool(10); + + for (String item : items) { + executor.submit(() -> { + processItem(item); + results.add("Processed: " + item); // 非线程安全操作 + }); + } + + // 没有shutdown和awaitTermination + } + + private void processItem(String item) { + // 模拟处理 + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + // 不正确的中断处理 + } + } + + // 不安全的缓存操作 + public Object getCachedValue(String key) { + if (!cache.containsKey(key)) { + // 计算值的过程可能很耗时 + Object value = computeExpensiveValue(key); + cache.put(key, value); // 竞态条件 + return value; + } + return cache.get(key); + } + + private Object computeExpensiveValue(String key) { + try { + Thread.sleep(2000); // 模拟耗时操作 + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + return "Value for " + key; + } + + // 生产者消费者问题 + private Queue queue = new LinkedList<>(); + private boolean finished = false; + + public void producer() { + for (int i = 0; i < 100; i++) { + queue.offer("Item " + i); // 非线程安全 + } + finished = true; // 可见性问题 + } + + public void consumer() { + while (!finished || !queue.isEmpty()) { + String item = queue.poll(); // 可能NPE + if (item != null) { + System.out.println("Consumed: " + item); + } + } + } + + // 资源竞争 + private int sharedResource = 0; + + public void updateResource(int value) { + // 非原子操作 + sharedResource = sharedResource + value; + } + + public int getResource() { + return sharedResource; + } + + // 不正确的同步 + public synchronized void synchronizedMethod() { + // 在同步方法中调用其他对象的方法 + String result = externalService.process("data"); + results.add(result); // 外部调用可能耗时很长 + } + + private ExternalService externalService = new ExternalService(); + + class ExternalService { + public String process(String data) { + try { + Thread.sleep(5000); // 模拟网络调用 + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + return "Processed: " + data; + } + } + + // ThreadLocal内存泄漏 + private static ThreadLocal threadLocalBuilder = new ThreadLocal() { + @Override + protected StringBuilder initialValue() { + return new StringBuilder(); + } + }; + + public String buildString(String... parts) { + StringBuilder builder = threadLocalBuilder.get(); + for (String part : parts) { + builder.append(part); + } + String result = builder.toString(); + // 没有清理ThreadLocal + return result; + } +} diff --git a/DataProcessor.java b/DataProcessor.java new file mode 100644 index 0000000..96f7f32 --- /dev/null +++ b/DataProcessor.java @@ -0,0 +1,285 @@ +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.*; + +/** + * 复杂数据处理类 - 包含设计模式误用、反射滥用等高级问题 + */ +public class DataProcessor extends Thread { + + // 滥用继承,应该用组合 + private static Map globalCache = new HashMap<>(); // 线程不安全 + private List rules = new ArrayList<>(); + private volatile boolean isRunning = true; + + // 单例模式的错误实现 + private static DataProcessor instance; + + public static DataProcessor getInstance() { + if (instance == null) { // 线程不安全 + instance = new DataProcessor(); + } + return instance; + } + + // 构造器做了太多事情 + public DataProcessor() { + loadConfiguration(); + initializeRules(); + setupDatabase(); + startBackgroundTasks(); + registerShutdownHook(); + } + + // 方法太长,职责太多 + public ProcessingResult processData(Object inputData, String type, Map options) { + long startTime = System.currentTimeMillis(); + + // 类型检查用instanceof链 + if (inputData instanceof String) { + String strData = (String) inputData; + if (strData.length() > 1000000) { // 魔法数字 + throw new RuntimeException("Data too large"); + } + + // 字符串处理逻辑 + String processed = processStringData(strData, options); + return new ProcessingResult(processed, "string", startTime); + + } else if (inputData instanceof List) { + List listData = (List) inputData; + if (listData.size() > 10000) { // 另一个魔法数字 + // 分批处理 + List results = new ArrayList<>(); + for (int i = 0; i < listData.size(); i += 1000) { + int end = Math.min(i + 1000, listData.size()); + List batch = listData.subList(i, end); + Object batchResult = processBatchData(batch, options); + results.add(batchResult); + } + return new ProcessingResult(results, "list", startTime); + } else { + return new ProcessingResult(processBatchData(listData, options), "list", startTime); + } + + } else if (inputData instanceof Map) { + Map mapData = (Map) inputData; + Map result = new HashMap<>(); + + // 反射滥用 + for (Object key : mapData.keySet()) { + try { + Object value = mapData.get(key); + Class valueClass = value.getClass(); + Method[] methods = valueClass.getDeclaredMethods(); + + for (Method method : methods) { + if (method.getName().startsWith("get")) { + method.setAccessible(true); + Object methodResult = method.invoke(value); + result.put(key.toString() + "_" + method.getName(), methodResult); + } + } + } catch (Exception e) { + // 吞掉异常 + continue; + } + } + + return new ProcessingResult(result, "map", startTime); + } else { + // 用反射处理未知类型 + return processWithReflection(inputData, options, startTime); + } + } + + // 深层嵌套和复杂逻辑 + private ProcessingResult processWithReflection(Object obj, Map options, long startTime) { + try { + Class clazz = obj.getClass(); + Field[] fields = clazz.getDeclaredFields(); + Map result = new HashMap<>(); + + for (Field field : fields) { + field.setAccessible(true); + Object value = field.get(obj); + + if (value != null) { + if (value instanceof String) { + String strValue = (String) value; + if (strValue.contains("password") || strValue.contains("secret")) { + result.put(field.getName(), "***REDACTED***"); + } else if (strValue.length() > 100) { + if (options.containsKey("truncate") && "true".equals(options.get("truncate"))) { + result.put(field.getName(), strValue.substring(0, 100) + "..."); + } else { + result.put(field.getName(), strValue); + } + } else { + result.put(field.getName(), strValue); + } + } else if (value instanceof Number) { + Number numValue = (Number) value; + if (options.containsKey("multiply")) { + try { + double multiplier = Double.parseDouble(options.get("multiply")); + result.put(field.getName(), numValue.doubleValue() * multiplier); + } catch (NumberFormatException e) { + result.put(field.getName(), numValue); + } + } else { + result.put(field.getName(), numValue); + } + } else if (value instanceof Collection) { + Collection collection = (Collection) value; + if (collection.size() > 0) { + List processedItems = new ArrayList<>(); + for (Object item : collection) { + if (item instanceof String || item instanceof Number) { + processedItems.add(item); + } else { + // 递归处理,可能栈溢出 + ProcessingResult itemResult = processWithReflection(item, options, + System.currentTimeMillis()); + processedItems.add(itemResult.getData()); + } + } + result.put(field.getName(), processedItems); + } + } else { + // 更深层递归 + ProcessingResult nestedResult = processWithReflection(value, options, + System.currentTimeMillis()); + result.put(field.getName(), nestedResult.getData()); + } + } + } + + return new ProcessingResult(result, "reflection", startTime); + + } catch (Exception e) { + throw new RuntimeException("Reflection processing failed", e); + } + } + + // 线程安全问题 + @Override + public void run() { + while (isRunning) { + try { + // 处理缓存清理 + if (globalCache.size() > 1000) { + globalCache.clear(); // 竞态条件 + } + + // 执行规则 + for (ProcessingRule rule : rules) { // 可能并发修改 + rule.execute(); + } + + Thread.sleep(5000); + } catch (InterruptedException e) { + // 不正确的中断处理 + isRunning = false; + } + } + } + + // 资源管理问题 + private void loadConfiguration() { + Properties props = new Properties(); + try { + props.load(this.getClass().getResourceAsStream("/config.properties")); + // 文件流没有关闭 + } catch (Exception e) { + // 使用默认配置,但没有日志 + } + } + + // 内存泄漏风险 + private void initializeRules() { + // 创建大量规则但没有清理机制 + for (int i = 0; i < 1000; i++) { + rules.add(new ProcessingRule("Rule_" + i)); + } + } + + // 硬编码和配置问题 + private void setupDatabase() { + String url = "jdbc:mysql://localhost:3306/app"; // 硬编码 + String user = "root"; + String pass = "password123"; + // 创建连接但没有管理 + } + + private void startBackgroundTasks() { + // 创建线程但没有管理 + new Thread(this).start(); + } + + private void registerShutdownHook() { + Runtime.getRuntime().addShutdownHook(new Thread(() -> { + cleanup(); + })); + } + + private void cleanup() { + isRunning = false; + // 不完整的清理逻辑 + } + + // 辅助方法 + private String processStringData(String data, Map options) { + return data.toUpperCase(); // 简单处理 + } + + private Object processBatchData(List batch, Map options) { + return batch.toString(); // 简单处理 + } + + // 嵌套类 + class ProcessingRule { + private String name; + + ProcessingRule(String name) { + this.name = name; + } + + void execute() { + // 规则执行逻辑 + globalCache.put(name + "_executed", System.currentTimeMillis()); + } + } + + // 结果类设计问题 + static class ProcessingResult { + private Object data; + private String type; + private long processingTime; + + ProcessingResult(Object data, String type, long startTime) { + this.data = data; + this.type = type; + this.processingTime = System.currentTimeMillis() - startTime; + } + + // 缺少getter方法 + public Object getData() { + return data; + } + + public String getType() { + return type; + } + + public long getProcessingTime() { + return processingTime; + } + + // toString方法可能包含敏感信息 + @Override + public String toString() { + return "ProcessingResult{data=" + data + ", type='" + type + "', time=" + processingTime + "}"; + } + } +} diff --git a/DatabaseConnection.java b/DatabaseConnection.java new file mode 100644 index 0000000..da2d0d4 --- /dev/null +++ b/DatabaseConnection.java @@ -0,0 +1,110 @@ +import java.io.FileInputStream; +import java.io.IOException; +import java.sql.*; +import java.util.Properties; + +/** + * 数据库连接管理类 - 包含资源泄漏和连接管理问题 + */ +public class DatabaseConnection { + private static String DB_URL = "jdbc:mysql://localhost:3306/test"; // 硬编码URL + private static String USERNAME = "root"; + private static String PASSWORD = "123456"; // 硬编码密码 + + // 未使用连接池 + public static Connection getConnection() throws SQLException { + return DriverManager.getConnection(DB_URL, USERNAME, PASSWORD); + } + + // 资源泄漏 - 没有关闭连接 + public void executeQuery(String sql) { + try { + Connection conn = getConnection(); + Statement stmt = conn.createStatement(); + ResultSet rs = stmt.executeQuery(sql); + + while (rs.next()) { + System.out.println(rs.getString(1)); + } + // 没有关闭资源! + } catch (SQLException e) { + System.out.println("Database error occurred"); + } + } + + // 不正确的事务处理 + public void updateUserData(int userId, String newName) { + Connection conn = null; + try { + conn = getConnection(); + conn.setAutoCommit(false); + + PreparedStatement stmt1 = conn.prepareStatement("UPDATE users SET name = ? WHERE id = ?"); + stmt1.setString(1, newName); + stmt1.setInt(2, userId); + stmt1.executeUpdate(); + + // 这里可能抛出异常 + PreparedStatement stmt2 = conn + .prepareStatement("UPDATE user_stats SET last_updated = NOW() WHERE user_id = ?"); + stmt2.setInt(1, userId); + stmt2.executeUpdate(); + + conn.commit(); // 如果上面出错,这行不会执行 + + } catch (SQLException e) { + // 没有回滚事务 + e.printStackTrace(); + } finally { + // 不正确的资源清理 + if (conn != null) { + try { + conn.close(); + } catch (SQLException e) { + // 忽略关闭异常 + } + } + } + } + + // 批量操作效率低下 + public void insertMultipleUsers(String[][] userData) { + for (String[] user : userData) { + // 每次循环都创建新连接 + try (Connection conn = getConnection()) { + String sql = "INSERT INTO users (name, email) VALUES (?, ?)"; + PreparedStatement stmt = conn.prepareStatement(sql); + stmt.setString(1, user[0]); + stmt.setString(2, user[1]); + stmt.executeUpdate(); + } catch (SQLException e) { + continue; // 忽略错误继续处理 + } + } + } + + // 同步方法可能导致性能问题 + public synchronized ResultSet queryUsers() throws SQLException { + Connection conn = getConnection(); + Statement stmt = conn.createStatement(); + return stmt.executeQuery("SELECT * FROM users"); + // 返回ResultSet但连接可能被关闭 + } + + // 配置文件处理有问题 + public void loadDatabaseConfig() { + Properties props = new Properties(); + try { + FileInputStream fis = new FileInputStream("db.properties"); + props.load(fis); + // 没有关闭FileInputStream + + DB_URL = props.getProperty("db.url"); + USERNAME = props.getProperty("db.username"); + PASSWORD = props.getProperty("db.password"); + + } catch (IOException e) { + // 使用默认配置,但没有日志记录 + } + } +} diff --git a/FileProcessor.java b/FileProcessor.java new file mode 100644 index 0000000..c42e2e9 --- /dev/null +++ b/FileProcessor.java @@ -0,0 +1,159 @@ +import java.io.*; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * 文件处理类 - 包含IO异常处理和资源管理问题 + */ +public class FileProcessor { + + private static final String DEFAULT_ENCODING = "UTF-8"; + private List processedFiles = new ArrayList<>(); + + // 不正确的异常处理 + public String readFile(String fileName) { + try { + BufferedReader reader = new BufferedReader(new FileReader(fileName)); + StringBuilder content = new StringBuilder(); + String line; + + while ((line = reader.readLine()) != null) { + content.append(line).append("\n"); + } + // 没有关闭reader! + return content.toString(); + + } catch (Exception e) { + return ""; // 吞掉所有异常 + } + } + + // 资源泄漏 + public void writeFile(String fileName, String content) throws IOException { + FileWriter writer = new FileWriter(fileName); + writer.write(content); + // 没有关闭writer或处理异常 + } + + // 大文件内存问题 + public List readAllLines(String fileName) { + List lines = new ArrayList<>(); + try { + // 一次性读取所有行到内存 + BufferedReader reader = new BufferedReader(new FileReader(fileName)); + String line; + while ((line = reader.readLine()) != null) { + lines.add(line); + } + reader.close(); + } catch (IOException e) { + System.out.println("Error reading file: " + fileName); + } + return lines; + } + + // 不安全的文件路径操作 + public void copyFile(String sourcePath, String destPath) { + try { + // 没有验证路径安全性 + File source = new File(sourcePath); + File dest = new File(destPath); + + FileInputStream fis = new FileInputStream(source); + FileOutputStream fos = new FileOutputStream(dest); + + byte[] buffer = new byte[1024]; + int length; + while ((length = fis.read(buffer)) > 0) { + fos.write(buffer, 0, length); + } + + // 只关闭了一个流 + fis.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + // 同步方法性能问题 + public synchronized void processFile(String fileName) { + if (processedFiles.contains(fileName)) { + return; + } + + try { + Thread.sleep(1000); // 模拟长时间处理 + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + + processedFiles.add(fileName); + } + + // 递归删除目录 - 安全风险 + public void deleteDirectory(File directory) { + if (directory.isDirectory()) { + File[] files = directory.listFiles(); + if (files != null) { + for (File file : files) { + deleteDirectory(file); // 可能栈溢出 + } + } + } + directory.delete(); // 没有检查删除结果 + } + + // 硬编码文件路径 + public void createLogFile() { + try { + File logFile = new File("/tmp/app.log"); // 硬编码路径 + if (!logFile.exists()) { + logFile.createNewFile(); + } + + FileWriter writer = new FileWriter(logFile, true); + writer.write("Log entry at " + new Date()); + writer.close(); + + } catch (IOException e) { + // 忽略异常 + } + } + + // 不正确的文件检查 + public boolean isValidFile(String fileName) { + File file = new File(fileName); + return file.exists(); // 没有检查是否为文件、是否可读等 + } + + // CSV解析问题 + public List parseCsv(String fileName) { + List records = new ArrayList<>(); + try { + BufferedReader reader = new BufferedReader(new FileReader(fileName)); + String line; + while ((line = reader.readLine()) != null) { + // 简单分割,没有处理引号内的逗号 + String[] fields = line.split(","); + records.add(fields); + } + } catch (IOException e) { + return null; // 不一致的返回值 + } + return records; + } + + // 临时文件没有清理 + public String processLargeFile(String inputFile) { + try { + File tempFile = File.createTempFile("processing", ".tmp"); + // 处理逻辑... + return tempFile.getAbsolutePath(); + // 没有清理临时文件! + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/RestController.java b/RestController.java new file mode 100644 index 0000000..11ad4cc --- /dev/null +++ b/RestController.java @@ -0,0 +1,209 @@ +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import java.io.IOException; +import java.util.*; + +/** + * REST控制器类 - 包含Web安全、验证和API设计问题 + */ +public class RestController { + + private static final String SECRET_KEY = "mySecretKey123"; // 硬编码密钥 + private Map users = new HashMap<>(); + + // 缺少输入验证和身份认证 + public String createUser(HttpServletRequest request, HttpServletResponse response) { + String name = request.getParameter("name"); + String email = request.getParameter("email"); + String password = request.getParameter("password"); + + // 没有验证输入 + User user = new User(name, email, password); + users.put(email, user); + + // 返回敏感信息 + return "User created: " + user.toString(); + } + + // SQL注入风险 + public String getUserData(HttpServletRequest request) { + String userId = request.getParameter("id"); + // 直接拼接SQL,存在注入风险 + String sql = "SELECT * FROM users WHERE id = " + userId; + return executeQuery(sql); + } + + // 缺少CSRF保护 + public void deleteUser(HttpServletRequest request) { + String userId = request.getParameter("userId"); + // 没有CSRF token验证 + users.remove(userId); + } + + // 信息泄漏 + public String login(HttpServletRequest request) { + String email = request.getParameter("email"); + String password = request.getParameter("password"); + + User user = users.get(email); + if (user == null) { + return "User not found with email: " + email; // 泄漏用户是否存在 + } + + if (!user.password.equals(password)) { + return "Invalid password for user: " + email; // 泄漏信息 + } + + return "Login successful. Secret key: " + SECRET_KEY; // 泄漏密钥 + } + + // 没有速率限制 + public String sendEmail(HttpServletRequest request) { + String email = request.getParameter("email"); + String subject = request.getParameter("subject"); + String body = request.getParameter("body"); + + // 没有验证发送频率 + for (int i = 0; i < 100; i++) { + sendEmailInternal(email, subject, body); + } + + return "Emails sent"; + } + + // 文件上传漏洞 + public String uploadFile(HttpServletRequest request) { + String fileName = request.getParameter("fileName"); + String content = request.getParameter("content"); + + // 没有验证文件类型和大小 + // 没有防止路径遍历 + String path = "/uploads/" + fileName; + saveFile(path, content); + + return "File uploaded to: " + path; + } + + // XSS漏洞 + public String displayUserComment(HttpServletRequest request, HttpServletResponse response) throws IOException { + String comment = request.getParameter("comment"); + + // 直接输出用户输入,存在XSS风险 + response.getWriter().write("
User comment: " + comment + "
"); + return null; + } + + // 权限绕过 + public String getAdminData(HttpServletRequest request) { + String userRole = request.getParameter("role"); + + // 客户端传递权限信息 + if ("admin".equals(userRole)) { + return "Sensitive admin data: " + getSecretData(); + } + + return "Access denied"; + } + + // 不安全的重定向 + public void redirect(HttpServletRequest request, HttpServletResponse response) throws IOException { + String url = request.getParameter("redirect"); + + // 没有验证重定向URL + response.sendRedirect(url); + } + + // 会话固定漏洞 + public String createSession(HttpServletRequest request) { + String sessionId = request.getParameter("sessionId"); + + // 使用客户端提供的会话ID + if (sessionId != null) { + request.getSession().setAttribute("customSessionId", sessionId); + } + + return "Session created with ID: " + sessionId; + } + + // 不正确的错误处理 + public String processPayment(HttpServletRequest request) { + try { + String amount = request.getParameter("amount"); + String cardNumber = request.getParameter("cardNumber"); + + // 模拟支付处理 + if (cardNumber.length() != 16) { + throw new RuntimeException("Invalid card number: " + cardNumber); + } + + return "Payment processed for amount: " + amount; + + } catch (Exception e) { + // 返回详细错误信息 + return "Payment failed: " + e.getMessage() + " Stack trace: " + Arrays.toString(e.getStackTrace()); + } + } + + // 资源消耗攻击 + public String generateReport(HttpServletRequest request) { + String format = request.getParameter("format"); + int size = Integer.parseInt(request.getParameter("size")); + + // 没有限制资源使用 + List data = new ArrayList<>(); + for (int i = 0; i < size; i++) { + data.add("Data item " + i); + } + + return "Generated report with " + data.size() + " items"; + } + + // 不安全的API密钥处理 + public String callExternalAPI(HttpServletRequest request) { + String apiKey = request.getParameter("apiKey"); + + // API密钥通过URL参数传递 + String url = "https://api.example.com/data?key=" + apiKey; + + // 记录包含API密钥的URL + System.out.println("Calling API: " + url); + + return "API call completed"; + } + + // 辅助方法 + private String executeQuery(String sql) { + return "Query result for: " + sql; + } + + private void sendEmailInternal(String email, String subject, String body) { + // 模拟发送邮件 + } + + private void saveFile(String path, String content) { + // 模拟保存文件 + } + + private String getSecretData() { + return "TOP_SECRET_ADMIN_DATA"; + } + + // 用户类 + static class User { + String name; + String email; + String password; // 明文存储密码 + + User(String name, String email, String password) { + this.name = name; + this.email = email; + this.password = password; + } + + @Override + public String toString() { + return "User{name='" + name + "', email='" + email + "', password='" + password + "'}"; + } + } +} diff --git a/StringUtils.java b/StringUtils.java new file mode 100644 index 0000000..7964b3e --- /dev/null +++ b/StringUtils.java @@ -0,0 +1,155 @@ +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 字符串工具类 - 包含空指针、性能和逻辑问题 + */ +public class StringUtils { + + private static final String SPECIAL_CHARS = "!@#$%^&*()"; + + // 空指针风险 + public static boolean isEmpty(String str) { + return str.length() == 0; // 没有检查null + } + + // 性能问题 - 字符串拼接 + public static String joinStrings(String[] strings, String separator) { + String result = ""; + for (int i = 0; i < strings.length; i++) { + result += strings[i]; // 不应该用+拼接 + if (i < strings.length - 1) { + result += separator; + } + } + return result; + } + + // 正则表达式每次都编译 + public static boolean isValidEmail(String email) { + if (email == null) + return false; + return email.matches("^[A-Za-z0-9+_.-]+@(.+)$"); // 简单的正则,每次都编译 + } + + // 不正确的字符串比较 + public static boolean isCommand(String input, String command) { + return input.toLowerCase() == command.toLowerCase(); // 应该用equals + } + + // 无限循环风险 + public static String removeAllSpaces(String str) { + while (str.contains(" ")) { + str = str.replace(" ", ""); // 可能无限循环 + } + return str; + } + + // 内存泄漏风险 + public static List splitAndCache(String text, String delimiter) { + // 静态缓存但没有清理机制 + static Map> cache = new HashMap<>(); + + if (cache.containsKey(text)) { + return cache.get(text); + } + + List result = Arrays.asList(text.split(delimiter)); + cache.put(text, result); // 缓存会无限增长 + return result; + } + + // 不安全的字符串操作 + public static String sanitizeInput(String input) { + if (input == null) + return null; + + // 不完整的清理 + return input.replace("", "") + .replace("javascript:", ""); + // 容易被绕过 + } + + // 硬编码和魔法数字 + public static String truncate(String str, int maxLength) { + if (str.length() > maxLength) { + return str.substring(0, maxLength) + "..."; // 魔法字符串 + } + return str; + } + + // 效率低下的字符计数 + public static int countOccurrences(String text, char target) { + int count = 0; + for (int i = 0; i < text.length(); i++) { + if (text.charAt(i) == target) { + count++; + } + } + return count; // 可以用Collections.frequency或Stream + } + + // 不正确的编码处理 + public static String encodeString(String input) { + try { + return java.net.URLEncoder.encode(input, "UTF-8"); + } catch (Exception e) { + return input; // 忽略编码异常 + } + } + + // 复杂的条件判断 + public static boolean isValidPassword(String password) { + if (password == null || password.length() < 8) { + return false; + } + + boolean hasUpper = false; + boolean hasLower = false; + boolean hasDigit = false; + boolean hasSpecial = false; + + for (int i = 0; i < password.length(); i++) { + char c = password.charAt(i); + if (c >= 'A' && c <= 'Z') + hasUpper = true; + if (c >= 'a' && c <= 'z') + hasLower = true; + if (c >= '0' && c <= '9') + hasDigit = true; + if (SPECIAL_CHARS.indexOf(c) != -1) + hasSpecial = true; + } + + return hasUpper && hasLower && hasDigit && hasSpecial; + } + + // 线程安全问题 + private static StringBuilder buffer = new StringBuilder(); // 共享可变状态 + + public static String processText(String input) { + buffer.setLength(0); // 清空但线程不安全 + buffer.append("Processed: "); + buffer.append(input); + return buffer.toString(); + } + + // 递归可能栈溢出 + public static String reverse(String str) { + if (str.length() <= 1) { + return str; + } + return reverse(str.substring(1)) + str.charAt(0); + } + + // 不一致的null处理 + public static String capitalize(String str) { + if (str == null || str.isEmpty()) { + return str; // 对null和empty不一致处理 + } + return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase(); + } +} diff --git a/Test.java b/Test.java new file mode 100644 index 0000000..429106e --- /dev/null +++ b/Test.java @@ -0,0 +1,10 @@ + +/** + * + * @author chengfei.jin + */ +public class Test { + public static void main(String[] args) { + System.out.println("Hello, World!"); + } +} \ No newline at end of file diff --git a/UserService.java b/UserService.java new file mode 100644 index 0000000..62c0b7a --- /dev/null +++ b/UserService.java @@ -0,0 +1,91 @@ +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +/** + * 用户服务类 - 故意包含多个安全和代码质量问题 + * + * @author chengfei.jin + */ +public class UserService { + private static Connection connection; + private String adminPassword = "admin123"; // 硬编码密码 + + // SQL注入漏洞 + public User getUserById(String userId) { + try { + String sql = "SELECT * FROM users WHERE id = " + userId; // SQL注入风险 + Statement stmt = connection.createStatement(); + ResultSet rs = stmt.executeQuery(sql); + + if (rs.next()) { + return new User(rs.getString("name"), rs.getString("email")); + } + } catch (Exception e) { + // 空的异常处理 + } + return null; + } + + // 密码处理问题 + public boolean validatePassword(String username, String password) { + String storedPassword = getPasswordFromDB(username); + // 直接比较明文密码 + if (password.equals(storedPassword)) { + return true; + } + return false; + } + + // 方法太长,职责不单一 + public void createUser(String name, String email, String password, String address, String phone) { + if (name == null || email == null) + return; // 缺少详细验证 + + // 未加密存储密码 + String sql = "INSERT INTO users (name, email, password, address, phone) VALUES ('" + + name + "', '" + email + "', '" + password + "', '" + address + "', '" + phone + "')"; + + try { + Statement stmt = connection.createStatement(); + stmt.executeUpdate(sql); + + // 发送欢迎邮件 + sendWelcomeEmail(email); + + // 记录日志 + System.out.println("User created: " + name); + + // 创建默认设置 + createDefaultSettings(name); + + } catch (SQLException e) { + e.printStackTrace(); // 不应该直接打印栈跟踪 + } + } + + private String getPasswordFromDB(String username) { + // 模拟返回明文密码 + return "password123"; + } + + private void sendWelcomeEmail(String email) { + // 空实现 + } + + private void createDefaultSettings(String username) { + // 空实现 + } + + // 内部类没有访问修饰符 + class User { + String name; + String email; + + User(String name, String email) { + this.name = name; + this.email = email; + } + } +} diff --git a/simple_utils.py b/simple_utils.py deleted file mode 100644 index 6de0ca6..0000000 --- a/simple_utils.py +++ /dev/null @@ -1,11 +0,0 @@ -# simple_utils.py - A tiny utility library - -def reverse_string(text): - """Reverses the characters in a string.""" - return text[::-1] - -def count_words(sentence): - return len(sentence.split()) - -def celsius_to_fahrenheit(celsius): - return (celsius * 9/5) + 32 \ No newline at end of file