From 8a8290802947c1481b5bb1c3b57790c497cb7b1e Mon Sep 17 00:00:00 2001
From: zooko <zooko@zooko.com>
Date: Tue, 16 Jun 2009 03:47:51 +0530
Subject: [PATCH] fix segfault when invalid arguments are passed to constructor

Ignore-this: 3e7a6bfe32af144af39c4f8edd7e170e

darcs-hash:fc87292445de462e9b296cbc1e6eda584f5748b1
---
 zfec/zfec/_fecmodule.c      | 18 ++++++++++--------
 zfec/zfec/test/test_zfec.py | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/zfec/zfec/_fecmodule.c b/zfec/zfec/_fecmodule.c
index 38645bc..bab1a49 100644
--- a/zfec/zfec/_fecmodule.c
+++ b/zfec/zfec/_fecmodule.c
@@ -62,15 +62,15 @@ Encoder_init(Encoder *self, PyObject *args, PyObject *kwdict) {
         return -1;
 
     if (ink < 1) {
-        PyErr_Format(py_fec_error, "Precondition violation: first argument is required to be greater than or equal to 1, but it was %d", self->kk);
+        PyErr_Format(py_fec_error, "Precondition violation: first argument is required to be greater than or equal to 1, but it was %d", ink);
         return -1;
     }
     if (inm < 1) {
-        PyErr_Format(py_fec_error, "Precondition violation: second argument is required to be greater than or equal to 1, but it was %d", self->mm);
+        PyErr_Format(py_fec_error, "Precondition violation: second argument is required to be greater than or equal to 1, but it was %d", inm);
         return -1;
     }
     if (inm > 256) {
-        PyErr_Format(py_fec_error, "Precondition violation: second argument is required to be less than or equal to 256, but it was %d", self->mm);
+        PyErr_Format(py_fec_error, "Precondition violation: second argument is required to be less than or equal to 256, but it was %d", inm);
         return -1;
     }
     if (ink > inm) {
@@ -220,7 +220,8 @@ Encoder_encode(Encoder *self, PyObject *args) {
 
 static void
 Encoder_dealloc(Encoder * self) {
-    fec_free(self->fec_matrix);
+    if (self->fec_matrix)
+        fec_free(self->fec_matrix);
     self->ob_type->tp_free((PyObject*)self);
 }
 
@@ -321,15 +322,15 @@ Decoder_init(Encoder *self, PyObject *args, PyObject *kwdict) {
         return -1;
 
     if (ink < 1) {
-        PyErr_Format(py_fec_error, "Precondition violation: first argument is required to be greater than or equal to 1, but it was %d", self->kk);
+        PyErr_Format(py_fec_error, "Precondition violation: first argument is required to be greater than or equal to 1, but it was %d", ink);
 	return -1;
     }
     if (inm < 1) {
-        PyErr_Format(py_fec_error, "Precondition violation: second argument is required to be greater than or equal to 1, but it was %d", self->mm);
+        PyErr_Format(py_fec_error, "Precondition violation: second argument is required to be greater than or equal to 1, but it was %d", inm);
 	return -1;
     }
     if (inm > 256) {
-        PyErr_Format(py_fec_error, "Precondition violation: second argument is required to be less than or equal to 256, but it was %d", self->mm);
+        PyErr_Format(py_fec_error, "Precondition violation: second argument is required to be less than or equal to 256, but it was %d", inm);
 	return -1;
     }
     if (ink > inm) {
@@ -492,7 +493,8 @@ Decoder_decode(Decoder *self, PyObject *args) {
 
 static void
 Decoder_dealloc(Decoder * self) {
-    fec_free(self->fec_matrix);
+    if (self->fec_matrix)
+        fec_free(self->fec_matrix);
     self->ob_type->tp_free((PyObject*)self);
 }
 
diff --git a/zfec/zfec/test/test_zfec.py b/zfec/zfec/test/test_zfec.py
index 3e51a78..5fd9173 100755
--- a/zfec/zfec/test/test_zfec.py
+++ b/zfec/zfec/test/test_zfec.py
@@ -110,6 +110,43 @@ class ZFecTest(unittest.TestCase):
         if VERBOSE:
             print "%d randomized tests pass." % (i+1)
 
+    def test_bad_args_construct_decoder(self):
+        try:
+            zfec.Decoder(-1, -1)
+        except zfec.Error, e:
+            assert "argument is required to be greater than or equal to 1" in str(e), e
+        else:
+            self.fail("Should have gotten an exception from out-of-range arguments.")
+
+        try:
+            zfec.Decoder(1, 257)
+        except zfec.Error, e:
+            assert "argument is required to be less than or equal to 256" in str(e), e
+        else:
+            self.fail("Should have gotten an exception from out-of-range arguments.")
+
+        try:
+            zfec.Decoder(3, 2)
+        except zfec.Error, e:
+            assert "first argument is required to be less than or equal to the second argument" in str(e), e
+        else:
+            self.fail("Should have gotten an exception from out-of-range arguments.")
+
+    def test_bad_args_construct_encoder(self):
+        try:
+            zfec.Encoder(-1, -1)
+        except zfec.Error, e:
+            assert "argument is required to be greater than or equal to 1" in str(e), e
+        else:
+            self.fail("Should have gotten an exception from out-of-range arguments.")
+
+        try:
+            zfec.Encoder(1, 257)
+        except zfec.Error, e:
+            assert "argument is required to be less than or equal to 256" in str(e), e
+        else:
+            self.fail("Should have gotten an exception from out-of-range arguments.")
+
     def test_bad_args_dec(self):
         decer = zfec.Decoder(2, 4)
 
-- 
2.45.2