Merge pull request #2900 from harfbuzz/nodiscard-buffer

Mark buffer modification methods that can fail with nodiscard
This commit is contained in:
Behdad Esfahbod 2021-03-15 18:50:02 -07:00 committed by GitHub
commit daeb277346
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 150 additions and 178 deletions

View File

@ -117,11 +117,7 @@ jobs:
- image: ubuntu:20.04 - image: ubuntu:20.04
steps: steps:
- checkout - checkout
- run: apt update || true; DEBIAN_FRONTEND=noninteractive apt install -y wget gnupg - run: apt update || true
#- run: wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
#- run: echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal main" > /etc/apt/sources.list.d/llvmdev.list
#- run: echo "deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal main" > /etc/apt/sources.list.d/llvmdevsrc.list
#- run: apt update || true
- run: DEBIAN_FRONTEND=noninteractive apt install -y clang lld git binutils meson pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev - run: DEBIAN_FRONTEND=noninteractive apt install -y clang lld git binutils meson pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev
# asan+ubsan # asan+ubsan
- run: rm -rf build && meson build --default-library=static -Db_sanitize=address,undefined --buildtype=debugoptimized --wrap-mode=nodownload -Dexperimental_api=true - run: rm -rf build && meson build --default-library=static -Db_sanitize=address,undefined --buildtype=debugoptimized --wrap-mode=nodownload -Dexperimental_api=true
@ -132,9 +128,7 @@ jobs:
# msan, needs --force-fallback-for=glib,freetype2 also which doesn't work yet but runs fuzzer cases at least # msan, needs --force-fallback-for=glib,freetype2 also which doesn't work yet but runs fuzzer cases at least
- run: rm -rf build && meson build --default-library=static -Db_sanitize=memory --buildtype=debugoptimized --wrap-mode=nodownload -Dauto_features=disabled -Dtests=enabled -Dexperimental_api=true - run: rm -rf build && meson build --default-library=static -Db_sanitize=memory --buildtype=debugoptimized --wrap-mode=nodownload -Dauto_features=disabled -Dtests=enabled -Dexperimental_api=true
- run: ninja -Cbuild -j8 && meson test -Cbuild --print-errorlogs | asan_symbolize | c++filt - run: ninja -Cbuild -j8 && meson test -Cbuild --print-errorlogs | asan_symbolize | c++filt
# test -std=c++2a and -Weverything of nightly clang builds
- run: clang -c src/harfbuzz.cc src/hb-subset*.cc -DHB_NO_MT -Werror -std=c++2a - run: clang -c src/harfbuzz.cc src/hb-subset*.cc -DHB_NO_MT -Werror -std=c++2a
- run: clang -c src/hb-*.cc -DHB_NO_MT -Werror -Weverything -Wno-old-style-cast -Wno-documentation -Wno-documentation-unknown-command -Wno-c++98-compat -Wno-cast-qual -Wno-c++98-compat-pedantic -Wno-sign-conversion -Wno-padded -Wno-shorten-64-to-32 -Wno-reserved-id-macro -Wno-float-conversion -Wno-format-pedantic -Wno-shadow -Wno-conversion -Wno-zero-as-null-pointer-constant -Wno-missing-field-initializers -Wno-used-but-marked-unused -Wno-unused-macros -Wno-comma -Wno-float-equal -Wno-disabled-macro-expansion -Wno-weak-vtables -Wno-unused-parameter -Wno-covered-switch-default -Wno-unreachable-code -Wno-unused-template -DHB_WITH_WIN1256
crossbuild-win32: crossbuild-win32:
executor: win32-executor executor: win32-executor

View File

