Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ jobs:
node: 22
host: x86
target: x86
# This is a self-hosted runner, github doesn't have this architecture yet.
- os: macos-m1
- os: macos-latest
node: 22
host: arm64
target: arm64
Expand All @@ -48,10 +47,6 @@ jobs:
node-version: ${{ matrix.node }}
architecture: ${{ matrix.host }}

- name: Add yarn (self-hosted)
if: matrix.os == 'macos-m1'
run: npm install -g yarn

- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v1.1
if: contains(matrix.os, 'windows')
Expand Down Expand Up @@ -99,6 +94,10 @@ jobs:
- name: Package prebuilt binaries
run: yarn node-pre-gyp package --target_arch=${{ env.TARGET }}

- name: Rebuild with assertions and re-test
if: contains(matrix.os, 'ubuntu')
run: yarn build:assert && yarn test

- name: Prepare for saving artifact
run: |
ARTIFACT_NAME=$(echo prebuilt-binaries-${{ matrix.os }}-${{ matrix.target }} | sed 's/[^-a-zA-Z0-9]/_/g')
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"build": "node-pre-gyp build",
"build:debug": "node-pre-gyp build --debug",
"install": "node-pre-gyp install --fallback-to-build",
"build:assert": "CXXFLAGS=\"${CXXFLAGS:-} -D_GLIBCXX_ASSERTIONS\" node-pre-gyp rebuild --build-from-source",
"pretest": "node test/support/createdb.js",
"test": "mocha -R spec --timeout 480000",
"test:memory": "node test/support/memory_check.js",
Expand Down
5 changes: 3 additions & 2 deletions src/marshal.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Marshaller {
}

void _writeBytes(const void *bytes, size_t nbytes) {
if (nbytes == 0) return;
size_t offset = buffer.size();
buffer.resize(buffer.size() + nbytes);
memcpy(&buffer[offset], bytes, nbytes);
Expand All @@ -57,7 +58,7 @@ class Marshaller {

void append(const Marshaller &marshaller) {
const std::vector<char> &buf = marshaller.getBuffer();
_writeBytes(&buf[0], buf.size());
_writeBytes(buf.data(), buf.size());
}

// Marshal the given value depending on its type.
Expand All @@ -68,7 +69,7 @@ class Marshaller {
}

void marshalString(const std::string &value) {
marshalString(&value[0], value.size());
marshalString(value.data(), value.size());
}

void marshalString(const char *value, int32_t size) {
Expand Down
29 changes: 29 additions & 0 deletions test/allMarshal.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,34 @@ describe('Database#allMarshal', function() {
}
});

it('should handle empty result set', function(done) {
db.allMarshal("SELECT * FROM foo WHERE 1=0", function(err, result) {
if (err) throw err;
// Should be a dict with column names mapping to empty lists:
// {s<col>[\x00\x00\x00\x00 ...} for each column, terminated by '0'
assert.ok(Buffer.isBuffer(result));
var parsed = sqlite3.parse(result);
assert.deepEqual(parsed, {row: [], num: [], flt: [], blb: []});
done();
});
});

it('should handle empty string and blob values', function(done) {
db.run("CREATE TABLE bar (txt text, blb blob)", function(err) {
if (err) throw err;
db.run("INSERT INTO bar VALUES('', X'')", function(err) {
if (err) throw err;
db.allMarshal("SELECT * FROM bar", function(err, result) {
if (err) throw err;
assert.ok(Buffer.isBuffer(result));
var parsed = sqlite3.parse(result);
assert.deepEqual(parsed.txt, ['']);
assert.deepEqual(parsed.blb, [new Uint8Array(0)]);
done();
});
});
});
});

after(function(done) { db.close(done); });
});
3 changes: 3 additions & 0 deletions test/marshal-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ describe('marshal', function() {
return new Uint8Array(Buffer.from(str));
}
const samples = [
// Empty string and empty buffer exercise _writeBytes with 0 bytes.
['', 'u\x00\x00\x00\x00'],
[new Uint8Array(0), 's\x00\x00\x00\x00'],
[null, 'N'],
[1, 'i\x01\x00\x00\x00'],
[1000000, 'i@B\x0f\x00'],
Expand Down
Loading