Fix null safety issues and tighten type parameters#34
Merged
Harry-Chen merged 1 commit intomasterfrom Mar 13, 2026
Merged
Conversation
…ghtening - Fix AbsoluteUriRecord infinite recursion between uri/decodedType getters - Fix Version constructor assigning to local parameter instead of this.value - Fix EIR.bytes and BluetoothLowEnergyRecord.payload unsafe runtime casts - Fix SignatureRecord payload setter using immutable getter copy - Tighten parameter types: bytesToInt, bigIntToBytes, LEAddress, etc. - Remove unnecessary .cast() calls and redundant nullable types - Simplify bool comparisons in ndef.dart (MB != true → !MB) Made-with: Cursor
There was a problem hiding this comment.
Pull request overview
This PR improves null-safety and type correctness across the NDEF Dart library, aiming to reduce forced casts/unwrapping and make payload/byte handling more consistent across record implementations.
Changes:
- Tighten nullability on key constructors/setters (e.g.,
UriRecord.fromString/fromUri,ByteUtils.bytesToInt/bigIntToBytes). - Standardize several
payloadgetters to return non-nullableUint8Listand simplify byte assembly (Uint8List.fromList(...)). - Minor refactors/cleanups (boolean flag checks, list indexing cleanup, internal field usage fixes).
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/utilities.dart | Makes byte/int conversion APIs non-nullable and simplifies Version constructor logic. |
| lib/records/well_known/uri.dart | Tightens constructor parameter nullability for URI creation. |
| lib/records/well_known/smart_poster.dart | Simplifies icon map indexing (first) in setter. |
| lib/records/well_known/signature.dart | Fixes certificate store mutation to target the backing store list. |
| lib/records/well_known/handover.dart | Makes payload getters non-nullable and simplifies payload building; tightens carrier TNF handling. |
| lib/records/well_known/device_info.dart | Removes nullable ints in payload assembly and simplifies local payload list creation. |
| lib/records/media/bluetooth.dart | Removes unsafe casts, tightens some parameter nullability, and makes payload building consistent. |
| lib/records/absolute_uri.dart | Simplifies URI getter and removes redundant override. |
| lib/record.dart | Adjusts type/id setters toward stronger typing (removes explicit cast in decodedType setter; tightens idString). |
| lib/ndef.dart | Simplifies MB/ME/CF boolean checks during decode. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| /// Sets the decoded type string, encoding it to UTF-8 bytes. | ||
| set decodedType(String? decodedType) { | ||
| encodedType = utf8.encode(decodedType!) as Uint8List?; | ||
| encodedType = utf8.encode(decodedType!); |
Comment on lines
578
to
584
| set icon(Map<String?, Uint8List?>? icon) { | ||
| String? decodedType = icon!.keys.toList()[0]; | ||
| String? decodedType = icon!.keys.first; | ||
| _checkValidIconType(decodedType!); | ||
| iconRecord = MimeRecord( | ||
| decodedType: decodedType, | ||
| payload: icon.values.toList()[0], | ||
| payload: icon.values.first, | ||
| ); |
Comment on lines
+52
to
56
| if (!records.last.flags.ME) { | ||
| throw FormatException("ME flag is not set in last record"); | ||
| } | ||
| if (records.last.flags.CF != false) { | ||
| if (records.last.flags.CF) { | ||
| throw FormatException("CF flag is set in last record"); |
Comment on lines
775
to
+776
| TypeNameFormat get carrierTnf { | ||
| return TypeNameFormat.values[_carrierTnf!]; | ||
| return TypeNameFormat.values[_carrierTnf]; |
Comment on lines
953
to
956
| for (var e in attributes.entries) { | ||
| data.add(e.value.length + 1); | ||
| data.add(EIR.typeNumMap[e.key]); | ||
| data.add(EIR.typeNumMap[e.key]!); | ||
| data.addAll(e.value); |
Comment on lines
1208
to
+1211
| for (var e in attributes.entries) { | ||
| payload.add(e.value.length + 1); | ||
| payload.add(EIR.typeNumMap[e.key!]!); | ||
| payload.addAll(e.value); | ||
| data.add(e.value.length + 1); | ||
| data.add(EIR.typeNumMap[e.key]!); | ||
| data.addAll(e.value); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request focuses on improving type safety and code clarity across the NDEF Dart library by removing unnecessary nullability, eliminating forced casts, and simplifying payload and byte handling. Many constructors and setters now require non-null arguments, and payload-related methods consistently return non-nullable
Uint8List. There are also several minor logic and style cleanups.Key improvements include:
Type Safety and Nullability Improvements
Uint8List,String, andBigIntrequired and non-nullable in constructors and setters throughout the codebase. This reduces the need for null checks and forced casts, making the code safer and easier to understand. [1] [2] [3] [4] [5] [6]Payload and Byte Handling Consistency
Uint8List, removing nullable returns and unnecessary casts. This simplifies encoding logic and ensures payloads are always available in the expected format. [1] [2] [3] [4] [5]Logic and Style Cleanups
if (!record.flags.MB)instead ofif (record.flags.MB != true), for improved readability.as Uint8Listand.cast()when assembling lists of bytes, favoringUint8List.fromList(...)for clarity and correctness. [1] [2] [3] [4] [5] [6]API and Constructor Simplification
requiredparameters and direct assignments, and removed extraneous null checks and forced unwrapping. [1] [2] [3]Minor Refactorings
decodedTypeandidString, and removed redundant overrides in record subclasses. [1] [2] [3]These changes collectively make the library more robust, less error-prone, and easier to maintain.
Made-with: Cursor