@ -101,7 +101,7 @@ class ConstraintSet (object):
self._indent (depth + 2), cp, index + i, ')' if i == len (self._c) - 1 else ' &&')) self._indent (depth + 2), cp, index + i, ')' if i == len (self._c) - 1 else ' &&'))
s.append ('{}{{\n'.format (indent)) s.append ('{}{{\n'.format (indent))
for i in range (index): for i in range (index):
s.append ('{}buffer->next_glyph ();\n'.format (self._indent (depth + 1))) s.append ('{}(void) buffer->next_glyph ();\n'.format (self._indent (depth + 1)))
s.append ('{}matched = true;\n'.format (self._indent (depth + 1))) s.append ('{}matched = true;\n'.format (self._indent (depth + 1)))
s.append ('{}}}\n'.format (indent)) s.append ('{}}}\n'.format (indent))
else: else:
@ -171,15 +171,15 @@ print ()
print ('static void') print ('static void')
print ('_output_dotted_circle (hb_buffer_t *buffer)') print ('_output_dotted_circle (hb_buffer_t *buffer)')
print ('{') print ('{')
print (' hb_glyph_info_t &dottedcircle = buffer->output_glyph (0x25CCu);') print (' (void) buffer->output_glyph (0x25CCu);')
print (' _hb_glyph_info_reset_continuation (&dottedcircle);') print (' _hb_glyph_info_reset_continuation (&buffer->prev());')
print ('}') print ('}')
print () print ()
print ('static void') print ('static void')
print ('_output_with_dotted_circle (hb_buffer_t *buffer)') print ('_output_with_dotted_circle (hb_buffer_t *buffer)')
print ('{') print ('{')
print (' _output_dotted_circle (buffer);') print (' _output_dotted_circle (buffer);')
print (' buffer->next_glyph ();') print (' (void) buffer->next_glyph ();')
print ('}') print ('}')
print () print ()
@ -211,7 +211,7 @@ for script, constraints in sorted (constraints.items (), key=lambda s_c: script_
print (' {') print (' {')
print ('\tbool matched = false;') print ('\tbool matched = false;')
write (str (constraints)) write (str (constraints))
print ('\tbuffer->next_glyph ();') print ('\t(void) buffer->next_glyph ();')
print ('\tif (matched) _output_with_dotted_circle (buffer);') print ('\tif (matched) _output_with_dotted_circle (buffer);')
print (' }') print (' }')
print (' break;') print (' break;')

View File

@ -831,7 +831,7 @@ struct StateTableDriver
break; break;
if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0) if (!(entry.flags & context_t::DontAdvance) || buffer->max_ops-- <= 0)
buffer->next_glyph (); (void) buffer->next_glyph ();
} }
if (!c->in_place) if (!c->in_place)

View File

@ -499,7 +499,7 @@ struct LigatureSubtable
} }
DEBUG_MSG (APPLY, nullptr, "Moving to stack position %u", cursor - 1); DEBUG_MSG (APPLY, nullptr, "Moving to stack position %u", cursor - 1);
buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]); if (unlikely (!buffer->move_to (match_positions[--cursor % ARRAY_LENGTH (match_positions)]))) return;
if (unlikely (!actionData->sanitize (&c->sanitizer))) break; if (unlikely (!actionData->sanitize (&c->sanitizer))) break;
action = *actionData; action = *actionData;
@ -525,25 +525,25 @@ struct LigatureSubtable
hb_codepoint_t lig = ligatureData; hb_codepoint_t lig = ligatureData;
DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig); DEBUG_MSG (APPLY, nullptr, "Produced ligature %u", lig);
buffer->replace_glyph (lig); if (unlikely (!buffer->replace_glyph (lig))) return;
unsigned int lig_end = match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] + 1u; unsigned int lig_end = match_positions[(match_length - 1u) % ARRAY_LENGTH (match_positions)] + 1u;
/* Now go and delete all subsequent components. */ /* Now go and delete all subsequent components. */
while (match_length - 1u > cursor) while (match_length - 1u > cursor)
{ {
DEBUG_MSG (APPLY, nullptr, "Skipping ligature component"); DEBUG_MSG (APPLY, nullptr, "Skipping ligature component");
buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]); if (unlikely (!buffer->move_to (match_positions[--match_length % ARRAY_LENGTH (match_positions)]))) return;
buffer->replace_glyph (DELETED_GLYPH); if (unlikely (!buffer->replace_glyph (DELETED_GLYPH))) return;
} }
buffer->move_to (lig_end); if (unlikely (!buffer->move_to (lig_end))) return;
buffer->merge_out_clusters (match_positions[cursor % ARRAY_LENGTH (match_positions)], buffer->out_len); buffer->merge_out_clusters (match_positions[cursor % ARRAY_LENGTH (match_positions)], buffer->out_len);
} }
actionData++; actionData++;
} }
while (!(action & LigActionLast)); while (!(action & LigActionLast));
buffer->move_to (end); if (unlikely (!buffer->move_to (end))) return;
} }
} }
@ -733,17 +733,16 @@ struct InsertionSubtable
bool before = flags & MarkedInsertBefore; bool before = flags & MarkedInsertBefore;
unsigned int end = buffer->out_len; unsigned int end = buffer->out_len;
buffer->move_to (mark); if (unlikely (!buffer->move_to (mark))) return;
if (buffer->idx < buffer->len && !before) if (buffer->idx < buffer->len && !before)
buffer->copy_glyph (); if (unlikely (!buffer->copy_glyph ())) return;
/* TODO We ignore KashidaLike setting. */ /* TODO We ignore KashidaLike setting. */
for (unsigned int i = 0; i < count; i++) if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return;
buffer->output_glyph (glyphs[i]);
if (buffer->idx < buffer->len && !before) if (buffer->idx < buffer->len && !before)
buffer->skip_glyph (); buffer->skip_glyph ();
buffer->move_to (end + count); if (unlikely (!buffer->move_to (end + count))) return;
buffer->unsafe_to_break_from_outbuffer (mark, hb_min (buffer->idx + 1, buffer->len)); buffer->unsafe_to_break_from_outbuffer (mark, hb_min (buffer->idx + 1, buffer->len));
} }
@ -764,10 +763,9 @@ struct InsertionSubtable
unsigned int end = buffer->out_len; unsigned int end = buffer->out_len;
if (buffer->idx < buffer->len && !before) if (buffer->idx < buffer->len && !before)
buffer->copy_glyph (); if (unlikely (!buffer->copy_glyph ())) return;
/* TODO We ignore KashidaLike setting. */ /* TODO We ignore KashidaLike setting. */
for (unsigned int i = 0; i < count; i++) if (unlikely (!buffer->replace_glyphs (0, count, glyphs))) return;
buffer->output_glyph (glyphs[i]);
if (buffer->idx < buffer->len && !before) if (buffer->idx < buffer->len && !before)
buffer->skip_glyph (); buffer->skip_glyph ();
@ -786,7 +784,7 @@ struct InsertionSubtable
* *
* https://github.com/harfbuzz/harfbuzz/issues/1224#issuecomment-427691417 * https://github.com/harfbuzz/harfbuzz/issues/1224#issuecomment-427691417
*/ */
buffer->move_to ((flags & DontAdvance) ? end : end + count); if (unlikely (!buffer->move_to ((flags & DontAdvance) ? end : end + count))) return;
} }
} }

