Compare commits
No commits in common. "018e51109abf322c776ce7eee90e857364dd15c8" and "e54a060b552e99c2dadd6eebd654723329afcb13" have entirely different histories.
018e51109a
...
e54a060b55
@ -1,39 +0,0 @@
|
|||||||
From 2c22de4fc6e4a097ace36eec8b03535b5e2486fe Mon Sep 17 00:00:00 2001
|
|
||||||
From: starlet-dx <15929766099@163.com>
|
|
||||||
Date: Fri, 16 Jun 2023 14:00:11 +0800
|
|
||||||
Subject: [PATCH 1/1] Merge pull request from GHSA-562r-vg33-8x8h
|
|
||||||
|
|
||||||
* Fix: createTempFile vulnerability on unix like systems where temporary files can be read by other users on the system
|
|
||||||
|
|
||||||
* Update site with change logs and new version information
|
|
||||||
|
|
||||||
Origin:
|
|
||||||
https://github.com/pgjdbc/pgjdbc/commit/9008dc9aade6dbfe4efafcd6872ebc55f4699cf5
|
|
||||||
---
|
|
||||||
src/main/java/org/postgresql/util/StreamWrapper.java | 3 ++-
|
|
||||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
|
||||||
|
|
||||||
diff --git a/src/main/java/org/postgresql/util/StreamWrapper.java b/src/main/java/org/postgresql/util/StreamWrapper.java
|
|
||||||
index c4027ce..49f0b5d 100644
|
|
||||||
--- a/src/main/java/org/postgresql/util/StreamWrapper.java
|
|
||||||
+++ b/src/main/java/org/postgresql/util/StreamWrapper.java
|
|
||||||
@@ -17,6 +17,7 @@ import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
+import java.nio.file.Files;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Wrapper around a length-limited InputStream.
|
|
||||||
@@ -51,7 +52,7 @@ public class StreamWrapper {
|
|
||||||
|
|
||||||
if (memoryLength == -1) {
|
|
||||||
final int diskLength;
|
|
||||||
- final File tempFile = File.createTempFile(TEMP_FILE_PREFIX, null);
|
|
||||||
+ final File tempFile = Files.createTempFile(TEMP_FILE_PREFIX, null).toFile();
|
|
||||||
FileOutputStream diskOutputStream = new FileOutputStream(tempFile);
|
|
||||||
diskOutputStream.write(rawData);
|
|
||||||
try {
|
|
||||||
--
|
|
||||||
2.30.0
|
|
||||||
|
|
||||||
@ -1,295 +0,0 @@
|
|||||||
From e479be16967ae20af1bd57187738d5243052bbee Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dave Cramer <davecramer@gmail.com>
|
|
||||||
Date: Mon, 19 Feb 2024 08:20:59 -0500
|
|
||||||
Subject: [PATCH] Merge pull request from GHSA-24rp-q3w6-vc56
|
|
||||||
|
|
||||||
* SQL Injection via line comment generation for 42_4_x
|
|
||||||
|
|
||||||
* fix: Add parentheses around NULL parameter values in simple query mode
|
|
||||||
|
|
||||||
---------
|
|
||||||
|
|
||||||
Co-authored-by: Sehrope Sarkuni <sehrope@jackdb.com>
|
|
||||||
---
|
|
||||||
.../core/v3/SimpleParameterList.java | 112 +++++++++++-------
|
|
||||||
.../core/v3/V3ParameterListTests.java | 6 +-
|
|
||||||
.../jdbc/ParameterInjectionTest.java | 67 +++++++++++
|
|
||||||
3 files changed, 142 insertions(+), 43 deletions(-)
|
|
||||||
create mode 100644 src/test/java/org/postgresql/jdbc/ParameterInjectionTest.java
|
|
||||||
|
|
||||||
diff --git a/src/main/java/org/postgresql/core/v3/SimpleParameterList.java b/src/main/java/org/postgresql/core/v3/SimpleParameterList.java
|
|
||||||
index 969880b..b996e0b 100644
|
|
||||||
--- a/src/main/java/org/postgresql/core/v3/SimpleParameterList.java
|
|
||||||
+++ b/src/main/java/org/postgresql/core/v3/SimpleParameterList.java
|
|
||||||
@@ -172,6 +172,58 @@ class SimpleParameterList implements V3ParameterList {
|
|
||||||
}
|
|
||||||
bind(index, NULL_OBJECT, oid, binaryTransfer);
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ /**
|
|
||||||
+ * <p>Escapes a given text value as a literal, wraps it in single quotes, casts it to the
|
|
||||||
+ * to the given data type, and finally wraps the whole thing in parentheses.</p>
|
|
||||||
+ *
|
|
||||||
+ * <p>For example, "123" and "int4" becomes "('123'::int)"</p>
|
|
||||||
+ *
|
|
||||||
+ * <p>The additional parentheses is added to ensure that the surrounding text of where the
|
|
||||||
+ * parameter value is entered does modify the interpretation of the value.</p>
|
|
||||||
+ *
|
|
||||||
+ * <p>For example if our input SQL is: <code>SELECT ?b</code></p>
|
|
||||||
+ *
|
|
||||||
+ * <p>Using a parameter value of '{}' and type of json we'd get:</p>
|
|
||||||
+ *
|
|
||||||
+ * <pre>
|
|
||||||
+ * test=# SELECT ('{}'::json)b;
|
|
||||||
+ * b
|
|
||||||
+ * ----
|
|
||||||
+ * {}
|
|
||||||
+ * </pre>
|
|
||||||
+ *
|
|
||||||
+ * <p>But without the parentheses the result changes:</p>
|
|
||||||
+ *
|
|
||||||
+ * <pre>
|
|
||||||
+ * test=# SELECT '{}'::jsonb;
|
|
||||||
+ * jsonb
|
|
||||||
+ * -------
|
|
||||||
+ * {}
|
|
||||||
+ * </pre>
|
|
||||||
+ **/
|
|
||||||
+ private static String quoteAndCast(String text, String type, boolean standardConformingStrings) {
|
|
||||||
+ StringBuilder sb = new StringBuilder((text.length() + 10) / 10 * 11); // Add 10% for escaping.
|
|
||||||
+ sb.append("('");
|
|
||||||
+ try {
|
|
||||||
+ Utils.escapeLiteral(sb, text, standardConformingStrings);
|
|
||||||
+ } catch (SQLException e) {
|
|
||||||
+ // This should only happen if we have an embedded null
|
|
||||||
+ // and there's not much we can do if we do hit one.
|
|
||||||
+ //
|
|
||||||
+ // To force a server side failure, we deliberately include
|
|
||||||
+ // a zero byte character in the literal to force the server
|
|
||||||
+ // to reject the command.
|
|
||||||
+ sb.append('\u0000');
|
|
||||||
+ }
|
|
||||||
+ sb.append("'");
|
|
||||||
+ if (type != null) {
|
|
||||||
+ sb.append("::");
|
|
||||||
+ sb.append(type);
|
|
||||||
+ }
|
|
||||||
+ sb.append(")");
|
|
||||||
+ return sb.toString();
|
|
||||||
+ }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString(/* @Positive */ int index, boolean standardConformingStrings) {
|
|
||||||
@@ -180,100 +232,80 @@ class SimpleParameterList implements V3ParameterList {
|
|
||||||
if (paramValue == null) {
|
|
||||||
return "?";
|
|
||||||
} else if (paramValue == NULL_OBJECT) {
|
|
||||||
- return "NULL";
|
|
||||||
+ return "(NULL)";
|
|
||||||
} else if ((flags[index] & BINARY) == BINARY) {
|
|
||||||
// handle some of the numeric types
|
|
||||||
|
|
||||||
switch (paramTypes[index]) {
|
|
||||||
case Oid.INT2:
|
|
||||||
short s = ByteConverter.int2((byte[]) paramValue, 0);
|
|
||||||
- return Short.toString(s);
|
|
||||||
+ return quoteAndCast(Short.toString(s), "int2", standardConformingStrings);
|
|
||||||
|
|
||||||
case Oid.INT4:
|
|
||||||
int i = ByteConverter.int4((byte[]) paramValue, 0);
|
|
||||||
- return Integer.toString(i);
|
|
||||||
+ return quoteAndCast(Integer.toString(i), "int4", standardConformingStrings);
|
|
||||||
|
|
||||||
case Oid.INT8:
|
|
||||||
long l = ByteConverter.int8((byte[]) paramValue, 0);
|
|
||||||
- return Long.toString(l);
|
|
||||||
+ return quoteAndCast(Long.toString(l), "int8", standardConformingStrings);
|
|
||||||
|
|
||||||
case Oid.FLOAT4:
|
|
||||||
float f = ByteConverter.float4((byte[]) paramValue, 0);
|
|
||||||
if (Float.isNaN(f)) {
|
|
||||||
- return "'NaN'::real";
|
|
||||||
+ return "('NaN'::real)";
|
|
||||||
}
|
|
||||||
- return Float.toString(f);
|
|
||||||
+ return quoteAndCast(Float.toString(f), "float", standardConformingStrings);
|
|
||||||
|
|
||||||
case Oid.FLOAT8:
|
|
||||||
double d = ByteConverter.float8((byte[]) paramValue, 0);
|
|
||||||
if (Double.isNaN(d)) {
|
|
||||||
- return "'NaN'::double precision";
|
|
||||||
+ return "('NaN'::double precision)";
|
|
||||||
}
|
|
||||||
- return Double.toString(d);
|
|
||||||
+ return quoteAndCast(Double.toString(d), "double precision", standardConformingStrings);
|
|
||||||
|
|
||||||
case Oid.NUMERIC:
|
|
||||||
Number n = ByteConverter.numeric((byte[]) paramValue);
|
|
||||||
if (n instanceof Double) {
|
|
||||||
assert ((Double) n).isNaN();
|
|
||||||
- return "'NaN'::numeric";
|
|
||||||
+ return "('NaN'::numeric)";
|
|
||||||
}
|
|
||||||
return n.toString();
|
|
||||||
|
|
||||||
case Oid.UUID:
|
|
||||||
String uuid =
|
|
||||||
new UUIDArrayAssistant().buildElement((byte[]) paramValue, 0, 16).toString();
|
|
||||||
- return "'" + uuid + "'::uuid";
|
|
||||||
+ return quoteAndCast(uuid, "uuid", standardConformingStrings);
|
|
||||||
|
|
||||||
case Oid.POINT:
|
|
||||||
PGpoint pgPoint = new PGpoint();
|
|
||||||
pgPoint.setByteValue((byte[]) paramValue, 0);
|
|
||||||
- return "'" + pgPoint.toString() + "'::point";
|
|
||||||
+ return quoteAndCast(pgPoint.toString(), "point", standardConformingStrings);
|
|
||||||
|
|
||||||
case Oid.BOX:
|
|
||||||
PGbox pgBox = new PGbox();
|
|
||||||
pgBox.setByteValue((byte[]) paramValue, 0);
|
|
||||||
- return "'" + pgBox.toString() + "'::box";
|
|
||||||
+ return quoteAndCast(pgBox.toString(), "box", standardConformingStrings);
|
|
||||||
}
|
|
||||||
return "?";
|
|
||||||
} else {
|
|
||||||
String param = paramValue.toString();
|
|
||||||
-
|
|
||||||
- // add room for quotes + potential escaping.
|
|
||||||
- StringBuilder p = new StringBuilder(3 + (param.length() + 10) / 10 * 11);
|
|
||||||
-
|
|
||||||
- // No E'..' here since escapeLiteral escapes all things and it does not use \123 kind of
|
|
||||||
- // escape codes
|
|
||||||
- p.append('\'');
|
|
||||||
- try {
|
|
||||||
- p = Utils.escapeLiteral(p, param, standardConformingStrings);
|
|
||||||
- } catch (SQLException sqle) {
|
|
||||||
- // This should only happen if we have an embedded null
|
|
||||||
- // and there's not much we can do if we do hit one.
|
|
||||||
- //
|
|
||||||
- // The goal of toString isn't to be sent to the server,
|
|
||||||
- // so we aren't 100% accurate (see StreamWrapper), put
|
|
||||||
- // the unescaped version of the data.
|
|
||||||
- //
|
|
||||||
- p.append(param);
|
|
||||||
- }
|
|
||||||
- p.append('\'');
|
|
||||||
int paramType = paramTypes[index];
|
|
||||||
if (paramType == Oid.TIMESTAMP) {
|
|
||||||
- p.append("::timestamp");
|
|
||||||
+ return quoteAndCast(param, "timestamp", standardConformingStrings);
|
|
||||||
} else if (paramType == Oid.TIMESTAMPTZ) {
|
|
||||||
- p.append("::timestamp with time zone");
|
|
||||||
+ return quoteAndCast(param, "timestamp with time zone", standardConformingStrings);
|
|
||||||
} else if (paramType == Oid.TIME) {
|
|
||||||
- p.append("::time");
|
|
||||||
+ return quoteAndCast(param, "time", standardConformingStrings);
|
|
||||||
} else if (paramType == Oid.TIMETZ) {
|
|
||||||
- p.append("::time with time zone");
|
|
||||||
+ return quoteAndCast(param, "time with time zone", standardConformingStrings);
|
|
||||||
} else if (paramType == Oid.DATE) {
|
|
||||||
- p.append("::date");
|
|
||||||
+ return quoteAndCast(param, "date", standardConformingStrings);
|
|
||||||
} else if (paramType == Oid.INTERVAL) {
|
|
||||||
- p.append("::interval");
|
|
||||||
+ return quoteAndCast(param, "interval", standardConformingStrings);
|
|
||||||
} else if (paramType == Oid.NUMERIC) {
|
|
||||||
- p.append("::numeric");
|
|
||||||
+ return quoteAndCast(param, "numeric", standardConformingStrings);
|
|
||||||
}
|
|
||||||
- return p.toString();
|
|
||||||
+ return quoteAndCast(param, null, standardConformingStrings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
diff --git a/src/test/java/org/postgresql/core/v3/V3ParameterListTests.java b/src/test/java/org/postgresql/core/v3/V3ParameterListTests.java
|
|
||||||
index 200004f..19c51cb 100644
|
|
||||||
--- a/src/test/java/org/postgresql/core/v3/V3ParameterListTests.java
|
|
||||||
+++ b/src/test/java/org/postgresql/core/v3/V3ParameterListTests.java
|
|
||||||
@@ -58,8 +58,8 @@ public class V3ParameterListTests {
|
|
||||||
s2SPL.setIntParameter(4, 8);
|
|
||||||
|
|
||||||
s1SPL.appendAll(s2SPL);
|
|
||||||
- assertEquals(
|
|
||||||
- "Expected string representation of values does not match outcome.",
|
|
||||||
- "<[1 ,2 ,3 ,4 ,5 ,6 ,7 ,8]>", s1SPL.toString());
|
|
||||||
+ assertEquals("Expected string representation of values does not match outcome.",
|
|
||||||
+ "<[('1'::int4) ,('2'::int4) ,('3'::int4) ,('4'::int4) ,('5'::int4) ,('6'::int4) ,('7'::int4) ,('8'::int4)]>", s1SPL.toString());
|
|
||||||
+
|
|
||||||
}
|
|
||||||
}
|
|
||||||
diff --git a/src/test/java/org/postgresql/jdbc/ParameterInjectionTest.java b/src/test/java/org/postgresql/jdbc/ParameterInjectionTest.java
|
|
||||||
new file mode 100644
|
|
||||||
index 0000000..2a33acd
|
|
||||||
--- /dev/null
|
|
||||||
+++ b/src/test/java/org/postgresql/jdbc/ParameterInjectionTest.java
|
|
||||||
@@ -0,0 +1,67 @@
|
|
||||||
+/*
|
|
||||||
+ * Copyright (c) 2024, PostgreSQL Global Development Group
|
|
||||||
+ * See the LICENSE file in the project root for more information.
|
|
||||||
+ */
|
|
||||||
+
|
|
||||||
+package org.postgresql.jdbc;
|
|
||||||
+
|
|
||||||
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
||||||
+import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
+
|
|
||||||
+import org.postgresql.test.TestUtil;
|
|
||||||
+
|
|
||||||
+import org.junit.jupiter.api.Test;
|
|
||||||
+
|
|
||||||
+import java.sql.Connection;
|
|
||||||
+import java.sql.PreparedStatement;
|
|
||||||
+import java.sql.ResultSet;
|
|
||||||
+
|
|
||||||
+public class ParameterInjectionTest {
|
|
||||||
+ @Test
|
|
||||||
+ public void negateParameter() throws Exception {
|
|
||||||
+ try (Connection conn = TestUtil.openDB()) {
|
|
||||||
+ PreparedStatement stmt = conn.prepareStatement("SELECT -?");
|
|
||||||
+
|
|
||||||
+ stmt.setInt(1, 1);
|
|
||||||
+ try (ResultSet rs = stmt.executeQuery()) {
|
|
||||||
+ assertTrue(rs.next());
|
|
||||||
+ assertEquals(1, rs.getMetaData().getColumnCount(), "number of result columns must match");
|
|
||||||
+ int value = rs.getInt(1);
|
|
||||||
+ assertEquals(-1, value, "Input value 1");
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ stmt.setInt(1, -1);
|
|
||||||
+ try (ResultSet rs = stmt.executeQuery()) {
|
|
||||||
+ assertTrue(rs.next());
|
|
||||||
+ assertEquals(1, rs.getMetaData().getColumnCount(), "number of result columns must match");
|
|
||||||
+ int value = rs.getInt(1);
|
|
||||||
+ assertEquals(1, value, "Input value -1");
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ @Test
|
|
||||||
+ public void negateParameterWithContinuation() throws Exception {
|
|
||||||
+ try (Connection conn = TestUtil.openDB()) {
|
|
||||||
+ PreparedStatement stmt = conn.prepareStatement("SELECT -?, ?");
|
|
||||||
+
|
|
||||||
+ stmt.setInt(1, 1);
|
|
||||||
+ stmt.setString(2, "\nWHERE false --");
|
|
||||||
+ try (ResultSet rs = stmt.executeQuery()) {
|
|
||||||
+ assertTrue(rs.next(), "ResultSet should contain a row");
|
|
||||||
+ assertEquals(2, rs.getMetaData().getColumnCount(), "rs.getMetaData().getColumnCount(");
|
|
||||||
+ int value = rs.getInt(1);
|
|
||||||
+ assertEquals(-1, value);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ stmt.setInt(1, -1);
|
|
||||||
+ stmt.setString(2, "\nWHERE false --");
|
|
||||||
+ try (ResultSet rs = stmt.executeQuery()) {
|
|
||||||
+ assertTrue(rs.next(), "ResultSet should contain a row");
|
|
||||||
+ assertEquals(2, rs.getMetaData().getColumnCount(), "rs.getMetaData().getColumnCount(");
|
|
||||||
+ int value = rs.getInt(1);
|
|
||||||
+ assertEquals(1, value);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
--
|
|
||||||
2.33.0
|
|
||||||
|
|
||||||
@ -1,338 +0,0 @@
|
|||||||
From fe002b31f2c7dcf7e2fe75fe7fd18df4e4503abf Mon Sep 17 00:00:00 2001
|
|
||||||
From: Dave Cramer <davecramer@gmail.com>
|
|
||||||
Date: Tue, 20 Feb 2024 10:01:14 -0500
|
|
||||||
Subject: [PATCH] Merge pull request from GHSA-24rp-q3w6-vc56
|
|
||||||
|
|
||||||
* SQL Injection via line comment generation for 42_4_x
|
|
||||||
|
|
||||||
* fix: Add parentheses around NULL parameter values in simple query mode
|
|
||||||
|
|
||||||
* simplify code, handle binary and add tests
|
|
||||||
|
|
||||||
---------
|
|
||||||
|
|
||||||
Co-authored-by: Sehrope Sarkuni <sehrope@jackdb.com>
|
|
||||||
---
|
|
||||||
.../core/v3/SimpleParameterList.java | 69 +++++---
|
|
||||||
.../jdbc/ParameterInjectionTest.java | 155 +++++++++++++-----
|
|
||||||
2 files changed, 162 insertions(+), 62 deletions(-)
|
|
||||||
|
|
||||||
diff --git a/src/main/java/org/postgresql/core/v3/SimpleParameterList.java b/src/main/java/org/postgresql/core/v3/SimpleParameterList.java
|
|
||||||
index 95cdaa4..d2d27fd 100644
|
|
||||||
--- a/src/main/java/org/postgresql/core/v3/SimpleParameterList.java
|
|
||||||
+++ b/src/main/java/org/postgresql/core/v3/SimpleParameterList.java
|
|
||||||
@@ -202,7 +202,7 @@ class SimpleParameterList implements V3ParameterList {
|
|
||||||
* {}
|
|
||||||
* </pre>
|
|
||||||
**/
|
|
||||||
- private static String quoteAndCast(String text, String type, boolean standardConformingStrings) {
|
|
||||||
+ private static String quoteAndCast(String text, /* @Nullable */ String type, boolean standardConformingStrings) {
|
|
||||||
StringBuilder sb = new StringBuilder((text.length() + 10) / 10 * 11); // Add 10% for escaping.
|
|
||||||
sb.append("('");
|
|
||||||
try {
|
|
||||||
@@ -233,35 +233,47 @@ class SimpleParameterList implements V3ParameterList {
|
|
||||||
return "?";
|
|
||||||
} else if (paramValue == NULL_OBJECT) {
|
|
||||||
return "(NULL)";
|
|
||||||
- } else if ((flags[index] & BINARY) == BINARY) {
|
|
||||||
+ }
|
|
||||||
+ String textValue;
|
|
||||||
+ String type;
|
|
||||||
+ if ((flags[index] & BINARY) == BINARY) {
|
|
||||||
// handle some of the numeric types
|
|
||||||
-
|
|
||||||
switch (paramTypes[index]) {
|
|
||||||
case Oid.INT2:
|
|
||||||
short s = ByteConverter.int2((byte[]) paramValue, 0);
|
|
||||||
- return quoteAndCast(Short.toString(s), "int2", standardConformingStrings);
|
|
||||||
+ textValue = Short.toString(s);
|
|
||||||
+ type = "int2";
|
|
||||||
+ break;
|
|
||||||
|
|
||||||
case Oid.INT4:
|
|
||||||
int i = ByteConverter.int4((byte[]) paramValue, 0);
|
|
||||||
- return quoteAndCast(Integer.toString(i), "int4", standardConformingStrings);
|
|
||||||
+ textValue = Integer.toString(i);
|
|
||||||
+ type = "int4";
|
|
||||||
+ break;
|
|
||||||
|
|
||||||
case Oid.INT8:
|
|
||||||
long l = ByteConverter.int8((byte[]) paramValue, 0);
|
|
||||||
- return quoteAndCast(Long.toString(l), "int8", standardConformingStrings);
|
|
||||||
+ textValue = Long.toString(l);
|
|
||||||
+ type = "int8";
|
|
||||||
+ break;
|
|
||||||
|
|
||||||
case Oid.FLOAT4:
|
|
||||||
float f = ByteConverter.float4((byte[]) paramValue, 0);
|
|
||||||
if (Float.isNaN(f)) {
|
|
||||||
return "('NaN'::real)";
|
|
||||||
}
|
|
||||||
- return quoteAndCast(Float.toString(f), "float", standardConformingStrings);
|
|
||||||
+ textValue = Float.toString(f);
|
|
||||||
+ type = "real";
|
|
||||||
+ break;
|
|
||||||
|
|
||||||
case Oid.FLOAT8:
|
|
||||||
double d = ByteConverter.float8((byte[]) paramValue, 0);
|
|
||||||
if (Double.isNaN(d)) {
|
|
||||||
return "('NaN'::double precision)";
|
|
||||||
}
|
|
||||||
- return quoteAndCast(Double.toString(d), "double precision", standardConformingStrings);
|
|
||||||
+ textValue = Double.toString(d);
|
|
||||||
+ type = "double precision";
|
|
||||||
+ break;
|
|
||||||
|
|
||||||
case Oid.NUMERIC:
|
|
||||||
Number n = ByteConverter.numeric((byte[]) paramValue);
|
|
||||||
@@ -269,44 +281,55 @@ class SimpleParameterList implements V3ParameterList {
|
|
||||||
assert ((Double) n).isNaN();
|
|
||||||
return "('NaN'::numeric)";
|
|
||||||
}
|
|
||||||
- return n.toString();
|
|
||||||
+ textValue = n.toString();
|
|
||||||
+ type = "numeric";
|
|
||||||
+ break;
|
|
||||||
|
|
||||||
case Oid.UUID:
|
|
||||||
- String uuid =
|
|
||||||
+ textValue =
|
|
||||||
new UUIDArrayAssistant().buildElement((byte[]) paramValue, 0, 16).toString();
|
|
||||||
- return quoteAndCast(uuid, "uuid", standardConformingStrings);
|
|
||||||
+ type = "uuid";
|
|
||||||
+ break;
|
|
||||||
|
|
||||||
case Oid.POINT:
|
|
||||||
PGpoint pgPoint = new PGpoint();
|
|
||||||
pgPoint.setByteValue((byte[]) paramValue, 0);
|
|
||||||
- return quoteAndCast(pgPoint.toString(), "point", standardConformingStrings);
|
|
||||||
+ textValue = pgPoint.toString();
|
|
||||||
+ type = "point";
|
|
||||||
+ break;
|
|
||||||
|
|
||||||
case Oid.BOX:
|
|
||||||
PGbox pgBox = new PGbox();
|
|
||||||
pgBox.setByteValue((byte[]) paramValue, 0);
|
|
||||||
- return quoteAndCast(pgBox.toString(), "box", standardConformingStrings);
|
|
||||||
+ textValue = pgBox.toString();
|
|
||||||
+ type = "box";
|
|
||||||
+ break;
|
|
||||||
+
|
|
||||||
+ default:
|
|
||||||
+ return "?";
|
|
||||||
}
|
|
||||||
- return "?";
|
|
||||||
} else {
|
|
||||||
- String param = paramValue.toString();
|
|
||||||
+ textValue = paramValue.toString();
|
|
||||||
int paramType = paramTypes[index];
|
|
||||||
if (paramType == Oid.TIMESTAMP) {
|
|
||||||
- return quoteAndCast(param, "timestamp", standardConformingStrings);
|
|
||||||
+ type = "timestamp";
|
|
||||||
} else if (paramType == Oid.TIMESTAMPTZ) {
|
|
||||||
- return quoteAndCast(param, "timestamp with time zone", standardConformingStrings);
|
|
||||||
+ type = "timestamp with time zone";
|
|
||||||
} else if (paramType == Oid.TIME) {
|
|
||||||
- return quoteAndCast(param, "time", standardConformingStrings);
|
|
||||||
+ type = "time";
|
|
||||||
} else if (paramType == Oid.TIMETZ) {
|
|
||||||
- return quoteAndCast(param, "time with time zone", standardConformingStrings);
|
|
||||||
+ type = "time with time zone";
|
|
||||||
} else if (paramType == Oid.DATE) {
|
|
||||||
- return quoteAndCast(param, "date", standardConformingStrings);
|
|
||||||
+ type = "date";
|
|
||||||
} else if (paramType == Oid.INTERVAL) {
|
|
||||||
- return quoteAndCast(param, "interval", standardConformingStrings);
|
|
||||||
+ type = "interval";
|
|
||||||
} else if (paramType == Oid.NUMERIC) {
|
|
||||||
- return quoteAndCast(param, "numeric", standardConformingStrings);
|
|
||||||
+ type = "numeric";
|
|
||||||
+ } else {
|
|
||||||
+ type = null;
|
|
||||||
}
|
|
||||||
- return quoteAndCast(param, null, standardConformingStrings);
|
|
||||||
}
|
|
||||||
+ return quoteAndCast(textValue, type, standardConformingStrings);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
diff --git a/src/test/java/org/postgresql/jdbc/ParameterInjectionTest.java b/src/test/java/org/postgresql/jdbc/ParameterInjectionTest.java
|
|
||||||
index 2a33acd..10c0af3 100644
|
|
||||||
--- a/src/test/java/org/postgresql/jdbc/ParameterInjectionTest.java
|
|
||||||
+++ b/src/test/java/org/postgresql/jdbc/ParameterInjectionTest.java
|
|
||||||
@@ -12,56 +12,133 @@ import org.postgresql.test.TestUtil;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
+import java.math.BigDecimal;
|
|
||||||
import java.sql.Connection;
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
+import java.sql.SQLException;
|
|
||||||
|
|
||||||
public class ParameterInjectionTest {
|
|
||||||
- @Test
|
|
||||||
- public void negateParameter() throws Exception {
|
|
||||||
- try (Connection conn = TestUtil.openDB()) {
|
|
||||||
- PreparedStatement stmt = conn.prepareStatement("SELECT -?");
|
|
||||||
+ private interface ParameterBinder {
|
|
||||||
+ void bind(PreparedStatement stmt) throws SQLException;
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- stmt.setInt(1, 1);
|
|
||||||
- try (ResultSet rs = stmt.executeQuery()) {
|
|
||||||
- assertTrue(rs.next());
|
|
||||||
- assertEquals(1, rs.getMetaData().getColumnCount(), "number of result columns must match");
|
|
||||||
- int value = rs.getInt(1);
|
|
||||||
- assertEquals(-1, value, "Input value 1");
|
|
||||||
- }
|
|
||||||
+ private void testParamInjection(ParameterBinder bindPositiveOne, ParameterBinder bindNegativeOne)
|
|
||||||
+ throws SQLException {
|
|
||||||
+ try (Connection conn = TestUtil.openDB()) {
|
|
||||||
+ {
|
|
||||||
+ PreparedStatement stmt = conn.prepareStatement("SELECT -?");
|
|
||||||
+ bindPositiveOne.bind(stmt);
|
|
||||||
+ try (ResultSet rs = stmt.executeQuery()) {
|
|
||||||
+ assertTrue(rs.next());
|
|
||||||
+ assertEquals(1, rs.getMetaData().getColumnCount(),
|
|
||||||
+ "number of result columns must match");
|
|
||||||
+ int value = rs.getInt(1);
|
|
||||||
+ assertEquals(-1, value);
|
|
||||||
+ }
|
|
||||||
+ bindNegativeOne.bind(stmt);
|
|
||||||
+ try (ResultSet rs = stmt.executeQuery()) {
|
|
||||||
+ assertTrue(rs.next());
|
|
||||||
+ assertEquals(1, rs.getMetaData().getColumnCount(),
|
|
||||||
+ "number of result columns must match");
|
|
||||||
+ int value = rs.getInt(1);
|
|
||||||
+ assertEquals(1, value);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ {
|
|
||||||
+ PreparedStatement stmt = conn.prepareStatement("SELECT -?, ?");
|
|
||||||
+ bindPositiveOne.bind(stmt);
|
|
||||||
+ stmt.setString(2, "\nWHERE false --");
|
|
||||||
+ try (ResultSet rs = stmt.executeQuery()) {
|
|
||||||
+ assertTrue(rs.next(), "ResultSet should contain a row");
|
|
||||||
+ assertEquals(2, rs.getMetaData().getColumnCount(),
|
|
||||||
+ "rs.getMetaData().getColumnCount(");
|
|
||||||
+ int value = rs.getInt(1);
|
|
||||||
+ assertEquals(-1, value);
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- stmt.setInt(1, -1);
|
|
||||||
- try (ResultSet rs = stmt.executeQuery()) {
|
|
||||||
- assertTrue(rs.next());
|
|
||||||
- assertEquals(1, rs.getMetaData().getColumnCount(), "number of result columns must match");
|
|
||||||
- int value = rs.getInt(1);
|
|
||||||
- assertEquals(1, value, "Input value -1");
|
|
||||||
- }
|
|
||||||
+ bindNegativeOne.bind(stmt);
|
|
||||||
+ stmt.setString(2, "\nWHERE false --");
|
|
||||||
+ try (ResultSet rs = stmt.executeQuery()) {
|
|
||||||
+ assertTrue(rs.next(), "ResultSet should contain a row");
|
|
||||||
+ assertEquals(2, rs.getMetaData().getColumnCount(), "rs.getMetaData().getColumnCount(");
|
|
||||||
+ int value = rs.getInt(1);
|
|
||||||
+ assertEquals(1, value);
|
|
||||||
}
|
|
||||||
+
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- @Test
|
|
||||||
- public void negateParameterWithContinuation() throws Exception {
|
|
||||||
- try (Connection conn = TestUtil.openDB()) {
|
|
||||||
- PreparedStatement stmt = conn.prepareStatement("SELECT -?, ?");
|
|
||||||
+ @Test
|
|
||||||
+ public void handleInt2() throws SQLException {
|
|
||||||
+ testParamInjection(
|
|
||||||
+ stmt -> {
|
|
||||||
+ stmt.setShort(1, (short) 1);
|
|
||||||
+ },
|
|
||||||
+ stmt -> {
|
|
||||||
+ stmt.setShort(1, (short) -1);
|
|
||||||
+ }
|
|
||||||
+ );
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- stmt.setInt(1, 1);
|
|
||||||
- stmt.setString(2, "\nWHERE false --");
|
|
||||||
- try (ResultSet rs = stmt.executeQuery()) {
|
|
||||||
- assertTrue(rs.next(), "ResultSet should contain a row");
|
|
||||||
- assertEquals(2, rs.getMetaData().getColumnCount(), "rs.getMetaData().getColumnCount(");
|
|
||||||
- int value = rs.getInt(1);
|
|
||||||
- assertEquals(-1, value);
|
|
||||||
- }
|
|
||||||
+ @Test
|
|
||||||
+ public void handleInt4() throws SQLException {
|
|
||||||
+ testParamInjection(
|
|
||||||
+ stmt -> {
|
|
||||||
+ stmt.setInt(1, 1);
|
|
||||||
+ },
|
|
||||||
+ stmt -> {
|
|
||||||
+ stmt.setInt(1, -1);
|
|
||||||
+ }
|
|
||||||
+ );
|
|
||||||
+ }
|
|
||||||
|
|
||||||
- stmt.setInt(1, -1);
|
|
||||||
- stmt.setString(2, "\nWHERE false --");
|
|
||||||
- try (ResultSet rs = stmt.executeQuery()) {
|
|
||||||
- assertTrue(rs.next(), "ResultSet should contain a row");
|
|
||||||
- assertEquals(2, rs.getMetaData().getColumnCount(), "rs.getMetaData().getColumnCount(");
|
|
||||||
- int value = rs.getInt(1);
|
|
||||||
- assertEquals(1, value);
|
|
||||||
- }
|
|
||||||
+ @Test
|
|
||||||
+ public void handleBigInt() throws SQLException {
|
|
||||||
+ testParamInjection(
|
|
||||||
+ stmt -> {
|
|
||||||
+ stmt.setLong(1, (long) 1);
|
|
||||||
+ },
|
|
||||||
+ stmt -> {
|
|
||||||
+ stmt.setLong(1, (long) -1);
|
|
||||||
}
|
|
||||||
- }
|
|
||||||
+ );
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ @Test
|
|
||||||
+ public void handleNumeric() throws SQLException {
|
|
||||||
+ testParamInjection(
|
|
||||||
+ stmt -> {
|
|
||||||
+ stmt.setBigDecimal(1, new BigDecimal("1"));
|
|
||||||
+ },
|
|
||||||
+ stmt -> {
|
|
||||||
+ stmt.setBigDecimal(1, new BigDecimal("-1"));
|
|
||||||
+ }
|
|
||||||
+ );
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ @Test
|
|
||||||
+ public void handleFloat() throws SQLException {
|
|
||||||
+ testParamInjection(
|
|
||||||
+ stmt -> {
|
|
||||||
+ stmt.setFloat(1, 1);
|
|
||||||
+ },
|
|
||||||
+ stmt -> {
|
|
||||||
+ stmt.setFloat(1, -1);
|
|
||||||
+ }
|
|
||||||
+ );
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ @Test
|
|
||||||
+ public void handleDouble() throws SQLException {
|
|
||||||
+ testParamInjection(
|
|
||||||
+ stmt -> {
|
|
||||||
+ stmt.setDouble(1, 1);
|
|
||||||
+ },
|
|
||||||
+ stmt -> {
|
|
||||||
+ stmt.setDouble(1, -1);
|
|
||||||
+ }
|
|
||||||
+ );
|
|
||||||
+ }
|
|
||||||
}
|
|
||||||
--
|
|
||||||
2.33.0
|
|
||||||
|
|
||||||
Binary file not shown.
@ -1,121 +0,0 @@
|
|||||||
Name: postgresql-jdbc
|
|
||||||
Summary: Postgresql JDBC Driver
|
|
||||||
Version: 42.4.1
|
|
||||||
Release: 3
|
|
||||||
License: BSD
|
|
||||||
URL: http://jdbc.postgresql.org/
|
|
||||||
|
|
||||||
Source0: https://repo1.maven.org/maven2/org/postgresql/postgresql/%{version}/postgresql-%{version}-jdbc-src.tar.gz
|
|
||||||
Patch0: CVE-2022-41946.patch
|
|
||||||
# https://github.com/pgjdbc/pgjdbc/commit/e479be16967ae20af1bd57187738d5243052bbee
|
|
||||||
Patch1: CVE-2024-1597-1.patch
|
|
||||||
# https://github.com/pgjdbc/pgjdbc/commit/fe002b31f2c7dcf7e2fe75fe7fd18df4e4503abf
|
|
||||||
Patch2: CVE-2024-1597-2.patch
|
|
||||||
|
|
||||||
BuildRequires: maven-local java-comment-preprocessor properties-maven-plugin classloader-leak-test-framework
|
|
||||||
BuildRequires: maven-enforcer-plugin maven-plugin-bundle maven-plugin-build-helper java-devel >= 1.8
|
|
||||||
BuildRequires: mvn(org.apache.maven.plugins:maven-clean-plugin) mvn(com.ongres.scram:client)
|
|
||||||
BuildRequires: mvn(org.apache.maven.surefire:surefire-junit-platform)
|
|
||||||
BuildRequires: mvn(org.junit.jupiter:junit-jupiter-api)
|
|
||||||
BuildRequires: mvn(org.junit.jupiter:junit-jupiter-engine)
|
|
||||||
BuildRequires: mvn(org.junit.jupiter:junit-jupiter-params)
|
|
||||||
BuildRequires: mvn(org.junit.vintage:junit-vintage-engine)
|
|
||||||
|
|
||||||
Obsoletes: %{name}-parent-poms < 42.2.2-2
|
|
||||||
Provides: pgjdbc = %version-%release
|
|
||||||
|
|
||||||
BuildArch: noarch
|
|
||||||
|
|
||||||
%description
|
|
||||||
PostgreSQL JDBC Driver (PgJDBC for short) allows Java programs to connect to
|
|
||||||
a PostgreSQL database using standard, database independent Java code. Is an
|
|
||||||
open source JDBC driver written in Pure Java (Type 4), and communicates in
|
|
||||||
the PostgreSQL native network protocol.
|
|
||||||
|
|
||||||
%package javadoc
|
|
||||||
Summary: API docs for %{name}
|
|
||||||
|
|
||||||
%description javadoc
|
|
||||||
This package contains the API Documentation for %{name}.
|
|
||||||
|
|
||||||
%package_help
|
|
||||||
|
|
||||||
%prep
|
|
||||||
%setup -c -q
|
|
||||||
mv postgresql-%{version}-jdbc-src/* .
|
|
||||||
%patch0 -p1
|
|
||||||
%patch1 -p1
|
|
||||||
%patch2 -p1
|
|
||||||
find -type f \( -name "*.jar" -or -name "*.class" \) | xargs rm -f
|
|
||||||
%pom_xpath_remove "pom:plugin[pom:artifactId = 'maven-shade-plugin']"
|
|
||||||
%mvn_file org.postgresql:postgresql %{name}/postgresql %{name} postgresql
|
|
||||||
%mvn_package ":*{parent,versions,prevjre}*" __noinstall
|
|
||||||
%mvn_alias org.postgresql:postgresql postgresql:postgresql
|
|
||||||
|
|
||||||
install -d pgjdbc/target/generated-sources/annotations
|
|
||||||
|
|
||||||
%pom_remove_dep uk.org.webcompere:system-stubs-jupiter
|
|
||||||
|
|
||||||
# remove tests that depend on the system-stubs-jupiter
|
|
||||||
rm src/test/java/org/postgresql/test/jdbc2/DriverTest.java \
|
|
||||||
src/test/java/org/postgresql/util/OSUtilTest.java \
|
|
||||||
src/test/java/org/postgresql/util/PGPropertyPasswordParserTest.java \
|
|
||||||
src/test/java/org/postgresql/util/PGPropertyServiceParserTest.java \
|
|
||||||
src/test/java/org/postgresql/util/StubEnvironmentAndProperties.java
|
|
||||||
|
|
||||||
%build
|
|
||||||
opts="-f"
|
|
||||||
%mvn_build $opts -- -DwaffleEnabled=false \
|
|
||||||
-DosgiEnabled=false \
|
|
||||||
-DexcludePackageNames=org.postgresql.osgi:org.postgresql.sspi
|
|
||||||
|
|
||||||
%install
|
|
||||||
%mvn_install
|
|
||||||
find %{_buildrootdir} -name "%{name}.xml" | xargs sed -i '/<metadata xmlns/{n;s/<uuid>[[:alnum:]]\{8\}-[[:alnum:]]\{4\}-[[:alnum:]]\{4\}-[[:alnum:]]\{4\}-[[:alnum:]]\{12\}<\/uuid>/<uuid>cb98d437-dced-4915-8d37-d4da43bac7f5<\/uuid>/g}'
|
|
||||||
find %{_buildrootdir} -name "%{name}.xml" | xargs sed -i '/postgresql.jar<\/path>/{n;s/<uuid>[[:alnum:]]\{8\}-[[:alnum:]]\{4\}-[[:alnum:]]\{4\}-[[:alnum:]]\{4\}-[[:alnum:]]\{12\}<\/uuid>/<uuid>ea4aac95-7377-4a79-bb46-78fcebb4104d<\/uuid>/g}'
|
|
||||||
find %{_buildrootdir} -name "%{name}.xml" | xargs sed -i '/postgresql.pom<\/path>/{n;s/<uuid>[[:alnum:]]\{8\}-[[:alnum:]]\{4\}-[[:alnum:]]\{4\}-[[:alnum:]]\{4\}-[[:alnum:]]\{12\}<\/uuid>/<uuid>0142aef6-864f-4570-aa9e-364f1cd7829c<\/uuid>/g}'
|
|
||||||
find %{_buildrootdir} -name "%{name}.xml" | xargs sed -i '/pgjdbc-aggregate.pom<\/path>/{n;s/<uuid>[[:alnum:]]\{8\}-[[:alnum:]]\{4\}-[[:alnum:]]\{4\}-[[:alnum:]]\{4\}-[[:alnum:]]\{12\}<\/uuid>/<uuid>f8e1101c-f6b2-40a9-8b31-7b54e7767880<\/uuid>/g}'
|
|
||||||
|
|
||||||
%files -f .mfiles
|
|
||||||
%license LICENSE
|
|
||||||
|
|
||||||
%files javadoc -f .mfiles-javadoc
|
|
||||||
%license LICENSE
|
|
||||||
|
|
||||||
%files help
|
|
||||||
%doc README.md
|
|
||||||
|
|
||||||
%changelog
|
|
||||||
* Mon Feb 26 2024 yaoxin <yao_xin001@hoperun.com> - 42.4.1-3
|
|
||||||
- Fix CVE-2024-1597
|
|
||||||
|
|
||||||
* Fri Jun 16 2023 yaoxin <yao_xin001@hoperun.com> - 42.4.1-2
|
|
||||||
- Fix CVE-2022-41946
|
|
||||||
|
|
||||||
* Tue Aug 09 2022 yaoxin <yaoxin30@h-partners.com> - 42.4.1-1
|
|
||||||
- Update to 42.4.1 to fix CVE-2022-31197
|
|
||||||
|
|
||||||
* Wed Feb 16 2022 houyingchao <houyingchao@huawei.com> - 42.2.25-1
|
|
||||||
- Upgrade to 42.2.25
|
|
||||||
- Fix CVE-2022-21724
|
|
||||||
|
|
||||||
* Thu Dec 11 2019 caomeng<caomeng5@huawei.com> - 42.2.4-4
|
|
||||||
- Package init
|
|
||||||
|
|
||||||
* Wed Aug 21 2019 renxudong <renxudong1@huawei.com> - 42.2.4-3
|
|
||||||
- Type:enhancement
|
|
||||||
- ID:NA
|
|
||||||
- SUG:NA
|
|
||||||
- DESC:revise patch name
|
|
||||||
|
|
||||||
* Tue Aug 20 2019 huangzheng <huangzheng22@huawei.com> - 42.2.4-2
|
|
||||||
- Type:enhancement
|
|
||||||
- ID:NA
|
|
||||||
- SUG:NA
|
|
||||||
- DESC:remove sensitive information
|
|
||||||
|
|
||||||
* Sun Apr 28 2019 wangjia <wangjia55@huawei.com> - 42.2.4-1.h1
|
|
||||||
- Type:enhancement
|
|
||||||
- ID:NA
|
|
||||||
- SUG:NA
|
|
||||||
- DESC:disable the failed tests that caused by BEP to repair binary diffrence
|
|
||||||
Loading…
x
Reference in New Issue
Block a user