mirror of
https://github.com/chatmail/core.git
synced 2026-05-21 15:56:30 +03:00
fix: use BufReader when reading .xdc files
This commit is contained in:
@@ -24,7 +24,7 @@ use std::path::Path;
|
|||||||
|
|
||||||
use anyhow::{anyhow, bail, ensure, format_err, Context as _, Result};
|
use anyhow::{anyhow, bail, ensure, format_err, Context as _, Result};
|
||||||
|
|
||||||
use async_zip::tokio::read::fs::ZipFileReader as FsZipFileReader;
|
use async_zip::tokio::read::seek::ZipFileReader as SeekZipFileReader;
|
||||||
use deltachat_contact_tools::sanitize_bidi_characters;
|
use deltachat_contact_tools::sanitize_bidi_characters;
|
||||||
use deltachat_derive::FromSql;
|
use deltachat_derive::FromSql;
|
||||||
use lettre_email::PartBuilder;
|
use lettre_email::PartBuilder;
|
||||||
@@ -32,6 +32,7 @@ use rusqlite::OptionalExtension;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
use tokio::{fs::File, io::BufReader};
|
||||||
|
|
||||||
use crate::chat::{self, Chat};
|
use crate::chat::{self, Chat};
|
||||||
use crate::constants::Chattype;
|
use crate::constants::Chattype;
|
||||||
@@ -262,7 +263,8 @@ impl Context {
|
|||||||
pub(crate) async fn ensure_sendable_webxdc_file(&self, path: &Path) -> Result<()> {
|
pub(crate) async fn ensure_sendable_webxdc_file(&self, path: &Path) -> Result<()> {
|
||||||
let filename = path.to_str().unwrap_or_default();
|
let filename = path.to_str().unwrap_or_default();
|
||||||
|
|
||||||
let valid = match FsZipFileReader::new(path).await {
|
let file = BufReader::new(File::open(path).await?);
|
||||||
|
let valid = match SeekZipFileReader::with_tokio(file).await {
|
||||||
Ok(archive) => {
|
Ok(archive) => {
|
||||||
if find_zip_entry(archive.file(), "index.html").is_none() {
|
if find_zip_entry(archive.file(), "index.html").is_none() {
|
||||||
warn!(self, "{} misses index.html", filename);
|
warn!(self, "{} misses index.html", filename);
|
||||||
@@ -839,7 +841,7 @@ fn parse_webxdc_manifest(bytes: &[u8]) -> Result<WebxdcManifest> {
|
|||||||
Ok(manifest)
|
Ok(manifest)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_blob(archive: &FsZipFileReader, name: &str) -> Result<Vec<u8>> {
|
async fn get_blob(archive: &mut SeekZipFileReader<BufReader<File>>, name: &str) -> Result<Vec<u8>> {
|
||||||
let (i, _) = find_zip_entry(archive.file(), name)
|
let (i, _) = find_zip_entry(archive.file(), name)
|
||||||
.ok_or_else(|| anyhow!("no entry found for {}", name))?;
|
.ok_or_else(|| anyhow!("no entry found for {}", name))?;
|
||||||
let mut reader = archive.reader_with_entry(i).await?;
|
let mut reader = archive.reader_with_entry(i).await?;
|
||||||
@@ -851,12 +853,16 @@ async fn get_blob(archive: &FsZipFileReader, name: &str) -> Result<Vec<u8>> {
|
|||||||
impl Message {
|
impl Message {
|
||||||
/// Get handle to a webxdc ZIP-archive.
|
/// Get handle to a webxdc ZIP-archive.
|
||||||
/// To check for file existence use archive.by_name(), to read a file, use get_blob(archive).
|
/// To check for file existence use archive.by_name(), to read a file, use get_blob(archive).
|
||||||
async fn get_webxdc_archive(&self, context: &Context) -> Result<FsZipFileReader> {
|
async fn get_webxdc_archive(
|
||||||
|
&self,
|
||||||
|
context: &Context,
|
||||||
|
) -> Result<SeekZipFileReader<BufReader<File>>> {
|
||||||
let path = self
|
let path = self
|
||||||
.get_file(context)
|
.get_file(context)
|
||||||
.ok_or_else(|| format_err!("No webxdc instance file."))?;
|
.ok_or_else(|| format_err!("No webxdc instance file."))?;
|
||||||
let path_abs = get_abs_path(context, &path);
|
let path_abs = get_abs_path(context, &path);
|
||||||
let archive = FsZipFileReader::new(path_abs).await?;
|
let file = BufReader::new(File::open(path_abs).await?);
|
||||||
|
let archive = SeekZipFileReader::with_tokio(file).await?;
|
||||||
Ok(archive)
|
Ok(archive)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -879,10 +885,10 @@ impl Message {
|
|||||||
name
|
name
|
||||||
};
|
};
|
||||||
|
|
||||||
let archive = self.get_webxdc_archive(context).await?;
|
let mut archive = self.get_webxdc_archive(context).await?;
|
||||||
|
|
||||||
if name == "index.html" {
|
if name == "index.html" {
|
||||||
if let Ok(bytes) = get_blob(&archive, "manifest.toml").await {
|
if let Ok(bytes) = get_blob(&mut archive, "manifest.toml").await {
|
||||||
if let Ok(manifest) = parse_webxdc_manifest(&bytes) {
|
if let Ok(manifest) = parse_webxdc_manifest(&bytes) {
|
||||||
if let Some(min_api) = manifest.min_api {
|
if let Some(min_api) = manifest.min_api {
|
||||||
if min_api > WEBXDC_API_VERSION {
|
if min_api > WEBXDC_API_VERSION {
|
||||||
@@ -895,15 +901,15 @@ impl Message {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get_blob(&archive, name).await
|
get_blob(&mut archive, name).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return info from manifest.toml or from fallbacks.
|
/// Return info from manifest.toml or from fallbacks.
|
||||||
pub async fn get_webxdc_info(&self, context: &Context) -> Result<WebxdcInfo> {
|
pub async fn get_webxdc_info(&self, context: &Context) -> Result<WebxdcInfo> {
|
||||||
ensure!(self.viewtype == Viewtype::Webxdc, "No webxdc instance.");
|
ensure!(self.viewtype == Viewtype::Webxdc, "No webxdc instance.");
|
||||||
let archive = self.get_webxdc_archive(context).await?;
|
let mut archive = self.get_webxdc_archive(context).await?;
|
||||||
|
|
||||||
let mut manifest = get_blob(&archive, "manifest.toml")
|
let mut manifest = get_blob(&mut archive, "manifest.toml")
|
||||||
.await
|
.await
|
||||||
.map(|bytes| parse_webxdc_manifest(&bytes).unwrap_or_default())
|
.map(|bytes| parse_webxdc_manifest(&bytes).unwrap_or_default())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|||||||
Reference in New Issue
Block a user