View File

@ -319,7 +319,7 @@ hb_buffer_t::swap_buffers ()
if (unlikely (!successful)) return; if (unlikely (!successful)) return;
assert (idx <= len); assert (idx <= len);
next_glyphs (len - idx); if (unlikely (!next_glyphs (len - idx))) return;
assert (have_output); assert (have_output);
have_output = false; have_output = false;
@ -342,31 +342,6 @@ hb_buffer_t::swap_buffers ()
idx = 0; idx = 0;
} }
void
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;
assert (idx + num_in <= len);
merge_clusters (idx, idx + num_in);
hb_glyph_info_t orig_info = info[idx];
hb_glyph_info_t *pinfo = &out_info[out_len];
for (unsigned int i = 0; i < num_out; i++)
{
*pinfo = orig_info;
pinfo->codepoint = glyph_data[i];
pinfo++;
}
idx += num_in;
out_len += num_out;
}
bool bool
hb_buffer_t::move_to (unsigned int i) hb_buffer_t::move_to (unsigned int i)
{ {
@ -1316,7 +1291,7 @@ hb_buffer_set_length (hb_buffer_t *buffer,
if (unlikely (hb_object_is_immutable (buffer))) if (unlikely (hb_object_is_immutable (buffer)))
return length == 0; return length == 0;
if (!buffer->ensure (length)) if (unlikely (!buffer->ensure (length)))
return false; return false;
/* Wipe the new space */ /* Wipe the new space */
@ -1546,7 +1521,10 @@ hb_buffer_add_utf (hb_buffer_t *buffer,
if (item_length == -1) if (item_length == -1)
item_length = text_length - item_offset; item_length = text_length - item_offset;
buffer->ensure (buffer->len + item_length * sizeof (T) / 4); if (unlikely (item_length < 0 ||
item_length > INT_MAX / 8 ||
!buffer->ensure (buffer->len + item_length * sizeof (T) / 4)))
return;
/* If buffer is empty and pre-context provided, install it. /* If buffer is empty and pre-context provided, install it.
* This check is written this way, to make sure people can * This check is written this way, to make sure people can

View File

@ -139,7 +139,7 @@ struct hb_buffer_t
/* Methods */ /* Methods */
bool in_error () const { return !successful; } HB_NODISCARD bool in_error () const { return !successful; }
void allocate_var (unsigned int start, unsigned int count) void allocate_var (unsigned int start, unsigned int count)
{ {
@ -186,7 +186,7 @@ struct hb_buffer_t
hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; } hb_glyph_info_t &prev () { return out_info[out_len ? out_len - 1 : 0]; }
hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; } hb_glyph_info_t prev () const { return out_info[out_len ? out_len - 1 : 0]; }
bool has_separate_output () const { return info != out_info; } HB_NODISCARD bool has_separate_output () const { return info != out_info; }
HB_INTERNAL void reset (); HB_INTERNAL void reset ();
@ -210,86 +210,89 @@ 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, template <typename T>
HB_NODISCARD bool replace_glyphs (unsigned int num_in,
unsigned int num_out, unsigned int num_out,
const hb_codepoint_t *glyph_data); const T *glyph_data)
void replace_glyph (hb_codepoint_t glyph_index)
{ {
if (unlikely (out_info != info || out_len != idx)) { if (unlikely (!make_room_for (num_in, num_out))) return false;
if (unlikely (!make_room_for (1, 1))) return;
out_info[out_len] = info[idx];
}
out_info[out_len].codepoint = glyph_index;
idx++; assert (idx + num_in <= len);
out_len++;
merge_clusters (idx, idx + num_in);
hb_glyph_info_t &orig_info = idx < len ? cur() : prev();
hb_glyph_info_t *pinfo = &out_info[out_len];
for (unsigned int i = 0; i < num_out; i++)
{
*pinfo = orig_info;
pinfo->codepoint = glyph_data[i];
pinfo++;
} }
idx += num_in;
out_len += num_out;
return true;
}
HB_NODISCARD bool replace_glyph (hb_codepoint_t glyph_index)
{ return replace_glyphs (1, 1, &glyph_index); }
/* 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_NODISCARD bool output_glyph (hb_codepoint_t glyph_index)
{ return replace_glyphs (0, 1, &glyph_index); }
HB_NODISCARD bool output_info (const hb_glyph_info_t &glyph_info)
{ {
if (unlikely (!make_room_for (0, 1))) return Crap (hb_glyph_info_t); if (unlikely (!make_room_for (0, 1))) return false;
if (unlikely (idx == len && !out_len))
return Crap (hb_glyph_info_t);
out_info[out_len] = idx < len ? info[idx] : out_info[out_len - 1];
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)
{
if (unlikely (!make_room_for (0, 1))) return;
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 () HB_NODISCARD bool copy_glyph ()
{ {
if (unlikely (!make_room_for (0, 1))) return; /* Extra copy because cur()'s return can be freed within
* output_info() call if buffer reallocates. */
out_info[out_len] = info[idx]; return output_info (hb_glyph_info_t (cur()));
out_len++;
} }
/* 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 HB_NODISCARD 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 HB_NODISCARD 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++; }
@ -329,14 +332,14 @@ struct hb_buffer_t
/* Internal methods */ /* Internal methods */
HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */ HB_NODISCARD HB_INTERNAL bool move_to (unsigned int i); /* i is output-buffer index. */
HB_INTERNAL bool enlarge (unsigned int size); HB_NODISCARD HB_INTERNAL bool enlarge (unsigned int size);
bool ensure (unsigned int size) HB_NODISCARD bool ensure (unsigned int size)
{ return likely (!size || size < allocated) ? true : enlarge (size); } { return likely (!size || size < allocated) ? true : enlarge (size); }
bool ensure_inplace (unsigned int size) HB_NODISCARD bool ensure_inplace (unsigned int size)
{ return likely (!size || size < allocated); } { return likely (!size || size < allocated); }
void assert_glyphs () void assert_glyphs ()
@ -349,7 +352,7 @@ struct hb_buffer_t
assert ((content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) || assert ((content_type == HB_BUFFER_CONTENT_TYPE_UNICODE) ||
(!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID))); (!len && (content_type == HB_BUFFER_CONTENT_TYPE_INVALID)));
} }
bool ensure_glyphs () HB_NODISCARD bool ensure_glyphs ()
{ {
if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS)) if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_GLYPHS))
{ {
@ -360,7 +363,7 @@ struct hb_buffer_t
} }
return true; return true;
} }
bool ensure_unicode () HB_NODISCARD bool ensure_unicode ()
{ {
if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_UNICODE)) if (unlikely (content_type != HB_BUFFER_CONTENT_TYPE_UNICODE))
{ {
@ -372,8 +375,8 @@ struct hb_buffer_t
return true; return true;
} }
HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out); HB_NODISCARD HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
HB_INTERNAL bool shift_forward (unsigned int count); HB_NODISCARD HB_INTERNAL bool shift_forward (unsigned int count);
typedef long scratch_buffer_t; typedef long scratch_buffer_t;
HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size); HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size);

