Fix a possible use-after-free in OpenGl2Batch.

IdList could reallocate its storage after we grab an interior
pointer, so just make a copy instead.
This commit is contained in:
Evil-Spirit 2016-12-02 22:01:48 +07:00 committed by whitequark
parent b975380493
commit 3858cbe249

View File

@ -703,24 +703,24 @@ public:
class EdgeDrawCall : public DrawCall { class EdgeDrawCall : public DrawCall {
public: public:
// Key // Key
Canvas::Stroke *stroke; Canvas::Stroke stroke;
// Data // Data
EdgeRenderer::Handle handle; EdgeRenderer::Handle handle;
virtual Canvas::Layer GetLayer() const override { return stroke->layer; }; virtual Canvas::Layer GetLayer() const override { return stroke.layer; };
virtual int GetZIndex() const override { return stroke->zIndex; }; virtual int GetZIndex() const override { return stroke.zIndex; };
static std::shared_ptr<DrawCall> Create(OpenGl2Renderer *renderer, const SEdgeList &el, static std::shared_ptr<DrawCall> Create(OpenGl2Renderer *renderer, const SEdgeList &el,
Canvas::Stroke *stroke) { Canvas::Stroke *stroke) {
EdgeDrawCall *dc = new EdgeDrawCall(); EdgeDrawCall *dc = new EdgeDrawCall();
dc->stroke = stroke; dc->stroke = *stroke;
dc->handle = renderer->edgeRenderer.Add(el); dc->handle = renderer->edgeRenderer.Add(el);
return std::shared_ptr<DrawCall>(dc); return std::shared_ptr<DrawCall>(dc);
} }
void Draw(OpenGl2Renderer *renderer) override { void Draw(OpenGl2Renderer *renderer) override {
ssglDepthRange(stroke->layer, stroke->zIndex); ssglDepthRange(stroke.layer, stroke.zIndex);
renderer->edgeRenderer.SetStroke(*stroke, 1.0 / renderer->camera.scale); renderer->edgeRenderer.SetStroke(stroke, 1.0 / renderer->camera.scale);
renderer->edgeRenderer.Draw(handle); renderer->edgeRenderer.Draw(handle);
} }
@ -732,27 +732,27 @@ public:
class OutlineDrawCall : public DrawCall { class OutlineDrawCall : public DrawCall {
public: public:
// Key // Key
Canvas::Stroke *stroke; Canvas::Stroke stroke;
// Data // Data
OutlineRenderer::Handle handle; OutlineRenderer::Handle handle;
Canvas::DrawOutlinesAs drawAs; Canvas::DrawOutlinesAs drawAs;
virtual Canvas::Layer GetLayer() const override { return stroke->layer; }; virtual Canvas::Layer GetLayer() const override { return stroke.layer; };
virtual int GetZIndex() const override { return stroke->zIndex; }; virtual int GetZIndex() const override { return stroke.zIndex; };
static std::shared_ptr<DrawCall> Create(OpenGl2Renderer *renderer, const SOutlineList &ol, static std::shared_ptr<DrawCall> Create(OpenGl2Renderer *renderer, const SOutlineList &ol,
Canvas::Stroke *stroke, Canvas::Stroke *stroke,
Canvas::DrawOutlinesAs drawAs) { Canvas::DrawOutlinesAs drawAs) {
OutlineDrawCall *dc = new OutlineDrawCall(); OutlineDrawCall *dc = new OutlineDrawCall();
dc->stroke = stroke; dc->stroke = *stroke;
dc->handle = renderer->outlineRenderer.Add(ol); dc->handle = renderer->outlineRenderer.Add(ol);
dc->drawAs = drawAs; dc->drawAs = drawAs;
return std::shared_ptr<DrawCall>(dc); return std::shared_ptr<DrawCall>(dc);
} }
void Draw(OpenGl2Renderer *renderer) override { void Draw(OpenGl2Renderer *renderer) override {
ssglDepthRange(stroke->layer, stroke->zIndex); ssglDepthRange(stroke.layer, stroke.zIndex);
renderer->outlineRenderer.SetStroke(*stroke, 1.0 / renderer->camera.scale); renderer->outlineRenderer.SetStroke(stroke, 1.0 / renderer->camera.scale);
renderer->outlineRenderer.Draw(handle, drawAs); renderer->outlineRenderer.Draw(handle, drawAs);
} }
@ -764,24 +764,24 @@ public:
class PointDrawCall : public DrawCall { class PointDrawCall : public DrawCall {
public: public:
// Key // Key
Canvas::Stroke *stroke; Canvas::Stroke stroke;
// Data // Data
IndexedMeshRenderer::Handle handle; IndexedMeshRenderer::Handle handle;
virtual Canvas::Layer GetLayer() const override { return stroke->layer; }; virtual Canvas::Layer GetLayer() const override { return stroke.layer; };
virtual int GetZIndex() const override { return stroke->zIndex; }; virtual int GetZIndex() const override { return stroke.zIndex; };
static std::shared_ptr<DrawCall> Create(OpenGl2Renderer *renderer, const SIndexedMesh &im, static std::shared_ptr<DrawCall> Create(OpenGl2Renderer *renderer, const SIndexedMesh &im,
Canvas::Stroke *stroke) { Canvas::Stroke *stroke) {
PointDrawCall *dc = new PointDrawCall(); PointDrawCall *dc = new PointDrawCall();
dc->stroke = stroke; dc->stroke = *stroke;
dc->handle = renderer->imeshRenderer.Add(im); dc->handle = renderer->imeshRenderer.Add(im);
return std::shared_ptr<DrawCall>(dc); return std::shared_ptr<DrawCall>(dc);
} }
void Draw(OpenGl2Renderer *renderer) override { void Draw(OpenGl2Renderer *renderer) override {
ssglDepthRange(stroke->layer, stroke->zIndex); ssglDepthRange(stroke.layer, stroke.zIndex);
renderer->imeshRenderer.UsePoint(*stroke, 1.0 / renderer->camera.scale); renderer->imeshRenderer.UsePoint(stroke, 1.0 / renderer->camera.scale);
renderer->imeshRenderer.Draw(handle); renderer->imeshRenderer.Draw(handle);
} }
@ -793,23 +793,25 @@ public:
class MeshDrawCall : public DrawCall { class MeshDrawCall : public DrawCall {
public: public:
// Key // Key
Canvas::Fill *fillFront; Canvas::Fill fillFront;
// Data // Data
MeshRenderer::Handle handle; MeshRenderer::Handle handle;
Canvas::Fill *fillBack; Canvas::Fill fillBack;
bool hasFillBack;
bool isShaded; bool isShaded;
virtual Canvas::Layer GetLayer() const override { return fillFront->layer; }; virtual Canvas::Layer GetLayer() const override { return fillFront.layer; };
virtual int GetZIndex() const override { return fillFront->zIndex; }; virtual int GetZIndex() const override { return fillFront.zIndex; };
static std::shared_ptr<DrawCall> Create(OpenGl2Renderer *renderer, const SMesh &m, static std::shared_ptr<DrawCall> Create(OpenGl2Renderer *renderer, const SMesh &m,
Canvas::Fill *fillFront, Canvas::Fill *fillBack = NULL, Canvas::Fill *fillFront, Canvas::Fill *fillBack = NULL,
bool isShaded = false) { bool isShaded = false) {
MeshDrawCall *dc = new MeshDrawCall(); MeshDrawCall *dc = new MeshDrawCall();
dc->fillFront = fillFront; dc->fillFront = *fillFront;
dc->handle = renderer->meshRenderer.Add(m); dc->handle = renderer->meshRenderer.Add(m);
dc->fillBack = fillBack; dc->fillBack = *fillBack;
dc->isShaded = isShaded; dc->isShaded = isShaded;
dc->hasFillBack = (fillBack != NULL);
return std::shared_ptr<DrawCall>(dc); return std::shared_ptr<DrawCall>(dc);
} }
@ -835,9 +837,9 @@ public:
glEnable(GL_POLYGON_OFFSET_FILL); glEnable(GL_POLYGON_OFFSET_FILL);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
if(fillBack) if(hasFillBack)
DrawFace(renderer, GL_FRONT, fillBack); DrawFace(renderer, GL_FRONT, &fillBack);
DrawFace(renderer, GL_BACK, fillFront); DrawFace(renderer, GL_BACK, &fillFront);
glDisable(GL_POLYGON_OFFSET_FILL); glDisable(GL_POLYGON_OFFSET_FILL);
glDisable(GL_CULL_FACE); glDisable(GL_CULL_FACE);