|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * IDENTIFICATION
|
11 |
| - * $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.179 2006/01/25 20:44:32 tgl Exp $ |
| 11 | + * $PostgreSQL: pgsql/src/interfaces/libpq/fe-exec.c,v 1.180 2006/03/03 20:57:32 tgl Exp $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
15 | 15 | #include "postgres_fe.h"
|
16 | 16 |
|
17 |
| -#include <errno.h> |
18 | 17 | #include <ctype.h>
|
19 | 18 | #include <fcntl.h>
|
20 | 19 |
|
@@ -2168,49 +2167,57 @@ PQoidValue(const PGresult *res)
|
2168 | 2167 |
|
2169 | 2168 | /*
|
2170 | 2169 | * PQcmdTuples -
|
2171 |
| - * If the last command was an INSERT/UPDATE/DELETE/MOVE/FETCH, return a |
2172 |
| - * string containing the number of inserted/affected tuples. If not, |
| 2170 | + * If the last command was INSERT/UPDATE/DELETE/MOVE/FETCH/COPY, return |
| 2171 | + * a string containing the number of inserted/affected tuples. If not, |
2173 | 2172 | * return "".
|
2174 | 2173 | *
|
2175 | 2174 | * XXX: this should probably return an int
|
2176 | 2175 | */
|
2177 | 2176 | char *
|
2178 | 2177 | PQcmdTuples(PGresult *res)
|
2179 | 2178 | {
|
2180 |
| - char *p; |
| 2179 | + char *p, *c; |
2181 | 2180 |
|
2182 | 2181 | if (!res)
|
2183 | 2182 | return "";
|
2184 | 2183 |
|
2185 | 2184 | if (strncmp(res->cmdStatus, "INSERT ", 7) == 0)
|
2186 | 2185 | {
|
2187 |
| - p = res->cmdStatus + 6; |
2188 |
| - p++; |
2189 |
| - /* INSERT: skip oid */ |
2190 |
| - while (*p != ' ' && *p) |
| 2186 | + p = res->cmdStatus + 7; |
| 2187 | + /* INSERT: skip oid and space */ |
| 2188 | + while (*p && *p != ' ') |
2191 | 2189 | p++;
|
| 2190 | + if (*p == 0) |
| 2191 | + goto interpret_error; /* no space? */ |
| 2192 | + p++; |
2192 | 2193 | }
|
2193 | 2194 | else if (strncmp(res->cmdStatus, "DELETE ", 7) == 0 ||
|
2194 | 2195 | strncmp(res->cmdStatus, "UPDATE ", 7) == 0)
|
2195 |
| - p = res->cmdStatus + 6; |
| 2196 | + p = res->cmdStatus + 7; |
2196 | 2197 | else if (strncmp(res->cmdStatus, "FETCH ", 6) == 0)
|
| 2198 | + p = res->cmdStatus + 6; |
| 2199 | + else if (strncmp(res->cmdStatus, "MOVE ", 5) == 0 || |
| 2200 | + strncmp(res->cmdStatus, "COPY ", 5) == 0) |
2197 | 2201 | p = res->cmdStatus + 5;
|
2198 |
| - else if (strncmp(res->cmdStatus, "MOVE ", 5) == 0) |
2199 |
| - p = res->cmdStatus + 4; |
2200 | 2202 | else
|
2201 | 2203 | return "";
|
2202 | 2204 |
|
2203 |
| - p++; |
2204 |
| - |
2205 |
| - if (*p == 0) |
| 2205 | + /* check that we have an integer (at least one digit, nothing else) */ |
| 2206 | + for (c = p; *c; c++) |
2206 | 2207 | {
|
2207 |
| - pqInternalNotice(&res->noticeHooks, |
2208 |
| - "could not interpret result from server: %s", |
2209 |
| - res->cmdStatus); |
2210 |
| - return ""; |
| 2208 | + if (!isdigit((unsigned char) *c)) |
| 2209 | + goto interpret_error; |
2211 | 2210 | }
|
| 2211 | + if (c == p) |
| 2212 | + goto interpret_error; |
2212 | 2213 |
|
2213 | 2214 | return p;
|
| 2215 | + |
| 2216 | +interpret_error: |
| 2217 | + pqInternalNotice(&res->noticeHooks, |
| 2218 | + "could not interpret result from server: %s", |
| 2219 | + res->cmdStatus); |
| 2220 | + return ""; |
2214 | 2221 | }
|
2215 | 2222 |
|
2216 | 2223 | /*
|
|
0 commit comments