View File

@ -289,7 +289,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
return true; return true;
} }
buffer->ensure (glyph_count); (void) buffer->ensure (glyph_count);
scratch = buffer->get_scratch_buffer (&scratch_size); scratch = buffer->get_scratch_buffer (&scratch_size);
while ((DIV_CEIL (sizeof (hb_graphite2_cluster_t) * buffer->len, sizeof (*scratch)) + while ((DIV_CEIL (sizeof (hb_graphite2_cluster_t) * buffer->len, sizeof (*scratch)) +
DIV_CEIL (sizeof (hb_codepoint_t) * glyph_count, sizeof (*scratch))) > scratch_size) DIV_CEIL (sizeof (hb_codepoint_t) * glyph_count, sizeof (*scratch))) > scratch_size)

View File

@ -659,7 +659,7 @@ struct hb_ot_apply_context_t :
void replace_glyph (hb_codepoint_t glyph_index) const void replace_glyph (hb_codepoint_t glyph_index) const
{ {
_set_glyph_props (glyph_index); _set_glyph_props (glyph_index);
buffer->replace_glyph (glyph_index); (void) buffer->replace_glyph (glyph_index);
} }
void replace_glyph_inplace (hb_codepoint_t glyph_index) const void replace_glyph_inplace (hb_codepoint_t glyph_index) const
{ {
@ -670,13 +670,13 @@ struct hb_ot_apply_context_t :
unsigned int class_guess) const unsigned int class_guess) const
{ {
_set_glyph_props (glyph_index, class_guess, true); _set_glyph_props (glyph_index, class_guess, true);
buffer->replace_glyph (glyph_index); (void) buffer->replace_glyph (glyph_index);
} }
void output_glyph_for_component (hb_codepoint_t glyph_index, void output_glyph_for_component (hb_codepoint_t glyph_index,
unsigned int class_guess) const unsigned int class_guess) const
{ {
_set_glyph_props (glyph_index, class_guess, false, true); _set_glyph_props (glyph_index, class_guess, false, true);
buffer->output_glyph (glyph_index); (void) buffer->output_glyph (glyph_index);
} }
}; };
@ -1043,7 +1043,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c,
hb_min (this_comp, last_num_components); hb_min (this_comp, last_num_components);
_hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp); _hb_glyph_info_set_lig_props_for_mark (&buffer->cur(), lig_id, new_lig_comp);
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
} }
last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur()); last_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
@ -1272,7 +1272,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c,
match_positions[next] += delta; match_positions[next] += delta;
} }
buffer->move_to (end); (void) buffer->move_to (end);
return_trace (true); return_trace (true);
} }

