mirror of https://github.com/nodejs/node.git
115 lines
3.4 KiB
JavaScript
115 lines
3.4 KiB
JavaScript
'use strict';
|
|
const common = require('../../common');
|
|
const assert = require('node:assert');
|
|
const path = require('node:path');
|
|
const sqlite = require('node:sqlite');
|
|
const test = require('node:test');
|
|
const fs = require('node:fs');
|
|
const childProcess = require('node:child_process');
|
|
|
|
if (process.config.variables.node_shared_sqlite) {
|
|
common.skip('Missing libsqlite_extension binary');
|
|
}
|
|
|
|
// Lib extension binary is named differently on different platforms
|
|
function resolveBuiltBinary() {
|
|
const buildDir = `${__dirname}/build/${common.buildType}`;
|
|
const lib = 'sqlite_extension';
|
|
const targetFile = fs.readdirSync(buildDir).find((file) => file.startsWith(lib));
|
|
return path.join(buildDir, targetFile);
|
|
}
|
|
|
|
const binary = resolveBuiltBinary();
|
|
|
|
test('should load extension successfully', () => {
|
|
const db = new sqlite.DatabaseSync(':memory:', {
|
|
allowExtension: true,
|
|
});
|
|
db.loadExtension(binary);
|
|
db.exec('SELECT noop(\'Hello, world!\');');
|
|
const query = db.prepare('SELECT noop(\'Hello, World!\') AS result');
|
|
const { result } = query.get();
|
|
assert.strictEqual(result, 'Hello, World!');
|
|
});
|
|
|
|
test('should not load extension', () => {
|
|
const db = new sqlite.DatabaseSync(':memory:', {
|
|
allowExtension: false,
|
|
});
|
|
assert.throws(() => {
|
|
db.exec('SELECT noop(\'Hello, world!\');');
|
|
}, {
|
|
message: 'no such function: noop',
|
|
code: 'ERR_SQLITE_ERROR',
|
|
});
|
|
assert.throws(() => {
|
|
db.loadExtension(binary);
|
|
}, {
|
|
message: 'extension loading is not allowed',
|
|
code: 'ERR_INVALID_STATE',
|
|
});
|
|
assert.throws(() => {
|
|
const query = db.prepare('SELECT load_extension(?)');
|
|
query.run(binary);
|
|
}, {
|
|
message: 'not authorized',
|
|
code: 'ERR_SQLITE_ERROR',
|
|
});
|
|
assert.throws(() => {
|
|
db.enableLoadExtension();
|
|
}, {
|
|
message: 'The "allow" argument must be a boolean.',
|
|
code: 'ERR_INVALID_ARG_TYPE',
|
|
});
|
|
|
|
assert.throws(() => {
|
|
db.enableLoadExtension(true);
|
|
}, {
|
|
message: 'Cannot enable extension loading because it was disabled at database creation.',
|
|
});
|
|
});
|
|
|
|
test('should load extension successfully with enableLoadExtension', () => {
|
|
const db = new sqlite.DatabaseSync(':memory:', {
|
|
allowExtension: true,
|
|
});
|
|
db.loadExtension(binary);
|
|
db.enableLoadExtension(false);
|
|
db.exec('SELECT noop(\'Hello, world!\');');
|
|
const query = db.prepare('SELECT noop(\'Hello, World!\') AS result');
|
|
const { result } = query.get();
|
|
assert.strictEqual(result, 'Hello, World!');
|
|
});
|
|
|
|
test('should not load extension with enableLoadExtension', () => {
|
|
const db = new sqlite.DatabaseSync(':memory:', {
|
|
allowExtension: true,
|
|
});
|
|
db.enableLoadExtension(false);
|
|
assert.throws(() => {
|
|
db.loadExtension(binary);
|
|
}, {
|
|
message: 'extension loading is not allowed',
|
|
});
|
|
});
|
|
|
|
test('should throw error if permission is enabled', async () => {
|
|
const [cmd, opts] = common.escapePOSIXShell`"${process.execPath}" `;
|
|
const code = `const sqlite = require('node:sqlite');
|
|
const db = new sqlite.DatabaseSync(':memory:', { allowExtension: true });`;
|
|
return new Promise((resolve) => {
|
|
childProcess.exec(
|
|
`${cmd} --permission -e "${code}"`,
|
|
{
|
|
...opts,
|
|
},
|
|
common.mustCall((err, _, stderr) => {
|
|
assert.strictEqual(err.code, 1);
|
|
assert.match(stderr, /Error: Cannot load SQLite extensions when the permission model is enabled/);
|
|
assert.match(stderr, /code: 'ERR_LOAD_SQLITE_EXTENSION'/);
|
|
resolve();
|
|
}),
|
|
);
|
|
});
|
|
});
|