Coverage Report

Created: 2022-07-08 00:21

/Users/erlendaasland/src/cpython.git/Modules/_sqlite/util.c
Line
Count
Source (jump to first uncovered line)
1
/* util.c - various utility functions
2
 *
3
 * Copyright (C) 2005-2010 Gerhard Häring <gh@ghaering.de>
4
 *
5
 * This file is part of pysqlite.
6
 *
7
 * This software is provided 'as-is', without any express or implied
8
 * warranty.  In no event will the authors be held liable for any damages
9
 * arising from the use of this software.
10
 *
11
 * Permission is granted to anyone to use this software for any purpose,
12
 * including commercial applications, and to alter it and redistribute it
13
 * freely, subject to the following restrictions:
14
 *
15
 * 1. The origin of this software must not be misrepresented; you must not
16
 *    claim that you wrote the original software. If you use this software
17
 *    in a product, an acknowledgment in the product documentation would be
18
 *    appreciated but is not required.
19
 * 2. Altered source versions must be plainly marked as such, and must not be
20
 *    misrepresented as being the original software.
21
 * 3. This notice may not be removed or altered from any source distribution.
22
 */
23
24
#include "module.h"
25
#include "connection.h"
26
27
// Returns non-NULL if a new exception should be raised
28
static PyObject *
29
get_exception_class(pysqlite_state *state, int errorcode)
30
112
{
31
112
    switch (errorcode) {
32
13
        case SQLITE_OK:
33
13
            PyErr_Clear();
34
13
            return NULL;
35
0
        case SQLITE_INTERNAL:
36
0
        case SQLITE_NOTFOUND:
37
0
            return state->InternalError;
38
2
        case SQLITE_NOMEM:
39
2
            return PyErr_NoMemory();
40
50
        case SQLITE_ERROR:
41
50
        case SQLITE_PERM:
42
53
        case SQLITE_ABORT:
43
56
        case SQLITE_BUSY:
44
56
        case SQLITE_LOCKED:
45
58
        case SQLITE_READONLY:
46
63
        case SQLITE_INTERRUPT:
47
63
        case SQLITE_IOERR:
48
63
        case SQLITE_FULL:
49
67
        case SQLITE_CANTOPEN:
50
67
        case SQLITE_PROTOCOL:
51
67
        case SQLITE_EMPTY:
52
67
        case SQLITE_SCHEMA:
53
67
            return state->OperationalError;
54
0
        case SQLITE_CORRUPT:
55
0
            return state->DatabaseError;
56
9
        case SQLITE_TOOBIG:
57
9
            return state->DataError;
58
10
        case SQLITE_CONSTRAINT:
59
10
        case SQLITE_MISMATCH:
60
10
            return state->IntegrityError;
61
0
        case SQLITE_MISUSE:
62
0
        case SQLITE_RANGE:
63
0
            return state->InterfaceError;
64
11
        default:
65
11
            return state->DatabaseError;
66
112
    }
67
112
}
68
69
static void
70
raise_exception(PyObject *type, int errcode, const char *errmsg)
71
97
{
72
97
    PyObject *exc = NULL;
73
97
    PyObject *args[] = { PyUnicode_FromString(errmsg), };
74
97
    if (args[0] == NULL) {
75
0
        goto exit;
76
0
    }
77
97
    exc = PyObject_Vectorcall(type, args, 1, NULL);
78
97
    Py_DECREF(args[0]);
79
97
    if (exc == NULL) {
80
0
        goto exit;
81
0
    }
82
83
97
    PyObject *code = PyLong_FromLong(errcode);
84
97
    if (code == NULL) {
85
0
        goto exit;
86
0
    }
87
97
    int rc = PyObject_SetAttrString(exc, "sqlite_errorcode", code);
88
97
    Py_DECREF(code);
89
97
    if (rc < 0) {
90
0
        goto exit;
91
0
    }
92
93
97
    const char *error_name = pysqlite_error_name(errcode);
94
97
    PyObject *name;
95
97
    if (error_name) {
96
97
        name = PyUnicode_FromString(error_name);
97
97
    }
98
0
    else {
99
0
        name = PyUnicode_InternFromString("unknown");
100
0
    }
101
97
    if (name == NULL) {
102
0
        goto exit;
103
0
    }
104
97
    rc = PyObject_SetAttrString(exc, "sqlite_errorname", name);
105
97
    Py_DECREF(name);
106
97
    if (rc < 0) {
107
0
        goto exit;
108
0
    }
109
110
97
    PyErr_SetObject(type, exc);
111
112
97
exit:
113
97
    Py_XDECREF(exc);
114
97
}
115
116
/**
117
 * Checks the SQLite error code and sets the appropriate DB-API exception.
118
 * Returns the error code (0 means no error occurred).
119
 */
120
int
121
_pysqlite_seterror(pysqlite_state *state, sqlite3 *db)
122
112
{
123
112
    int errorcode = sqlite3_errcode(db);
124
112
    PyObject *exc_class = get_exception_class(state, errorcode);
125
112
    if (exc_class == NULL) {
126
        // No new exception need be raised; just pass the error code
127
15
        return errorcode;
128
15
    }
129
130
    /* Create and set the exception. */
131
97
    int extended_errcode = sqlite3_extended_errcode(db);
132
97
    const char *errmsg = sqlite3_errmsg(db);
133
97
    raise_exception(exc_class, extended_errcode, errmsg);
134
97
    return extended_errcode;
135
112
}
136
137
#ifdef WORDS_BIGENDIAN
138
# define IS_LITTLE_ENDIAN 0
139
#else
140
0
# define IS_LITTLE_ENDIAN 1
141
#endif
142
143
sqlite_int64
144
_pysqlite_long_as_int64(PyObject * py_val)
145
367
{
146
367
    int overflow;
147
367
    long long value = PyLong_AsLongLongAndOverflow(py_val, &overflow);
148
367
    if (value == -1 && PyErr_Occurred())
149
0
        return -1;
150
367
    if (!overflow) {
151
# if SIZEOF_LONG_LONG > 8
152
        if (-0x8000000000000000LL <= value && value <= 0x7FFFFFFFFFFFFFFFLL)
153
# endif
154
356
            return value;
155
356
    }
156
11
    else if (sizeof(value) < sizeof(sqlite_int64)) {
157
0
        sqlite_int64 int64val;
158
0
        if (_PyLong_AsByteArray((PyLongObject *)py_val,
159
0
                                (unsigned char *)&int64val, sizeof(int64val),
160
0
                                IS_LITTLE_ENDIAN, 1 /* signed */) >= 0) {
161
0
            return int64val;
162
0
        }
163
0
    }
164
11
    PyErr_SetString(PyExc_OverflowError,
165
11
                    "Python int too large to convert to SQLite INTEGER");
166
11
    return -1;
167
367
}