Changeset 14724 in project


Ignore:
Timestamp:
05/21/09 19:17:39 (10 years ago)
Author:
sjamaan
Message:

Add escaping/unescaping and tests for that

Location:
release/4/postgresql/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • release/4/postgresql/trunk/postgresql.scm

    r14723 r14724  
    2121(module postgresql
    2222 (connect reset-connection disconnect connection?
    23   escape-string exec-query
     23  exec-query
    2424  result? result-rows result-columns result-column-name result-column-index
    2525  result-table-oid result-table-column-index result-column-format
    2626  result-column-type result-column-type-modifier result-value
    2727  result-affected-rows result-inserted-oid
    28   invalid-oid
     28  invalid-oid escape-string escape-bytea unescape-bytea
     29
    2930  query-fold-left query-for-each query-tuples named-tuples)
    3031
     
    410411
    411412;;;;;;;;;;;;;;;;;;;;;;
    412 ;; Value handling
     413;; Value escaping
    413414;;;;;;;;;;;;;;;;;;;;;;
    414415
    415416(define (escape-string conn str)
    416417  (define %escape-string-conn
     418    ;; This could be more efficient by copying straight into a Scheme object.
     419    ;; Now it's being copied by PQescapeStringConn, and Chicken copies it again
     420    ;; This can allocate up to twice as much memory than the string actually
     421    ;; uses; in extreme cases this could be a problem.
    417422    (foreign-lambda* c-string* ((pointer conn) (c-string from) (int fromlen))
    418423                     "int err = 0; char *to;"
     
    420425                     "PQescapeStringConn(conn, to, from, fromlen, &err);"
    421426                     "if (err) {"
    422                      "  free(to);"
    423                      "  C_return(NULL);"
     427                     "        free(to);"
     428                     "        C_return(NULL);"
    424429                     "}"
    425430                     "C_return(to);"
     
    428433      (postgresql-error 'escape-string
    429434                        (conc "String escaping failed. "
    430                               (PQerrorMessage conn)))))
     435                              (PQerrorMessage conn)) conn str)))
     436
     437(define (escape-bytea conn str)
     438  (define %escape-bytea-conn
     439    ;; This must copy because libpq returns a malloced ptr...
     440    (foreign-safe-lambda* scheme-object ((pointer conn)
     441                                         ;; not copied/NUL interpreted:
     442                                         ((const unsigned-c-string*) from)
     443                                         (int fromlen))
     444                     "size_t tolen=0; C_word res, *fin; unsigned char *esc;"
     445                     "esc = PQescapeByteaConn(conn, from, (size_t)fromlen, &tolen);"
     446                     "if (esc == NULL)"
     447                     "        C_return(C_SCHEME_FALSE);"
     448                     "fin = C_alloc(C_bytestowords(tolen + sizeof(C_header)));"
     449                     "/* tolen includes the resulting NUL byte */"
     450                     "res = C_string(&fin, tolen - 1, (char *)esc);"
     451                     "PQfreemem(esc);"
     452                     "C_return(res);"
     453                     ))
     454  (or (%escape-bytea-conn conn str (string-length str))
     455      (postgresql-error 'escape-bytea
     456                        (conc "Byte array escaping failed. "
     457                              (PQerrorMessage conn)) conn str)))
     458
     459(define (unescape-bytea str)
     460  (define %unescape-bytea
     461    ;; This must copy because libpq returns a malloced ptr...
     462    (foreign-safe-lambda* scheme-object (((const unsigned-c-string*) from))
     463                     "size_t tolen=0; C_word res, *fin; unsigned char *unesc;"
     464                     "unesc = PQunescapeBytea(from, &tolen);"
     465                     "if (unesc == NULL)"
     466                     "        C_return(C_SCHEME_FALSE);"
     467                     "fin = C_alloc(C_bytestowords(tolen + sizeof(C_header)));"
     468                     "res = C_string(&fin, tolen, (char *)unesc);"
     469                     "PQfreemem(unesc);"
     470                     "C_return(res);"
     471                     ))
     472  (or (%unescape-bytea str)
     473      (postgresql-error 'unescape-bytea
     474                        "Byte array unescaping failed (out of memory?)" str)))
    431475
    432476;;;;;;;;;;;;;;;;;;;;;;;;;;;
  • release/4/postgresql/trunk/tests/run.scm

    r14723 r14724  
    185185                                   "INSERT INTO foo (bar) VALUES (1);"
    186186                                   "COMMIT;")))))))
     187
     188(test-group "value escaping"
     189  (test "String is escaped correctly"
     190        "What''s up?"
     191        (escape-string conn "What's up?"))
     192  (test "Bytea is escaped correctly"
     193        "What''s\\012up?"
     194        (escape-bytea conn "What's\nup?"))
     195  (test "Bytea is unescaped correctly"
     196        "What's\nup?"
     197        ;; The extra quote is dropped here because it wouldn't be returned
     198        ;; by pgsql either.
     199        (unescape-bytea "What's\\012up?")))
Note: See TracChangeset for help on using the changeset viewer.