dproto
dproto copied to clipboard
Possible to use dproto in @safe code.
-
With this changes it should be possible to use structs generated with dproto in @safe functions. However, parsing protobuf code is still not @safe.
-
Removed deprecated inline imports.
Coverage decreased (-0.2%) to 74.663% when pulling 5e95d6d9d38832310333485253adfd82b3499567 on puzzlehawk:safeness into 4e47edbdd832dd425c9139d3b335a4f0d0a10e50 on msoucy:master.
My earlier comment, that @safe
should only be applied to non-templated functions and methods, should be taken as applying to the entire commit. It's simply not appropriate to make promises about templated methods where you have no way of knowing if the instantiation will actually be compatible with the @safe
attribute.
Apart from that, the commit message should be something meaningful explaining the rationale for the changes.
Broadly, I'm concerned that this PR is just trying to get dproto
code to compile inside @safe
code blocks, without actually thinking through the rationale of what actually is safe.
I speak here purely as a user, not a maintainer, but I would not be happy to see dproto
promising @safe
code without a better rationale than is given here for the changes made.
- Removed deprecated inline imports.
I don't see any sign of this in the diff ... ?
@WebDrake: Thanks for having a look at this.
Broadly, I'm concerned that this PR is just trying to get dproto code to compile inside @safe code blocks, without actually thinking through the rationale of what actually is safe.
Partially true. For me it seems to be important that processing of non-trusted data cannot lead to memory corruptions. dproto
will likely be used in networking where none of the incoming data can be trusted. Therefore I claim providing @safe
ty should be mandatory for that kind of library. Clearly we can argue about user provided code such as output ranges. For instance how to we handle R.put()
in writeProto()
? Do we require it to be @safe
? Could be reasonable. I agree that having writeProto()
just @trusted
would be dangerously transparent to the user.
- Removed deprecated inline imports.
I don't see any sign of this in the diff ... ?
Your eyes are right. Copy-paste accident on my side.
For me it seems to be important that processing of non-trusted data cannot lead to memory corruptions.
Yes. This is why it's important to differentiate between code that actually is safe, versus code that merely compiles inside a @safe
block. Your changes as they are currently actually make the user less safe, by providing a false promise that the code meets the requirements of @safe
.
Therefore I claim providing
@safe
ty should be mandatory for that kind of library.
Note that the library's ability to provide genuine guarantees of safety may depend on the way the downstream user is using the library. It isn't necessarily the place of a library author to ban use-cases that are incompatible with @safe
code blocks.
For instance how to we handle
R.put()
inwriteProto()
? Do we require it to be@safe
? Could be reasonable.
You should not be putting @trusted
on anything that you cannot manually verify as memory-safe. Given that you don't know what R
is, it would be very dangerous to use @trusted
in this context. A @safe
put()
method for the given R
is therefore a necessary (but not sufficient) condition in order for the corresponding writeProto()
instantiation to be inferred as @safe
.
In this case, I think the problem with writeProto()
may not only be whether R.put()
is safe, but also the cast to ubyte[]
. I would suggest looking at how converting a BuffType!T
to ubyte[]
could be made verifiably safe. Probably the best way would be to replace the cast with a function that takes BuffType!T
as input and returns a const(ubyte[])
in a way that is guaranteed safe for the types that the BuffType
template evaluates to.
Note that if BuffType!T
is a value-type, you may have to deal with the fact that the resulting ubyte[]
will be invalid the moment the BuffType!T src
variable goes out of scope.