Skip to content
This repository has been archived by the owner on Apr 23, 2022. It is now read-only.

Fix exception when decoded value is too large by doubling buffer #4

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

karamanolev
Copy link

  1. No need for the test files. There's a much simpler reproduction, which I included in the tests.
  2. Removed the test for NoDelta found. This will be covered in the logic for doubling the buffer. This changes the API a bit, since now you are free to get a larger delta than the second argument. However, I think that this is, in fact, the correct behavior from an API standpoint. Imagine you write your code, test it with reasonable inputs, everything works. One day your production code breaks, because of some edge case. I think cases of larger delta than the input should be handled by the client code, if it's actually an issue. Otherwise you will just surprise them badly.
  3. The above actually removes the need for the NoDelta exception, so it's removed as well.
  4. sizeof(int) - 4 is horrible, but I'm too lazy ATM to implement the correct solution, which is to check that you didn't overflow the int when left shifting in those 2 places. The error handling logic will be more complicated as well.
  5. The sprintf had a buffer overflow vulnerability. Fixed by using snprintf. I agree this can get a string truncated, but is much better than it was before.

@codecov
Copy link

codecov bot commented Dec 21, 2017

Codecov Report

Merging #4 into master will not change coverage.
The diff coverage is 100%.

@@          Coverage Diff          @@
##           master     #4   +/-   ##
=====================================
  Coverage     100%   100%           
=====================================
  Files           2      2           
  Lines          42     42           
=====================================
  Hits           42     42

Copy link
Owner

@samuelcolvin samuelcolvin left a comment

Choose a reason for hiding this comment

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

sorry for slow response.

Overall looks good, mostly trivial things to change except the behaviour when the delta is bigger than the input where I disagree with you.

output_buf = main_malloc(output_alloc);
result = xd3_encode_memory(input_bytes, input_size, source_bytes, source_size,
output_buf, &output_size, output_alloc, flags);
} else {
// output shouldn't be bigger than the original plus the delta, but give a little leeway
output_alloc = input_size + source_size * 11 / 10;
output_alloc = (input_size + source_size * 11 / 10) << buffer_double_cnt;
Copy link
Owner

Choose a reason for hiding this comment

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

can you remove comments that no longer make sense.

@@ -21,13 +21,13 @@ static PyObject * xdelta3_execute(PyObject *self, PyObject *args)

if (action == 0) {
// if the output would be longer than the input itself, there's no point using delta encoding
output_alloc = input_size;
output_alloc = input_size << buffer_double_cnt;
Copy link
Owner

Choose a reason for hiding this comment

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

I'm afraid I don't agree with this. Sorry.

If I'm getting a delta that is bigger than the input I want to get an error which I have to deal with as soon as possible. Silently "failing" to produce a useful delta is not good.

Please remove this.

@@ -57,6 +51,14 @@ def test_version():
xdelta3.print_version()


def test_huge_output():
Copy link
Owner

Choose a reason for hiding this comment

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

Makes much more sense 😄

if (result == ENOSPC) {
// Leave some leeway before we overflow int. This is a bad way, the better way would be to
// check above when we left shift.
if (buffer_double_cnt < sizeof(int) - 4) {
Copy link
Owner

Choose a reason for hiding this comment

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

can you at least add a comment explaining what this is doing please.

}
} else {
char exc_str[80];
sprintf(exc_str, "Error occur executing xdelta3: %s", xd3_strerror(result));
snprintf(exc_str, sizeof(exc_str) / sizeof(exc_str[0]),
Copy link
Owner

Choose a reason for hiding this comment

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

makes sense.

@samuelcolvin
Copy link
Owner

@karamanolev do you want to complete this?

@karamanolev
Copy link
Author

@samuelcolvin I'll address these soon, hopefully I'll find some time. Sorry.

@samuelcolvin
Copy link
Owner

No problems, thank you.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants