~ubuntu-branches/debian/wheezy/lua-expat/wheezy

« back to all changes in this revision

Viewing changes to .pc/luaexpat-xmldecl.patch/src/lxplib.c

  • Committer: Package Import Robot
  • Author(s): Enrico Tassi
  • Date: 2014-03-30 17:21:54 UTC
  • Revision ID: package-import@ubuntu.com-20140330172154-i1721ozpxnqhxdi0
Tags: 1.2.0-5+deb7u1
* Integrate upstream patches to fix potential DOS attack:
  - luaexpat-getcurrent-byte-count.patch
  - luaexpat-xmldecl.patch
  - luaexpat-option-chardata-merging.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
** $Id: lxplib.c,v 1.16 2007/06/05 20:03:12 carregal Exp $
 
3
** LuaExpat: Lua bind for Expat library
 
4
** See Copyright Notice in license.html
 
5
*/
 
6
 
 
7
 
 
8
#include <assert.h>
 
9
#include <stdlib.h>
 
10
#include <string.h>
 
11
 
 
12
#include "expat.h"
 
13
 
 
14
#include "lua.h"
 
15
#include "lauxlib.h"
 
16
#if ! defined (LUA_VERSION_NUM) || LUA_VERSION_NUM < 501
 
17
#include "compat-5.1.h"
 
18
#endif
 
19
 
 
20
#if (LUA_VERSION_NUM == 502)
 
21
 
 
22
#undef luaL_register
 
23
#define luaL_register(L,n,f) \
 
24
                { if ((n) == NULL) luaL_setfuncs(L,f,0); else luaL_newlib(L,f); }
 
25
#endif
 
26
 
 
27
#include "lxplib.h"
 
28
 
 
29
 
 
30
 
 
31
enum XPState {
 
32
  XPSpre,  /* parser just initialized */
 
33
  XPSok,   /* state while parsing */
 
34
  XPSfinished,  /* state after finished parsing */
 
35
  XPSerror,
 
36
  XPSstring  /* state while reading a string */
 
37
};
 
38
 
 
39
struct lxp_userdata {
 
40
  lua_State *L;
 
41
  XML_Parser parser;  /* associated expat parser */
 
42
  int tableref;  /* table with callbacks for this parser */
 
43
  enum XPState state;
 
44
  luaL_Buffer *b;  /* to concatenate sequences of cdata pieces */
 
45
};
 
46
 
 
47
typedef struct lxp_userdata lxp_userdata;
 
48
 
 
49
 
 
50
static int reporterror (lxp_userdata *xpu) {
 
51
  lua_State *L = xpu->L;
 
52
  XML_Parser p = xpu->parser;
 
53
  lua_pushnil(L);
 
54
  lua_pushstring(L, XML_ErrorString(XML_GetErrorCode(p)));
 
55
  lua_pushnumber(L, XML_GetCurrentLineNumber(p));
 
56
  lua_pushnumber(L, XML_GetCurrentColumnNumber(p) + 1);
 
57
  lua_pushnumber(L, XML_GetCurrentByteIndex(p) + 1);
 
58
  return 5;
 
59
}
 
60
 
 
61
 
 
62
static lxp_userdata *createlxp (lua_State *L) {
 
63
  lxp_userdata *xpu = (lxp_userdata *)lua_newuserdata(L, sizeof(lxp_userdata));
 
64
  xpu->tableref = LUA_REFNIL;  /* in case of errors... */
 
65
  xpu->parser = NULL;
 
66
  xpu->L = NULL;
 
67
  xpu->state = XPSpre;
 
68
  luaL_getmetatable(L, ParserType);
 
69
  lua_setmetatable(L, -2);
 
70
  return xpu;
 
71
}
 
72
 
 
73
 
 
74
static void lxpclose (lua_State *L, lxp_userdata *xpu) {
 
75
  luaL_unref(L, LUA_REGISTRYINDEX, xpu->tableref);
 
76
  xpu->tableref = LUA_REFNIL;
 
77
  if (xpu->parser)
 
78
    XML_ParserFree(xpu->parser);
 
79
  xpu->parser = NULL;
 
80
}
 
81
 
 
82
 
 
83
 
 
84
 
 
85
/*
 
86
** Auxiliary function to call a Lua handle
 
87
*/
 
88
static void docall (lxp_userdata *xpu, int nargs, int nres) {
 
89
  lua_State *L = xpu->L;
 
90
  assert(xpu->state == XPSok);
 
91
  if (lua_pcall(L, nargs + 1, nres, 0) != 0) {
 
92
    xpu->state = XPSerror;
 
93
    luaL_unref(L, LUA_REGISTRYINDEX, xpu->tableref);
 
94
    xpu->tableref = luaL_ref(L, LUA_REGISTRYINDEX);  /* error message */
 
95
  }
 
96
}
 
97
 
 
98
 
 
99
/*
 
100
** Check whether there is pending Cdata, and call its handle if necessary
 
101
*/
 
102
static void dischargestring (lxp_userdata *xpu) {
 
103
  assert(xpu->state == XPSstring);
 
104
  xpu->state = XPSok;
 
105
  luaL_pushresult(xpu->b);
 
106
  docall(xpu, 1, 0);
 
107
}
 
108
 
 
109
 
 
110
/*
 
111
** Check whether there is a Lua handle for a given event: If so,
 
112
** put it on the stack (to be called later), and also push `self'
 
113
*/
 
114
static int getHandle (lxp_userdata *xpu, const char *handle) {
 
115
  lua_State *L = xpu->L;
 
116
  if (xpu->state == XPSstring) dischargestring(xpu);
 
117
  if (xpu->state == XPSerror)
 
118
    return 0;  /* some error happened before; skip all handles */
 
119
  lua_pushstring(L, handle);
 
120
  lua_gettable(L, 3);
 
121
  if (lua_toboolean(L, -1) == 0) {
 
122
    lua_pop(L, 1);
 
123
    return 0;
 
124
  }
 
125
  if (!lua_isfunction(L, -1)) {
 
126
    luaL_error(L, "lxp `%s' callback is not a function", handle);
 
127
  }
 
128
  lua_pushvalue(L, 1);  /* first argument in every call (self) */
 
129
  return 1;
 
130
}
 
131
 
 
132
 
 
133
 
 
134
/*
 
135
** {======================================================
 
136
** Handles
 
137
** =======================================================
 
138
*/
 
139
 
 
140
 
 
141
static void f_StartCdata (void *ud) {
 
142
  lxp_userdata *xpu = (lxp_userdata *)ud;
 
143
  if (getHandle(xpu, StartCdataKey) == 0) return;  /* no handle */
 
144
  docall(xpu, 0, 0);
 
145
}
 
146
 
 
147
 
 
148
static void f_EndCdataKey (void *ud) {
 
149
  lxp_userdata *xpu = (lxp_userdata *)ud;
 
150
  if (getHandle(xpu, EndCdataKey) == 0) return;  /* no handle */
 
151
  docall(xpu, 0, 0);
 
152
}
 
153
 
 
154
 
 
155
static void f_CharData (void *ud, const char *s, int len) {
 
156
  lxp_userdata *xpu = (lxp_userdata *)ud;
 
157
  if (xpu->state == XPSok) {
 
158
    if (getHandle(xpu, CharDataKey) == 0) return;  /* no handle */
 
159
    xpu->state = XPSstring;
 
160
    luaL_buffinit(xpu->L, xpu->b);
 
161
  }
 
162
  if (xpu->state == XPSstring)
 
163
    luaL_addlstring(xpu->b, s, len);
 
164
}
 
165
 
 
166
 
 
167
static void f_Comment (void *ud, const char *data) {
 
168
  lxp_userdata *xpu = (lxp_userdata *)ud;
 
169
  if (getHandle(xpu, CommentKey) == 0) return;  /* no handle */
 
170
  lua_pushstring(xpu->L, data);
 
171
  docall(xpu, 1, 0);
 
172
}
 
