[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.
pull/2900/head
Behdad Esfahbod 4 years ago
parent a5b8e7db4d
commit 906c9928bb
  1. 6
      src/hb-buffer.cc
  2. 33
      src/hb-buffer.hh

@ -343,12 +343,12 @@ hb_buffer_t::swap_buffers ()
}
void
bool
hb_buffer_t::replace_glyphs (unsigned int num_in,
unsigned int num_out,
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);
@ -365,6 +365,8 @@ hb_buffer_t::replace_glyphs (unsigned int num_in,
idx += num_in;
out_len += num_out;
return true;
}
bool

@ -210,20 +210,22 @@ struct hb_buffer_t
HB_INTERNAL void clear_output ();
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,
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 (!make_room_for (1, 1))) return;
if (unlikely (out_info != info || out_len != idx))
{
if (unlikely (!make_room_for (1, 1))) return false;
out_info[out_len] = info[idx];
}
out_info[out_len].codepoint = glyph_index;
idx++;
out_len++;
return true;
}
/* 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)
@ -237,59 +239,60 @@ struct hb_buffer_t
out_info[out_len].codepoint = glyph_index;
out_len++;
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_len++;
return true;
}
/* 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_len++;
return true;
}
/* Copies glyph at idx to output and advance idx.
* If there's no output, just advance idx. */
void
next_glyph ()
bool next_glyph ()
{
if (have_output)
{
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_len++;
}
idx++;
return true;
}
/* Copies n glyphs at idx to output and advance idx.
* If there's no output, just advance idx. */
void
next_glyphs (unsigned int n)
bool next_glyphs (unsigned int n)
{
if (have_output)
{
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]));
}
out_len += n;
}
idx += n;
return true;
}
/* Advance idx without copying to output. */
void skip_glyph () { idx++; }

Loading…
Cancel
Save