View File

@ -1782,7 +1782,7 @@ apply_forward (OT::hb_ot_apply_context_t *c,
if (applied) if (applied)
ret = true; ret = true;
else else
buffer->next_glyph (); (void) buffer->next_glyph ();
} }
return ret; return ret;
} }

View File

@ -205,7 +205,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
{ {
/* Tone mark follows a valid syllable; move it in front, unless it's zero width. */ /* Tone mark follows a valid syllable; move it in front, unless it's zero width. */
buffer->unsafe_to_break_from_outbuffer (start, buffer->idx); buffer->unsafe_to_break_from_outbuffer (start, buffer->idx);
buffer->next_glyph (); if (unlikely (!buffer->next_glyph ())) break;
if (!is_zero_width_char (font, u)) if (!is_zero_width_char (font, u))
{ {
buffer->merge_out_clusters (start, end + 1); buffer->merge_out_clusters (start, end + 1);
@ -231,12 +231,12 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
chars[0] = 0x25CCu; chars[0] = 0x25CCu;
chars[1] = u; chars[1] = u;
} }
buffer->replace_glyphs (1, 2, chars); (void) buffer->replace_glyphs (1, 2, chars);
} }
else else
{ {
/* No dotted circle available in the font; just leave tone mark untouched. */ /* No dotted circle available in the font; just leave tone mark untouched. */
buffer->next_glyph (); (void) buffer->next_glyph ();
} }
} }
start = end = buffer->out_len; start = end = buffer->out_len;
@ -273,7 +273,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_codepoint_t s = SBase + (l - LBase) * NCount + (v - VBase) * TCount + tindex; hb_codepoint_t s = SBase + (l - LBase) * NCount + (v - VBase) * TCount + tindex;
if (font->has_glyph (s)) if (font->has_glyph (s))
{ {
buffer->replace_glyphs (t ? 3 : 2, 1, &s); (void) buffer->replace_glyphs (t ? 3 : 2, 1, &s);
end = start + 1; end = start + 1;
continue; continue;
} }
@ -285,13 +285,13 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
* Set jamo features on the individual glyphs, and advance past them. * Set jamo features on the individual glyphs, and advance past them.
*/ */
buffer->cur().hangul_shaping_feature() = LJMO; buffer->cur().hangul_shaping_feature() = LJMO;
buffer->next_glyph (); (void) buffer->next_glyph ();
buffer->cur().hangul_shaping_feature() = VJMO; buffer->cur().hangul_shaping_feature() = VJMO;
buffer->next_glyph (); (void) buffer->next_glyph ();
if (t) if (t)
{ {
buffer->cur().hangul_shaping_feature() = TJMO; buffer->cur().hangul_shaping_feature() = TJMO;
buffer->next_glyph (); (void) buffer->next_glyph ();
end = start + 3; end = start + 3;
} }
else else
@ -323,9 +323,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_codepoint_t new_s = s + new_tindex; hb_codepoint_t new_s = s + new_tindex;
if (font->has_glyph (new_s)) if (font->has_glyph (new_s))
{ {
buffer->replace_glyphs (2, 1, &new_s); (void) buffer->replace_glyphs (2, 1, &new_s);
if (unlikely (!buffer->successful))
break;
end = start + 1; end = start + 1;
continue; continue;
} }
@ -349,14 +347,14 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
(!tindex || font->has_glyph (decomposed[2]))) (!tindex || font->has_glyph (decomposed[2])))
{ {
unsigned int s_len = tindex ? 3 : 2; unsigned int s_len = tindex ? 3 : 2;
buffer->replace_glyphs (1, s_len, decomposed); (void) buffer->replace_glyphs (1, s_len, decomposed);
/* If we decomposed an LV because of a non-combining T following, /* If we decomposed an LV because of a non-combining T following,
* we want to include this T in the syllable. * we want to include this T in the syllable.
*/ */
if (has_glyph && !tindex) if (has_glyph && !tindex)
{ {
buffer->next_glyph (); (void) buffer->next_glyph ();
s_len++; s_len++;
} }
if (unlikely (!buffer->successful)) if (unlikely (!buffer->successful))
@ -384,17 +382,15 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
if (has_glyph) if (has_glyph)
{ {
/* We didn't decompose the S, so just advance past it. */ /* We didn't decompose the S, so just advance past it and fall through. */
end = start + 1; end = start + 1;
buffer->next_glyph ();
continue;
} }
} }
/* Didn't find a recognizable syllable, so we leave end <= start; /* Didn't find a recognizable syllable, so we leave end <= start;
* this will prevent tone-mark reordering happening. * this will prevent tone-mark reordering happening.
*/ */
buffer->next_glyph (); (void) buffer->next_glyph ();
} }
buffer->swap_buffers (); buffer->swap_buffers ();
} }

View File

@ -85,13 +85,13 @@ hb_syllabic_insert_dotted_circles (hb_font_t *font,
while (buffer->idx < buffer->len && buffer->successful && while (buffer->idx < buffer->len && buffer->successful &&
last_syllable == buffer->cur().syllable() && last_syllable == buffer->cur().syllable() &&
buffer->cur().complex_var_u8_category() == (unsigned) repha_category) buffer->cur().complex_var_u8_category() == (unsigned) repha_category)
buffer->next_glyph (); (void) buffer->next_glyph ();
} }
buffer->output_info (ginfo); (void) buffer->output_info (ginfo);
} }
else else
buffer->next_glyph (); (void) buffer->next_glyph ();
} }
buffer->swap_buffers (); buffer->swap_buffers ();
} }

View File

@ -323,20 +323,19 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
buffer->clear_output (); buffer->clear_output ();
unsigned int count = buffer->len; unsigned int count = buffer->len;
for (buffer->idx = 0; buffer->idx < count && buffer->successful;) for (buffer->idx = 0; buffer->idx < count /* No need for: && buffer->successful */;)
{ {
hb_codepoint_t u = buffer->cur().codepoint; hb_codepoint_t u = buffer->cur().codepoint;
if (likely (!IS_SARA_AM (u))) { if (likely (!IS_SARA_AM (u)))
buffer->next_glyph (); {
if (unlikely (!buffer->next_glyph ())) break;
continue; continue;
} }
/* Is SARA AM. Decompose and reorder. */ /* Is SARA AM. Decompose and reorder. */
hb_glyph_info_t &nikhahit = buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u)); (void) buffer->output_glyph (NIKHAHIT_FROM_SARA_AM (u));
_hb_glyph_info_set_continuation (&nikhahit); _hb_glyph_info_set_continuation (&buffer->prev());
buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u)); if (unlikely (!buffer->replace_glyph (SARA_AA_FROM_SARA_AM (u)))) break;
if (unlikely (!buffer->successful))
return;
/* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */ /* Make Nikhahit be recognized as a ccc=0 mark when zeroing widths. */
unsigned int end = buffer->out_len; unsigned int end = buffer->out_len;

View File

