zipruby 0.2.6 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of zipruby might be problematic. Click here for more details.

data/ext/extconf.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  require 'mkmf'
2
2
 
3
3
  if have_header('zlib.h') and have_library('z')
4
+ have_func('fseeko')
5
+ have_func('ftello')
6
+ have_func('mkstemp')
4
7
  create_makefile('zipruby')
5
8
  end
data/ext/tmpfile.c ADDED
@@ -0,0 +1,173 @@
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+ #include <sys/types.h>
5
+ #include <sys/stat.h>
6
+
7
+ #ifdef _WIN32
8
+ #include <windows.h>
9
+ #include <io.h>
10
+ #include <fcntl.h>
11
+ #include <share.h>
12
+ #endif
13
+
14
+ #include "tmpfile.h"
15
+ #include "ruby.h"
16
+
17
+ #ifndef _WIN32
18
+ #ifndef HAVE_MKSTEMP
19
+ int _zip_mkstemp(char *);
20
+ #define mkstemp _zip_mkstemp
21
+ #endif
22
+ #endif
23
+
24
+ static int write_from_proc(VALUE proc, int fd);
25
+ static VALUE proc_call(VALUE proc);
26
+
27
+ char *zipruby_tmpnam(void *data, int len) {
28
+ char *filnam;
29
+
30
+ #ifdef _WIN32
31
+ int fd;
32
+ char tmpdirnam[_MAX_PATH];
33
+ char tmpfilnam[_MAX_PATH];
34
+ int namlen;
35
+
36
+ memset(tmpdirnam, 0, _MAX_PATH);
37
+
38
+ if (GetTempPathA(_MAX_PATH, tmpdirnam) == 0) {
39
+ return NULL;
40
+ }
41
+
42
+ memset(tmpfilnam, 0, _MAX_PATH);
43
+
44
+ if (GetTempFileNameA(tmpdirnam, "zrb", 0, tmpfilnam) == 0) {
45
+ return NULL;
46
+ }
47
+
48
+ namlen = strlen(tmpfilnam) + 1;
49
+
50
+ if ((filnam = calloc(namlen, sizeof(char))) == NULL) {
51
+ return NULL;
52
+ }
53
+
54
+ if (strcpy_s(filnam, namlen, tmpfilnam) != 0) {
55
+ free(filnam);
56
+ return NULL;
57
+ }
58
+
59
+ if (data) {
60
+ if ((_sopen_s(&fd, filnam, _O_WRONLY | _O_BINARY, _SH_DENYRD, _S_IWRITE)) != 0) {
61
+ free(filnam);
62
+ return NULL;
63
+ }
64
+
65
+ if (len < 0) {
66
+ if (write_from_proc((VALUE) data, fd) == -1) {
67
+ free(filnam);
68
+ return NULL;
69
+ }
70
+ } else {
71
+ if (_write(fd, data, len) == -1) {
72
+ free(filnam);
73
+ return NULL;
74
+ }
75
+ }
76
+
77
+ if (_close(fd) == -1) {
78
+ free(filnam);
79
+ return NULL;
80
+ }
81
+ }
82
+ #else
83
+ int fd;
84
+ #ifdef P_tmpdir
85
+ int namlen = 16 + strlen(P_tmpdir);
86
+ char *dirnam = P_tmpdir;
87
+ #else
88
+ int namlen = 20;
89
+ char *dirnam = "/tmp";
90
+ #endif
91
+
92
+ if ((filnam = calloc(namlen, sizeof(char))) == NULL) {
93
+ return NULL;
94
+ }
95
+
96
+ strcpy(filnam, dirnam);
97
+ strcat(filnam, "/zipruby.XXXXXX");
98
+
99
+ if ((fd = mkstemp(filnam)) == -1) {
100
+ free(filnam);
101
+ return NULL;
102
+ }
103
+
104
+ if (data) {
105
+ if (len < 0) {
106
+ if (write_from_proc((VALUE) data, fd) == -1) {
107
+ free(filnam);
108
+ return NULL;
109
+ }
110
+ } else {
111
+ if (write(fd, data, len) == -1) {
112
+ free(filnam);
113
+ return NULL;
114
+ }
115
+ }
116
+ }
117
+
118
+ if (close(fd) == -1) {
119
+ free(filnam);
120
+ return NULL;
121
+ }
122
+ #endif
123
+
124
+ return filnam;
125
+ }
126
+
127
+ void zipruby_rmtmp(const char *tmpfilnam) {
128
+ struct stat st;
129
+
130
+ if (!tmpfilnam) {
131
+ return;
132
+ }
133
+
134
+ if (stat(tmpfilnam, &st) != 0) {
135
+ return;
136
+ }
137
+
138
+ #ifdef _WIN32
139
+ _unlink(tmpfilnam);
140
+ #else
141
+ unlink(tmpfilnam);
142
+ #endif
143
+ }
144
+
145
+ static int write_from_proc(VALUE proc, int fd) {
146
+ while (1) {
147
+ VALUE src = rb_protect(proc_call, proc, NULL);
148
+
149
+ if (TYPE(src) != T_STRING) {
150
+ break;
151
+ }
152
+
153
+ if (RSTRING(src)->len < 1) {
154
+ break;
155
+ }
156
+
157
+ #ifdef _WIN32
158
+ if (_write(fd, StringValuePtr(src), RSTRING(src)->len) == -1) {
159
+ return -1;
160
+ }
161
+ #else
162
+ if (write(fd, StringValuePtr(src), RSTRING(src)->len) == -1) {
163
+ return -1;
164
+ }
165
+ #endif
166
+ }
167
+
168
+ return 0;
169
+ }
170
+
171
+ static VALUE proc_call(VALUE proc) {
172
+ return rb_funcall(proc, rb_intern("call"), 0);
173
+ }
data/ext/tmpfile.h ADDED
@@ -0,0 +1,9 @@
1
+ #ifndef __TMPFILE_H__
2
+ #define __TMPFILE_H__
3
+
4
+ #include <stdio.h>
5
+
6
+ char *zipruby_tmpnam(void *data, int len);
7
+ void zipruby_rmtmp(const char *tmpfilnam);
8
+
9
+ #endif
data/ext/zip.h CHANGED
@@ -55,6 +55,8 @@ typedef int ssize_t;
55
55
  #define ZIP_CREATE 1
56
56
  #define ZIP_EXCL 2
57
57
  #define ZIP_CHECKCONS 4
58
+ // modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
59
+ #define ZIP_TRUNC 8
58
60
 
59
61
 
60
62
  /* flags for zip_name_locate, zip_fopen, zip_stat, ... */
@@ -207,6 +209,7 @@ int zip_unchange_archive(struct zip *);
207
209
  // modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
208
210
  int zip_decrypt(const char *path, const char *pwd, int pwdlen, int *errorp, int *wrongpwd);
209
211
  int zip_encrypt(const char *path, const char *pwd, int pwdlen, int *errorp);
212
+ int _zip_changed(struct zip *, int *);
210
213
 
211
214
  #ifdef __cplusplus
212
215
  }
data/ext/zip_close.c CHANGED
@@ -61,8 +61,7 @@ static void ch_set_error(struct zip_error *, zip_source_callback, void *);
61
61
  // modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
62
62
  //static int copy_data(FILE *, off_t, FILE *, struct zip_error *);
63
63
  //static int _zip_cdir_set_comment(struct zip_cdir *, struct zip *);
64
- static int _zip_changed(struct zip *, int *);
65
- // modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
64
+ //static int _zip_changed(struct zip *, int *);
66
65
  //static char *_zip_create_temp_output(struct zip *, FILE **);
67
66
 
68
67
 
@@ -512,7 +511,8 @@ _zip_cdir_set_comment(struct zip_cdir *dest, struct zip *src)
512
511
 
513
512
 
514
513
 
515
- static int
514
+ // modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
515
+ /*static*/ int
516
516
  _zip_changed(struct zip *za, int *survivorsp)
517
517
  {
518
518
  int changed, i, survivors;
data/ext/zip_open.c CHANGED
@@ -409,6 +409,10 @@ _zip_file_exists(const char *fn, int flags, int *zep)
409
409
  return -1;
410
410
  }
411
411
  }
412
+ // modified for Zip/Ruby by SUGAWARA Genki <sgwr_dts@yahoo.co.jp>
413
+ else if ((flags & ZIP_CREATE) && (flags & ZIP_TRUNC)) {
414
+ return 0;
415
+ }
412
416
  else if ((flags & ZIP_EXCL)) {
413
417
  set_error(zep, NULL, ZIP_ER_EXISTS);
414
418
  return -1;
data/ext/zipruby.h CHANGED
@@ -1,7 +1,7 @@
1
1
  #ifndef __ZIPRUBY_H__
2
2
  #define __ZIPRUBY_H__
3
3
 
4
- #define VERSION "0.2.6"
4
+ #define VERSION "0.2.8"
5
5
  #define ERRSTR_BUFSIZE 256
6
6
  #define DATA_BUFSIZE 8192
7
7
 
@@ -4,6 +4,7 @@
4
4
  #include "zipruby.h"
5
5
  #include "zipruby_archive.h"
6
6
  #include "zipruby_zip_source_proc.h"
7
+ #include "tmpfile.h"
7
8
  #include "ruby.h"
8
9
  #include "rubyio.h"
9
10
 
@@ -11,6 +12,7 @@ static VALUE zipruby_archive_alloc(VALUE klass);
11
12
  static void zipruby_archive_mark(struct zipruby_archive *p);
12
13
  static void zipruby_archive_free(struct zipruby_archive *p);
13
14
  static VALUE zipruby_archive_s_open(int argc, VALUE *argv, VALUE self);
15
+ static VALUE zipruby_archive_s_open_buffer(int argc, VALUE *argv, VALUE self);
14
16
  static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password);
15
17
  static VALUE zipruby_archive_s_encrypt(VALUE self, VALUE path, VALUE password);
16
18
  static VALUE zipruby_archive_close(VALUE self);
@@ -47,6 +49,7 @@ static VALUE zipruby_archive_commit(VALUE self);
47
49
  static VALUE zipruby_archive_is_open(VALUE self);
48
50
  static VALUE zipruby_archive_decrypt(VALUE self, VALUE password);
49
51
  static VALUE zipruby_archive_encrypt(VALUE self, VALUE password);
52
+ static VALUE zipruby_archive_read(VALUE self);
50
53
 
51
54
  extern VALUE Zip;
52
55
  VALUE Archive;
@@ -59,6 +62,7 @@ void Init_zipruby_archive() {
59
62
  rb_define_alloc_func(Archive, zipruby_archive_alloc);
60
63
  rb_include_module(Archive, rb_mEnumerable);
61
64
  rb_define_singleton_method(Archive, "open", zipruby_archive_s_open, -1);
65
+ rb_define_singleton_method(Archive, "open_buffer", zipruby_archive_s_open_buffer, -1);
62
66
  rb_define_singleton_method(Archive, "decrypt", zipruby_archive_s_decrypt, 2);
63
67
  rb_define_singleton_method(Archive, "encrypt", zipruby_archive_s_encrypt, 2);
64
68
  rb_define_method(Archive, "close", zipruby_archive_close, 0);
@@ -98,6 +102,7 @@ void Init_zipruby_archive() {
98
102
  rb_define_method(Archive, "open?", zipruby_archive_is_open, 0);
99
103
  rb_define_method(Archive, "decrypt", zipruby_archive_decrypt, 1);
100
104
  rb_define_method(Archive, "encrypt", zipruby_archive_encrypt, 1);
105
+ rb_define_method(Archive, "read", zipruby_archive_read, 0);
101
106
  }
102
107
 
103
108
  static VALUE zipruby_archive_alloc(VALUE klass) {
@@ -106,15 +111,23 @@ static VALUE zipruby_archive_alloc(VALUE klass) {
106
111
  p->archive = NULL;
107
112
  p->path = Qnil;
108
113
  p->flags = 0;
114
+ p->tmpfilnam = NULL;
115
+ p->buffer = Qnil;
109
116
 
110
117
  return Data_Wrap_Struct(klass, zipruby_archive_mark, zipruby_archive_free, p);
111
118
  }
112
119
 
113
120
  static void zipruby_archive_mark(struct zipruby_archive *p) {
114
121
  rb_gc_mark(p->path);
122
+ rb_gc_mark(p->buffer);
115
123
  }
116
124
 
117
125
  static void zipruby_archive_free(struct zipruby_archive *p) {
126
+ if (p->tmpfilnam) {
127
+ zipruby_rmtmp(p->tmpfilnam);
128
+ free(p->tmpfilnam);
129
+ }
130
+
118
131
  xfree(p);
119
132
  }
120
133
 
@@ -162,6 +175,76 @@ static VALUE zipruby_archive_s_open(int argc, VALUE *argv, VALUE self) {
162
175
  }
163
176
  }
164
177
 
178
+ /* */
179
+ static VALUE zipruby_archive_s_open_buffer(int argc, VALUE *argv, VALUE self) {
180
+ VALUE buffer, flags;
181
+ VALUE archive;
182
+ struct zipruby_archive *p_archive;
183
+ void *data = NULL;
184
+ int len = 0, i_flags = 0;
185
+ int errorp;
186
+
187
+ rb_scan_args(argc, argv, "02", &buffer, &flags);
188
+
189
+ if (FIXNUM_P(buffer) && NIL_P(flags)) {
190
+ flags = buffer;
191
+ buffer = Qnil;
192
+ }
193
+
194
+ if (!NIL_P(flags)) {
195
+ i_flags = NUM2INT(flags);
196
+ }
197
+
198
+ if (i_flags & ZIP_CREATE) {
199
+ if (!NIL_P(buffer)) {
200
+ Check_Type(buffer, T_STRING);
201
+ }
202
+
203
+ i_flags = (i_flags | ZIP_TRUNC);
204
+ } else if (TYPE(buffer) == T_STRING) {
205
+ data = StringValuePtr(buffer);
206
+ len = RSTRING(buffer)->len;
207
+ } else if (rb_obj_is_instance_of(buffer, rb_cProc)) {
208
+ data = (void *) buffer;
209
+ len = -1;
210
+ } else {
211
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Proc)", rb_class2name(CLASS_OF(buffer)));
212
+ }
213
+
214
+ archive = rb_funcall(Archive, rb_intern("new"), 0);
215
+ Data_Get_Struct(archive, struct zipruby_archive, p_archive);
216
+
217
+ if ((p_archive->tmpfilnam = zipruby_tmpnam(data, len)) == NULL) {
218
+ rb_raise(Error, "Open archive failed: Failed to create temporary file");
219
+ }
220
+
221
+ if ((p_archive->archive = zip_open(p_archive->tmpfilnam, i_flags, &errorp)) == NULL) {
222
+ char errstr[ERRSTR_BUFSIZE];
223
+ zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno);
224
+ rb_raise(Error, "Open archive failed: %s", errstr);
225
+ }
226
+
227
+ p_archive->path = rb_str_new2(p_archive->tmpfilnam);
228
+ p_archive->flags = i_flags;
229
+ p_archive->buffer = buffer;
230
+
231
+ if (rb_block_given_p()) {
232
+ VALUE retval;
233
+ int status;
234
+
235
+ retval = rb_protect(rb_yield, archive, &status);
236
+ zipruby_archive_close(archive);
237
+
238
+ if (status != 0) {
239
+ rb_jump_tag(status);
240
+ }
241
+
242
+ return retval;
243
+ } else {
244
+ return archive;
245
+ }
246
+ }
247
+
165
248
  /* */
166
249
  static VALUE zipruby_archive_s_decrypt(VALUE self, VALUE path, VALUE password) {
167
250
  int errorp, wrongpwd;
@@ -217,6 +300,7 @@ static VALUE zipruby_archive_s_encrypt(VALUE self, VALUE path, VALUE password) {
217
300
  /* */
218
301
  static VALUE zipruby_archive_close(VALUE self) {
219
302
  struct zipruby_archive *p_archive;
303
+ int changed, survivors;
220
304
 
221
305
  if (!zipruby_archive_is_open(self)) {
222
306
  return Qfalse;
@@ -225,14 +309,20 @@ static VALUE zipruby_archive_close(VALUE self) {
225
309
  Data_Get_Struct(self, struct zipruby_archive, p_archive);
226
310
  Check_Archive(p_archive);
227
311
 
312
+ changed = _zip_changed(p_archive->archive, &survivors);
313
+
228
314
  if (zip_close(p_archive->archive) == -1) {
229
315
  zip_unchange_all(p_archive->archive);
230
316
  zip_unchange_archive(p_archive->archive);
231
317
  rb_raise(Error, "Close archive failed: %s", zip_strerror(p_archive->archive));
232
318
  }
233
319
 
320
+ if (!NIL_P(p_archive->buffer) && changed) {
321
+ rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
322
+ }
323
+
324
+ zipruby_rmtmp(p_archive->tmpfilnam);
234
325
  p_archive->archive = NULL;
235
- p_archive->path = Qnil;
236
326
  p_archive->flags = 0;
237
327
 
238
328
  return Qtrue;
@@ -1068,17 +1158,24 @@ static VALUE zipruby_archive_each(VALUE self) {
1068
1158
  /* */
1069
1159
  static VALUE zipruby_archive_commit(VALUE self) {
1070
1160
  struct zipruby_archive *p_archive;
1161
+ int changed, survivors;
1071
1162
  int errorp;
1072
1163
 
1073
1164
  Data_Get_Struct(self, struct zipruby_archive, p_archive);
1074
1165
  Check_Archive(p_archive);
1075
1166
 
1167
+ changed = _zip_changed(p_archive->archive, &survivors);
1168
+
1076
1169
  if (zip_close(p_archive->archive) == -1) {
1077
1170
  zip_unchange_all(p_archive->archive);
1078
1171
  zip_unchange_archive(p_archive->archive);
1079
1172
  rb_raise(Error, "Commit archive failed: %s", zip_strerror(p_archive->archive));
1080
1173
  }
1081
1174
 
1175
+ if (!NIL_P(p_archive->buffer) && changed) {
1176
+ rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
1177
+ }
1178
+
1082
1179
  p_archive->archive = NULL;
1083
1180
  p_archive->flags = (p_archive->flags & ~(ZIP_CREATE | ZIP_EXCL));
1084
1181
 
@@ -1103,6 +1200,7 @@ static VALUE zipruby_archive_is_open(VALUE self) {
1103
1200
  static VALUE zipruby_archive_decrypt(VALUE self, VALUE password) {
1104
1201
  struct zipruby_archive *p_archive;
1105
1202
  long pwdlen;
1203
+ int changed, survivors;
1106
1204
  int errorp;
1107
1205
 
1108
1206
  Check_Type(password, T_STRING);
@@ -1117,12 +1215,18 @@ static VALUE zipruby_archive_decrypt(VALUE self, VALUE password) {
1117
1215
  Data_Get_Struct(self, struct zipruby_archive, p_archive);
1118
1216
  Check_Archive(p_archive);
1119
1217
 
1218
+ changed = _zip_changed(p_archive->archive, &survivors);
1219
+
1120
1220
  if (zip_close(p_archive->archive) == -1) {
1121
1221
  zip_unchange_all(p_archive->archive);
1122
1222
  zip_unchange_archive(p_archive->archive);
1123
1223
  rb_raise(Error, "Decrypt archive failed: %s", zip_strerror(p_archive->archive));
1124
1224
  }
1125
1225
 
1226
+ if (!NIL_P(p_archive->buffer) && changed) {
1227
+ rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
1228
+ }
1229
+
1126
1230
  p_archive->archive = NULL;
1127
1231
  p_archive->flags = (p_archive->flags & ~(ZIP_CREATE | ZIP_EXCL));
1128
1232
 
@@ -1141,6 +1245,7 @@ static VALUE zipruby_archive_decrypt(VALUE self, VALUE password) {
1141
1245
  static VALUE zipruby_archive_encrypt(VALUE self, VALUE password) {
1142
1246
  struct zipruby_archive *p_archive;
1143
1247
  long pwdlen;
1248
+ int changed, survivors;
1144
1249
  int errorp;
1145
1250
 
1146
1251
  Check_Type(password, T_STRING);
@@ -1155,12 +1260,18 @@ static VALUE zipruby_archive_encrypt(VALUE self, VALUE password) {
1155
1260
  Data_Get_Struct(self, struct zipruby_archive, p_archive);
1156
1261
  Check_Archive(p_archive);
1157
1262
 
1263
+ changed = _zip_changed(p_archive->archive, &survivors);
1264
+
1158
1265
  if (zip_close(p_archive->archive) == -1) {
1159
1266
  zip_unchange_all(p_archive->archive);
1160
1267
  zip_unchange_archive(p_archive->archive);
1161
1268
  rb_raise(Error, "Encrypt archive failed: %s", zip_strerror(p_archive->archive));
1162
1269
  }
1163
1270
 
1271
+ if (!NIL_P(p_archive->buffer) && changed) {
1272
+ rb_funcall(p_archive->buffer, rb_intern("replace"), 1, rb_funcall(self, rb_intern("read"), 0));
1273
+ }
1274
+
1164
1275
  p_archive->archive = NULL;
1165
1276
  p_archive->flags = (p_archive->flags & ~(ZIP_CREATE | ZIP_EXCL));
1166
1277
 
@@ -1174,3 +1285,56 @@ static VALUE zipruby_archive_encrypt(VALUE self, VALUE password) {
1174
1285
 
1175
1286
  return Qnil;
1176
1287
  }
1288
+
1289
+ static VALUE zipruby_archive_read(VALUE self) {
1290
+ VALUE retval = Qnil;
1291
+ struct zipruby_archive *p_archive;
1292
+ FILE *fzip;
1293
+ char buf[DATA_BUFSIZE];
1294
+ ssize_t n;
1295
+ int block_given;
1296
+
1297
+ Data_Get_Struct(self, struct zipruby_archive, p_archive);
1298
+
1299
+ if (NIL_P(p_archive->path)) {
1300
+ rb_raise(rb_eRuntimeError, "invalid Zip::Archive");
1301
+ }
1302
+
1303
+ #ifdef _WIN32
1304
+ if (fopen_s(&fzip ,StringValuePtr(p_archive->path), "rb") != 0) {
1305
+ rb_raise(Error, "Read archive failed: Cannot open archive");
1306
+ }
1307
+ #else
1308
+ if ((fzip = fopen(StringValuePtr(p_archive->path), "rb")) == NULL) {
1309
+ rb_raise(Error, "Read archive failed: Cannot open archive");
1310
+ }
1311
+ #endif
1312
+
1313
+ block_given = rb_block_given_p();
1314
+
1315
+ while ((n = fread(buf, 1, sizeof(buf), fzip)) > 0) {
1316
+ if (block_given) {
1317
+ rb_yield(rb_str_new(buf, n));
1318
+ } else {
1319
+ if (NIL_P(retval)) {
1320
+ retval = rb_str_new(buf, n);
1321
+ } else {
1322
+ rb_str_buf_cat(retval, buf, n);
1323
+ }
1324
+ }
1325
+ }
1326
+
1327
+ #ifdef RUBY_WIN32_H
1328
+ #undef fclose
1329
+ fclose(fzip);
1330
+ #define fclose(f) rb_w32_fclose(f)
1331
+ #else
1332
+ fclose(fzip);
1333
+ #endif
1334
+
1335
+ if (n == -1) {
1336
+ rb_raise(Error, "Read archive failed");
1337
+ }
1338
+
1339
+ return retval;
1340
+ }
@@ -8,6 +8,8 @@ struct zipruby_archive {
8
8
  struct zip *archive;
9
9
  VALUE path;
10
10
  int flags;
11
+ char *tmpfilnam;
12
+ VALUE buffer;
11
13
  };
12
14
 
13
15
  void Init_zipruby_archive();
data/ext/zipruby_zip.c CHANGED
@@ -12,6 +12,7 @@ void Init_zipruby_zip() {
12
12
  rb_define_const(Zip, "CREATE", INT2NUM(ZIP_CREATE));
13
13
  rb_define_const(Zip, "EXCL", INT2NUM(ZIP_EXCL));
14
14
  rb_define_const(Zip, "CHECKCONS", INT2NUM(ZIP_CHECKCONS));
15
+ rb_define_const(Zip, "TRUNC", INT2NUM(ZIP_TRUNC));
15
16
 
16
17
  rb_define_const(Zip, "FL_NOCASE", INT2NUM(ZIP_FL_NOCASE));
17
18
  rb_define_const(Zip, "FL_NODIR", INT2NUM(ZIP_FL_NODIR));
@@ -5,6 +5,10 @@
5
5
  #include "zipruby_zip_source_proc.h"
6
6
  #include "ruby.h"
7
7
 
8
+ static VALUE proc_call(VALUE proc) {
9
+ return rb_funcall(proc, rb_intern("call"), 0);
10
+ }
11
+
8
12
  static ssize_t read_proc(void *state, void *data, size_t len, enum zip_source_cmd cmd) {
9
13
  struct read_proc *z;
10
14
  VALUE src;
@@ -19,13 +23,12 @@ static ssize_t read_proc(void *state, void *data, size_t len, enum zip_source_cm
19
23
  return 0;
20
24
 
21
25
  case ZIP_SOURCE_READ:
22
- src = rb_funcall(z->proc, rb_intern("call"), 1, ULONG2NUM(len));
26
+ src = rb_protect(proc_call, z->proc, NULL);
23
27
 
24
- if (NIL_P(src)) {
28
+ if (TYPE(src) != T_STRING) {
25
29
  return 0;
26
30
  }
27
31
 
28
- src = rb_check_convert_type(src, T_STRING, "String", "to_s");
29
32
  n = RSTRING(src)->len;
30
33
 
31
34
  if (n > 0) {