semacode 0.7.2 → 0.7.3

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -22,4 +22,19 @@ CHANGELOG
22
22
 
23
23
  * Fixes compiler errors with Fink not finding malloc.h
24
24
 
25
- * Given up on making the gem do auto-require
25
+ * Given up on making the gem do auto-require
26
+
27
+ * Fixes a memory leak where the encoding list wasn't being freed.
28
+
29
+
30
+ 2007-03-04 guido
31
+
32
+ * Free up internal memory allocated before we throw an exception
33
+
34
+ * Throw ArgError and RangeError exceptions rather than Runtime exceptions
35
+
36
+ * Don't return an inconsistent semacode when presented with overlong input
37
+
38
+ * Don't fail quietly either, throw an exception
39
+
40
+ * Very conservatively use a far smaller maximum value for input length than the header file suggests
data/README CHANGED
@@ -141,3 +141,9 @@ The C code can throw runtime exceptions. Be sure to include
141
141
  a catch block if you want to use this in production. Mostly
142
142
  the exceptions are not recoverable, except for when the data
143
143
  is too long, in which case you can shorten it and try again.
144
+
145
+ There are two type of exceptions that it will throw. The first
146
+ is a RangeError exception, which happens when the input is too
147
+ long or when it just can't find a fit for the data. The second
148
+ is a ArgumentError (ArgError?) exception that gets thrown when
149
+ the input contains data it cannot handle.
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require 'rake/gempackagetask'
3
3
 
4
4
  spec = Gem::Specification.new do |s|
5
5
  s.name = "semacode"
6
- s.version = "0.7.2"
6
+ s.version = "0.7.3"
7
7
  s.author = "Guido Sohne"
8
8
  s.email = "guido@sohne.net"
9
9
  s.homepage = "http://sohne.net/projects/semafox/"
data/ext/iec16022ecc200.c CHANGED
@@ -211,8 +211,7 @@ ecc200placement (int *array, int NR, int NC)
211
211
  static void
212
212
  ecc200 (unsigned char *binary, int bytes, int datablock, int rsblock)
213
213
  {
214
- int blocks = (bytes + 2) / datablock,
215
- b;
214
+ int blocks = (bytes + 2) / datablock, b;
216
215
  rs_init_gf (0x12d);
217
216
  rs_init_code (rsblock, 1);
218
217
  for (b = 0; b < blocks; b++)
@@ -240,7 +239,8 @@ ecc200encode (unsigned char *t, int tl, unsigned char *s, int sl, char *encoding
240
239
  sp = 0;
241
240
  if (strlen (encoding) < sl)
242
241
  {
243
- rb_raise(rb_eRuntimeError, "encoding string too short");
242
+ free(encoding);
243
+ rb_raise(rb_eArgError, "encoding string too short");
244
244
  return 0;
245
245
  }
246
246
  // do the encoding
@@ -281,7 +281,8 @@ ecc200encode (unsigned char *t, int tl, unsigned char *s, int sl, char *encoding
281
281
  {
282
282
  if (newenc == 'x')
283
283
  {
284
- rb_raise(rb_eRuntimeError, "cannot encode character in X12", c);
284
+ free(encoding);
285
+ rb_raise(rb_eArgError, "cannot encode character in X12", c);
285
286
  return 0;
286
287
  }
287
288
  c &= 0x7f;
@@ -295,7 +296,8 @@ ecc200encode (unsigned char *t, int tl, unsigned char *s, int sl, char *encoding
295
296
  {
296
297
  if (newenc == 'x')
297
298
  {
298
- rb_raise(rb_eRuntimeError, "cannot encode character in X12", c);
299
+ free(encoding);
300
+ rb_raise(rb_eArgError, "cannot encode character in X12", c);
299
301
  return 0;
300
302
  }
301
303
  if (c < 32)
@@ -318,6 +320,7 @@ ecc200encode (unsigned char *t, int tl, unsigned char *s, int sl, char *encoding
318
320
  out[p++] = (w - s3);
319
321
  } else
320
322
  {
323
+ free(encoding);
321
324
  rb_raise(rb_eRuntimeError, "this should not be happening!", c);
322
325
  return 0;
323
326
  }
@@ -429,7 +432,8 @@ ecc200encode (unsigned char *t, int tl, unsigned char *s, int sl, char *encoding
429
432
  }
430
433
  break;
431
434
  default:
432
- rb_raise(rb_eRuntimeError, "unknown encoding attempted");
435
+ free(encoding);
436
+ rb_raise(rb_eArgError, "unknown encoding attempted");
433
437
  return 0; // failed
434
438
  }
435
439
  }
@@ -798,12 +802,28 @@ void iec16022init(int *Wptr, int *Hptr, const char *barcode)
798
802
  unsigned char *
799
803
  iec16022ecc200 (int *Wptr, int *Hptr, char **encodingptr, int barcodelen, unsigned char *barcode, int *lenp, int *maxp, int *eccp)
800
804
  {
801
- unsigned char binary[3000]; // encoded raw data and ecc to place in barcode
805
+ // GS
806
+ // max semacode size is 3116 (from iec16022ecc200.h)
807
+ // we over compensate and check that the input is within this length
808
+ // to avoid any buffer overflow conditions.
809
+ unsigned char binary[4096]; // encoded raw data and ecc to place in barcode
802
810
  int W = 0,
803
811
  H = 0;
804
812
  char *encoding = 0;
805
813
  unsigned char *grid = 0;
806
814
  struct ecc200matrix_s *matrix;
815
+
816
+ // GS
817
+ // using the length from the 144x144 semacode in the matrix
818
+ // I don't trust the 3116 maximum length value ... and
819
+ // besides how many characters do you really need in a
820
+ // semacode?
821
+
822
+ if(barcodelen > 1556) {
823
+ rb_raise(rb_eRangeError, "barcode is too long (> 1556 chars)");
824
+ return NULL;
825
+ }
826
+
807
827
  memset (binary, 0, sizeof (binary));
808
828
  if (encodingptr)
809
829
  encoding = *encodingptr;
@@ -818,7 +838,7 @@ iec16022ecc200 (int *Wptr, int *Hptr, char **encodingptr, int barcodelen, unsign
818
838
  for (matrix = ecc200matrix; matrix->W && (matrix->W != W || matrix->H != H); matrix++);
819
839
  if (!matrix->W)
820
840
  {
821
- rb_raise(rb_eRuntimeError, "invalid size for barcode");
841
+ rb_raise(rb_eRangeError, "invalid size for barcode");
822
842
  return 0;
823
843
  }
824
844
  if (!encoding)
@@ -831,7 +851,8 @@ iec16022ecc200 (int *Wptr, int *Hptr, char **encodingptr, int barcodelen, unsign
831
851
  e = encmake (barcodelen, barcode, &len, 0);
832
852
  if (len > matrix->bytes)
833
853
  {
834
- rb_raise(rb_eRuntimeError, "cannot make barcode fit");
854
+ free(e);
855
+ rb_raise(rb_eRangeError, "cannot make barcode fit");
835
856
  return 0;
836
857
  }
837
858
  }
@@ -860,7 +881,8 @@ iec16022ecc200 (int *Wptr, int *Hptr, char **encodingptr, int barcodelen, unsign
860
881
  }
861
882
  if (!matrix->W)
862
883
  {
863
- rb_raise(rb_eRuntimeError, "overlong barcode");
884
+ free(encoding);
885
+ rb_raise(rb_eRangeError, "overlong barcode");
864
886
  return 0;
865
887
  }
866
888
  W = matrix->W;
@@ -868,7 +890,8 @@ iec16022ecc200 (int *Wptr, int *Hptr, char **encodingptr, int barcodelen, unsign
868
890
  }
869
891
  if (!ecc200encode (binary, matrix->bytes, barcode, barcodelen, encoding, lenp))
870
892
  {
871
- rb_raise(rb_eRuntimeError, "barcode too long for expected encoding");
893
+ free(encoding);
894
+ rb_raise(rb_eRangeError, "barcode too long for expected encoding");
872
895
  return 0;
873
896
  }
874
897
  // ecc code
data/ext/reedsol.h CHANGED
@@ -1,3 +1,5 @@
1
+ /* don't compile in the main function from reedsol.c */
2
+ #define LIB
1
3
 
2
4
  void rs_init_gf(int poly);
3
5
  void rs_init_code(int nsym, int index);
data/ext/semacode.c CHANGED
@@ -38,12 +38,17 @@ Due to a bug in the underlying encoder, we do two things
38
38
  semacode_t*
39
39
  encode_string(semacode_t *semacode, int message_length, char *message)
40
40
  {
41
+ /* avoid obvious bad cases */
42
+ if(semacode == NULL || message == NULL || message_length < 1) {
43
+ return NULL;
44
+ }
45
+
41
46
  /* deallocate if exists already */
42
- if(semacode !=NULL && semacode->data != NULL)
47
+ if(semacode->data != NULL)
43
48
  free(semacode->data);
44
49
 
45
50
  /* deallocate if exists already */
46
- if(semacode !=NULL && semacode->encoding != NULL)
51
+ if(semacode->encoding != NULL)
47
52
  free(semacode->encoding);
48
53
 
49
54
  bzero(semacode, sizeof(semacode_t));
@@ -87,6 +92,7 @@ semacode_free(semacode_t *semacode)
87
92
  if(semacode->data != NULL)
88
93
  free(semacode->encoding);
89
94
  free(semacode->data);
95
+ /* zero before freeing */
90
96
  bzero(semacode, sizeof(semacode));
91
97
  free(semacode);
92
98
  }
@@ -100,7 +106,7 @@ semacode_allocate(VALUE klass)
100
106
  }
101
107
 
102
108
  /*
103
- Initialize the semacode. This function is called after a semaode is
109
+ Initialize the semacode. This function is called after a semacode is
104
110
  created. Ruby objects are created using a new method, and then initialized
105
111
  via the 'initialize' method once they have been allocated.
106
112
 
@@ -358,6 +364,7 @@ Init_semacode_native()
358
364
  {
359
365
  rb_mSemacode = rb_define_module ("DataMatrix");
360
366
  rb_cEncoder = rb_define_class_under(rb_mSemacode, "Encoder", rb_cObject);
367
+
361
368
  rb_define_alloc_func(rb_cEncoder, semacode_allocate);
362
369
 
363
370
  rb_define_method(rb_cEncoder, "initialize", semacode_init, 1);
metadata CHANGED
@@ -3,7 +3,7 @@ rubygems_version: 0.9.2
3
3
  specification_version: 1
4
4
  name: semacode
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.7.2
6
+ version: 0.7.3
7
7
  date: 2007-03-04 00:00:00 +00:00
8
8
  summary: Create semacodes (2D barcodes) using Ruby.
9
9
  require_paths: