Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CommandAPDU reuse data object to avoid PIN copy #80

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

metsma
Copy link
Contributor

@metsma metsma commented Aug 6, 2024

WE2-1007

Signed-off-by: Raul Metsma [email protected]

lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp.hpp Outdated Show resolved Hide resolved
lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp.hpp Show resolved Hide resolved
lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp.hpp Show resolved Hide resolved
lib/libpcsc-cpp/src/utils.cpp Show resolved Hide resolved
}
insert(begin(), {cls, ins, p1, p2, static_cast<byte_type>(size())});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it so that when using the T=0 protocol, the Le field should be omitted? Shouldn't you handle protocol differences here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have many cases where we send with T=0 Le field and do not have any issues reported:
https://github.com/web-eid/libelectronic-id/blob/main/src/electronic-ids/pcsc/EIDIDEMIA.cpp#L146-L152
https://github.com/web-eid/libelectronic-id/blob/main/src/electronic-ids/pcsc/FinEID.cpp#L161-L162
If this is issue we should handle this in transfer()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer that we test T=0 properly before merging.

mrts
mrts previously approved these changes Sep 20, 2024
if (d.size() > MAX_DATA_SIZE) {
throw std::invalid_argument("Command chaining and extended lenght not supported");
}
d.insert(d.begin(), {cls, ins, p1, p2, static_cast<byte_type>(d.size())});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

insert() can cause a memory copy.

Let's use make_move_iterator for moving the data?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how make_move_iterator avoids vector resize? it does same way resize to current vector and moves elements from one vector to other.

Copy link
Member

@mrts mrts Sep 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make_move_iterator cannot avoid vector resize, but it can avoid a hidden memory copy if we allocate a sufficiently large target vector and move elements from the source vector to the target vector.

@@ -47,24 +47,23 @@ inline pcsc_cpp::byte_vector addPaddingToPin(pcsc_cpp::byte_vector&& pin, size_t
pcsc_cpp::byte_type paddingChar)
{
pin.resize(std::max(pin.size(), paddingLength), paddingChar);
return pin;
return std::move(pin);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return std::move(pin);
return pin;

This is not needed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I disagree, see https://stackoverflow.com/a/14857144. When you have a function that takes an rvalue reference, modifies it, and then returns a copy of it, std::move() should be used as far as I understand. Yakk-Adam Nevraumont mentions that in C++20 the behavior changes, but I would like to see a specific reference and explanation of the new behavior.

pin is an lvalue within the function scope, even though it's an rvalue reference parameter. Returning an lvalue would typically invoke a copy - and yes, this may be elided with NRVO as you imply, but by explicitly applying std::move we can be sure that it is moved as intended and not rely on probable behavior.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By the way, we should deal with the resize() problem here as well.

@mrts mrts self-requested a review September 24, 2024 16:22
@mrts mrts dismissed their stale review September 24, 2024 16:23

There are open questions still.

metsma and others added 4 commits October 16, 2024 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants