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

vips_target_finish can fail silently resulting in corrupted or null output #2801

Closed
flga opened this issue May 13, 2022 · 1 comment
Closed
Labels

Comments

@flga
Copy link

flga commented May 13, 2022

Bug report

Describe the bug
Currently vips_target_finish returns void, this can be a problem because it needs to call vips_target_flush which can fail.
This silences any errors that might occur on the last write to the target, and can be particularly devious if all the writes up to that point fit into the target buffer, causing the only write to actually occur to fail silently.

In summary, when using the streaming api (at least _custom) any output that is less than VIPS_TARGET_BUFFER_SIZE can fail unbeknownst to the caller.

To Reproduce
Load and save a small image with a write implementation that fails.

#include <stdio.h>
#include <unistd.h>
#include <vips/vips.h>

gint64 write_cb(VipsTargetCustom *target_custom, gpointer data, gint64 length, gpointer user_data) {
  printf("quick, duck! it's a cosmic ray!\n");
  return -1;
};

int main() {
  VipsSource *source = vips_source_new_from_file("box.jpg");
  VipsTargetCustom *target_custom = vips_target_custom_new();
  g_signal_connect(target_custom, "write", G_CALLBACK(write_cb), NULL);

  VipsImage *img;
  if (vips_jpegload_source(source, &img, "access", VIPS_ACCESS_SEQUENTIAL, NULL)) {
    printf("%s\n", vips_error_buffer());
    return 1;
  }

  if (vips_jpegsave_target(img, VIPS_TARGET(target_custom), NULL)) {
    printf("%s\n", vips_error_buffer());
    return 1;
  }

  printf("phew!\n");
  return 0;
}

box.jpg
box

Environment

@flga flga added the bug label May 13, 2022
jcupitt added a commit that referenced this issue May 14, 2022
since finish did not return an error code

also make sure we don't call target_end from inside _dispose, since that
can't signal error either

see #2801
@jcupitt
Copy link
Member

jcupitt commented May 14, 2022

You're right, I remember worrying about this.

I've made a PR for a fix.

@jcupitt jcupitt closed this as completed May 14, 2022
jcupitt added a commit that referenced this issue May 20, 2022
since finish did not return an error code

also make sure we don't call target_end from inside _dispose, since that
can't signal error either

see #2801
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants