Skip to content

Commit 6b6806f

Browse files
committed
Added finalizers to ssl.EVP_PKEY, removing remaining known memory leaks
1 parent 8f9befd commit 6b6806f

28 files changed

+529
-357
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# 0.2.1
2+
* Added finalizers for `ssl.EVP_PKEY` and running tests under `valgrind` unable
3+
to find any obvious memory leaks.
4+
* Increased Flutter SDK constraint to `>=1.22.0-12.1.pre` (current beta).
5+
16
# 0.2.0
27
* Added `ios` support.
38
* Added `<2.0.0` upper-bound on Flutter SDK constraint.

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ Future<void> main() async {
4343

4444
**Missing:**
4545
* Exceptions and errors thrown for invalid input is not tested yet.
46-
* Finalizers not implemented yet, hence, memory leaks of keys is a known
47-
issues in the native implementation.
4846
* The native implementation executes on the main-thread, however, all expensive
4947
APIs are asynchronous, so they can be offloaded in the future.
5048

android/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ add_library(
6969

7070
# Source files
7171
../src/webcrypto.c
72+
../src/webcrypto_dart_dl.c
7273
../src/symbols.generated.c
7374
${dart_dl_sources}
7475
${crypto_sources}

example/pubspec.lock

Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -35,28 +35,28 @@ packages:
3535
name: async
3636
url: "https://pub.dartlang.org"
3737
source: hosted
38-
version: "2.4.2"
38+
version: "2.5.0-nullsafety"
3939
boolean_selector:
4040
dependency: transitive
4141
description:
4242
name: boolean_selector
4343
url: "https://pub.dartlang.org"
4444
source: hosted
45-
version: "2.0.0"
45+
version: "2.1.0-nullsafety"
4646
characters:
4747
dependency: transitive
4848
description:
4949
name: characters
5050
url: "https://pub.dartlang.org"
5151
source: hosted
52-
version: "1.0.0"
52+
version: "1.1.0-nullsafety.2"
5353
charcode:
5454
dependency: transitive
5555
description:
5656
name: charcode
5757
url: "https://pub.dartlang.org"
5858
source: hosted
59-
version: "1.1.3"
59+
version: "1.2.0-nullsafety"
6060
cli_util:
6161
dependency: transitive
6262
description:
@@ -70,14 +70,14 @@ packages:
7070
name: clock
7171
url: "https://pub.dartlang.org"
7272
source: hosted
73-
version: "1.0.1"
73+
version: "1.1.0-nullsafety"
7474
collection:
7575
dependency: transitive
7676
description:
7777
name: collection
7878
url: "https://pub.dartlang.org"
7979
source: hosted
80-
version: "1.14.13"
80+
version: "1.15.0-nullsafety.2"
8181
convert:
8282
dependency: "direct main"
8383
description:
@@ -119,7 +119,7 @@ packages:
119119
name: fake_async
120120
url: "https://pub.dartlang.org"
121121
source: hosted
122-
version: "1.1.0"
122+
version: "1.1.0-nullsafety"
123123
ffi:
124124
dependency: transitive
125125
description:
@@ -133,7 +133,7 @@ packages:
133133
name: file
134134
url: "https://pub.dartlang.org"
135135
source: hosted
136-
version: "5.2.1"
136+
version: "6.0.0-nullsafety.1"
137137
flutter:
138138
dependency: "direct main"
139139
description: flutter
@@ -194,13 +194,6 @@ packages:
194194
url: "https://pub.dartlang.org"
195195
source: hosted
196196
version: "3.1.4"
197-
intl:
198-
dependency: transitive
199-
description:
200-
name: intl
201-
url: "https://pub.dartlang.org"
202-
source: hosted
203-
version: "0.16.1"
204197
io:
205198
dependency: transitive
206199
description:
@@ -214,7 +207,7 @@ packages:
214207
name: js
215208
url: "https://pub.dartlang.org"
216209
source: hosted
217-
version: "0.6.2"
210+
version: "0.6.3-nullsafety.1"
218211
json_rpc_2:
219212
dependency: transitive
220213
description:
@@ -235,14 +228,14 @@ packages:
235228
name: matcher
236229
url: "https://pub.dartlang.org"
237230
source: hosted
238-
version: "0.12.8"
231+
version: "0.12.10-nullsafety"
239232
meta:
240233
dependency: transitive
241234
description:
242235
name: meta
243236
url: "https://pub.dartlang.org"
244237
source: hosted
245-
version: "1.1.8"
238+
version: "1.3.0-nullsafety.2"
246239
mime:
247240
dependency: transitive
248241
description:
@@ -284,35 +277,35 @@ packages:
284277
name: path
285278
url: "https://pub.dartlang.org"
286279
source: hosted
287-
version: "1.7.0"
280+
version: "1.8.0-nullsafety"
288281
pedantic:
289282
dependency: transitive
290283
description:
291284
name: pedantic
292285
url: "https://pub.dartlang.org"
293286
source: hosted
294-
version: "1.9.0"
287+
version: "1.10.0-nullsafety.1"
295288
platform:
296289
dependency: transitive
297290
description:
298291
name: platform
299292
url: "https://pub.dartlang.org"
300293
source: hosted
301-
version: "2.2.1"
294+
version: "3.0.0-nullsafety.1"
302295
pool:
303296
dependency: transitive
304297
description:
305298
name: pool
306299
url: "https://pub.dartlang.org"
307300
source: hosted
308-
version: "1.4.0"
301+
version: "1.5.0-nullsafety.1"
309302
process:
310303
dependency: transitive
311304
description:
312305
name: process
313306
url: "https://pub.dartlang.org"
314307
source: hosted
315-
version: "3.0.13"
308+
version: "4.0.0-nullsafety.1"
316309
pub_semver:
317310
dependency: transitive
318311
description:
@@ -359,42 +352,42 @@ packages:
359352
name: source_map_stack_trace
360353
url: "https://pub.dartlang.org"
361354
source: hosted
362-
version: "2.0.0"
355+
version: "2.1.0-nullsafety.2"
363356
source_maps:
364357
dependency: transitive
365358
description:
366359
name: source_maps
367360
url: "https://pub.dartlang.org"
368361
source: hosted
369-
version: "0.10.9"
362+
version: "0.10.10-nullsafety.1"
370363
source_span:
371364
dependency: transitive
372365
description:
373366
name: source_span
374367
url: "https://pub.dartlang.org"
375368
source: hosted
376-
version: "1.7.0"
369+
version: "1.8.0-nullsafety"
377370
stack_trace:
378371
dependency: transitive
379372
description:
380373
name: stack_trace
381374
url: "https://pub.dartlang.org"
382375
source: hosted
383-
version: "1.9.5"
376+
version: "1.10.0-nullsafety"
384377
stream_channel:
385378
dependency: transitive
386379
description:
387380
name: stream_channel
388381
url: "https://pub.dartlang.org"
389382
source: hosted
390-
version: "2.0.0"
383+
version: "2.1.0-nullsafety"
391384
string_scanner:
392385
dependency: transitive
393386
description:
394387
name: string_scanner
395388
url: "https://pub.dartlang.org"
396389
source: hosted
397-
version: "1.0.5"
390+
version: "1.1.0-nullsafety"
398391
sync_http:
399392
dependency: transitive
400393
description:
@@ -408,42 +401,42 @@ packages:
408401
name: term_glyph
409402
url: "https://pub.dartlang.org"
410403
source: hosted
411-
version: "1.1.0"
404+
version: "1.2.0-nullsafety"
412405
test:
413406
dependency: "direct dev"
414407
description:
415408
name: test
416409
url: "https://pub.dartlang.org"
417410
source: hosted
418-
version: "1.15.2"
411+
version: "1.16.0-nullsafety.4"
419412
test_api:
420413
dependency: transitive
421414
description:
422415
name: test_api
423416
url: "https://pub.dartlang.org"
424417
source: hosted
425-
version: "0.2.17"
418+
version: "0.2.19-nullsafety"
426419
test_core:
427420
dependency: transitive
428421
description:
429422
name: test_core
430423
url: "https://pub.dartlang.org"
431424
source: hosted
432-
version: "0.3.10"
425+
version: "0.3.12-nullsafety.4"
433426
typed_data:
434427
dependency: transitive
435428
description:
436429
name: typed_data
437430
url: "https://pub.dartlang.org"
438431
source: hosted
439-
version: "1.2.0"
432+
version: "1.3.0-nullsafety.2"
440433
vector_math:
441434
dependency: transitive
442435
description:
443436
name: vector_math
444437
url: "https://pub.dartlang.org"
445438
source: hosted
446-
version: "2.0.8"
439+
version: "2.1.0-nullsafety.2"
447440
vm_service:
448441
dependency: transitive
449442
description:
@@ -501,5 +494,5 @@ packages:
501494
source: hosted
502495
version: "2.2.1"
503496
sdks:
504-
dart: ">=2.9.0-14.0.dev <3.0.0"
497+
dart: ">=2.10.0-4.0.dev <2.10.0"
505498
flutter: ">=1.17.0 <2.0.0"

ios/Classes/include_webcrypto.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@
2222

2323
#include "../../src/symbols.generated.c"
2424
#include "../../src/webcrypto.c"
25+
#include "../../src/webcrypto_dart_dl.c"

lib/src/boringssl/evp.dart

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,16 @@ final EVP_PKEY_new = resolve(Sym.EVP_PKEY_new)
4040
/// ```c
4141
/// void EVP_PKEY_free(EVP_PKEY *pkey);
4242
/// ```
43-
final EVP_PKEY_free = resolve(Sym.EVP_PKEY_free)
44-
.lookupFunc<Void Function(Pointer<EVP_PKEY>)>()
45-
.asFunction<void Function(Pointer<EVP_PKEY>)>();
43+
final EVP_PKEY_free_ =
44+
resolve(Sym.EVP_PKEY_free).lookupFunc<Void Function(Pointer<EVP_PKEY>)>();
45+
46+
/// EVP_PKEY_free frees all data referenced by pkey and then frees pkey itself.
47+
///
48+
/// ```c
49+
/// void EVP_PKEY_free(EVP_PKEY *pkey);
50+
/// ```
51+
final EVP_PKEY_free =
52+
EVP_PKEY_free_.asFunction<void Function(Pointer<EVP_PKEY>)>();
4653

4754
/// EVP_PKEY_id returns the type of pkey, which is one of the EVP_PKEY_* values.
4855
///
@@ -86,15 +93,15 @@ final EVP_PKEY_set1_RSA = resolve(Sym.EVP_PKEY_set1_RSA)
8693
.lookupFunc<Int32 Function(Pointer<EVP_PKEY>, Pointer<RSA>)>()
8794
.asFunction<int Function(Pointer<EVP_PKEY>, Pointer<RSA>)>();
8895

89-
final EVP_PKEY_get0_RSA = resolve(Sym.EVP_PKEY_get0_RSA)
96+
final EVP_PKEY_get1_RSA = resolve(Sym.EVP_PKEY_get1_RSA)
9097
.lookupFunc<Pointer<RSA> Function(Pointer<EVP_PKEY>)>()
9198
.asFunction<Pointer<RSA> Function(Pointer<EVP_PKEY>)>();
9299

93100
final EVP_PKEY_set1_EC_KEY = resolve(Sym.EVP_PKEY_set1_EC_KEY)
94101
.lookupFunc<Int32 Function(Pointer<EVP_PKEY>, Pointer<EC_KEY>)>()
95102
.asFunction<int Function(Pointer<EVP_PKEY>, Pointer<EC_KEY>)>();
96103

97-
final EVP_PKEY_get0_EC_KEY = resolve(Sym.EVP_PKEY_get0_EC_KEY)
104+
final EVP_PKEY_get1_EC_KEY = resolve(Sym.EVP_PKEY_get1_EC_KEY)
98105
.lookupFunc<Pointer<EC_KEY> Function(Pointer<EVP_PKEY>)>()
99106
.asFunction<Pointer<EC_KEY> Function(Pointer<EVP_PKEY>)>();
100107

lib/src/boringssl/lookup/lookup_symbol_dart.dart

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,37 +23,9 @@ final Pointer<Void> Function(Sym) lookupSymbol = () {
2323
return lookup;
2424
}
2525

26-
try {
27-
// If there is no binary webcrypto library to be found we check if the
28-
// current executable already contains BoringSSL symbols. This happens to be
29-
// the case for the Dart Linux release at-least.
30-
final library = DynamicLibrary.executable();
31-
32-
// CRYPTO_library_init initializes the crypto library. It must be called if
33-
// the library is built with BORINGSSL_NO_STATIC_INITIALIZER. Otherwise, it
34-
// does nothing and a static initializer is used instead. It is safe to call
35-
// this function multiple times and concurrently from multiple threads.
36-
//
37-
// On some ARM configurations, this function may require filesystem access
38-
// and should be called before entering a sandbox.
39-
//
40-
// OPENSSL_EXPORT void CRYPTO_library_init(void);
41-
// ignore: non_constant_identifier_names
42-
final CRYPTO_library_init = library
43-
.lookup<NativeFunction<Void Function()>>('CRYPTO_library_init')
44-
.asFunction<void Function()>();
45-
46-
// Always initalize BoringSSL to be on the safe side.
47-
CRYPTO_library_init();
48-
49-
return (Sym s) => library.lookup<Void>(s.name);
50-
} on ArgumentError {
51-
// pass, we'll throw UnsupportedError a few lines further down.
52-
}
53-
5426
throw UnsupportedError(
5527
'package:webcrypto cannot be used from Dart or `pub run test` '
56-
'unless `pub run webcrypto:setup` has been run for the current '
28+
'unless `flutter pub run webcrypto:setup` has been run for the current '
5729
'root project.',
5830
);
5931
}();

lib/src/boringssl/lookup/lookup_symbol_flutter.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,12 @@ final Pointer<Void> Function(Sym) lookupSymbol = () {
3333
.asFunction<Pointer<Void> Function(int)>();
3434

3535
// Return a function from Sym to lookup using `webcrypto_lookup_symbol`
36-
return (Sym s) => webcrypto_lookup_symbol(s.index);
36+
final lookup = (Sym s) => webcrypto_lookup_symbol(s.index);
37+
38+
// Initialize the dynamic linking with Dart.
39+
initialize_dart_dl(lookup);
40+
41+
return lookup;
3742
} on ArgumentError {
3843
final lookup = lookupLibraryInDotDartTool();
3944
if (lookup != null) {

0 commit comments

Comments
 (0)