/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2014-2020 Samsung Electronics Co., Ltd. All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <stddef.h>
#include <dpl/db/sql_connection.h>
#include <dpl/db/naive_synchronization_object.h>
-#include <dpl/assert.h>
#include <dpl/scoped_ptr.h>
#include <unistd.h>
+#include <cassert>
#include <cstdio>
#include <cstdarg>
#include <memory>
namespace {
const int MAX_RETRY = 10;
-
-struct ScopedVaList {
- ~ScopedVaList()
- {
- va_end(args);
- }
- va_list args;
-};
-
-#define scoped_va_start(name, param) ScopedVaList name; va_start(name.args, param);
}
namespace CKM {
m_masterConnection(connection),
m_stmt(NULL)
{
- Assert(connection != NULL);
+ assert(connection != NULL);
// Notify all after potentially synchronized database connection access
ScopedNotifyAll notifyAll(connection->m_synchronizationObject.get());
for (int i = 0; i < MAX_RETRY; i++) {
- int ret = sqlcipher3_prepare_v2(connection->m_connection,
+ int ret = sqlite3_prepare_v2(connection->m_connection,
buffer, strlen(buffer),
&m_stmt, NULL);
- if (ret == SQLCIPHER_OK) {
+ if (ret == SQLITE_OK) {
LogPedantic("Prepared data command: " << buffer);
// Increment stored data command count
++m_masterConnection->m_dataCommandsCount;
return;
- } else if (ret == SQLCIPHER_BUSY) {
+ } else if (ret == SQLITE_BUSY) {
LogPedantic("Collision occurred while preparing SQL command");
// Synchronize if synchronization object is available
}
// Fatal error
- const char *error = sqlcipher3_errmsg(m_masterConnection->m_connection);
+ const char *error = sqlite3_errmsg(m_masterConnection->m_connection);
LogError("SQL prepare data command failed");
LogError(" Statement: " << buffer);
{
LogPedantic("SQL data command finalizing");
- if (sqlcipher3_finalize(m_stmt) != SQLCIPHER_OK)
+ if (sqlite3_finalize(m_stmt) != SQLITE_OK)
LogError("Failed to finalize data command");
// Decrement stored data command count
void SqlConnection::DataCommand::CheckBindResult(int result)
{
- if (result != SQLCIPHER_OK) {
- const char *error = sqlcipher3_errmsg(
+ if (result != SQLITE_OK) {
+ const char *error = sqlite3_errmsg(
m_masterConnection->m_connection);
LogError("Failed to bind SQL statement parameter");
}
}
+//LCOV_EXCL_START
void SqlConnection::DataCommand::BindNull(
SqlConnection::ArgumentIndex position)
{
- CheckBindResult(sqlcipher3_bind_null(m_stmt, position));
+ CheckBindResult(sqlite3_bind_null(m_stmt, position));
LogPedantic("SQL data command bind null: ["
<< position << "]");
}
+//LCOV_EXCL_STOP
void SqlConnection::DataCommand::BindInteger(
SqlConnection::ArgumentIndex position,
int value)
{
- CheckBindResult(sqlcipher3_bind_int(m_stmt, position, value));
+ CheckBindResult(sqlite3_bind_int(m_stmt, position, value));
LogPedantic("SQL data command bind integer: ["
<< position << "] -> " << value);
}
+//LCOV_EXCL_START
void SqlConnection::DataCommand::BindInt8(
SqlConnection::ArgumentIndex position,
int8_t value)
{
- CheckBindResult(sqlcipher3_bind_int(m_stmt, position,
+ CheckBindResult(sqlite3_bind_int(m_stmt, position,
static_cast<int>(value)));
LogPedantic("SQL data command bind int8: ["
<< position << "] -> " << value);
SqlConnection::ArgumentIndex position,
int16_t value)
{
- CheckBindResult(sqlcipher3_bind_int(m_stmt, position,
+ CheckBindResult(sqlite3_bind_int(m_stmt, position,
static_cast<int>(value)));
LogPedantic("SQL data command bind int16: ["
<< position << "] -> " << value);
SqlConnection::ArgumentIndex position,
int32_t value)
{
- CheckBindResult(sqlcipher3_bind_int(m_stmt, position,
+ CheckBindResult(sqlite3_bind_int(m_stmt, position,
static_cast<int>(value)));
LogPedantic("SQL data command bind int32: ["
<< position << "] -> " << value);
SqlConnection::ArgumentIndex position,
int64_t value)
{
- CheckBindResult(sqlcipher3_bind_int64(m_stmt, position,
- static_cast<sqlcipher3_int64>(value)));
+ CheckBindResult(sqlite3_bind_int64(m_stmt, position,
+ static_cast<sqlite3_int64>(value)));
LogPedantic("SQL data command bind int64: ["
<< position << "] -> " << value);
}
SqlConnection::ArgumentIndex position,
float value)
{
- CheckBindResult(sqlcipher3_bind_double(m_stmt, position,
+ CheckBindResult(sqlite3_bind_double(m_stmt, position,
static_cast<double>(value)));
LogPedantic("SQL data command bind float: ["
<< position << "] -> " << value);
SqlConnection::ArgumentIndex position,
double value)
{
- CheckBindResult(sqlcipher3_bind_double(m_stmt, position, value));
+ CheckBindResult(sqlite3_bind_double(m_stmt, position, value));
LogPedantic("SQL data command bind double: ["
<< position << "] -> " << value);
}
+//LCOV_EXCL_STOP
void SqlConnection::DataCommand::BindString(
SqlConnection::ArgumentIndex position,
}
// Assume that text may disappear
- CheckBindResult(sqlcipher3_bind_text(m_stmt, position,
+ CheckBindResult(sqlite3_bind_text(m_stmt, position,
value, strlen(value),
- SQLCIPHER_TRANSIENT));
+ SQLITE_TRANSIENT));
LogPedantic("SQL data command bind string: ["
<< position << "] -> " << value);
}
// Assume that blob may dissappear
- CheckBindResult(sqlcipher3_bind_blob(m_stmt, position,
+ CheckBindResult(sqlite3_bind_blob(m_stmt, position,
raw.data(), raw.size(),
- SQLCIPHER_TRANSIENT));
+ SQLITE_TRANSIENT));
LogPedantic("SQL data command bind blob of size: ["
<< position << "] -> " << raw.size());
}
+//LCOV_EXCL_START
void SqlConnection::DataCommand::BindInteger(
SqlConnection::ArgumentIndex position,
const boost::optional<int> &value)
else
BindNull(position);
}
+//LCOV_EXCL_STOP
bool SqlConnection::DataCommand::Step()
{
m_masterConnection->m_synchronizationObject.get());
for (int i = 0; i < MAX_RETRY; i++) {
- int ret = sqlcipher3_step(m_stmt);
+ int ret = sqlite3_step(m_stmt);
- if (ret == SQLCIPHER_ROW) {
+ if (ret == SQLITE_ROW) {
LogPedantic("SQL data command step ROW");
return true;
- } else if (ret == SQLCIPHER_DONE) {
+ } else if (ret == SQLITE_DONE) {
LogPedantic("SQL data command step DONE");
return false;
- } else if (ret == SQLCIPHER_BUSY) {
+ } else if (ret == SQLITE_BUSY) {
LogPedantic("Collision occurred while executing SQL command");
// Synchronize if synchronization object is available
}
// Fatal error
- const char *error = sqlcipher3_errmsg(m_masterConnection->m_connection);
+ const char *error = sqlite3_errmsg(m_masterConnection->m_connection);
LogError("SQL step data command failed");
LogError(" Error: " << error);
* According to:
* http://www.sqllite.org/c3ref/stmt.html
*
- * if last sqlcipher3_step command on this stmt returned an error,
- * then sqlcipher3_reset will return that error, althought it is not an error.
- * So sqlcipher3_reset allways succedes.
+ * if last sqlite3_step command on this stmt returned an error,
+ * then sqlite3_reset will return that error, althought it is not an error.
+ * So sqlite3_reset allways succedes.
*/
- sqlcipher3_reset(m_stmt);
+ sqlite3_reset(m_stmt);
LogPedantic("SQL data command reset");
}
void SqlConnection::DataCommand::CheckColumnIndex(
SqlConnection::ColumnIndex column)
{
- if (column < 0 || column >= sqlcipher3_column_count(m_stmt))
+ if (column < 0 || column >= sqlite3_column_count(m_stmt))
ThrowMsg(Exception::InvalidColumn, "Column index is out of bounds");
}
+//LCOV_EXCL_START
bool SqlConnection::DataCommand::IsColumnNull(
SqlConnection::ColumnIndex column)
{
LogPedantic("SQL data command get column type: [" << column << "]");
CheckColumnIndex(column);
- return sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL;
+ return sqlite3_column_type(m_stmt, column) == SQLITE_NULL;
}
+//LCOV_EXCL_STOP
int SqlConnection::DataCommand::GetColumnInteger(
SqlConnection::ColumnIndex column)
{
LogPedantic("SQL data command get column integer: [" << column << "]");
CheckColumnIndex(column);
- int value = sqlcipher3_column_int(m_stmt, column);
+ int value = sqlite3_column_int(m_stmt, column);
LogPedantic(" Value: " << value);
return value;
}
+//LCOV_EXCL_START
int8_t SqlConnection::DataCommand::GetColumnInt8(
SqlConnection::ColumnIndex column)
{
LogPedantic("SQL data command get column int8: [" << column << "]");
CheckColumnIndex(column);
- int8_t value = static_cast<int8_t>(sqlcipher3_column_int(m_stmt, column));
+ int8_t value = static_cast<int8_t>(sqlite3_column_int(m_stmt, column));
LogPedantic(" Value: " << value);
return value;
}
{
LogPedantic("SQL data command get column int16: [" << column << "]");
CheckColumnIndex(column);
- int16_t value = static_cast<int16_t>(sqlcipher3_column_int(m_stmt, column));
+ int16_t value = static_cast<int16_t>(sqlite3_column_int(m_stmt, column));
LogPedantic(" Value: " << value);
return value;
}
{
LogPedantic("SQL data command get column int32: [" << column << "]");
CheckColumnIndex(column);
- int32_t value = static_cast<int32_t>(sqlcipher3_column_int(m_stmt, column));
+ int32_t value = static_cast<int32_t>(sqlite3_column_int(m_stmt, column));
LogPedantic(" Value: " << value);
return value;
}
{
LogPedantic("SQL data command get column int64: [" << column << "]");
CheckColumnIndex(column);
- int64_t value = static_cast<int64_t>(sqlcipher3_column_int64(m_stmt, column));
+ int64_t value = static_cast<int64_t>(sqlite3_column_int64(m_stmt, column));
LogPedantic(" Value: " << value);
return value;
}
{
LogPedantic("SQL data command get column float: [" << column << "]");
CheckColumnIndex(column);
- float value = static_cast<float>(sqlcipher3_column_double(m_stmt, column));
+ float value = static_cast<float>(sqlite3_column_double(m_stmt, column));
LogPedantic(" Value: " << value);
return value;
}
{
LogPedantic("SQL data command get column double: [" << column << "]");
CheckColumnIndex(column);
- double value = sqlcipher3_column_double(m_stmt, column);
+ double value = sqlite3_column_double(m_stmt, column);
LogPedantic(" Value: " << value);
return value;
}
+//LCOV_EXCL_STOP
std::string SqlConnection::DataCommand::GetColumnString(
SqlConnection::ColumnIndex column)
CheckColumnIndex(column);
const char *value = reinterpret_cast<const char *>(
- sqlcipher3_column_text(m_stmt, column));
+ sqlite3_column_text(m_stmt, column));
LogPedantic("Value: " << (value ? value : "NULL"));
CheckColumnIndex(column);
const unsigned char *value = reinterpret_cast<const unsigned char *>(
- sqlcipher3_column_blob(m_stmt, column));
+ sqlite3_column_blob(m_stmt, column));
if (value == NULL)
return RawBuffer();
- int length = sqlcipher3_column_bytes(m_stmt, column);
+ int length = sqlite3_column_bytes(m_stmt, column);
LogPedantic("Got blob of length: " << length);
return RawBuffer(value, value + length);
}
+//LCOV_EXCL_START
boost::optional<int> SqlConnection::DataCommand::GetColumnOptionalInteger(
SqlConnection::ColumnIndex column)
{
<< column << "]");
CheckColumnIndex(column);
- if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL)
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL)
return boost::optional<int>();
- int value = sqlcipher3_column_int(m_stmt, column);
+ int value = sqlite3_column_int(m_stmt, column);
LogPedantic(" Value: " << value);
return boost::optional<int>(value);
}
<< column << "]");
CheckColumnIndex(column);
- if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL)
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL)
return boost::optional<int8_t>();
- int8_t value = static_cast<int8_t>(sqlcipher3_column_int(m_stmt, column));
+ int8_t value = static_cast<int8_t>(sqlite3_column_int(m_stmt, column));
LogPedantic(" Value: " << value);
return boost::optional<int8_t>(value);
}
<< column << "]");
CheckColumnIndex(column);
- if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL)
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL)
return boost::optional<int16_t>();
- int16_t value = static_cast<int16_t>(sqlcipher3_column_int(m_stmt, column));
+ int16_t value = static_cast<int16_t>(sqlite3_column_int(m_stmt, column));
LogPedantic(" Value: " << value);
return boost::optional<int16_t>(value);
}
<< column << "]");
CheckColumnIndex(column);
- if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL)
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL)
return boost::optional<int32_t>();
- int32_t value = static_cast<int32_t>(sqlcipher3_column_int(m_stmt, column));
+ int32_t value = static_cast<int32_t>(sqlite3_column_int(m_stmt, column));
LogPedantic(" Value: " << value);
return boost::optional<int32_t>(value);
}
<< column << "]");
CheckColumnIndex(column);
- if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL)
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL)
return boost::optional<int64_t>();
- int64_t value = static_cast<int64_t>(sqlcipher3_column_int64(m_stmt, column));
+ int64_t value = static_cast<int64_t>(sqlite3_column_int64(m_stmt, column));
LogPedantic(" Value: " << value);
return boost::optional<int64_t>(value);
}
<< column << "]");
CheckColumnIndex(column);
- if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL)
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL)
return boost::optional<float>();
- float value = static_cast<float>(sqlcipher3_column_double(m_stmt, column));
+ float value = static_cast<float>(sqlite3_column_double(m_stmt, column));
LogPedantic(" Value: " << value);
return boost::optional<float>(value);
}
<< column << "]");
CheckColumnIndex(column);
- if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL)
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL)
return boost::optional<double>();
- double value = sqlcipher3_column_double(m_stmt, column);
+ double value = sqlite3_column_double(m_stmt, column);
LogPedantic(" Value: " << value);
return boost::optional<double>(value);
}
LogPedantic("SQL data command get column blog: [" << column << "]");
CheckColumnIndex(column);
- if (sqlcipher3_column_type(m_stmt, column) == SQLCIPHER_NULL)
+ if (sqlite3_column_type(m_stmt, column) == SQLITE_NULL)
return boost::optional<RawBuffer>();
const unsigned char *value = reinterpret_cast<const unsigned char *>(
- sqlcipher3_column_blob(m_stmt, column));
+ sqlite3_column_blob(m_stmt, column));
- int length = sqlcipher3_column_bytes(m_stmt, column);
+ int length = sqlite3_column_bytes(m_stmt, column);
LogPedantic("Got blob of length: " << length);
RawBuffer temp(value, value + length);
return boost::optional<RawBuffer>(temp);
}
+//LCOV_EXCL_STOP
void SqlConnection::Connect(const std::string &address,
Flag::Option flag)
// Connect to database
int result;
- result = sqlcipher3_open_v2(
+ result = sqlite3_open_v2(
address.c_str(),
&m_connection,
flag,
NULL);
- if (result == SQLCIPHER_OK) {
+ if (result == SQLITE_OK) {
LogPedantic("Connected to DB");
} else {
LogError("Failed to connect to DB!");
TurnOnForeignKeys();
}
-const std::string SQLCIPHER_RAW_PREFIX = "x'";
-const std::string SQLCIPHER_RAW_SUFIX = "'";
-const std::size_t SQLCIPHER_RAW_DATA_SIZE = 32;
+const std::string SQLITE_RAW_PREFIX = "x'";
+const std::string SQLITE_RAW_SUFIX = "'";
+const std::size_t SQLITE_RAW_DATA_SIZE = 32;
RawBuffer rawToHexString(const RawBuffer &raw)
{
- RawBuffer output;
-
- for (auto &e : raw) {
- char result[3];
- snprintf(result, sizeof(result), "%02X", (e & 0xff));
- output.push_back(static_cast<unsigned char>(result[0]));
- output.push_back(static_cast<unsigned char>(result[1]));
- }
-
- return output;
+ return hexDump<RawBuffer, true>(raw);
}
RawBuffer createHexPass(const RawBuffer &rawPass)
// We are required to pass 64byte long hex password made out of 32byte raw
// binary data
RawBuffer output;
- std::copy(SQLCIPHER_RAW_PREFIX.begin(), SQLCIPHER_RAW_PREFIX.end(),
+ std::copy(SQLITE_RAW_PREFIX.begin(), SQLITE_RAW_PREFIX.end(),
std::back_inserter(output));
RawBuffer password = rawToHexString(rawPass);
std::copy(password.begin(), password.end(),
std::back_inserter(output));
- std::copy(SQLCIPHER_RAW_SUFIX.begin(), SQLCIPHER_RAW_SUFIX.end(),
+ std::copy(SQLITE_RAW_SUFIX.begin(), SQLITE_RAW_SUFIX.end(),
std::back_inserter(output));
return output;
return;
}
- if (rawPass.size() != SQLCIPHER_RAW_DATA_SIZE)
+ if (rawPass.size() != SQLITE_RAW_DATA_SIZE)
ThrowMsg(Exception::InvalidArguments,
"Binary data for raw password should be 32 bytes long.");
RawBuffer pass = createHexPass(rawPass);
- int result = sqlcipher3_key(m_connection, pass.data(), pass.size());
+ int result = sqlite3_key(m_connection, pass.data(), pass.size());
- if (result == SQLCIPHER_OK) {
+ if (result == SQLITE_OK) {
LogPedantic("Set key on DB");
} else {
- //sqlcipher3_key fails only when m_connection == NULL || key == NULL ||
+ //sqlite3_key fails only when m_connection == NULL || key == NULL ||
// key length == 0
LogError("Failed to set key on DB");
ThrowMsg(Exception::InvalidArguments, result);
m_isKeySet = true;
};
+//LCOV_EXCL_START
void SqlConnection::ResetKey(const RawBuffer &rawPassOld,
const RawBuffer &rawPassNew)
{
return;
}
- AssertMsg(rawPassOld.size() == SQLCIPHER_RAW_DATA_SIZE &&
- rawPassNew.size() == SQLCIPHER_RAW_DATA_SIZE,
- "Binary data for raw password should be 32 bytes long.");
+ // Binary data for raw password should be 32 bytes long.
+ assert(rawPassOld.size() == SQLITE_RAW_DATA_SIZE &&
+ rawPassNew.size() == SQLITE_RAW_DATA_SIZE);
- // sqlcipher3_rekey requires for key to be already set
+ // sqlite3_rekey requires for key to be already set
if (!m_isKeySet)
SetKey(rawPassOld);
RawBuffer pass = createHexPass(rawPassNew);
- int result = sqlcipher3_rekey(m_connection, pass.data(), pass.size());
+ int result = sqlite3_rekey(m_connection, pass.data(), pass.size());
- if (result == SQLCIPHER_OK) {
+ if (result == SQLITE_OK) {
LogPedantic("Reset key on DB");
} else {
- //sqlcipher3_rekey fails only when m_connection == NULL || key == NULL ||
+ //sqlite3_rekey fails only when m_connection == NULL || key == NULL ||
// key length == 0
LogError("Failed to reset key on DB");
ThrowMsg(Exception::InvalidArguments, result);
}
}
+//LCOV_EXCL_STOP
void SqlConnection::Disconnect()
{
LogPedantic("Disconnecting from DB...");
// All stored data commands must be deleted before disconnect
- AssertMsg(m_dataCommandsCount == 0,
- "All stored procedures must be deleted"
- " before disconnecting SqlConnection");
+ assert(m_dataCommandsCount == 0);
int result;
- result = sqlcipher3_close(m_connection);
+ result = sqlite3_close(m_connection);
- if (result != SQLCIPHER_OK) {
- const char *error = sqlcipher3_errmsg(m_connection);
+ if (result != SQLITE_OK) {
+ const char *error = sqlite3_errmsg(m_connection);
LogError("SQL close failed");
LogError(" Error: " << error);
Throw(Exception::InternalError);
}
DataCommandUniquePtr command =
- PrepareDataCommand("select tbl_name from sqlcipher_master where name=?;");
+ PrepareDataCommand("select tbl_name from sqlite_master where name=?;");
command->BindString(1, tableName);
}
}
+//LCOV_EXCL_START
int SqlConnection::Output::Callback(void *param, int columns, char **values,
char **names)
{
m_values.push_back(std::move(row));
}
+//LCOV_EXCL_STOP
void SqlConnection::ExecCommandHelper(Output *out, const char *format,
va_list args)
for (int i = 0; i < MAX_RETRY; i++) {
char *errorBuffer;
- int ret = sqlcipher3_exec(m_connection,
+ int ret = sqlite3_exec(m_connection,
queryPtr.get(),
out ? &Output::Callback : NULL,
out,
// Take allocated error buffer
if (errorBuffer != NULL) {
errorMsg = errorBuffer;
- sqlcipher3_free(errorBuffer);
+ sqlite3_free(errorBuffer);
}
- if (ret == SQLCIPHER_OK)
+ if (ret == SQLITE_OK)
return;
- if (ret == SQLCIPHER_BUSY) {
+ if (ret == SQLITE_BUSY) {
LogPedantic("Collision occurred while executing SQL command");
// Synchronize if synchronization object is available
ThrowMsg(Exception::InternalError, "sqlite permanently busy");
}
+//LCOV_EXCL_START
void SqlConnection::ExecCommand(Output *out, const char *format, ...)
{
- scoped_va_start(svl, format);
-
- ExecCommandHelper(out, format, svl.args);
+ va_list args;
+ va_start(args, format);
+ try {
+ ExecCommandHelper(out, format, args);
+ } catch (...) {
+ va_end(args);
+ throw;
+ }
+ va_end(args);
}
+//LCOV_EXCL_STOP
void SqlConnection::ExecCommand(const char *format, ...)
{
- scoped_va_start(svl, format);
-
- ExecCommandHelper(NULL, format, svl.args);
+ va_list args;
+ va_start(args, format);
+ try {
+ ExecCommandHelper(NULL, format, args);
+ } catch (...) {
+ va_end(args);
+ throw;
+ }
+ va_end(args);
}
SqlConnection::DataCommandUniquePtr SqlConnection::PrepareDataCommand(
return DataCommandUniquePtr(new DataCommand(this, buffer.get()));
}
+//LCOV_EXCL_START
SqlConnection::RowID SqlConnection::GetLastInsertRowID() const
{
- return static_cast<RowID>(sqlcipher3_last_insert_rowid(m_connection));
+ return static_cast<RowID>(sqlite3_last_insert_rowid(m_connection));
}
+//LCOV_EXCL_STOP
void SqlConnection::TurnOnForeignKeys()
{