[buffer] Return success status from buffer ops that can fail

Previous error-handling philosophy was that user doesn't need to
immediately know whether operation failed. But as can be seen after
we added malloc-failing fuzzing, there's just so many places in the
code that a failure of these operations needs to be mitigated before
further operations. So I'm moving towards returning success here,
and possibly making it nodiscard.
This commit is contained in:
Behdad Esfahbod 2021-03-15 13:13:45 -06:00
parent a5b8e7db4d
commit 906c9928bb
2 changed files with 22 additions and 17 deletions

View File

@ -343,12 +343,12 @@ hb_buffer_t::swap_buffers ()
} }
void bool
hb_buffer_t::replace_glyphs (unsigned int num_in, hb_buffer_t::replace_glyphs (unsigned int num_in,
unsigned int num_out, unsigned int num_out,
const uint32_t *glyph_data) const uint32_t *glyph_data)
{ {
if (unlikely (!make_room_for (num_in, num_out))) return; if (unlikely (!make_room_for (num_in, num_out))) return false;
assert (idx + num_in <= len); assert (idx + num_in <= len);
@ -365,6 +365,8 @@ hb_buffer_t::replace_glyphs (unsigned int num_in,
idx += num_in; idx += num_in;
out_len += num_out; out_len += num_out;
return true;
} }
bool bool

View File

@ -210,20 +210,22 @@ struct hb_buffer_t
HB_INTERNAL void clear_output (); HB_INTERNAL void clear_output ();
HB_INTERNAL void clear_positions (); HB_INTERNAL void clear_positions ();
HB_INTERNAL void replace_glyphs (unsigned int num_in, HB_INTERNAL bool replace_glyphs (unsigned int num_in,
unsigned int num_out, unsigned int num_out,
const hb_codepoint_t *glyph_data); const hb_codepoint_t *glyph_data);
void replace_glyph (hb_codepoint_t glyph_index) bool replace_glyph (hb_codepoint_t glyph_index)
{ {
if (unlikely (out_info != info || out_len != idx)) { if (unlikely (out_info != info || out_len != idx))
if (unlikely (!make_room_for (1, 1))) return; {
if (unlikely (!make_room_for (1, 1))) return false;
out_info[out_len] = info[idx]; out_info[out_len] = info[idx];
} }
out_info[out_len].codepoint = glyph_index; out_info[out_len].codepoint = glyph_index;
idx++; idx++;
out_len++; out_len++;
return true;
} }
/* Makes a copy of the glyph at idx to output and replace glyph_index */ /* Makes a copy of the glyph at idx to output and replace glyph_index */
hb_glyph_info_t & output_glyph (hb_codepoint_t glyph_index) hb_glyph_info_t & output_glyph (hb_codepoint_t glyph_index)
@ -237,59 +239,60 @@ struct hb_buffer_t
out_info[out_len].codepoint = glyph_index; out_info[out_len].codepoint = glyph_index;
out_len++; out_len++;
return out_info[out_len - 1]; return out_info[out_len - 1];
} }
void output_info (const hb_glyph_info_t &glyph_info) bool output_info (const hb_glyph_info_t &glyph_info)
{ {
if (unlikely (!make_room_for (0, 1))) return; if (unlikely (!make_room_for (0, 1))) return false;
out_info[out_len] = glyph_info; out_info[out_len] = glyph_info;
out_len++; out_len++;
return true;
} }
/* Copies glyph at idx to output but doesn't advance idx */ /* Copies glyph at idx to output but doesn't advance idx */
void copy_glyph () bool copy_glyph ()
{ {
if (unlikely (!make_room_for (0, 1))) return; if (unlikely (!make_room_for (0, 1))) return false;
out_info[out_len] = info[idx]; out_info[out_len] = info[idx];
out_len++; out_len++;
return true;
} }
/* Copies glyph at idx to output and advance idx. /* Copies glyph at idx to output and advance idx.
* If there's no output, just advance idx. */ * If there's no output, just advance idx. */
void bool next_glyph ()
next_glyph ()
{ {
if (have_output) if (have_output)
{ {
if (out_info != info || out_len != idx) if (out_info != info || out_len != idx)
{ {
if (unlikely (!make_room_for (1, 1))) return; if (unlikely (!make_room_for (1, 1))) return false;
out_info[out_len] = info[idx]; out_info[out_len] = info[idx];
} }
out_len++; out_len++;
} }
idx++; idx++;
return true;
} }
/* Copies n glyphs at idx to output and advance idx. /* Copies n glyphs at idx to output and advance idx.
* If there's no output, just advance idx. */ * If there's no output, just advance idx. */
void bool next_glyphs (unsigned int n)
next_glyphs (unsigned int n)
{ {
if (have_output) if (have_output)
{ {
if (out_info != info || out_len != idx) if (out_info != info || out_len != idx)
{ {
if (unlikely (!make_room_for (n, n))) return; if (unlikely (!make_room_for (n, n))) return false;
memmove (out_info + out_len, info + idx, n * sizeof (out_info[0])); memmove (out_info + out_len, info + idx, n * sizeof (out_info[0]));
} }
out_len += n; out_len += n;
} }
idx += n; idx += n;
return true;
} }
/* Advance idx without copying to output. */ /* Advance idx without copying to output. */
void skip_glyph () { idx++; } void skip_glyph () { idx++; }