diff --git a/src/hb-wasm-shape.cc b/src/hb-wasm-shape.cc index 05de4a20e..b43a8c9fb 100644 --- a/src/hb-wasm-shape.cc +++ b/src/hb-wasm-shape.cc @@ -283,10 +283,20 @@ _hb_wasm_shape (hb_shape_plan_t *shape_plan, const hb_feature_t *features, unsigned int num_features) { + if (unlikely (buffer->in_error ())) + return false; + bool ret = true; hb_face_t *face = font->face; const hb_wasm_face_data_t *face_data = face->data.wasm; + bool retried = false; + if (0) + { +retry: + DEBUG_MSG (WASM, font, "Retrying..."); + } + wasm_function_inst_t func = nullptr; hb_wasm_shape_plan_t *plan = acquire_shape_plan (face, face_data); @@ -340,15 +350,25 @@ _hb_wasm_shape (hb_shape_plan_t *shape_plan, if (unlikely (buffer->in_error ())) { - DEBUG_MSG (WASM, module_inst, "Buffer in error. Memory allocation fail?"); - goto fail; + DEBUG_MSG (WASM, module_inst, "Buffer in error. Memory allocation fail in the wasm?"); + if (retried) + goto fail; + buffer->successful = true; + retried = true; + release_shape_plan (face_data, plan); + goto retry; } if (unlikely (!ret)) { DEBUG_MSG (WASM, module_inst, "Calling shape() failed: %s", wasm_runtime_get_exception(module_inst)); - goto fail; + if (retried) + goto fail; + buffer->successful = true; + retried = true; + release_shape_plan (face_data, plan); + goto retry; } /* TODO Regularize clusters according to direction & cluster level, diff --git a/src/wasm-graphite/shape.cc b/src/wasm-graphite/shape.cc index 6aec37280..24b1b5fe1 100644 --- a/src/wasm-graphite/shape.cc +++ b/src/wasm-graphite/shape.cc @@ -83,6 +83,8 @@ shape (void *shape_plan, unsigned length = contents.length; uint32_t *chars = (uint32_t *) malloc (length * sizeof (uint32_t)); + if (!chars) + return false; for (unsigned int i = 0; i < contents.length; ++i) chars[i] = contents.info[i].codepoint; @@ -114,6 +116,8 @@ shape (void *shape_plan, buffer_contents_realloc (&contents, length); cluster_t *clusters = (cluster_t *) malloc (length * sizeof (cluster_t)); uint32_t *gids = (uint32_t *) malloc (length * sizeof (uint32_t)); + if (!clusters || !gids) + return false; memset (clusters, 0, sizeof (clusters[0]) * length); codepoint_t *pg = gids;