@ -23,15 +23,15 @@
static void static void
_output_dotted_circle (hb_buffer_t *buffer) _output_dotted_circle (hb_buffer_t *buffer)
{ {
hb_glyph_info_t &dottedcircle = buffer->output_glyph (0x25CCu); (void) buffer->output_glyph (0x25CCu);
_hb_glyph_info_reset_continuation (&dottedcircle); _hb_glyph_info_reset_continuation (&buffer->prev());
} }
static void static void
_output_with_dotted_circle (hb_buffer_t *buffer) _output_with_dotted_circle (hb_buffer_t *buffer)
{ {
_output_dotted_circle (buffer); _output_dotted_circle (buffer);
buffer->next_glyph (); (void) buffer->next_glyph ();
} }
void void
@ -96,12 +96,12 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
buffer->idx + 2 < count && buffer->idx + 2 < count &&
0x0907u == buffer->cur (2).codepoint) 0x0907u == buffer->cur (2).codepoint)
{ {
buffer->next_glyph (); (void) buffer->next_glyph ();
matched = true; matched = true;
} }
break; break;
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer); if (matched) _output_with_dotted_circle (buffer);
} }
break; break;
@ -122,7 +122,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
matched = 0x09E2u == buffer->cur (1).codepoint; matched = 0x09E2u == buffer->cur (1).codepoint;
break; break;
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer); if (matched) _output_with_dotted_circle (buffer);
} }
break; break;
@ -158,7 +158,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
} }
break; break;
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer); if (matched) _output_with_dotted_circle (buffer);
} }
break; break;
@ -182,7 +182,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
matched = 0x0ABEu == buffer->cur (1).codepoint; matched = 0x0ABEu == buffer->cur (1).codepoint;
break; break;
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer); if (matched) _output_with_dotted_circle (buffer);
} }
break; break;
@ -200,7 +200,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
matched = 0x0B57u == buffer->cur (1).codepoint; matched = 0x0B57u == buffer->cur (1).codepoint;
break; break;
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer); if (matched) _output_with_dotted_circle (buffer);
} }
break; break;
@ -214,7 +214,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
{ {
matched = true; matched = true;
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer); if (matched) _output_with_dotted_circle (buffer);
} }
break; break;
@ -237,7 +237,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
matched = 0x0C55u == buffer->cur (1).codepoint; matched = 0x0C55u == buffer->cur (1).codepoint;
break; break;
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer); if (matched) _output_with_dotted_circle (buffer);
} }
break; break;
@ -255,7 +255,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
matched = 0x0CCCu == buffer->cur (1).codepoint; matched = 0x0CCCu == buffer->cur (1).codepoint;
break; break;
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer); if (matched) _output_with_dotted_circle (buffer);
} }
break; break;
@ -281,7 +281,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
} }
break; break;
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer); if (matched) _output_with_dotted_circle (buffer);
} }
break; break;
@ -316,7 +316,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
} }
break; break;
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer); if (matched) _output_with_dotted_circle (buffer);
} }
break; break;
@ -337,7 +337,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
matched = 0x11042u == buffer->cur (1).codepoint; matched = 0x11042u == buffer->cur (1).codepoint;
break; break;
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer); if (matched) _output_with_dotted_circle (buffer);
} }
break; break;
@ -358,7 +358,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
} }
break; break;
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer); if (matched) _output_with_dotted_circle (buffer);
} }
break; break;
@ -384,7 +384,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
} }
break; break;
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer); if (matched) _output_with_dotted_circle (buffer);
} }
break; break;
@ -404,7 +404,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
} }
break; break;
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer); if (matched) _output_with_dotted_circle (buffer);
} }
break; break;
@ -427,7 +427,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
matched = 0x116B2u == buffer->cur (1).codepoint; matched = 0x116B2u == buffer->cur (1).codepoint;
break; break;
} }
buffer->next_glyph (); (void) buffer->next_glyph ();
if (matched) _output_with_dotted_circle (buffer); if (matched) _output_with_dotted_circle (buffer);
} }
break; break;

View File

@ -101,8 +101,9 @@ set_glyph (hb_glyph_info_t &info, hb_font_t *font)
static inline void static inline void
output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph) output_char (hb_buffer_t *buffer, hb_codepoint_t unichar, hb_codepoint_t glyph)
{ {
/* This is very confusing indeed. */
buffer->cur().glyph_index() = glyph; buffer->cur().glyph_index() = glyph;
buffer->output_glyph (unichar); /* This is very confusing indeed. */ (void) buffer->output_glyph (unichar);
_hb_glyph_info_set_unicode_props (&buffer->prev(), buffer); _hb_glyph_info_set_unicode_props (&buffer->prev(), buffer);
} }
@ -110,7 +111,7 @@ static inline void
next_char (hb_buffer_t *buffer, hb_codepoint_t glyph) next_char (hb_buffer_t *buffer, hb_codepoint_t glyph)
{ {
buffer->cur().glyph_index() = glyph; buffer->cur().glyph_index() = glyph;
buffer->next_glyph (); (void) buffer->next_glyph ();
} }
static inline void static inline void
@ -229,30 +230,35 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c,
if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index())) if (font->get_variation_glyph (buffer->cur().codepoint, buffer->cur(+1).codepoint, &buffer->cur().glyph_index()))
{ {
hb_codepoint_t unicode = buffer->cur().codepoint; hb_codepoint_t unicode = buffer->cur().codepoint;
buffer->replace_glyphs (2, 1, &unicode); (void) buffer->replace_glyphs (2, 1, &unicode);
} }
else else
{ {
/* Just pass on the two characters separately, let GSUB do its magic. */ /* Just pass on the two characters separately, let GSUB do its magic. */
set_glyph (buffer->cur(), font); set_glyph (buffer->cur(), font);
buffer->next_glyph (); (void) buffer->next_glyph ();
set_glyph (buffer->cur(), font); set_glyph (buffer->cur(), font);
buffer->next_glyph (); (void) buffer->next_glyph ();
} }
/* Skip any further variation selectors. */ /* Skip any further variation selectors. */
while (buffer->idx < end && unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint))) while (buffer->idx < end &&
buffer->successful &&
unlikely (buffer->unicode->is_variation_selector (buffer->cur().codepoint)))
{ {
set_glyph (buffer->cur(), font); set_glyph (buffer->cur(), font);
buffer->next_glyph (); (void) buffer->next_glyph ();
} }
} else { }
else
{
set_glyph (buffer->cur(), font); set_glyph (buffer->cur(), font);
buffer->next_glyph (); (void) buffer->next_glyph ();
} }
} }
if (likely (buffer->idx < end)) { if (likely (buffer->idx < end))
{
set_glyph (buffer->cur(), font); set_glyph (buffer->cur(), font);
buffer->next_glyph (); (void) buffer->next_glyph ();
} }
} }
@ -348,7 +354,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
sizeof (buffer->info[0]), sizeof (buffer->info[0]),
&buffer->cur().glyph_index(), &buffer->cur().glyph_index(),
sizeof (buffer->info[0])); sizeof (buffer->info[0]));
buffer->next_glyphs (done); if (unlikely (!buffer->next_glyphs (done))) break;
} }
while (buffer->idx < end && buffer->successful) while (buffer->idx < end && buffer->successful)
decompose_current_character (&c, might_short_circuit); decompose_current_character (&c, might_short_circuit);
@ -429,8 +435,8 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
buffer->clear_output (); buffer->clear_output ();
count = buffer->len; count = buffer->len;
unsigned int starter = 0; unsigned int starter = 0;
buffer->next_glyph (); (void) buffer->next_glyph ();
while (buffer->idx < count && buffer->successful) while (buffer->idx < count /* No need for: && buffer->successful */)
{ {
hb_codepoint_t composed, glyph; hb_codepoint_t composed, glyph;
if (/* We don't try to compose a non-mark character with it's preceding starter. if (/* We don't try to compose a non-mark character with it's preceding starter.
@ -452,9 +458,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
font->get_nominal_glyph (composed, &glyph)) font->get_nominal_glyph (composed, &glyph))
{ {
/* Composes. */ /* Composes. */
buffer->next_glyph (); /* Copy to out-buffer. */ if (unlikely (!buffer->next_glyph ())) break; /* Copy to out-buffer. */
if (unlikely (!buffer->successful))
return;
buffer->merge_out_clusters (starter, buffer->out_len); buffer->merge_out_clusters (starter, buffer->out_len);
buffer->out_len--; /* Remove the second composable. */ buffer->out_len--; /* Remove the second composable. */
/* Modify starter and carry on. */ /* Modify starter and carry on. */
@ -467,7 +471,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
} }
/* Blocked, or doesn't compose. */ /* Blocked, or doesn't compose. */
buffer->next_glyph (); if (unlikely (!buffer->next_glyph ())) break;
if (info_cc (buffer->prev()) == 0) if (info_cc (buffer->prev()) == 0)
starter = buffer->out_len - 1; starter = buffer->out_len - 1;

View File

@ -534,7 +534,7 @@ hb_insert_dotted_circle (hb_buffer_t *buffer, hb_font_t *font)
hb_glyph_info_t info = dottedcircle; hb_glyph_info_t info = dottedcircle;
info.cluster = buffer->cur().cluster; info.cluster = buffer->cur().cluster;
info.mask = buffer->cur().mask; info.mask = buffer->cur().mask;
buffer->output_info (info); (void) buffer->output_info (info);
buffer->swap_buffers (); buffer->swap_buffers ();
} }

View File

@ -97,7 +97,7 @@ for filename in args:
if not reference: if not reference:
print ('%s "%s" %s %s --unicodes %s' % print ('%s "%s" %s %s --unicodes %s' %
(hb_shape, fontfile, ' '.join(extra_options), options, unicodes)) (hb_shape, fontfile, ' '.join(extra_options), ' '.join(options), unicodes))
if "--font-funcs=ft" in options and not have_freetype: if "--font-funcs=ft" in options and not have_freetype:
skips += 1 skips += 1