const css_stylesheet* sheet;
css_select_ctx_count_sheets(state.select_ctx, &n_sheets);
for (i = 0; i < n_sheets; i++) {
- css_code = css_select_ctx_get_sheet(state.select_ctx, i, &sheet);
- if (css_code != CSS_OK && code == svgtiny_OK) {
- code = svgtiny_LIBCSS_ERROR;
+ /* Note the use of (n_sheets - 1 - i) below to
+ * remove/destroy the sheets in reverse order, last-in
+ * first-out. */
+ css_code = css_select_ctx_get_sheet(state.select_ctx,
+ n_sheets - 1 - i,
+ &sheet);
+ if (css_code != CSS_OK) {
+ if (code == svgtiny_OK) {
+ code = svgtiny_LIBCSS_ERROR;
+ }
+ /* If we didn't get a new sheet, don't try to
+ * remove/destroy whatever happens to live at
+ * the pointer. */
+ continue;
+ }
+ /* Remove the sheets from the context as well, since
+ * there is no promise that css_select_ctx_destroy()
+ * will not try to access them. */
+ css_code = css_select_ctx_remove_sheet(state.select_ctx, sheet);
+ if (css_code != CSS_OK) {
+ if (code == svgtiny_OK) {
+ code = svgtiny_LIBCSS_ERROR;
+ }
+ /* Don't try to destroy the sheet if removal
+ * failed, because that would suggest that our
+ * implied contract (that nobody else modifies
+ * our context) has been violated. */
+ continue;
}
css_code = css_stylesheet_destroy((css_stylesheet*)sheet);
if (css_code != CSS_OK && code == svgtiny_OK) {