mirror of
https://github.com/storytold/photocraft.git
synced 2026-11-02 18:13:39 +00:00
Cap UTF-8 text collection and guard mesh lookups in warp validation
block_chars now takes at most the remaining text allowance, matching the mixed-segment arm. The mesh-fit check uses guarded lookups for the us, vs and points arrays so a malformed mesh returns false instead of panicking. Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
This commit is contained in:
@@ -69,14 +69,14 @@ pub(crate) fn read(r: &mut Reader, id: ObjId, world: Affine) -> Option<Text> {
|
||||
/// inline object (page number, anchor) takes one `U+FFFC` before its segment's text. Stops once
|
||||
/// `total` plus these characters would pass the cap.
|
||||
fn block_chars(s: &Stream, glyphs: ObjId, total: usize, placeholders: &mut bool) -> Vec<char> {
|
||||
// One past the allowance is enough to trip the check in `read`; both arms stop there.
|
||||
let room = MAX_CHARS.saturating_sub(total).saturating_add(1);
|
||||
match s.str(glyphs, b"Utf8") {
|
||||
Some(t) => t.chars().collect(),
|
||||
Some(t) => t.chars().take(room).collect(),
|
||||
None => {
|
||||
// Inline objects (page numbers, anchors) each take one index before the segment text.
|
||||
let mut v = Vec::new();
|
||||
// One past the allowance is enough to trip the check below; shared segments
|
||||
// repeated by reference must not expand beyond it first.
|
||||
let room = MAX_CHARS.saturating_sub(total).saturating_add(1);
|
||||
// Shared segments repeated by reference must not expand beyond the allowance first.
|
||||
for seg in s.objs(glyphs, b"Mixd") {
|
||||
if v.len() >= room {
|
||||
break;
|
||||
|
||||
+11
-3
@@ -1111,12 +1111,20 @@ impl Warp {
|
||||
/// One sample row (`j` within patch row `pj`) of [`Self::mesh_is_box_fit`].
|
||||
fn mesh_row_is_box_fit(&self, m: &BezierMesh, pj: usize, j: usize, pc: usize) -> bool {
|
||||
let nx = m.nx();
|
||||
let v = m.vs[pj] + (m.vs[pj + 1] - m.vs[pj]) * j as f64 / 3.0;
|
||||
let (Some(&v0), Some(&v1)) = (m.vs.get(pj), m.vs.get(pj + 1)) else {
|
||||
return false;
|
||||
};
|
||||
let v = v0 + (v1 - v0) * j as f64 / 3.0;
|
||||
for pi in 0..pc {
|
||||
let (Some(&u0), Some(&u1)) = (m.us.get(pi), m.us.get(pi + 1)) else {
|
||||
return false;
|
||||
};
|
||||
for i in 0..4 {
|
||||
let u = m.us[pi] + (m.us[pi + 1] - m.us[pi]) * i as f64 / 3.0;
|
||||
let u = u0 + (u1 - u0) * i as f64 / 3.0;
|
||||
let expected = self.box_point(u, v);
|
||||
let actual = m.points[(3 * pj + j) * nx + 3 * pi + i];
|
||||
let Some(&actual) = m.points.get((3 * pj + j) * nx + 3 * pi + i) else {
|
||||
return false;
|
||||
};
|
||||
if !point_fits(expected, actual) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user