#"header too large" when handling images

2 messages · Page 1 of 1 (latest)

fresh willow
#

i am working on a large project and i have this very simple image viewer:

import { invoke } from "@tauri-apps/api";
import { useState } from "react";

export default function image_viewer(file_selected: string | null){
    const [image, set_image] = useState("");
    let update = async () => {
        // all of these lines do exactly what you think.
        // i don't think it's neccesery to add the rust side, since this doesn't
        // affect the issue
        if (file_selected == null) {return;}
        let name: string = await invoke('system_get', {key: 'name'});
        let password: string = await invoke('system_get', {key: 'password'});
        let bytes: string = await invoke('read_file', {name, password,file: file_selected});
        if (bytes == null) {return;}
        set_image(bytes);
    }
    let html = <div className="outer">
        <img className="inner" src={image}>
        </img>
    </div>
    return {html, update};
}

when the image is too large, it returns "[image bytes] (header too large)". tauri also links to https://www.cve.org/CVERecord?id=CVE-2018-12121 for the reason why this happens, but i'm not sure how can i fix this issue, since as far as i know, either set_image or the <img> tag are causing this issue, and neither of them can be removed from this code. how can i fix this issue?

fresh willow
#

okay so i realized the issue is related to how <img> is parsing src. so i tried looking up how can i fix that issue and i found out that it would be better to decode the image and encode it in base64,

so i added this function:

#[tauri::command]
pub fn image_to_string(bytes: Vec<u8>) -> Value {
    let reader = image::io::Reader::new(std::io::Cursor::new(bytes));
    let reader = reader.with_guessed_format();
    if reader.is_err(){return Value::Null}
    let result = reader.unwrap().decode();
    if result.is_err() {return Value::Null}
    let result = base64::encode(result.unwrap().as_bytes());
    return Value::String(result);
}

and now the code looks like this:

import { invoke } from "@tauri-apps/api";
import { useState } from "react";

export default function image_viewer(file_selected: string | null){
    const [image, set_image] = useState("");
    let update = async () => {
        // all of these lines do exactly what you think.
        // i don't think it's neccesery to add the rust side, since this doesn't
        // affect the issue
        if (file_selected == null) {return;}
        let name: string = await invoke('system_get', {key: 'name'});
        let password: string = await invoke('system_get', {key: 'password'});
        let bytes = await invoke('read_file', {name, password,file: file_selected});
        if (bytes == null) {return;}
        let result: string = await invoke('image_to_string', {bytes})
        set_image(result);
    }
    let html = <div className="outer">
        <img className="inner" src={image}>
        </img>
    </div>
    return {html, update};
}