173
 
 
174
 
 
175
static void f_Default (void *ud, const char *data, int len) {
 
176
  lxp_userdata *xpu = (lxp_userdata *)ud;
 
177
  if (getHandle(xpu, DefaultKey) == 0) return;  /* no handle */
 
178
  lua_pushlstring(xpu->L, data, len);
 
179
  docall(xpu, 1, 0);
 
180
}
 
181
 
 
182
 
 
183
static void f_DefaultExpand (void *ud, const char *data, int len) {
 
184
  lxp_userdata *xpu = (lxp_userdata *)ud;
 
185
  if (getHandle(xpu, DefaultExpandKey) == 0) return;  /* no handle */
 
186
  lua_pushlstring(xpu->L, data, len);
 
187
  docall(xpu, 1, 0);
 
188
}
 
189
 
 
190
 
 
191
static void f_StartElement (void *ud, const char *name, const char **attrs) {
 
192
  lxp_userdata *xpu = (lxp_userdata *)ud;
 
193
  lua_State *L = xpu->L;
 
194
  int lastspec = XML_GetSpecifiedAttributeCount(xpu->parser) / 2;
 
195
  int i = 1;
 
196
  if (getHandle(xpu, StartElementKey) == 0) return;  /* no handle */
 
197
  lua_pushstring(L, name);
 
198
  lua_newtable(L);
 
199
  while (*attrs) {
 
200
    if (i <= lastspec) {
 
201
      lua_pushnumber(L, i++);
 
202
      lua_pushstring(L, *attrs);
 
203
      lua_settable(L, -3);
 
204
    }
 
205
    lua_pushstring(L, *attrs++);
 
206
    lua_pushstring(L, *attrs++);
 
207
    lua_settable(L, -3);
 
208
  }
 
209
  docall(xpu, 2, 0);  /* call function with self, name, and attributes */
 
210
}
 
211
 
 
212
 
 
213
static void f_EndElement (void *ud, const char *name) {
 
214
  lxp_userdata *xpu = (lxp_userdata *)ud;
 
215
  if (getHandle(xpu, EndElementKey) == 0) return;  /* no handle */
 
216
  lua_pushstring(xpu->L, name);
 
217
  docall(xpu, 1, 0);
 
218
}
 
219
 
 
220
 
 
221
static int f_ExternaEntity (XML_Parser p, const char *context,
 
222
                                          const char *base,
 
223
                                          const char *systemId,
 
224
                                          const char *publicId) {
 
225
  lxp_userdata *xpu = (lxp_userdata *)XML_GetUserData(p);
 
226
  lua_State *L = xpu->L;
 
227
  lxp_userdata *child;
 
228
  int status;
 
229
  if (getHandle(xpu, ExternalEntityKey) == 0) return 1;  /* no handle */
 
230
  child = createlxp(L);
 
231
  child->parser = XML_ExternalEntityParserCreate(p, context, NULL);
 
232
  if (!child->parser)
 
233
    luaL_error(L, "XML_ParserCreate failed");
 
234
  lua_rawgeti(L, LUA_REGISTRYINDEX, xpu->tableref);  /* child uses the same table of its father */
 
235
  child->tableref = luaL_ref(L, LUA_REGISTRYINDEX);
 
236
  lua_pushstring(L, base);
 
237
  lua_pushstring(L, systemId);
 
238
  lua_pushstring(L, publicId);
 
239
  docall(xpu, 4, 1);
 
240
  status = lua_toboolean(L, -1);
 
241
  lua_pop(L, 1);
 
242
  lxpclose(L, child);
 
243
  return status;
 
244
}
 
245
 
 
246
 
 
247
static void f_StartNamespaceDecl (void *ud, const char *prefix,
 
248
                                            const char *uri) {
 
249
  lxp_userdata *xpu = (lxp_userdata *)ud;
 
250
  lua_State *L = xpu->L;
 
251
  if (getHandle(xpu, StartNamespaceDeclKey) == 0) return;  /* no handle */
 
252
  lua_pushstring(L, prefix);
 
253
  lua_pushstring(L, uri);
 
254
  docall(xpu, 2, 0);
 
255
}
 
256
 
 
257
 
 
258
static void f_EndNamespaceDecl (void *ud, const char *prefix) {
 
259
  lxp_userdata *xpu = (lxp_userdata *)ud;
 
260
  if (getHandle(xpu, EndNamespaceDeclKey) == 0) return;  /* no handle */
 
261
  lua_pushstring(xpu->L, prefix);
 
262
  docall(xpu, 1, 0);
 
263
}
 
264
 
 
265
 
 
266
static void f_NotationDecl (void *ud, const char *notationName,
 
267
                                      const char *base,
 
268
                                      const char *systemId,
 
269
                                      const char *publicId) {
 
270
  lxp_userdata *xpu = (lxp_userdata *)ud;
 
271
  lua_State *L = xpu->L;
 
272
  if (getHandle(xpu, NotationDeclKey) == 0) return;  /* no handle */
 
273
  lua_pushstring(L, notationName);
 
274
  lua_pushstring(L, base);
 
275
  lua_pushstring(L, systemId);
 
276
  lua_pushstring(L, publicId);
 
277
  docall(xpu, 4, 0);
 
278
}
 
279
 
 
280
 
 
281
static int f_NotStandalone (void *ud) {
 
282
  int status;
 
283
  lxp_userdata *xpu = (lxp_userdata *)ud;
 
284
  lua_State *L = xpu->L;
 
285
  if (getHandle(xpu, NotStandaloneKey) == 0) return 1;  /* no handle */
 
286
  docall(xpu, 0, 1);
 
287
  status = lua_toboolean(L, -1);
 
288
  lua_pop(L, 1);
 
289
  return status;
 
290
}
 
291
 
 
292
 
 
293
static void f_ProcessingInstruction (void *ud, const char *target,
 
294
                                               const char *data) {
 
295
  lxp_userdata *xpu = (lxp_userdata *)ud;
 
296
  lua_State *L = xpu->L;
 
297
  if (getHandle(xpu, ProcessingInstructionKey) == 0) return;  /* no handle */
 
298
  lua_pushstring(L, target);
 
299
  lua_pushstring(L, data);
 
300
  docall(xpu, 2, 0);
 
301
}
 
302
 
 
303
 
 
304
static void f_UnparsedEntityDecl (void *ud, const char *entityName,
 
305
                                            const char *base,
 
306
                                            const char *systemId,
 
307
                                            const char *publicId,
 
308
                                            const char *notationName) {
 
309
  lxp_userdata *xpu = (lxp_userdata *)ud;
 
310
  lua_State *L = xpu->L;
 
311
  if (getHandle(xpu, UnparsedEntityDeclKey) == 0) return;  /* no handle */
 
312
  lua_pushstring(L, entityName);
 
313
  lua_pushstring(L, base);
 
314
  lua_pushstring(L, systemId);
 
315
  lua_pushstring(L, publicId);
 
316
  lua_pushstring(L, notationName);
 
317
  docall(xpu, 5, 0);
 
318
}
 
319
 
 
320
static void f_StartDoctypeDecl (void *ud, const XML_Char *doctypeName,
 
321
                                          const XML_Char *sysid,
 
322
                                          const XML_Char *pubid,
 
323
                                          int has_internal_subset) {
 
324
  lxp_userdata *xpu = (lxp_userdata *)ud;
 
325
  if (getHandle(xpu, StartDoctypeDeclKey) == 0) return;  /* no handle */
 
326
  lua_pushstring(xpu->L, doctypeName);
 
327
  lua_pushstring(xpu->L, sysid);
 
328
  lua_pushstring(xpu->L, pubid);
 
329
  lua_pushboolean(xpu->L, has_internal_subset);
 
330
  docall(xpu, 4, 0);
 
331
}
 
332
 
 
333
/* }====================================================== */
 
334
 
 
335
 
 
336
 
 
337
static int hasfield (lua_State *L, const char *fname) {
 
338
  int res;
 
339
  lua_pushstring(L, fname);
 
340
  lua_gettable(L, 1);
 
341
  res = !lua_isnil(L, -1);
 
342
  lua_pop(L, 1);
 
343
  return res;
 
344
}
 
345
 
 
346
 
 
347
static void checkcallbacks (lua_State *L) {
 
348
  static const char *const validkeys[] = {
 
349
    "StartCdataSection", "EndCdataSection", "CharacterData", "Comment",
 
350
    "Default", "DefaultExpand", "StartElement", "EndElement",
 
351
    "ExternalEntityRef", "StartNamespaceDecl", "EndNamespaceDecl",
 
352
    "NotationDecl", "NotStandalone", "ProcessingInstruction",
 
353
    "UnparsedEntityDecl", "StartDoctypeDecl", NULL};
 
354
  if (hasfield(L, "_nonstrict")) return;
 
355
  lua_pushnil(L);
 
356
  while (lua_next(L, 1)) {
 
357
    lua_pop(L, 1);  /* remove value */
 
358
#if ! defined (LUA_VERSION_NUM) || LUA_VERSION_NUM < 501
 
359
    if (lua_type(L, -1) != LUA_TSTRING ||
 
360
        luaL_findstring(lua_tostring(L, -1), validkeys) < 0)
 
361
      luaL_error(L, "invalid key `%s' in callback table", lua_tostring(L, -1));
 
362
#else
 
363
    luaL_checkoption(L, -1, NULL, validkeys);
 
364
#endif
 
365
  }
 
366
}
 
367
 
 
368
 
 
369
static int lxp_make_parser (lua_State *L) {
 
370
  XML_Parser p;
 
371
  char sep = *luaL_optstring(L, 2, "");
 
372
  lxp_userdata *xpu = createlxp(L);
 
373
  p = xpu->parser = (sep == '\0') ? XML_ParserCreate(NULL) :
 
374
                                    XML_ParserCreateNS(NULL, sep);
 
375
  if (!p)
 
376
    luaL_error(L, "XML_ParserCreate failed");
 
377
  luaL_checktype(L, 1, LUA_TTABLE);
 
378
  checkcallbacks(L);
 
379
  lua_pushvalue(L, 1);
 
380
  xpu->tableref = luaL_ref(L, LUA_REGISTRYINDEX);
 
381
  XML_SetUserData(p, xpu);
 
382
  if (hasfield(L, StartCdataKey) || hasfield(L, EndCdataKey))
 
383
    XML_SetCdataSectionHandler(p, f_StartCdata, f_EndCdataKey);
 
384
  if (hasfield(L, CharDataKey))
 
385
    XML_SetCharacterDataHandler(p, f_CharData);
 
386
  if (hasfield(L, CommentKey))
 
387
    XML_SetCommentHandler(p, f_Comment);
 
388
  if (hasfield(L, DefaultKey))
 
389
    XML_SetDefaultHandler(p, f_Default);
 
390
  if (hasfield(L, DefaultExpandKey))
 
391
    XML_SetDefaultHandlerExpand(p, f_DefaultExpand);
 
392
  if (hasfield(L, StartElementKey) || hasfield(L, EndElementKey))
 
393
    XML_SetElementHandler(p, f_StartElement, f_EndElement);
 
394
  if (hasfield(L, ExternalEntityKey))
 
395
    XML_SetExternalEntityRefHandler(p, f_ExternaEntity);
 
396
  if (hasfield(L, StartNamespaceDeclKey) || hasfield(L, EndNamespaceDeclKey))
 
397
    XML_SetNamespaceDeclHandler(p, f_StartNamespaceDecl, f_EndNamespaceDecl);
 
398
  if (hasfield(L, NotationDeclKey))
 
399
    XML_SetNotationDeclHandler(p, f_NotationDecl);
 
400
  if (hasfield(L, NotStandaloneKey))
 
401
    XML_SetNotStandaloneHandler(p, f_NotStandalone);
 
402
  if (hasfield(L, ProcessingInstructionKey))
 
403
    XML_SetProcessingInstructionHandler(p, f_ProcessingInstruction);
 
404
  if (hasfield(L, UnparsedEntityDeclKey))
 
405
    XML_SetUnparsedEntityDeclHandler(p, f_UnparsedEntityDecl);
 
406
  if (hasfield(L, StartDoctypeDeclKey))
 
407
    XML_SetStartDoctypeDeclHandler(p, f_StartDoctypeDecl);
 
408
  return 1;
 
409
}
 
410
 
 
411
 
 
412
static lxp_userdata *checkparser (lua_State *L, int idx) {
 
413
  lxp_userdata *xpu = (lxp_userdata *)luaL_checkudata(L, idx, ParserType);
 
414
  luaL_argcheck(L, xpu, idx, "expat parser expected");
 
415
  luaL_argcheck(L, xpu->parser, idx, "parser is closed");
 
416
  return xpu;
 
417
}
 
418
 
 
419
 
 
420
static int parser_gc (lua_State *L) {
 
421
  lxp_userdata *xpu = (lxp_userdata *)luaL_checkudata(L, 1, ParserType);
 
422
  luaL_argcheck(L, xpu, 1, "expat parser expected");
 
423
  lxpclose(L, xpu);
 
424
  return 0;
 
425
}
 
426
 
 
427
 
 
428
static int setbase (lua_State *L) {
 
429
  lxp_userdata *xpu = checkparser(L, 1);
 
430
  if (XML_SetBase(xpu->parser, luaL_checkstring(L, 2)) == 0)
 
431
    luaL_error(L, "no memory to store base");
 
432
  return 0;
 
433
}
 
434
 
 
435
 
 
436
static int getbase (lua_State *L) {
 
437
  lxp_userdata *xpu = checkparser(L, 1);
 
438
  lua_pushstring(L, XML_GetBase(xpu->parser));
 
439
  return 1;
 
440
}
 
441
 
 
442
 
 
443
static int getcallbacks (lua_State *L) {
 
444
  lxp_userdata *xpu = checkparser(L, 1);
 
445
  lua_rawgeti(L, LUA_REGISTRYINDEX, xpu->tableref);
 
446
  return 1;
 
447
}
 
448
 
 
449
 
 
450
static int parse_aux (lua_State *L, lxp_userdata *xpu, const char *s,
 
451
                      size_t len) {
 
452
  luaL_Buffer b;
 
453
  int status;
 
454
  xpu->L = L;
 
455
  xpu->state = XPSok;
 
456
  xpu->b = &b;
 
457
  lua_settop(L, 2);
 
458
  lua_rawgeti(L, LUA_REGISTRYINDEX, xpu->tableref);  /* to be used by handlers */
 
459
  status = XML_Parse(xpu->parser, s, (int)len, s == NULL);
 
460
  if (xpu->state == XPSstring) dischargestring(xpu);
 
461
  if (xpu->state == XPSerror) {  /* callback error? */
 
462
    lua_rawgeti(L, LUA_REGISTRYINDEX, xpu->tableref);  /* get original msg. */
 
463
    lua_error(L);
 
464
  }
 
465
  if (s == NULL) xpu->state = XPSfinished;
 
466
  if (status) {
 
467
    lua_pushboolean(L, 1);
 
468
    return 1;
 
469
  }
 
470
  else { /* error */
 
471
    return reporterror(xpu);
 
472
  }
 
473
}
 
474
 
 
475
 
 
476
static int lxp_parse (lua_State *L) {
 
477
  lxp_userdata *xpu = checkparser(L, 1);
 
478
  size_t len;
 
479
  const char *s = luaL_optlstring(L, 2, NULL, &len);
 
480
  if (xpu->state == XPSfinished && s != NULL) {
 
481
    lua_pushnil(L);
 
482
    lua_pushliteral(L, "cannot parse - document is finished");
 
483
    return 2;
 
484
  }
 
485
  return parse_aux(L, xpu, s, len);
 
486
}
 
487
 
 
488
 
 
489
static int lxp_close (lua_State *L) {
 
490
  int status = 1;
 
491
  lxp_userdata *xpu = (lxp_userdata *)luaL_checkudata(L, 1, ParserType);
 
492
  luaL_argcheck(L, xpu, 1, "expat parser expected");
 
493
  if (xpu->state != XPSfinished)
 
494
    status = parse_aux(L, xpu, NULL, 0);
 
495
  lxpclose(L, xpu);
 
496
  if (status > 1) luaL_error(L, "error closing parser: %s",
 
497
                                lua_tostring(L, -status+1));
 
498
  return 0;
 
499
}
 
500
 
 
501
 
 
502
static int lxp_pos (lua_State *L) {
 
503
  lxp_userdata *xpu = checkparser(L, 1);
 
504
  XML_Parser p = xpu->parser;
 
505
  lua_pushnumber(L, XML_GetCurrentLineNumber(p));
 
506
  lua_pushnumber(L, XML_GetCurrentColumnNumber(p) + 1);
 
507
  lua_pushnumber(L, XML_GetCurrentByteIndex(p) + 1);
 
508
  return 3;
 
509
}
 
510
 
 
511
 
 
512
static int lxp_setencoding (lua_State *L) {
 
513
  lxp_userdata *xpu = checkparser(L, 1);
 
514
  const char *encoding = luaL_checkstring(L, 2);
 
515
  luaL_argcheck(L, xpu->state == XPSpre, 1, "invalid parser state");
 
516
  XML_SetEncoding(xpu->parser, encoding);
 
517
  return 0;
 
518
}
 
519
 
 
520
static int lxp_stop (lua_State *L) {
 
521
  lxp_userdata *xpu = checkparser(L, 1);
 
522
  lua_pushboolean(L, XML_StopParser(xpu->parser, XML_FALSE) == XML_STATUS_OK);
 
523
  return 1;
 
524
}
 
525
 
 
526
static int lxp_getcurrentbytecount (lua_State* L) {
 
527
  lxp_userdata *xpu = checkparser(L, 1);
 
528
  lua_pushinteger(L, XML_GetCurrentByteCount(xpu->parser));
 
529
  return 1;
 
530
}
 
531
 
 
532
static const struct luaL_Reg lxp_meths[] = {
 
533
  {"parse", lxp_parse},
 
534
  {"close", lxp_close},
 
535
  {"__gc", parser_gc},
 
536
  {"pos", lxp_pos},
 
537
  {"getcurrentbytecount", lxp_getcurrentbytecount},
 
538
  {"setencoding", lxp_setencoding},
 
539
  {"getcallbacks", getcallbacks},
 
540
  {"getbase", getbase},
 
541
  {"setbase", setbase},
 
542
  {"stop", lxp_stop},
 
543
  {NULL, NULL}
 
544
};
 
545
 
 
546
static const struct luaL_Reg lxp_funcs[] = {
 
547
  {"new", lxp_make_parser},
 
548
  {NULL, NULL}
 
549
};
 
550
 
 
551
 
 
552
/*
 
553
** Assumes the table is on top of the stack.
 
554
*/
 
555
static void set_info (lua_State *L) {
 
556
        lua_pushliteral (L, "_COPYRIGHT");
 
557
        lua_pushliteral (L, "Copyright (C) 2003-2007 Kepler Project");
 
558
        lua_settable (L, -3);
 
559
        lua_pushliteral (L, "_DESCRIPTION");
 
560
        lua_pushliteral (L, "LuaExpat is a SAX XML parser based on the Expat library");
 
561
        lua_settable (L, -3);
 
562
        lua_pushliteral (L, "_VERSION");
 
563
        lua_pushliteral (L, "LuaExpat 1.2.0");
 
564
        lua_settable (L, -3);
 
565
}
 
566
 
 
567
 
 
568
int luaopen_lxp (lua_State *L) {
 
569
  luaL_newmetatable(L, ParserType);
 
570
  lua_pushliteral(L, "__index");
 
571
  lua_pushvalue(L, -2);
 
572
  lua_rawset(L, -3);
 
573
  luaL_register (L, NULL, lxp_meths);
 
574
  luaL_register (L, "lxp", lxp_funcs);
 
575
  set_info (L);
 
576
 
 
577
  return 1;
 
578
}