Skip to content

Commit edbb2c8

Browse files
implausiblesrajko
authored andcommitted
Force duplication of libgit objects when it is convenient
the structs git_tree_entry, git_oid, and git_signature all represent structs which are owned by some other object. In order to simplify our memory model, we should always duplicate these 3 structs when we pull them out of libgit2. This detaches these types of structs from their owning object, such that when we delete a commit, none of the oids or signatures that we retrieved from that commit would cause bad memory access.
1 parent 93fd4f2 commit edbb2c8

3 files changed

Lines changed: 27 additions & 4 deletions

File tree

generate/input/descriptor.json

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,6 +1275,9 @@
12751275
"ignore": true
12761276
},
12771277
"oid": {
1278+
"dupFunction": "git_oid_cpy",
1279+
"freeFunctionName": "free",
1280+
"selfDuplicating": true,
12781281
"shouldAlloc": true,
12791282
"functions": {
12801283
"git_oid_cpy": {
@@ -1879,6 +1882,8 @@
18791882
}
18801883
},
18811884
"signature": {
1885+
"dupFunction": "git_signature_dup",
1886+
"selfDuplicating": true,
18821887
"functions": {
18831888
"git_signature_default": {
18841889
"isAsync": false
@@ -2218,9 +2223,6 @@
22182223
"tree": {
22192224
"selfFreeing": true,
22202225
"functions": {
2221-
"git_tree_entry_free": {
2222-
"ignore": true
2223-
},
22242226
"git_tree_entry_byindex": {
22252227
"jsFunctionName": "_entryByIndex"
22262228
},
@@ -2253,6 +2255,11 @@
22532255
}
22542256
}
22552257
},
2258+
"tree_entry": {
2259+
"dupFunction": "git_tree_entry_dup",
2260+
"freeFunctionName": "git_tree_entry_free",
2261+
"selfDuplicating": true
2262+
},
22562263
"writestream": {
22572264
"cType": "git_writestream",
22582265
"needsForwardDeclaration": false

generate/scripts/helpers.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,10 @@ var Helpers = {
181181
typeDef.dependencies = [];
182182
typeDef.selfFreeing = Boolean(typeDefOverrides.selfFreeing);
183183

184+
if (typeDefOverrides.freeFunctionName) {
185+
typeDef.freeFunctionName = typeDefOverrides.freeFunctionName;
186+
}
187+
184188
typeDef.fields = typeDef.fields || [];
185189
typeDef.fields.forEach(function (field, index, allFields) {
186190
var fieldOverrides = typeDefOverrides.fields || {};

generate/templates/templates/class_content.cc

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,17 @@ using namespace node;
2525

2626
{% if cType %}
2727
{{ cppClassName }}::{{ cppClassName }}({{ cType }} *raw, bool selfFreeing) {
28+
{% if selfDuplicating %}
29+
{% if shouldAlloc %}
30+
this->raw = ({{ cType }} *)malloc(sizeof({{ cType }}));
31+
{{ dupFunction }}(this->raw, raw);
32+
{% else %}
33+
{{ dupFunction }}(&this->raw, raw);
34+
{% endif %}
35+
{% else %}
2836
this->raw = raw;
2937
this->selfFreeing = selfFreeing;
38+
{%endif%}
3039

3140
if (selfFreeing) {
3241
SelfFreeingInstanceCount++;
@@ -37,7 +46,10 @@ using namespace node;
3746
}
3847

3948
{{ cppClassName }}::~{{ cppClassName }}() {
40-
{% if freeFunctionName %}
49+
{% if selfDuplicating %}
50+
{{ freeFunctionName }}(this->raw);
51+
this->raw = NULL;
52+
{% elsif freeFunctionName %}
4153
if (this->selfFreeing) {
4254
{{ freeFunctionName }}(this->raw);
4355
SelfFreeingInstanceCount--;

0 commit comments

Comments
 (0)