2525import java .sql .Types ;
2626import java .util .Vector ;
2727
28- /* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.27 2003/07/09 05:12:04 barry Exp $
28+ /* $Header: /cvsroot/pgsql/src/interfaces/jdbc/org/postgresql/jdbc1/Attic/AbstractJdbc1Statement.java,v 1.28 2003/07/22 05:17:09 barry Exp $
2929 * This class defines methods of the jdbc1 specification. This class is
3030 * extended by org.postgresql.jdbc2.AbstractJdbc2Statement which adds the jdbc2
3131 * methods. The real Statement class (for jdbc1) is org.postgresql.jdbc1.Jdbc1Statement
@@ -1035,22 +1035,37 @@ public void setString(int parameterIndex, String x, String type) throws SQLExcep
10351035{
10361036sbuf .setLength (0 );
10371037sbuf .ensureCapacity (x .length () + (int )(x .length () /10 ));
1038- int i ;
1039-
10401038sbuf .append ('\'' );
1041- for (i =0 ;i <x .length () ; ++i )
1042- {
1043- char c =x .charAt (i );
1044- if (c =='\\' ||c =='\'' )
1045- sbuf .append ((char )'\\' );
1046- sbuf .append (c );
1047- }
1039+ escapeString (x ,sbuf );
10481040sbuf .append ('\'' );
10491041bind (parameterIndex ,sbuf .toString (),type );
10501042}
10511043}
10521044}
10531045
1046+ private String escapeString (String p_input ) {
1047+ // use the shared buffer object. Should never clash but this makes
1048+ // us thread safe!
1049+ synchronized (sbuf )
1050+ {
1051+ sbuf .setLength (0 );
1052+ sbuf .ensureCapacity (p_input .length ());
1053+ escapeString (p_input ,sbuf );
1054+ return sbuf .toString ();
1055+ }
1056+ }
1057+
1058+ private void escapeString (String p_input ,StringBuffer p_output ) {
1059+ for (int i =0 ;i <p_input .length () ; ++i )
1060+ {
1061+ char c =p_input .charAt (i );
1062+ if (c =='\\' ||c =='\'' )
1063+ p_output .append ((char )'\\' );
1064+ p_output .append (c );
1065+ }
1066+ }
1067+
1068+
10541069/*
10551070 * Set a parameter to a Java array of bytes. The driver converts this
10561071 * to a SQL VARBINARY or LONGVARBINARY (depending on the argument's
@@ -1467,7 +1482,7 @@ public void setObject(int parameterIndex, Object x, int targetSqlType, int scale
14671482if (x instanceof Boolean )
14681483bind (parameterIndex ,((Boolean )x ).booleanValue () ?"1" :"0" ,PG_BOOLEAN );
14691484else
1470- bind (parameterIndex ,x .toString (),PG_INTEGER );
1485+ bind (parameterIndex ,escapeString ( x .toString () ),PG_INTEGER );
14711486break ;
14721487case Types .TINYINT :
14731488case Types .SMALLINT :
@@ -1480,7 +1495,7 @@ public void setObject(int parameterIndex, Object x, int targetSqlType, int scale
14801495if (x instanceof Boolean )
14811496bind (parameterIndex , ((Boolean )x ).booleanValue () ?"1" :"0" ,PG_BOOLEAN );
14821497else
1483- bind (parameterIndex ,x .toString (),PG_NUMERIC );
1498+ bind (parameterIndex ,escapeString ( x .toString () ),PG_NUMERIC );
14841499break ;
14851500case Types .CHAR :
14861501case Types .VARCHAR :
@@ -1913,15 +1928,12 @@ public String toString()
19131928}
19141929
19151930/*
1916- * There are a lot of setXXX classes which all basically do
1917- * the same thing.We need a method which actually does the
1918- * set for us.
1919- *
1920- * @param paramIndex the index into the inString
1921- * @param s a string to be stored
1922- * @exception SQLException if something goes wrong
1931+ * Note if s is a String it should be escaped by the caller to avoid SQL
1932+ * injection attacks. It is not done here for efficency reasons as
1933+ * most calls to this method do not require escaping as the source
1934+ * of the string is known safe (i.e. Integer.toString())
19231935 */
1924- protected void bind (int paramIndex ,Object s ,String type )throws SQLException
1936+ private void bind (int paramIndex ,Object s ,String type )throws SQLException
19251937{
19261938if (paramIndex <1 ||paramIndex >m_binds .length )
19271939throw new PSQLException ("postgresql.prep.range" );
@@ -2072,7 +2084,9 @@ private java.sql.Date dateFromString (String s) throws SQLException
20722084if (timezoneLocation >7 &&timezoneLocation +3 ==s .length ())
20732085{
20742086timezone =Integer .parseInt (s .substring (timezoneLocation +1 ,s .length ()));
2075- localoffset =java .util .Calendar .getInstance ().getTimeZone ().getOffset (millis );
2087+ localoffset =java .util .Calendar .getInstance ().getTimeZone ().getRawOffset ();
2088+ if (java .util .Calendar .getInstance ().getTimeZone ().inDaylightTime (new java .sql .Date (millis )))
2089+ localoffset +=60 *60 *1000 ;
20762090if (s .charAt (timezoneLocation )=='+' )
20772091timezone *=-1 ;
20782092}
@@ -2101,7 +2115,9 @@ private java.sql.Time timeFromString (String s) throws SQLException
21012115if (timezoneLocation != -1 &&timezoneLocation +3 ==s .length ())
21022116{
21032117timezone =Integer .parseInt (s .substring (timezoneLocation +1 ,s .length ()));
2104- localoffset =java .util .Calendar .getInstance ().getTimeZone ().getOffset (millis );
2118+ localoffset =java .util .Calendar .getInstance ().getTimeZone ().getRawOffset ();
2119+ if (java .util .Calendar .getInstance ().getTimeZone ().inDaylightTime (new java .sql .Date (millis )))
2120+ localoffset +=60 *60 *1000 ;
21052121if (s .charAt (timezoneLocation )=='+' )
21062122timezone *=-1 ;
21072123}
@@ -2146,7 +2162,9 @@ else if (timezoneLocation > 8)
21462162if (timezoneLocation >8 &&timezoneLocation +3 ==s .length ())
21472163{
21482164timezone =Integer .parseInt (s .substring (timezoneLocation +1 ,s .length ()));
2149- localoffset =java .util .Calendar .getInstance ().getTimeZone ().getOffset (millis );
2165+ localoffset =java .util .Calendar .getInstance ().getTimeZone ().getRawOffset ();
2166+ if (java .util .Calendar .getInstance ().getTimeZone ().inDaylightTime (new java .sql .Date (millis )))
2167+ localoffset +=60 *60 *1000 ;
21502168if (s .charAt (timezoneLocation )=='+' )
21512169timezone *=-1 ;
21522170}