mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Fix to prevent SQL injection attacks for code calling setObject(int,Object,int)
where Object is a user supplied String and the type is a numeric type (i.e. INTEGER,LONG,etc). Also applied a patch from Kim Ho that fixes compile problems under jdk1.2 Modified Files: jdbc/org/postgresql/Driver.java.in jdbc/org/postgresql/jdbc1/AbstractJdbc1Statement.java
This commit is contained in:
parent
11cb598c39
commit
0a73f69cb4
@ -6,7 +6,7 @@
|
|||||||
* Copyright (c) 2003, PostgreSQL Global Development Group
|
* Copyright (c) 2003, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/Driver.java.in,v 1.32 2003/07/21 20:48:31 barry Exp $
|
* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/Attic/Driver.java.in,v 1.33 2003/07/22 05:17:09 barry Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -503,6 +503,6 @@ public class Driver implements java.sql.Driver
|
|||||||
|
|
||||||
|
|
||||||
//The build number should be incremented for every new build
|
//The build number should be incremented for every new build
|
||||||
private static int m_buildNumber = 206;
|
private static int m_buildNumber = 207;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ import java.sql.Timestamp;
|
|||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.27 2003/07/09 05:12:04 barry Exp $
|
/* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.28 2003/07/22 05:17:09 barry Exp $
|
||||||
* This class defines methods of the jdbc1 specification. This class is
|
* This class defines methods of the jdbc1 specification. This class is
|
||||||
* extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
|
* extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
|
||||||
* methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
|
* methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
|
||||||
@ -1035,22 +1035,37 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
|
|||||||
{
|
{
|
||||||
sbuf.setLength(0);
|
sbuf.setLength(0);
|
||||||
sbuf.ensureCapacity(x.length() + (int)(x.length() / 10));
|
sbuf.ensureCapacity(x.length() + (int)(x.length() / 10));
|
||||||
int i;
|
|
||||||
|
|
||||||
sbuf.append('\'');
|
sbuf.append('\'');
|
||||||
for (i = 0 ; i < x.length() ; ++i)
|
escapeString(x, sbuf);
|
||||||
{
|
|
||||||
char c = x.charAt(i);
|
|
||||||
if (c == '\\' || c == '\'')
|
|
||||||
sbuf.append((char)'\\');
|
|
||||||
sbuf.append(c);
|
|
||||||
}
|
|
||||||
sbuf.append('\'');
|
sbuf.append('\'');
|
||||||
bind(parameterIndex, sbuf.toString(), type);
|
bind(parameterIndex, sbuf.toString(), type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String escapeString(String p_input) {
|
||||||
|
// use the shared buffer object. Should never clash but this makes
|
||||||
|
// us thread safe!
|
||||||
|
synchronized (sbuf)
|
||||||
|
{
|
||||||
|
sbuf.setLength(0);
|
||||||
|
sbuf.ensureCapacity(p_input.length());
|
||||||
|
escapeString(p_input, sbuf);
|
||||||
|
return sbuf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void escapeString(String p_input, StringBuffer p_output) {
|
||||||
|
for (int i = 0 ; i < p_input.length() ; ++i)
|
||||||
|
{
|
||||||
|
char c = p_input.charAt(i);
|
||||||
|
if (c == '\\' || c == '\'')
|
||||||
|
p_output.append((char)'\\');
|
||||||
|
p_output.append(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set a parameter to a Java array of bytes. The driver converts this
|
* Set a parameter to a Java array of bytes. The driver converts this
|
||||||
* to a SQL VARBINARY or LONGVARBINARY (depending on the argument's
|
* to a SQL VARBINARY or LONGVARBINARY (depending on the argument's
|
||||||
@ -1467,7 +1482,7 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
|
|||||||
if (x instanceof Boolean)
|
if (x instanceof Boolean)
|
||||||
bind(parameterIndex,((Boolean)x).booleanValue() ? "1" :"0", PG_BOOLEAN);
|
bind(parameterIndex,((Boolean)x).booleanValue() ? "1" :"0", PG_BOOLEAN);
|
||||||
else
|
else
|
||||||
bind(parameterIndex, x.toString(), PG_INTEGER);
|
bind(parameterIndex, escapeString(x.toString()), PG_INTEGER);
|
||||||
break;
|
break;
|
||||||
case Types.TINYINT:
|
case Types.TINYINT:
|
||||||
case Types.SMALLINT:
|
case Types.SMALLINT:
|
||||||
@ -1480,7 +1495,7 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
|
|||||||
if (x instanceof Boolean)
|
if (x instanceof Boolean)
|
||||||
bind(parameterIndex, ((Boolean)x).booleanValue() ? "1" : "0", PG_BOOLEAN);
|
bind(parameterIndex, ((Boolean)x).booleanValue() ? "1" : "0", PG_BOOLEAN);
|
||||||
else
|
else
|
||||||
bind(parameterIndex, x.toString(), PG_NUMERIC);
|
bind(parameterIndex, escapeString(x.toString()), PG_NUMERIC);
|
||||||
break;
|
break;
|
||||||
case Types.CHAR:
|
case Types.CHAR:
|
||||||
case Types.VARCHAR:
|
case Types.VARCHAR:
|
||||||
@ -1913,15 +1928,12 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There are a lot of setXXX classes which all basically do
|
* Note if s is a String it should be escaped by the caller to avoid SQL
|
||||||
* the same thing. We need a method which actually does the
|
* injection attacks. It is not done here for efficency reasons as
|
||||||
* set for us.
|
* most calls to this method do not require escaping as the source
|
||||||
*
|
* of the string is known safe (i.e. Integer.toString())
|
||||||
* @param paramIndex the index into the inString
|
|
||||||
* @param s a string to be stored
|
|
||||||
* @exception SQLException if something goes wrong
|
|
||||||
*/
|
*/
|
||||||
protected void bind(int paramIndex, Object s, String type) throws SQLException
|
private void bind(int paramIndex, Object s, String type) throws SQLException
|
||||||
{
|
{
|
||||||
if (paramIndex < 1 || paramIndex > m_binds.length)
|
if (paramIndex < 1 || paramIndex > m_binds.length)
|
||||||
throw new PSQLException("postgresql.prep.range");
|
throw new PSQLException("postgresql.prep.range");
|
||||||
@ -2072,7 +2084,9 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
|
|||||||
if (timezoneLocation>7 && timezoneLocation+3 == s.length())
|
if (timezoneLocation>7 && timezoneLocation+3 == s.length())
|
||||||
{
|
{
|
||||||
timezone = Integer.parseInt(s.substring(timezoneLocation+1,s.length()));
|
timezone = Integer.parseInt(s.substring(timezoneLocation+1,s.length()));
|
||||||
localoffset = java.util.Calendar.getInstance().getTimeZone().getOffset(millis);
|
localoffset = java.util.Calendar.getInstance().getTimeZone().getRawOffset();
|
||||||
|
if (java.util.Calendar.getInstance().getTimeZone().inDaylightTime(new java.sql.Date(millis)))
|
||||||
|
localoffset += 60*60*1000;
|
||||||
if (s.charAt(timezoneLocation)=='+')
|
if (s.charAt(timezoneLocation)=='+')
|
||||||
timezone*=-1;
|
timezone*=-1;
|
||||||
}
|
}
|
||||||
@ -2101,7 +2115,9 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
|
|||||||
if (timezoneLocation != -1 && timezoneLocation+3 == s.length())
|
if (timezoneLocation != -1 && timezoneLocation+3 == s.length())
|
||||||
{
|
{
|
||||||
timezone = Integer.parseInt(s.substring(timezoneLocation+1,s.length()));
|
timezone = Integer.parseInt(s.substring(timezoneLocation+1,s.length()));
|
||||||
localoffset = java.util.Calendar.getInstance().getTimeZone().getOffset(millis);
|
localoffset = java.util.Calendar.getInstance().getTimeZone().getRawOffset();
|
||||||
|
if (java.util.Calendar.getInstance().getTimeZone().inDaylightTime(new java.sql.Date(millis)))
|
||||||
|
localoffset += 60*60*1000;
|
||||||
if (s.charAt(timezoneLocation)=='+')
|
if (s.charAt(timezoneLocation)=='+')
|
||||||
timezone*=-1;
|
timezone*=-1;
|
||||||
}
|
}
|
||||||
@ -2146,7 +2162,9 @@ public abstract class AbstractJdbc1Statement implements BaseStatement
|
|||||||
if (timezoneLocation>8 && timezoneLocation+3 == s.length())
|
if (timezoneLocation>8 && timezoneLocation+3 == s.length())
|
||||||
{
|
{
|
||||||
timezone = Integer.parseInt(s.substring(timezoneLocation+1,s.length()));
|
timezone = Integer.parseInt(s.substring(timezoneLocation+1,s.length()));
|
||||||
localoffset = java.util.Calendar.getInstance().getTimeZone().getOffset(millis);
|
localoffset = java.util.Calendar.getInstance().getTimeZone().getRawOffset();
|
||||||
|
if (java.util.Calendar.getInstance().getTimeZone().inDaylightTime(new java.sql.Date(millis)))
|
||||||
|
localoffset += 60*60*1000;
|
||||||
if (s.charAt(timezoneLocation)=='+')
|
if (s.charAt(timezoneLocation)=='+')
|
||||||
timezone*=-1;
|
timezone*=-1;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user