├── .gitignore ├── GNUmakefile ├── LICENSE ├── Makefile ├── config.h.guess ├── debian ├── changelog ├── compat ├── control ├── copyright ├── liblua5.1-openssl.files ├── liblua5.1-openssl.install ├── liblua5.2-openssl.files ├── liblua5.2-openssl.install └── rules ├── doc ├── luaossl.pdf └── luaossl.tex ├── examples ├── lm.hash ├── pkey.info ├── self.x509 └── vrfy.sig ├── mk ├── changelog ├── luapath ├── vendor.cc └── vendor.os ├── regress ├── 00-store-verify.lua ├── 104-interposition-discarded.lua ├── 115-test-aead.lua ├── 148-custom-extensions.lua ├── 167-verify-cert.lua ├── 177-reset-bio.lua ├── 53-csr-extensions.lua ├── 82-bn_prepops-null-deref.lua ├── 95-kdf.lua └── regress.lua ├── src ├── GNUmakefile ├── Makefile ├── openssl.auxlib.lua ├── openssl.bignum.lua ├── openssl.c ├── openssl.cipher.lua ├── openssl.des.lua ├── openssl.digest.lua ├── openssl.hmac.lua ├── openssl.kdf.lua ├── openssl.lua ├── openssl.ocsp.basic.lua ├── openssl.ocsp.response.lua ├── openssl.pkcs12.lua ├── openssl.pkey.lua ├── openssl.pubkey.lua ├── openssl.rand.lua ├── openssl.ssl.context.lua ├── openssl.ssl.lua ├── openssl.x509.altname.lua ├── openssl.x509.chain.lua ├── openssl.x509.crl.lua ├── openssl.x509.csr.lua ├── openssl.x509.extension.lua ├── openssl.x509.lua ├── openssl.x509.name.lua ├── openssl.x509.store.lua └── openssl.x509.verify_param.lua └── vendor └── compat53 ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── c-api ├── compat-5.3.c └── compat-5.3.h ├── compat53 ├── init.lua └── module.lua ├── lbitlib.c ├── lprefix.h ├── lstrlib.c ├── ltablib.c ├── lutf8lib.c ├── rockspecs ├── bit32-5.3.5-1.rockspec ├── bit32-scm-1.rockspec ├── compat53-0.1-1.rockspec ├── compat53-0.2-1.rockspec ├── compat53-0.3-1.rockspec ├── compat53-0.4-1.rockspec ├── compat53-0.5-1.rockspec ├── compat53-0.7-1.rockspec ├── compat53-0.8-1.rockspec └── compat53-scm-0.rockspec └── tests ├── test-bit32.lua ├── test.lua └── testmod.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.so 3 | *.rockspec 4 | *.rock 5 | config.h 6 | doc/*.aux 7 | doc/*.idx 8 | doc/*.log 9 | doc/*.toc 10 | doc/*.out 11 | -------------------------------------------------------------------------------- /GNUmakefile: -------------------------------------------------------------------------------- 1 | # non-recursive prologue 2 | sp := $(sp).x 3 | dirstack_$(sp) := $(d) 4 | d := $(abspath $(lastword $(MAKEFILE_LIST))/..) 5 | 6 | ifeq ($(origin GUARD_$(d)), undefined) 7 | GUARD_$(d) := 1 8 | 9 | 10 | all: # default target 11 | 12 | # 13 | # G N U M A K E F U N C T I O N S 14 | # 15 | KNOWN_APIS = 5.1 5.2 5.3 5.4 16 | 17 | # template for invoking luapath script 18 | LUAPATH := $(d)/mk/luapath 19 | LUAPATH_FN = $(shell env CC='$(subst ',\\',$(CC))' CPPFLAGS='$(subst ',\\',$(CPPFLAGS))' LDFLAGS='$(subst ',\\',$(LDFLAGS))' $(LUAPATH) -krxm3 -I '$(subst ',\\',$(DESTDIR)$(includedir))' -I/usr/include -I/usr/local/include -P '$(subst ',\\',$(DESTDIR)$(bindir))' -P '$(subst ',\\',$(bindir))' -L '$(subst ',\\',$(DESTDIR)$(libdir))' -L '$(subst ',\\',$(libdir))' -v$(1) $(2)) 20 | 21 | # check whether luapath can locate Lua $(1) headers 22 | HAVE_API_FN = $(and $(filter $(1),$(call LUAPATH_FN,$(1),version)),$(1)$(info enabling Lua $(1))) 23 | 24 | # check whether $(1) in LUA_APIS or $(LUA$(1:.=)_CPPFLAGS) is non-empty 25 | WITH_API_FN = $$(and $$(or $$(filter $(1),$$(LUA_APIS)),$$(LUA$(subst .,,$(1))_CPPFLAGS)),$(1)) 26 | 27 | # 28 | # E N V I R O N M E N T C O N F I G U R A T I O N 29 | # 30 | -include $(d)/.config 31 | 32 | prefix ?= /usr/local 33 | includedir ?= $(prefix)/include 34 | libdir ?= $(prefix)/lib 35 | datadir ?= $(prefix)/share 36 | bindir ?= $(prefix)/bin 37 | lua51cpath ?= $(libdir)/lua/5.1 38 | lua51path ?= $(datadir)/lua/5.1 39 | lua52cpath ?= $(libdir)/lua/5.2 40 | lua52path ?= $(datadir)/lua/5.2 41 | lua53cpath ?= $(libdir)/lua/5.3 42 | lua53path ?= $(datadir)/lua/5.3 43 | lua54cpath ?= $(libdir)/lua/5.4 44 | lua54path ?= $(datadir)/lua/5.4 45 | 46 | 47 | AR ?= ar 48 | RANLIB ?= ranlib 49 | M4 ?= m4 50 | MV ?= mv 51 | RM ?= rm 52 | CP ?= cp 53 | RMDIR ?= rmdir 54 | MKDIR ?= mkdir 55 | CHMOD ?= chmod 56 | INSTALL ?= install 57 | INSTALL_DATA ?= $(INSTALL) -m 644 58 | TOUCH ?= touch 59 | TEE ?= tee 60 | TEE_A ?= $(TEE) -a 61 | 62 | # see Lua Autodetection, below 63 | 64 | .PHONY: $(d)/config 65 | 66 | PRINT_$(d) = printf "%s = %s\n" '$(1)' '$(subst ',\\',$(2))' | $(TEE_A) '$(3)' 67 | 68 | LAZY_$(d) = \ 69 | prefix includedir libdir datadir bindir \ 70 | lua51cpath lua51path lua52cpath lua52path lua53cpath lua53path lua54cpath lua54path \ 71 | CC ALL_CPPFLAGS CPPFLAGS ALL_CFLAGS CFLAGS ALL_LDFLAGS LDFLAGS \ 72 | ALL_SOFLAGS SOFLAGS ALL_LIB LIBS \ 73 | $(foreach API,$(KNOWN_APIS),ALL_LUA$(subst .,,$(API))_CPPFLAGS) \ 74 | AR RANLIB M4 MV RM CP RMDIR MKDIR CHMOD INSTALL INSTALL_DATA TOUCH \ 75 | TEE TEE_A 76 | 77 | NONLAZY_$(d) = \ 78 | LUA_APIS \ 79 | $(foreach API,$(KNOWN_APIS),LUAC$(subst .,,$(API))) \ 80 | $(foreach API,$(KNOWN_APIS),$(and $(call WITH_API_FN,$(API)),LUA$(subst .,,$(API))_CPPFLAGS)) 81 | 82 | $(d)/config: 83 | $(TOUCH) $(@D)/.config.tmp 84 | @$(foreach V,$(LAZY_$(@D)), $(call PRINT_$(@D),$(V),$(value $(V)),$(@D)/.config.tmp);) 85 | @$(foreach V,$(NONLAZY_$(@D)), $(call PRINT_$(@D),$(V),$($(V)),$(@D)/.config.tmp);) 86 | $(MV) $(@D)/.config.tmp $(@D)/.config 87 | 88 | # add local targets if building from inside project tree 89 | ifneq "$(filter $(abspath $(d)/..)/%, $(abspath $(firstword $(MAKEFILE_LIST))))" "" 90 | .PHONY: config configure 91 | 92 | config configure: $(d)/config 93 | endif 94 | 95 | 96 | # 97 | # L U A A U T O D E T E C T I O N 98 | # 99 | 100 | # set LUA_APIS if empty or "?" 101 | ifeq ($(or $(strip $(LUA_APIS)),?),?) 102 | override LUA_APIS := $(call HAVE_API_FN,5.1) $(call HAVE_API_FN,5.2) $(call HAVE_API_FN,5.3) $(call HAVE_API_FN,5.4) 103 | endif 104 | 105 | define LUAXY_template 106 | 107 | # set luaXYcpath if empty or "?" 108 | ifeq ($$(or $$(strip $$(lua$(subst .,,$(1))cpath)),?),?) 109 | override lua$(subst .,,$(1))cpath := $$(or $$(call LUAPATH_FN,$(1),cdir),$$(libdir)/lua/$(1)) 110 | endif 111 | 112 | # set luaXYpath if empty or "?" 113 | ifeq ($$(or $$(strip $$(lua$(subst .,,$(1))path)),?),?) 114 | override lua$(subst .,,$(1))path = $$(or $$(call LUAPATH_FN,$(1),ldir),$$(datadir)/lua/$(1)) 115 | endif 116 | 117 | # set LUAXY_CPPFLAGS if undefined or "?" (NB: can be empty if path already in $(CPPFLAGS)) 118 | ifeq ($$(and $$(findstring undefined,$$(origin LUA$(subst .,,$(1))_CPPFLAGS)),?),?) 119 | override LUA$(subst .,,$(1))_CPPFLAGS = $$(and $$(call WITH_API_FN,$(1)),$$(call LUAPATH_FN,$(1),cppflags)) 120 | endif 121 | 122 | # set ALL_LUAXY_CPPFLAGS if empty or "?" 123 | ifeq ($$(or $$(strip $$(ALL_LUA$(subst .,,$(1))_CPPFLAGS)),?),?) 124 | override ALL_LUA$(subst .,,$(1))_CPPFLAGS = $$(LUA$(subst .,,$(1))_CPPFLAGS) 125 | endif 126 | 127 | # set LUAXYC if empty or "?" 128 | ifeq ($$(or $$(strip $$(LUAC$(subst .,,$(1)))),?),?) 129 | override LUAC$(subst .,,$(1)) = $$(or $$(call LUAPATH_FN,$(1),luac),true) 130 | endif 131 | 132 | endef # LUAXY_template 133 | 134 | $(eval $(call LUAXY_template,5.1)) 135 | $(eval $(call LUAXY_template,5.2)) 136 | $(eval $(call LUAXY_template,5.3)) 137 | $(eval $(call LUAXY_template,5.4)) 138 | 139 | # 140 | # A U T O D E T E C T C O M P I L A T I O N F L A G S 141 | # 142 | cc-option ?= $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \ 143 | > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi;) 144 | 145 | VENDOR_OS_$(d) := $(shell $(d)/mk/vendor.os) 146 | VENDOR_CC_$(d) := $(shell env CC="$(CC)" $(d)/mk/vendor.cc) 147 | 148 | # 149 | # ALL_CPPFLAGS 150 | # 151 | ifeq ($(origin ALL_CPPFLAGS), undefined) 152 | 153 | ifneq ($(VENDOR_OS_$(d)), OpenBSD) 154 | ALL_CPPFLAGS += -D_REENTRANT -D_THREAD_SAFE -D_GNU_SOURCE 155 | endif 156 | 157 | ifeq ($(VENDOR_OS_$(d)), SunOS) 158 | ALL_CPPFLAGS += -Usun -D_XPG4_2 -D__EXTENSIONS__ 159 | endif 160 | 161 | ALL_CPPFLAGS += $(CPPFLAGS) 162 | 163 | endif # ALL_CPPFLAGS 164 | 165 | # 166 | # ALL_CFLAGS 167 | # 168 | ifeq ($(origin ALL_CFLAGS), undefined) 169 | 170 | ifeq ($(VENDOR_CC_$(d)), gcc) 171 | ALL_CFLAGS += -O2 -std=gnu99 -fPIC 172 | ALL_CFLAGS += -g -Wall -Wextra $(call cc-option, -Wno-missing-field-initializers) $(call cc-option, -Wno-override-init) -Wno-unused 173 | endif 174 | 175 | ifeq ($(VENDOR_CC_$(d)), clang) 176 | ALL_CFLAGS += -O2 -std=gnu99 -fPIC 177 | ALL_CFLAGS += -g -Wall -Wextra -Wno-missing-field-initializers -Wno-initializer-overrides -Wno-unused -Wno-dollar-in-identifier-extension 178 | endif 179 | 180 | ifeq ($(VENDOR_CC_$(d)), sunpro) 181 | ALL_CFLAGS += -xcode=pic13 182 | ALL_CFLAGS += -g 183 | # 184 | # Solaris Studio supports anonymous unions just fine; but it complains 185 | # incessantly about them. 186 | # 187 | ALL_CFLAGS += -erroff=E_ANONYMOUS_UNION_DECL 188 | endif 189 | 190 | ifeq ($(VENDOR_OS_$(d)), Darwin) 191 | ALL_CFLAGS += -Wno-deprecated-declarations 192 | endif 193 | 194 | ALL_CFLAGS += $(CFLAGS) 195 | 196 | endif # ALL_CFLAGS 197 | 198 | # 199 | # ALL_SOFLAGS 200 | # 201 | ifeq ($(origin ALL_SOFLAGS), undefined) 202 | 203 | ifeq ($(VENDOR_OS_$(d)), Darwin) 204 | ALL_SOFLAGS += -bundle -undefined dynamic_lookup 205 | else 206 | ALL_SOFLAGS += -shared 207 | endif 208 | 209 | ALL_SOFLAGS += $(SOFLAGS) 210 | 211 | endif # ALL_SOFLAGS 212 | 213 | # 214 | # ALL_LDFLAGS 215 | # 216 | ifeq ($(origin ALL_LDFLAGS), undefined) 217 | 218 | ALL_LDFLAGS += -L$(DESTDIR)$(libdir) -L$(libdir) 219 | ALL_LDFLAGS += $(LDFLAGS) 220 | 221 | endif # ALL_LDFLAGS 222 | 223 | # 224 | # ALL_LIBS 225 | # 226 | ifeq ($(origin ALL_LIBS), undefined) 227 | 228 | # put $(LIBS) first as they're more likely to be higher-level dependencies 229 | ALL_LIBS += $(LIBS) 230 | ALL_LIBS += -lssl -lcrypto -lpthread 231 | 232 | # NetBSD, FreeBSD, OpenBSD (and presumably descendants) lack any libdl; 233 | # dlopen, et al are part of libc. 234 | ifneq ($(patsubst %BSD,BSD,$(VENDOR_OS_$(d))), BSD) 235 | ALL_LIBS += -ldl 236 | endif 237 | 238 | # This only seems to be necessary on Linux. Darwin and OpenBSD lack a librt. 239 | # On OpenBSD clock_gettime is part of libc. Others have librt, but linking 240 | # it in is unnecessary. 241 | ifeq ($(VENDOR_OS_$(d)), Linux) 242 | ALL_LIBS += -lrt 243 | endif 244 | 245 | ALL_LIBS += -lm 246 | 247 | endif # ALL_LIBS 248 | 249 | 250 | # 251 | # P R O J E C T R U L E S 252 | # 253 | include $(d)/src/GNUmakefile 254 | 255 | $(d)/config.h: $(d)/config.h.guess 256 | $(CP) $< $@ 257 | 258 | 259 | # 260 | # C L E A N R U L E S 261 | # 262 | .PHONY: $(d)/clean~ clean~ 263 | 264 | $(d)/clean~: 265 | $(RM) -f $(@D)/*~ 266 | 267 | clean~: $(d)/clean~ 268 | 269 | 270 | # 271 | # D E B I A N R U L E S 272 | # 273 | ifneq "$(filter $(abspath $(d))/%, $(abspath $(firstword $(MAKEFILE_LIST))))" "" 274 | 275 | DPKG_BUILDPACKAGE ?= dpkg-buildpackage 276 | FAKEROOT ?= fakeroot 277 | DPKG_BUILDPACKAGE_OPTIONS ?= -b -uc -us 278 | 279 | .PHONY: $(d)/debian $(d)/debian-clean debian deb debian-clean deb-clean 280 | 281 | $(d)/debian: 282 | cd $(@D) && $(DPKG_BUILDPACKAGE) -rfakeroot $(DPKG_BUILDPACKAGE_OPTIONS) 283 | 284 | $(d)/debian-clean: 285 | cd $(@D) && $(FAKEROOT) ./debian/rules clean 286 | 287 | debian deb: $(d)/debian 288 | 289 | debian-clean deb-clean: $(d)/debian-clean 290 | 291 | endif # debian guard 292 | 293 | 294 | # 295 | # R E D H A T R U L E S 296 | # 297 | ifneq "$(filter $(abspath $(d))/%, $(abspath $(firstword $(MAKEFILE_LIST))))" "" 298 | .PHONY: $(d)/redhat $(d)/redhat-clean redhat rpm redhat-clean rpm-clean 299 | 300 | redhat rpm: $(d)/redhat 301 | 302 | redhat-clean rpm-clean: $(d)/redhat-clean 303 | 304 | endif # redhat guard 305 | 306 | 307 | # 308 | # R E L E A S E T A R B A L L R U L E S 309 | # 310 | ifneq "$(filter $(abspath $(d))/%, $(abspath $(firstword $(MAKEFILE_LIST))))" "" 311 | 312 | LUAOSSL_VERSION := $(shell $(d)/mk/changelog version) 313 | 314 | .PHONY: $(d)/luaossl-$(LUAOSSL_VERSION).tgz release 315 | 316 | $(d)/luaossl-$(LUAOSSL_VERSION).tgz: 317 | cd $(@D) && git archive --format=tar --prefix=$(basename $(@F))/ HEAD | gzip -c > $@ 318 | 319 | release: $(d)/luaossl-$(LUAOSSL_VERSION).tgz 320 | 321 | endif # release guard 322 | 323 | 324 | endif # include guard 325 | 326 | # non-recursive epilogue 327 | d := $(dirstack_$(sp)) 328 | sp := $(basename $(sp)) 329 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2 | 2012-2017 William Ahern 3 | 2015-2019 Daurnimator 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to 7 | deal in the Software without restriction, including without limitation the 8 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9 | sell copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 | IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .POSIX: 2 | 3 | all: 4 | +gmake -f GNUmakefile all 5 | 6 | .DEFAULT: 7 | +gmake -f GNUmakefile $< 8 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | liblua-openssl (20220711-0) unstable; urgency=low 2 | 3 | * fix luaL_Buffer usage (#189) 4 | * fix OpenSSL 3 compatibility (#199) 5 | * add cipher:getTag() / cipher:setTag() for AEAD (#201) 6 | 7 | -- Daurnimator Mon, 11 Jul 2022 15:39:13 +1000 8 | 9 | liblua-openssl (20200709-0) unstable; urgency=low 10 | 11 | * fix loading from DER files when type set to any (#177) 12 | * fix lifetime of certificates from <2000 (#178) 13 | 14 | -- Daurnimator Thu, 09 Jul 2020 23:09:31 +1000 15 | 16 | liblua-openssl (20190731-0) unstable; urgency=low 17 | 18 | * introduce workarounds for LuaJIT 47bit userdata (#173) 19 | 20 | -- Daurnimator Wed, 31 Jul 2019 23:14:21 +1000 21 | 22 | liblua-openssl (20190612-0) unstable; urgency=low 23 | 24 | * Add kdf module for key derivation (#154) 25 | * Add cert:verify() to verify certificates without a store (#167) 26 | * Add support for arbitrary pkey types (#161) 27 | * Rename :setCurvesList() to :setGroups() (old alias kept for now) 28 | * Note: This is the last release to support OpenSSL 0.9.8 (#169) 29 | 30 | -- Daurnimator Wed, 12 Jun 2019 17:24:48 +1000 31 | 32 | liblua-openssl (20181207-0) unstable; urgency=low 33 | 34 | * Add context.pushffi 35 | * Add :setCertificateChain() and :getCertificateChain() 36 | 37 | -- Daurnimator Fri, 07 Dec 2018 14:42:26 -0800 38 | 39 | liblua-openssl (20181102-0) unstable; urgency=low 40 | 41 | * Update SSL options 42 | * Add Basic TLSv1.3 support 43 | * Cache objects so that equal pointers result in same lua object 44 | * Fix non-DER value for CA basic constraint 45 | * Add context:getContext() 46 | * Add context:addCustomExtension() and openssl.extensionSupported() 47 | * Add context:useServerInfo() and context:useServerInfoFile() 48 | * Add ssl and context getter+setter for readahead flag 49 | * Add ssl and context :setCipherSuites() for TLSv1.3 50 | * Add conspicuously missing ssl:setCipherList() 51 | 52 | -- Daurnimator Fri, 02 Nov 2018 17:37:23 +1100 53 | 54 | liblua-openssl (20180708-0) unstable; urgency=low 55 | 56 | * Fix incorrect class check in :getTLSextStatusType() 57 | * Update lua-compat-5.3 58 | * Add context:setTicketKeys(), context:getTicketKeys(), context:getTicketKeysLength() 59 | 60 | -- Daurnimator Sun, 08 Jul 2018 23:49:25 +1000 61 | 62 | liblua-openssl (20180530-0) unstable; urgency=low 63 | 64 | * Bind functions for manipulating csr requested extensions 65 | * Add :toPEM() to various objects 66 | * Bind modular bignum functions 67 | * Add ssl:getMasterKey() 68 | * Add ssl.pushffi() 69 | * Add ssl:getCertificate() and context:getCertificate() 70 | * store:add("./empty-file") no longer throws 71 | * Add ssl:getServerTemporaryKey() 72 | * Add x509.crl:lookupSerial() and x509.crl:lookupCertificate() 73 | * Fix precision loss when using Lua 5.3 with 64bit integers. 74 | 75 | -- Daurnimator Wed, 30 May 2018 17:44:42 +1000 76 | 77 | liblua-openssl (20171028-0) unstable; urgency=low 78 | 79 | * Add win32 support 80 | * Fix bug where exp would be NULL in pkey.new() 81 | 82 | -- Daurnimator Sat, 28 Oct 2017 13:19:32 +1100 83 | 84 | liblua-openssl (20170903-0) unstable; urgency=low 85 | 86 | * Fix pkey.new failing when generating RSA keys 87 | * Fix loading C modules clearing interposed fields 88 | * Fix building compat-5.3.o 89 | 90 | -- Daurnimator Sun, 03 Sep 2017 22:39:20 +1000 91 | 92 | liblua-openssl (20170901-0) unstable; urgency=low 93 | 94 | * New openssl.ocsp.basic and openssl.ocsp.response modules 95 | * Add x509:getOCSP() 96 | * Add x509:getSignatureName() (#79) 97 | * Add crl:verify(publickey) 98 | * Add pkcs12.parse(bag[, passphrase]) 99 | * Add context:setStore(store) and context:getStore() 100 | * Add context:setParam(params) and context:getParam() 101 | * Add context:setCurvesList(string [, ...]) 102 | * Add context:setAlpnSelect(cb) 103 | * Add context:setTLSextStatusType(type) and context:getTLSextStatusType() 104 | * Add ssl:getVerifyResult() (#75) 105 | * Add ssl:setContext(context) (#84) 106 | * Add ssl:setVerify([mode][, depth]) and ssl:getVerify() (#84) 107 | * Add ssl:setCertificate(crt), ssl:setPrivateKey(key), ssl:setCurvesList(string [, ...]) (#84) 108 | * Add ssl:setTLSextStatusType(type) and ssl:getTLSextStatusType() 109 | * Add ssl:setTLSextStatusOCSPResp(or) and ssl:getTLSextStatusOCSPResp() 110 | * Use lua-compat-5.3 (fixes LuaJIT header file compatibility) (#94) 111 | * Add generator field to replace exp when generating a DH key 112 | * Move away from interfaces deprecated in OpenSSL 1.1.0 113 | 114 | -- Daurnimator Fri, 01 Sep 2017 14:20:00 +1000 115 | 116 | liblua-openssl (20161214-0) unstable; urgency=low 117 | 118 | * Refactor of bignum operations, fixes bn:sqr() 119 | 120 | -- William Ahern 121 | 122 | liblua-openssl (20161209-0) unstable; urgency=low 123 | 124 | * Add ssl:getVerifyResult() 125 | 126 | -- William Ahern 127 | 128 | liblua-openssl (20161208-0) unstable; urgency=low 129 | 130 | * openssl.x509.store:addDefaults() new function to add the operating system's default ca's to a certificate store. 131 | * openssl.x509.store:add() can now take a CRL 132 | * openssl.ssl.context:getStore() new function that returns a reference to a context's certificate store 133 | * openssl.pkey:encrypt() and openssl.pkey:decrypt() 134 | * openssl.ssl.new() to construct an SSL* given a SSL_CTX* 135 | * Bindings for X509_VERIFY_PARAM* 136 | 137 | -- William Ahern 138 | 139 | liblua-openssl (20161101-0) unstable; urgency=low 140 | 141 | * Rename bignum methods tobin, todec, tohex to CamelCase: toDecimal, toDecimal, toHex 142 | 143 | -- William Ahern 144 | 145 | liblua-openssl (20161029-0) unstable; urgency=low 146 | 147 | * Add lots of bignum methods 148 | * Allow hex strings creating bignums 149 | * Expose openssl.x509.csr 150 | * Use autoguess project to get platform features 151 | 152 | -- William Ahern 153 | 154 | liblua-openssl (20151221-0) unstable; urgency=low 155 | 156 | * Add :tohex and :todec methods to bignums, and make metamethods 157 | accessible directly. (daurnimator) 158 | * Add __idiv metamethod for Lua 5.3. (daurnimator) 159 | 160 | -- William Ahern Mon, 21 Dec 2015 02:35:12 -0800 161 | 162 | liblua-openssl (20151218-0) unstable; urgency=low 163 | 164 | * Add :tobin method to bignums. (daurnimator) 165 | * Add :getParameters method to pkeys. (daurnimator) 166 | * Fix build when SSLv3 support is not present. 167 | 168 | -- William Ahern Fri, 18 Dec 2015 03:09:29 -0800 169 | 170 | liblua-openssl (20150727-0) unstable; urgency=low 171 | 172 | * More extension work from Kaarle Ritvanen. 173 | * Add DTLS support. 174 | * More extension work from kunkku. 175 | * Fix bug in ex_newstate which could cause application data attached 176 | to OpenSSL objects using OpenSSL's external application data API to be 177 | prematurely invalidated as-if the Lua interperter was destroyed. 178 | 179 | -- William Ahern Mon, 27 Jul 2015 01:42:46 -0700 180 | 181 | liblua-openssl (20150504-0) unstable; urgency=low 182 | 183 | * Use lightuserdata as registry keys. C function hashes aren't stable 184 | in LuaJIT. 185 | * Add openssl.version as binding for SSLeay_version. 186 | * Fix build on OpenBSD 5.6 libressl. 187 | 188 | -- William Ahern Mon, 04 May 2015 17:49:08 -0700 189 | 190 | liblua-openssl (20150422-0) unstable; urgency=low 191 | 192 | * Add support for ALPN server callback, SSL_CTX_set_alpn_select_cb. 193 | * Fix X509_STORE double-free bug on older OpenSSL releases (< 1.0.2) 194 | by implementing and using our own X509_STORE_free routine which properly 195 | checks reference counts. Workaround adapted from Ruby OpenSSL bindings. 196 | * Fix strerror_r usage on glibc. 197 | 198 | -- William Ahern Wed, 22 Apr 2015 15:39:14 -0700 199 | 200 | liblua-openssl (20150304-0) unstable; urgency=low 201 | 202 | * Merge ALPN support from quae@daurnimator.com. 203 | 204 | -- William Ahern Wed, 04 Mar 2015 18:11:13 -0800 205 | 206 | liblua-openssl (20150225-0) unstable; urgency=low 207 | 208 | * Add DES module to help implement NTLM authentication protocol. 209 | 210 | -- William Ahern Wed, 25 Feb 2015 12:46:41 -0800 211 | 212 | liblua-openssl (20141028-0) unstable; urgency=low 213 | 214 | * Add ssl:getVersion and ssl:getClientVersion. 215 | * Fix "TLS" and "SSL" method names for context.new. OpenSSL TLSv1_method() 216 | literally only speaks 1.0, not 1.0 and above. "TLS" now uses 217 | SSLv23_method and disables SSLv2 and SSLv3. "SSL" uses SSLv23_method and 218 | disables SSLv2. 219 | 220 | -- William Ahern Tue, 28 Oct 2014 21:03:23 -0700 221 | 222 | liblua-openssl (20140923-0) unstable; urgency=low 223 | 224 | * Add more CRL support from Kaarle Ritvanen. 225 | * Add prelimiary 5.3 support. 226 | * Add SSL_CTX and SSL option support. 227 | * Add ephemeral key support. 228 | * Add Server Name Indication (SNI) support. 229 | * Fix issue which prevented loading public and private keys together. 230 | * Add bindings to opensslv.h and opensslconf.h. 231 | 232 | -- William Ahern Tue, 23 Sep 2014 20:32:32 -0700 233 | 234 | liblua-openssl (20140718-0) unstable; urgency=low 235 | 236 | * Add CRL spport from Kaarle Ritvanen. 237 | * Add PKCS1 support from Kaarle Ritvanen. 238 | * Add AIX platform support. 239 | * Add rand.stir. 240 | 241 | -- William Ahern Fri, 18 Jul 2014 22:44:31 -0700 242 | 243 | liblua-openssl (20140328-0) unstable; urgency=low 244 | 245 | * Add DER input/output formats. 246 | * Add GEN_DIRNAME alternative names. 247 | * Change the return value of several methods from boolean true 248 | to the method object, to allow easy call chaining in Lua. 249 | * Fix rand.uniform to use lua_Unsigned when it's a 64-bit type (Lua 5.3). 250 | * Rename openssl.pubkey to openssl.pkey. 251 | 252 | -- William Ahern Fri, 28 Mar 2014 22:44:31 -0700 253 | 254 | liblua-openssl (20140322-0) unstable; urgency=low 255 | 256 | * Add Lua 5.3 support. 257 | * Add user guide. 258 | 259 | -- William Ahern Sat, 22 Mar 2014 20:23:56 -0800 260 | 261 | liblua-openssl (20140131-0) unstable; urgency=low 262 | 263 | * Add multi-threaded re-entrancy protection, including explicitly 264 | synchronizing OpenSSL initialization because OpenSSL doesn't appear to 265 | use its own locking callbacks from initialization routines. 266 | 267 | -- William Ahern Fri, 31 Jan 2014 14:27:30 -0800 268 | 269 | liblua-openssl (20131209-1) unstable; urgency=low 270 | 271 | * Initial release after splitting from cqueues project. 272 | 273 | -- William Ahern Sun, 09 Dec 2013 21:17:33 -0800 274 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 9 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: liblua-openssl 2 | Section: unknown 3 | Priority: extra 4 | Maintainer: William Ahern 5 | Build-Depends: debhelper (>= 9), m4, dh-lua, libssl-dev 6 | Standards-Version: 3.9.2 7 | 8 | Package: liblua5.1-openssl 9 | Architecture: any 10 | Depends: openssl, liblua5.1-0 11 | Description: Comprehensive OpenSSL bindings. 12 | 13 | Package: liblua5.2-openssl 14 | Architecture: any 15 | Depends: openssl, liblua5.2-0 16 | Description: Comprehensive OpenSSL bindings. 17 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Author: William Ahern 2 | Download: http://25thandclement.com/~william/projects/luaossl.html 3 | 4 | Files: * 5 | Copyright: © 2012-2013, William Ahern 6 | License: MIT 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to 9 | deal in the Software without restriction, including without limitation the 10 | rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 11 | sell copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23 | IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /debian/liblua5.1-openssl.files: -------------------------------------------------------------------------------- 1 | usr/lib/lua/5.1/_openssl.so 2 | usr/share/lua/5.1/openssl* 3 | -------------------------------------------------------------------------------- /debian/liblua5.1-openssl.install: -------------------------------------------------------------------------------- 1 | debian/tmp/usr/lib/lua/5.1/_openssl.so usr/lib/lua/5.1 2 | debian/tmp/usr/share/lua/5.1/openssl* usr/share/lua/5.1 3 | -------------------------------------------------------------------------------- /debian/liblua5.2-openssl.files: -------------------------------------------------------------------------------- 1 | usr/lib/lua/5.2/_openssl.so 2 | usr/share/lua/5.2/openssl* 3 | -------------------------------------------------------------------------------- /debian/liblua5.2-openssl.install: -------------------------------------------------------------------------------- 1 | debian/tmp/usr/lib/lua/5.2/_openssl.so usr/lib/lua/5.2 2 | debian/tmp/usr/share/lua/5.2/openssl* usr/share/lua/5.2 3 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | CFLAGS := -O3 -g -fstack-protector --param=ssp-buffer-size=4 4 | 5 | DESTDIR=debian/tmp 6 | prefix=/usr 7 | build=liblua5.1-openssl liblua5.2-openssl 8 | install=$(addsuffix -install,$(build)) 9 | 10 | %: 11 | dh $@ 12 | 13 | override_dh_auto_configure: 14 | true 15 | 16 | override_dh_auto_build: 17 | make DESTDIR=$(DESTDIR) prefix=$(prefix) $(build) 18 | 19 | override_dh_auto_install: 20 | make DESTDIR=$(DESTDIR) prefix=$(prefix) $(install) 21 | 22 | override_dh_auto_clean: 23 | make clean 24 | 25 | override_dh_auto_test: 26 | true 27 | -------------------------------------------------------------------------------- /doc/luaossl.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wahern/luaossl/8e9622c22f76d550594212c8bf5057f39d76f383/doc/luaossl.pdf -------------------------------------------------------------------------------- /examples/lm.hash: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | _=[[ 3 | : ${LUA:=$(command -v lua-5.2)} 4 | : ${LUA:=$(command -v lua5.2)} 5 | : ${LUA:=$(command -v lua-52)} 6 | : ${LUA:=$(command -v lua52)} 7 | : ${LUA:=$(command -v luajit)} 8 | : ${LUA:=$(command -v lua)} 9 | 10 | exec ${LUA} "$0" "$@" 11 | ]] 12 | 13 | local des = require"openssl.des" 14 | local cipher = require"openssl.cipher" 15 | local bit32 = require"bit32" 16 | 17 | local function lm_encrypt(key) 18 | return cipher.new"DES-ECB":encrypt(key, nil, false):final"KGS!@#$%" 19 | end -- lm_encrypt 20 | 21 | local lshift = bit32.lshift 22 | local band = bit32.band 23 | local rshift = bit32.rshift 24 | local bor = bit32.bor 25 | 26 | local function lm_string_to_key(s) 27 | local s0, s1, s2, s3, s4, s5, s6 = string.byte(s, 1, 7) 28 | local k0, k1, k2, k3, k4, k5, k6, k7 29 | 30 | s0 = s0 or 0 31 | s1 = s1 or 0 32 | s2 = s2 or 0 33 | s3 = s3 or 0 34 | s4 = s4 or 0 35 | s5 = s5 or 0 36 | s6 = s6 or 0 37 | 38 | k0 = s0 39 | k1 = bor(band(lshift(s0, 7), 255), rshift(s1, 1)) 40 | k2 = bor(band(lshift(s1, 6), 255), rshift(s2, 2)) 41 | k3 = bor(band(lshift(s2, 5), 255), rshift(s3, 3)) 42 | k4 = bor(band(lshift(s3, 4), 255), rshift(s4, 4)) 43 | k5 = bor(band(lshift(s4, 3), 255), rshift(s5, 5)) 44 | k6 = bor(band(lshift(s5, 2), 255), rshift(s6, 6)) 45 | k7 = band(lshift(s6, 1), 255) 46 | 47 | return des.set_odd_parity(string.char(k0, k1, k2, k3, k4, k5, k6, k7)) 48 | end -- lm_string_to_key 49 | 50 | local function lm_hash(pass) 51 | pass = string.upper(pass) 52 | 53 | if #pass < 14 then 54 | pass = pass .. string.rep(string.char(0), 14 - #pass) 55 | end 56 | 57 | local key1 = lm_string_to_key(string.sub(pass, 1, 7)) 58 | local key2 = lm_string_to_key(string.sub(pass, 8, 14)) 59 | 60 | return lm_encrypt(key1) .. lm_encrypt(key2) 61 | end -- lm_hash 62 | 63 | local function tohex(s) 64 | return (string.gsub(s, ".", function (c) 65 | return string.format("%.2x", string.byte(c)) 66 | end)) 67 | end -- tohex 68 | 69 | local pass = ... or "passphrase" 70 | 71 | print(pass, tohex(lm_hash(pass))) 72 | -------------------------------------------------------------------------------- /examples/pkey.info: -------------------------------------------------------------------------------- 1 | local pkey = require"openssl.pkey" 2 | 3 | local rsa = pkey.new{ type = "RSA", bits = 512 } 4 | 5 | for k, v in pairs(rsa:getParameters()) do 6 | print(k, v) 7 | end 8 | 9 | -------------------------------------------------------------------------------- /examples/self.x509: -------------------------------------------------------------------------------- 1 | #!/usr/local/lua52/bin/lua 2 | -- 3 | -- Example self-signed X.509 certificate generation. 4 | -- 5 | -- Skips intermediate CSR object, which is just an antiquated way for 6 | -- specifying subject DN and public key to CAs. See API documentation for 7 | -- CSR generation. 8 | -- 9 | 10 | local keytype = ... 11 | 12 | local openssl = require"openssl" 13 | local pkey = require"openssl.pkey" 14 | local x509 = require"openssl.x509" 15 | local name = require"openssl.x509.name" 16 | local altname = require"openssl.x509.altname" 17 | 18 | -- generate our public/private key pair 19 | local function genkey(type) 20 | type = string.upper(type or (not openssl.NO_EC and "EC") or "RSA") 21 | 22 | if type == "RSA" then 23 | return pkey.new{ type = "RSA", bits = 1024 } 24 | elseif type == "DSA" then 25 | return pkey.new{ type = "DSA", bits = 1024 } 26 | else 27 | return pkey.new{ type = "EC", curve = "prime192v1" } 28 | end 29 | end 30 | 31 | local key = genkey(keytype) 32 | 33 | -- our Subject and Issuer DN (self-signed, so same) 34 | local dn = name.new() 35 | dn:add("C", "US") 36 | dn:add("ST", "California") 37 | dn:add("L", "San Francisco") 38 | dn:add("O", "Acme, Inc") 39 | dn:add("CN", "acme.inc") 40 | 41 | -- our Alternative Names 42 | local alt = altname.new() 43 | alt:add("DNS", "acme.inc") 44 | alt:add("DNS", "*.acme.inc") 45 | 46 | -- build our certificate 47 | local crt = x509.new() 48 | 49 | crt:setVersion(3) 50 | crt:setSerial(47) 51 | 52 | crt:setSubject(dn) 53 | crt:setIssuer(crt:getSubject()) 54 | crt:setSubjectAlt(alt) 55 | 56 | local issued, expires = crt:getLifetime() 57 | crt:setLifetime(issued, expires + 60) -- good for 60 seconds 58 | 59 | crt:setBasicConstraints{ CA = true, pathLen = 2 } 60 | crt:setBasicConstraintsCritical(true) 61 | 62 | crt:setPublicKey(key) 63 | crt:sign(key) 64 | 65 | print(crt:text()) 66 | -------------------------------------------------------------------------------- /examples/vrfy.sig: -------------------------------------------------------------------------------- 1 | #!/usr/local/lua52/bin/lua 2 | -- 3 | -- Example public-key signature verification. 4 | -- 5 | 6 | local keytype, hash = ... 7 | 8 | local openssl = require"openssl" 9 | local pkey = require"openssl.pkey" 10 | local digest = require"openssl.digest" 11 | 12 | -- generate a public/private key pair 13 | local function genkey(type) 14 | type = string.upper(type or (not openssl.NO_EC and "EC") or "RSA") 15 | 16 | if type == "RSA" then 17 | return pkey.new{ type = "RSA", bits = 1024 } 18 | elseif type == "DSA" then 19 | return pkey.new{ type = "DSA", bits = 1024 } 20 | else 21 | return pkey.new{ type = "EC", curve = "prime192v1" } 22 | end 23 | end 24 | 25 | local key = genkey(keytype) 26 | if hash == nil then 27 | hash = key:getDefaultDigestName() 28 | end 29 | 30 | -- digest our message using an appropriate digest 31 | local data = digest.new(hash) 32 | data:update(... or "hello world") 33 | 34 | -- generate a signature for our data 35 | local sig = key:sign(data) 36 | 37 | -- to prove verification works, instantiate a new object holding just 38 | -- the public key 39 | local pub = pkey.new(key:toPEM"public") 40 | 41 | -- a utility routine to output our signature 42 | local function tohex(b) 43 | local x = "" 44 | for i = 1, #b do 45 | x = x .. string.format("%.2x", string.byte(b, i)) 46 | end 47 | return x 48 | end 49 | 50 | print("verified", pub:verify(sig, data)) 51 | print("key-type", pub:type()) 52 | print("hash-type", hash) 53 | print("signature", tohex(sig)) 54 | -------------------------------------------------------------------------------- /mk/changelog: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e # strict errors 3 | set -u # don't expand unbound variables 4 | set -f # disable pathname expansion 5 | set -C # noclobber 6 | \unalias -a # no command surprises 7 | export LC_ALL=C # no locale headaches 8 | unset IFS # no field splitting surprises 9 | 10 | 11 | RELPATH=${0%/*} 12 | : RELPATH=${RELPATH:-.} 13 | 14 | CHANGELOG=${RELPATH}/../debian/changelog 15 | ROOTDIR=${RELPATH}/.. 16 | 17 | GIT="$(command -v git)" 18 | 19 | 20 | changelog() { 21 | if [ ! -f ${CHANGELOG} ]; then 22 | printf -- "${CHANGELOG}: No such file\n" >&2 23 | exit 1 24 | fi 25 | 26 | cat ${CHANGELOG} 27 | } 28 | 29 | 30 | usage() { 31 | cat <<-EOF 32 | usage: ${0##*/} [-h] version|author|commit 33 | -h print this usage message 34 | 35 | version most recent package version number 36 | author author of most recent log message 37 | commit Git hash of most recent commit 38 | 39 | Report bugs to 40 | EOF 41 | } 42 | 43 | while getopts h OPT; do 44 | case "${OPT}" in 45 | h) 46 | usage 47 | exit 0 48 | ;; 49 | *) 50 | usage >&2 51 | exit 1 52 | ;; 53 | esac 54 | done 55 | 56 | shift $(($OPTIND - 1)) 57 | 58 | 59 | case "${1:-version}" in 60 | version) 61 | changelog | sed -ne ' 62 | s/.*(\([1-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\).*).*/\1/ 63 | t Found 64 | d 65 | :Found 66 | p 67 | q 68 | ' 69 | ;; 70 | author) 71 | changelog | sed -ne ' 72 | s/.*<\([^>]*@[^>]*\)>.*/\1/ 73 | t Found 74 | d 75 | :Found 76 | p 77 | q 78 | ' 79 | ;; 80 | commit) 81 | test -n "${GIT}" -a -d ${ROOTDIR}/.git || exit 1 82 | 83 | cd ${ROOTDIR} 84 | ${GIT} show --pretty='%H' HEAD 2>/dev/null | sed -n '1p' 85 | ;; 86 | *) 87 | usage >&2 88 | exit 1 89 | ;; 90 | esac 91 | 92 | exit 0 93 | -------------------------------------------------------------------------------- /mk/vendor.cc: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | : ${CC:=cc} 6 | 7 | ${CC} -E - <<-EOF | awk '/sunpro/||/clang/||/gcc/||/other/{ print $1; exit; }' 8 | #if defined __SUNPRO_C 9 | sunpro 10 | #elif defined __clang__ 11 | clang 12 | #elif defined __GNUC__ 13 | gcc 14 | #else 15 | other 16 | #endif 17 | EOF 18 | -------------------------------------------------------------------------------- /mk/vendor.os: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | uname -s 4 | -------------------------------------------------------------------------------- /regress/00-store-verify.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | require"regress".export".*" 4 | 5 | local st = store.new() 6 | 7 | local ca_key, ca_crt = genkey() 8 | st:add(ca_crt) 9 | 10 | local key, crt = genkey("RSA", ca_key, ca_crt) 11 | 12 | local ok, proof_or_reason = st:verify(crt) 13 | check(ok, "%s", proof_or_reason) 14 | 15 | --for _,crt in pairs(proof_or_reason) do 16 | -- print(crt:text()) 17 | --end 18 | 19 | say"OK" 20 | -------------------------------------------------------------------------------- /regress/104-interposition-discarded.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | require"regress".export".*" 4 | 5 | local ssl_context = require "openssl.ssl.context" 6 | 7 | local value = {} 8 | ssl_context.interpose("foo", value) 9 | check(ssl_context.new().foo == value, "interpose failed") 10 | 11 | require "openssl.ssl" -- Pick a module that doesn't get loaded by regress.lua 12 | check(ssl_context.new().foo == value, "loading a module reset methods") 13 | -------------------------------------------------------------------------------- /regress/115-test-aead.lua: -------------------------------------------------------------------------------- 1 | local regress = require "regress"; 2 | local openssl = require "openssl"; 3 | local cipher = require "openssl.cipher" 4 | 5 | 6 | -- Test AES-256-GCM 7 | local key = "abcdefghijklmnopabcdefghijklmnop" 8 | local iv = "123456123456" 9 | local message = "My secret message" 10 | 11 | function test_aead(params) 12 | local c = cipher.new(params.cipher):encrypt(key, iv) 13 | 14 | local encrypted = c:update(message) 15 | regress.check(encrypted) 16 | regress.check(c:final(), "fail final encrypt") 17 | 18 | local tag = assert(c:getTag(params.tag_length)) 19 | regress.check(tag and #tag == params.tag_length) 20 | 21 | 22 | -- Now for the decryption 23 | local d = cipher.new(params.cipher):decrypt(key, iv) 24 | d:setTag(tag); 25 | 26 | local decrypted = d:update(encrypted) 27 | regress.check(decrypted == message, "decrypted message doesn't match") 28 | regress.check(d:final(), "fail final decrypt") 29 | end 30 | 31 | test_aead { 32 | cipher = "aes-256-gcm"; 33 | tag_length = 16; 34 | } 35 | 36 | test_aead { 37 | cipher = "aes-256-ccm"; 38 | tag_length = 12; 39 | } 40 | -------------------------------------------------------------------------------- /regress/148-custom-extensions.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local regress = require "regress" 4 | local cqueues = require "cqueues" 5 | local cs = require "cqueues.socket" 6 | local openssl_ctx = require "openssl.ssl.context" 7 | 8 | local cli_ctx, srv_ctx 9 | local call_check = 0 10 | 11 | cli_ctx = regress.getsslctx("TLS", false, false) 12 | regress.check(cli_ctx.addCustomExtension, "Custom extension support not available") 13 | local function c_add_ext(ssl, ext_type, context) -- luacheck: ignore 212 14 | call_check = call_check + 1 15 | return "from the client" 16 | end 17 | local function c_parse_ext(ssl, ext_type, context, data) -- luacheck: ignore 212 18 | call_check = call_check + 2 19 | assert(data == "from the server") 20 | return true 21 | end 22 | cli_ctx:addCustomExtension(5000, 23 | openssl_ctx.EXT_CLIENT_HELLO + 24 | openssl_ctx.EXT_TLS1_2_SERVER_HELLO + 25 | openssl_ctx.EXT_TLS1_3_SERVER_HELLO 26 | , c_add_ext, c_parse_ext) 27 | 28 | 29 | srv_ctx = regress.getsslctx("TLS", true) 30 | local function s_add_ext(ssl, ext_type, context) -- luacheck: ignore 212 31 | call_check = call_check + 4 32 | return "from the server" 33 | end 34 | local function s_parse_ext(ssl, ext_type, context, data) -- luacheck: ignore 212 35 | call_check = call_check + 8 36 | assert(data == "from the client") 37 | return true 38 | end 39 | srv_ctx:addCustomExtension(5000, 40 | openssl_ctx.EXT_CLIENT_HELLO + 41 | openssl_ctx.EXT_TLS1_2_SERVER_HELLO + 42 | openssl_ctx.EXT_TLS1_3_SERVER_HELLO 43 | , s_add_ext, s_parse_ext) 44 | 45 | 46 | local srv, cli = regress.check(cs.pair(cs.SOCK_STREAM)) 47 | local main = regress.check(cqueues.new()) 48 | main:wrap(function () 49 | regress.check(cli:starttls(cli_ctx)) 50 | end) 51 | main:wrap(function () 52 | regress.check(srv:starttls(srv_ctx)) 53 | end) 54 | regress.check(main:loop()) 55 | 56 | regress.check(call_check == 15, "callback count doesn't match") 57 | regress.say "OK" 58 | -------------------------------------------------------------------------------- /regress/167-verify-cert.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local regress = require "regress" 4 | 5 | if (regress.openssl.OPENSSL_VERSION_NUMBER and regress.openssl.OPENSSL_VERSION_NUMBER < 0x10002000) 6 | or (regress.openssl.LIBRESSL_VERSION_NUMBER and regress.openssl.LIBRESSL_VERSION_NUMBER < 0x20705000) 7 | then 8 | -- skipping test due to different behaviour in earlier OpenSSL versions 9 | return 10 | end 11 | 12 | local params = regress.verify_param.new() 13 | params:setDepth(0) 14 | 15 | local ca_key, ca_crt = regress.genkey() 16 | do -- should fail as no trust anchor 17 | regress.check(not ca_crt:verify({params=params, chain=nil, store=nil})) 18 | end 19 | 20 | local store = regress.store.new() 21 | store:add(ca_crt) 22 | do -- should succeed as cert is in the store 23 | regress.check(ca_crt:verify({params=params, chain=nil, store=store})) 24 | end 25 | 26 | local intermediate_key, intermediate_crt = regress.genkey(nil, ca_key, ca_crt) 27 | do -- should succeed as ca cert is in the store 28 | regress.check(intermediate_crt:verify({params=params, chain=nil, store=store})) 29 | end 30 | 31 | local _, crt = regress.genkey(nil, intermediate_key, intermediate_crt) 32 | do -- should fail as intermediate cert is missing 33 | regress.check(not crt:verify({params=params, chain=nil, store=store})) 34 | end 35 | 36 | local chain = regress.chain.new() 37 | chain:add(intermediate_crt) 38 | do -- should fail as max depth is too low 39 | regress.check(not crt:verify({params=params, chain=chain, store=store})) 40 | end 41 | 42 | params:setDepth(1) 43 | do -- should succeed 44 | regress.check(crt:verify({params=params, chain=chain, store=store})) 45 | end 46 | 47 | regress.say "OK" 48 | -------------------------------------------------------------------------------- /regress/177-reset-bio.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local regress = require "regress" 4 | 5 | local ok, err 6 | 7 | local key = regress.pkey.new() 8 | 9 | -- generate a minimal certificate and export to DER 10 | local x509 = regress.x509.new() 11 | x509:setPublicKey(key) 12 | x509:sign(key) 13 | local x509_der = x509:tostring("DER") 14 | 15 | ok, err = pcall(regress.x509.new, x509_der) 16 | regress.check(ok, "failed to load DER certificate: %s", err) 17 | 18 | -- generate a minimal crl and export to DER 19 | local crl = regress.crl.new() 20 | crl:sign(key) 21 | local crl_der = crl:tostring("DER") 22 | 23 | ok, err = pcall(regress.crl.new, crl_der) 24 | regress.check(ok, "failed to load DER CRL: %s", err) 25 | 26 | -- generate a minimal csr and export to DER 27 | local csr = regress.csr.new() 28 | csr:setPublicKey(key) 29 | csr:sign(key) 30 | local csr_der = csr:tostring("DER") 31 | 32 | ok, err = pcall(regress.csr.new, csr_der) 33 | regress.check(ok, "failed to load DER CSR: %s", err) 34 | 35 | regress.say "OK" 36 | -------------------------------------------------------------------------------- /regress/53-csr-extensions.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local auxlib = require"openssl.auxlib" 4 | local pkey = require "openssl.pkey" 5 | local x509_csr = require"_openssl.x509.csr" 6 | local x509_altname = require"openssl.x509.altname" 7 | local x509_name = require"openssl.x509.name" 8 | 9 | local _basename = arg and arg[0] and arg[0]:match"([^/]+)$" or "UNKNOWN" 10 | 11 | local function cluck(fmt, ...) 12 | io.stderr:write(_basename, ": ", string.format(fmt, ...), "\n") 13 | end 14 | 15 | local function croak(fmt, ...) 16 | io.stderr:write(_basename, ": ", string.format(fmt, ...), "\n") 17 | os.exit(1) 18 | end 19 | 20 | local function OK() 21 | cluck("OK") 22 | return true 23 | end 24 | 25 | local _testno = 0 26 | local function testnames(altnames, expected) 27 | local matched = {} 28 | 29 | _testno = _testno + 1 30 | 31 | for type,data in auxlib.pairs(altnames) do 32 | local found 33 | 34 | for i,e in ipairs(expected) do 35 | if not matched[i] and e.type == type and e.data == data then 36 | cluck("expected match #%d.%d found (%s=%s)", _testno, i, type,data) 37 | 38 | matched[i] = true 39 | found = true 40 | end 41 | end 42 | 43 | if not found then 44 | return false, string.format("extra name in test #%d (%s=%s)", _testno, type, data) 45 | end 46 | end 47 | 48 | for i,e in ipairs(expected) do 49 | if not matched[i] then 50 | return false, string.format("expected match #%d.%d not found (%s=%s)", _testno, i, e.type, e.data) 51 | end 52 | end 53 | 54 | return true 55 | end 56 | 57 | local function checknames(altnames, expected) 58 | local ok, why = testnames(altnames, expected) 59 | 60 | if not ok then 61 | croak(why or "UNKNOWN") 62 | end 63 | 64 | return true 65 | end 66 | 67 | key = pkey.new({ bits = 4096 }) 68 | 69 | data = [[ 70 | -----BEGIN CERTIFICATE REQUEST----- 71 | MIIFQjCCAyoCAQAwUzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAk1OMRQwEgYDVQQH 72 | DAtNaW5uZWFwb2xpczEhMB8GA1UECwwYRG9tYWluIENvbnRyb2wgVmFsaWRhdGVk 73 | MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA4sXzE3GQtpFKiuGe389k 74 | MB0OaGXQxiI/yl6zm9PyYWe5aMpx1THDVhkWXemDVkduEqtLfa8GSNT0ps3BPdTx 75 | qxNwZ3J9xiVfNZZYO5ZSxs1g32M1lw20wIezLpbQ1ggyt01o9VTQDY6kA+D0G87B 76 | 4FtIZxVaXM2z5HVaGYyivxAygDukDsO+RU0NC9mYOfAP4rt/u/xp8LsW0b4aIFqx 77 | gPcBZj92B+Wi2B4sKSe1m5kMfmh+e8v981hbY7V8FUMebB63iRGF6GU4kjXiMMW6 78 | gSoc+usq9li8VxjxPngql9pyLqFIa/2gW0c9sKKB2X9tB0nmudjAUrjZjHZEDlNr 79 | yx15JHhEIT31yP9xGQpy5H+jBldp/shqaV4Alsou9Hn9W71ap7VHOWLrIcaZGKTn 80 | CVSSYPygn4Rm8Cgwbv5mP6G+SqGHAFqirEysAARUFxsjBLlkNaVFOA38l2cufH8n 81 | 1NE/B4iOG/ETvQDR/aKrbyKKo2k/hO941h3J9pwJcCikE0NsRcH6WAm8ifJ0Zd/q 82 | u8fqI8g9mYPbMWy11+njnfNOVFVhNOmM1/ZM66ac9zgGYncaHu4UzYnvWw75tDbF 83 | vA+oIJlcxBUtWeTcYRf4xEcRL8IcHEwh1BZq7bgP42Wu+0aBuaa3eYXNBApCNP39 84 | QmnHlo0iGH2rVeOfcq/wULcCAwEAAaCBqTCBpgYJKoZIhvcNAQkOMYGYMIGVMAkG 85 | A1UdEwQCMAAwCwYDVR0PBAQDAgXgMHsGA1UdEQR0MHKCE3NlcnZlcjEuZXhhbXBs 86 | ZS5jb22CEG1haWwuZXhhbXBsZS5jb22CD3d3dy5leGFtcGxlLmNvbYITd3d3LnN1 87 | Yi5leGFtcGxlLmNvbYIObXguZXhhbXBsZS5jb22CE3N1cHBvcnQuZXhhbXBsZS5j 88 | b20wDQYJKoZIhvcNAQEFBQADggIBAMiFPtDKVsy4HBhVkHSnbbIl41baaGGFjI/O 89 | MG8fI7P9jplq5rNZcLxSW2zLzMVuYzCoC+q5roRE5zVVyJlB+5dY0A8e2xKaWVOT 90 | AB9WvgepPvXDoGNViMBoX/idj3J2BU3e/cX08QWRPjKigwQWQWvUGsZYitGJv+Yv 91 | /LbIDlxr8Jr+1Txcm1EdXcff6Owlh6Nu59bgCMRdZvABmWfU5ULmUDTJnmc3P9St 92 | onz07v8ku8/XL7wwOfLJWVSVOk7RONySIJiPfVkgrU3YWiT64JaluDbFEIwnEgJS 93 | 04xL6Pl66bADXCaeG3pZ8ypCs41+4bqFvCnOYma0Sk8fv8hSCWvJfMQI+nQslPJu 94 | UuGK4C4EEnYvoh/Qs/XEshfrVaNcG0zER3XtsRPAjhZjTPTcRgEjpOI0w3TJAvlN 95 | LSQV4mXN6E2bcU+cRYvNSgqITwJ7c6wpsONwApIQwFryLsFSCHaIdSLpAZbEPNEW 96 | UPa3uWXk5lWrBBPPkxyPbt8D3zpzahY4ycYEFKdz8MLdgA7pDalI2XpwgmoUybkw 97 | AJnsFg7fnFc03R4FsqxCqvbRYj3Bccb8Uhg1zTeXU+7nxjP2yYdT+In16L9SYOsU 98 | 4ozEPqnGY9aI11i6C7hBwrUTvHYD6ZSDlylsUXKw/VZXQvS3+C0h6NuRmjBx8jNU 99 | RG1EyxL4 100 | -----END CERTIFICATE REQUEST----- 101 | ]] 102 | 103 | -- baseline 104 | do 105 | local expected = { 106 | { type = "DNS", data = "server1.example.com" }, 107 | { type = "DNS", data = "mail.example.com" }, 108 | { type = "DNS", data = "www.example.com" }, 109 | { type = "DNS", data = "www.sub.example.com" }, 110 | { type = "DNS", data = "mx.example.com" }, 111 | { type = "DNS", data = "support.example.com" }, 112 | } 113 | 114 | checknames((x509_csr.new(data)):getSubjectAlt(), expected) 115 | end 116 | 117 | -- modifying existing altnames 118 | do 119 | local expected = { 120 | { type = "DNS", data = "foo.com" }, 121 | { type = "DNS", data = "*.foo.com" }, 122 | } 123 | 124 | local csr = x509_csr.new(data) 125 | local gn = x509_altname.new() 126 | gn:add("DNS", "foo.com") 127 | gn:add("DNS", "*.foo.com") 128 | csr:setSubjectAlt(gn) 129 | csr:setPublicKey(key) 130 | csr:sign(key) 131 | 132 | -- check modified object 133 | checknames(csr:getSubjectAlt(), expected) 134 | -- check after a round-trip through PEM 135 | checknames(x509_csr.new(tostring(csr)):getSubjectAlt(), expected) 136 | end 137 | 138 | -- adding altnames where none existed 139 | do 140 | local expected = { 141 | name = { 142 | { type = "CN", data = "example.com" }, 143 | }, 144 | altname = { 145 | { type = "DNS", data = "foo.com" }, 146 | { type = "DNS", data = "*.foo.com" }, 147 | }, 148 | } 149 | 150 | local csr = x509_csr.new() 151 | local name = x509_name.new() 152 | name:add("CN", "example.com") 153 | csr:setSubject(name) 154 | local gn = x509_altname.new() 155 | gn:add("DNS", "foo.com") 156 | gn:add("DNS", "*.foo.com") 157 | csr:setSubjectAlt(gn) 158 | csr:setPublicKey(key) 159 | csr:sign(key) 160 | 161 | checknames(csr:getSubject(), expected.name) 162 | checknames(csr:getSubjectAlt(), expected.altname) 163 | 164 | local csr1 = x509_csr.new(tostring(csr)) 165 | checknames(csr1:getSubject(), expected.name) 166 | checknames(csr1:getSubjectAlt(), expected.altname) 167 | end 168 | 169 | return OK() 170 | 171 | -------------------------------------------------------------------------------- /regress/82-bn_prepops-null-deref.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | -- 3 | -- The following code could trigger a NULL dereference. 4 | -- 5 | -- bn_prepops(lua_State *L, BIGNUM **r, BIGNUM **a, BIGNUM **b, _Bool commute) { 6 | -- ... 7 | -- *b = checkbig(L, 2, &lvalue); 8 | -- ... 9 | -- } 10 | -- 11 | -- bn_sqr(lua_State *L) { 12 | -- BIGNUM *r, *a; 13 | -- 14 | -- bn_prepops(L, &r, &a, NULL, 1); 15 | -- ... 16 | -- } 17 | -- 18 | -- Caught by clang static analyzer. This was introduced with a patch adding 19 | -- the :sqr method. This should have been caught sooner as the :sqr method 20 | -- couldn't have possibly ever worked--a missing or non-numeric second 21 | -- operand would have thrown a Lua error, and a numeric second operand 22 | -- triggers the NULL dereference. 23 | -- 24 | require"regress".export".*" 25 | 26 | local function N(i) return bignum.new(i) end 27 | 28 | -- passing a second numeric operand triggered a NULL dereference 29 | local r = N(4):sqr(0) 30 | 31 | 32 | -- check minimal functionality of all our operators 33 | local tests = { 34 | { op = "add", a = 1, b = 1, r = 2 }, 35 | { op = "sub", a = 2, b = 1, r = 1 }, 36 | { op = "mul", a = 2, b = 2, r = 4 }, 37 | { op = "idiv", a = 4, b = 2, r = 2 }, 38 | { op = "mod", a = 4, b = 2, r = 0 }, 39 | { op = "exp", a = 2, b = 2, r = 4 }, 40 | { op = "sqr", a = 4, b = nil, r = 16 }, 41 | { op = "gcd", a = 47, b = 3, r = 1 }, 42 | } 43 | 44 | local function tdescr(t) 45 | return string.format("%s(%s, %s)", t.op, tostring(t.a), tostring(t.b)) 46 | end 47 | 48 | for i,t in ipairs(tests) do 49 | local a = N(t.a) 50 | local op = a[t.op] 51 | local ok, r 52 | 53 | if t.b then 54 | ok, r = pcall(op, a, t.b) 55 | else 56 | ok, r = pcall(op, a) 57 | end 58 | 59 | check(ok, "failed test #%d (%s) (%s)", i, tdescr(t), r) 60 | check(N(r) == N(t.r), "failed test #%d (%s) (expected %s, got %s)", i, tdescr(t), tostring(t.r), tostring(r)) 61 | end 62 | 63 | say"OK" 64 | -------------------------------------------------------------------------------- /regress/95-kdf.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local regress = require "regress" 4 | local kdf = require "openssl.kdf" 5 | 6 | local function hexstring(str) 7 | return (str:gsub("..", function(b) return string.char(tonumber(b, 16)) end)) 8 | end 9 | 10 | -- Scrypt Example 11 | regress.check(kdf.derive{ 12 | type = "id-scrypt"; -- the nid short-name is id-scrypt 13 | pass = ""; 14 | salt = ""; 15 | N = 16; 16 | r = 1; 17 | p = 1; 18 | outlen = 64; 19 | } == hexstring"77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906", 20 | "scrypt output doesn't match test vector") 21 | 22 | -- PBKDF2 Example 23 | regress.check(kdf.derive{ 24 | type = "PBKDF2"; 25 | pass = "password"; 26 | salt = "salt"; 27 | iter = 1; 28 | md = "sha1"; 29 | outlen = 20; 30 | } == hexstring"0c60c80f961f0e71f3a9b524af6012062fe037a6", 31 | "PBKDF2 output doesn't match test vector") 32 | 33 | -- TLS1-PRF Example 34 | regress.check(kdf.derive{ 35 | type = "TLS1-PRF"; 36 | md = "md5-sha1"; 37 | secret = hexstring"bded7fa5c1699c010be23dd06ada3a48349f21e5f86263d512c0c5cc379f0e780ec55d9844b2f1db02a96453513568d0"; 38 | seed = "master secret" 39 | .. hexstring"e5acaf549cd25c22d964c0d930fa4b5261d2507fad84c33715b7b9a864020693" 40 | .. hexstring"135e4d557fdf3aa6406d82975d5c606a9734c9334b42136e96990fbd5358cdb2"; 41 | outlen = 48; 42 | } == hexstring"2f6962dfbc744c4b2138bb6b3d33054c5ecc14f24851d9896395a44ab3964efc2090c5bf51a0891209f46c1e1e998f62", 43 | "TLS1-PRF output doesn't match test vector") 44 | 45 | regress.say "OK" 46 | -------------------------------------------------------------------------------- /regress/regress.lua: -------------------------------------------------------------------------------- 1 | local require = require -- may be overloaded by regress.require 2 | 3 | local regress = { 4 | openssl = require"openssl", 5 | bignum = require"openssl.bignum", 6 | kdf = require"openssl.kdf", 7 | pkey = require"openssl.pkey", 8 | x509 = require"openssl.x509", 9 | name = require"openssl.x509.name", 10 | altname = require"openssl.x509.altname", 11 | chain = require"openssl.x509.chain", 12 | store = require"openssl.x509.store", 13 | verify_param = require"openssl.x509.verify_param", 14 | crl = require"openssl.x509.crl", 15 | csr = require"openssl.x509.csr", 16 | pack = table.pack or function (...) 17 | local t = { ... } 18 | t.n = select("#", ...) 19 | return t 20 | end, 21 | unpack = table.unpack or unpack, 22 | } 23 | 24 | local emit_progname = os.getenv"REGRESS_PROGNAME" or "regress" 25 | local emit_verbose = tonumber(os.getenv"REGRESS_VERBOSE" or 1) 26 | local emit_info = {} 27 | local emit_ll = 0 28 | 29 | local function emit(fmt, ...) 30 | local msg = string.format(fmt, ...) 31 | 32 | for txt, nl in msg:gmatch("([^\n]*)(\n?)") do 33 | if emit_ll == 0 and #txt > 0 then 34 | io.stderr:write(emit_progname, ": ") 35 | emit_ll = #emit_progname + 2 36 | end 37 | 38 | io.stderr:write(txt, nl) 39 | 40 | if nl == "\n" then 41 | emit_ll = 0 42 | else 43 | emit_ll = emit_ll + #txt 44 | end 45 | end 46 | end -- emit 47 | 48 | local function emitln(fmt, ...) 49 | if emit_ll > 0 then 50 | emit"\n" 51 | end 52 | 53 | emit(fmt .. "\n", ...) 54 | end -- emitln 55 | 56 | local function emitinfo() 57 | for _, txt in ipairs(emit_info) do 58 | emitln("%s", txt) 59 | end 60 | end -- emitinfo 61 | 62 | function regress.say(...) 63 | emitln(...) 64 | end -- say 65 | 66 | function regress.panic(...) 67 | emitinfo() 68 | emitln(...) 69 | os.exit(1) 70 | end -- panic 71 | 72 | function regress.info(...) 73 | if emit_verbose > 1 then 74 | emitln(...) 75 | else 76 | emit_info[#emit_info + 1] = string.format(...) 77 | 78 | if emit_verbose > 0 then 79 | if emit_ll > 78 then 80 | emit"\n." 81 | else 82 | emit"." 83 | end 84 | end 85 | end 86 | end -- info 87 | 88 | function regress.check(v, ...) 89 | if v then 90 | return v, ... 91 | else 92 | regress.panic(...) 93 | end 94 | end -- check 95 | 96 | function regress.export(...) 97 | for _, pat in ipairs{ ... } do 98 | for k, v in pairs(regress) do 99 | if string.match(k, pat) then 100 | _G[k] = v 101 | end 102 | end 103 | end 104 | 105 | return regress 106 | end -- export 107 | 108 | function regress.require(modname) 109 | local ok, module = pcall(require, modname) 110 | 111 | regress.check(ok, "module %s required", modname) 112 | 113 | return module 114 | end -- regress.require 115 | 116 | local counter = 0 117 | function regress.genkey(type, ca_key, ca_crt) 118 | local pkey = regress.require"openssl.pkey" 119 | local x509 = regress.require"openssl.x509" 120 | local name = regress.require"openssl.x509.name" 121 | local altname = regress.require"openssl.x509.altname" 122 | local key 123 | 124 | type = string.upper(type or "RSA") 125 | 126 | if type == "EC" then 127 | key = regress.check(pkey.new{ type = "EC", curve = "prime192v1" }) 128 | else 129 | key = regress.check(pkey.new{ type = type, bits = 2048 }) 130 | end 131 | 132 | local dn = name.new() 133 | dn:add("C", "US") 134 | dn:add("ST", "California") 135 | dn:add("L", "San Francisco") 136 | dn:add("O", "Acme, Inc.") 137 | dn:add("CN", string.format("acme%d.inc", counter)) 138 | counter = counter + 1 139 | 140 | local alt = altname.new() 141 | alt:add("DNS", "acme.inc") 142 | alt:add("DNS", "localhost") 143 | 144 | local crt = x509.new() 145 | crt:setVersion(3) 146 | crt:setSerial(47) 147 | crt:setSubject(dn) 148 | crt:setIssuer((ca_crt or crt):getSubject()) 149 | crt:setSubjectAlt(alt) 150 | 151 | local issued, expires = crt:getLifetime() 152 | crt:setLifetime(issued, expires + 60) 153 | 154 | crt:setBasicConstraints{ CA = true, pathLen = 2 } 155 | crt:setBasicConstraintsCritical(true) 156 | 157 | crt:setPublicKey(key) 158 | crt:sign(ca_key or key) 159 | 160 | return key, crt 161 | end -- regress.genkey 162 | 163 | local function getsubtable(t, name, ...) 164 | name = name or false -- cannot be nil 165 | 166 | if not t[name] then 167 | t[name] = {} 168 | end 169 | 170 | if select('#', ...) > 0 then 171 | return getsubtable(t[name], ...) 172 | else 173 | return t[name] 174 | end 175 | end -- getsubtable 176 | 177 | function regress.newsslctx(protocol, accept, keytype) 178 | local context = regress.require"openssl.ssl.context" 179 | local ctx = context.new(protocol, accept) 180 | 181 | if keytype or keytype == nil then 182 | local key, crt = regress.genkey(keytype) 183 | 184 | ctx:setCertificate(crt) 185 | ctx:setPrivateKey(key) 186 | end 187 | 188 | return ctx 189 | end -- require.newsslctx 190 | 191 | local ctxcache = {} 192 | 193 | function regress.getsslctx(protocol, accept, keytype) 194 | local keycache = getsubtable(ctxcache, protocol, accept) 195 | 196 | if keytype == nil then 197 | keytype = "RSA" 198 | end 199 | 200 | local ctx = keycache[keytype] 201 | 202 | if not ctx then 203 | ctx = regress.newsslctx(protocol, accept, keytype) 204 | keycache[keytype] = ctx 205 | end 206 | 207 | return ctx 208 | end -- regress.getsslctx 209 | 210 | return regress 211 | -------------------------------------------------------------------------------- /src/GNUmakefile: -------------------------------------------------------------------------------- 1 | # non-recursive prologue 2 | sp := $(sp).x 3 | dirstack_$(sp) := $(d) 4 | d := $(abspath $(lastword $(MAKEFILE_LIST))/..) 5 | 6 | ifeq ($(origin GUARD_$(d)), undefined) 7 | GUARD_$(d) := 1 8 | 9 | 10 | # 11 | # E N V I R O N M E N T C O N F I G U R A T I O N 12 | # 13 | include $(d)/../GNUmakefile 14 | 15 | 16 | # 17 | # C O M P I L A T I O N F L A G S 18 | # 19 | CPPFLAGS_$(d) = $(ALL_CPPFLAGS) -DHAVE_CONFIG_H -DCOMPAT53_PREFIX=luaossl 20 | CFLAGS_$(d) = $(ALL_CFLAGS) 21 | SOFLAGS_$(d) = $(ALL_SOFLAGS) 22 | LDFLAGS_$(d) = $(ALL_LDFLAGS) 23 | LIBS_$(d) = $(ALL_LIBS) 24 | 25 | # 26 | # C O M P I L A T I O N R U L E S 27 | # 28 | OBJS_$(d) = openssl.o 29 | 30 | $(d)/config.h: $(abspath $(d)/..)/config.h 31 | $(CP) $< $@ 32 | 33 | define BUILD_$(d) 34 | 35 | $$(d)/$(1)/openssl.so: $$(addprefix $$(d)/$(1)/, $$(OBJS_$(d))) 36 | $$(CC) -o $$@ $$^ $$(SOFLAGS_$$(abspath $$(@D)/..)) $$(LDFLAGS_$$(abspath $$(@D)/..)) $$(LIBS_$$(abspath $$(@D)/..)) 37 | 38 | $$(d)/$(1)/%.o: $$(d)/%.c $$(d)/config.h 39 | $$(MKDIR) -p $$(@D) 40 | $$(CC) $$(CFLAGS_$$(" 248 | 249 | help: $(d)/help 250 | 251 | 252 | endif # include guard 253 | 254 | # non-recursive epilogue 255 | d := $(dirstack_$(sp)) 256 | sp := $(basename $(sp)) 257 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | .POSIX: 2 | 3 | all: 4 | +gmake -f GNUmakefile all 5 | 6 | .DEFAULT: 7 | +gmake -f GNUmakefile $< 8 | -------------------------------------------------------------------------------- /src/openssl.auxlib.lua: -------------------------------------------------------------------------------- 1 | local auxlib = {} 2 | 3 | if _VERSION == "Lua 5.1" then 4 | local _pairs = pairs 5 | 6 | function auxlib.pairs(t) 7 | if type(t) == "userdata" then 8 | local mt = getmetatable(t) 9 | 10 | if mt and mt.__pairs then 11 | return mt.__pairs(t) 12 | else 13 | return _pairs(t) 14 | end 15 | end 16 | end 17 | else 18 | auxlib.pairs = pairs 19 | end 20 | 21 | return auxlib 22 | -------------------------------------------------------------------------------- /src/openssl.bignum.lua: -------------------------------------------------------------------------------- 1 | local bignum = require"_openssl.bignum" 2 | 3 | return bignum 4 | -------------------------------------------------------------------------------- /src/openssl.cipher.lua: -------------------------------------------------------------------------------- 1 | local ctx = require"_openssl.cipher" 2 | 3 | return ctx 4 | -------------------------------------------------------------------------------- /src/openssl.des.lua: -------------------------------------------------------------------------------- 1 | local ctx = require"_openssl.des" 2 | 3 | return ctx 4 | -------------------------------------------------------------------------------- /src/openssl.digest.lua: -------------------------------------------------------------------------------- 1 | local ctx = require"_openssl.digest" 2 | 3 | return ctx 4 | -------------------------------------------------------------------------------- /src/openssl.hmac.lua: -------------------------------------------------------------------------------- 1 | local ctx = require"_openssl.hmac" 2 | 3 | return ctx 4 | -------------------------------------------------------------------------------- /src/openssl.kdf.lua: -------------------------------------------------------------------------------- 1 | local ctx = require"_openssl.kdf" 2 | 3 | return ctx 4 | -------------------------------------------------------------------------------- /src/openssl.lua: -------------------------------------------------------------------------------- 1 | return require"_openssl" 2 | -------------------------------------------------------------------------------- /src/openssl.ocsp.basic.lua: -------------------------------------------------------------------------------- 1 | local ob = require "_openssl.ocsp.basic" 2 | 3 | return ob 4 | -------------------------------------------------------------------------------- /src/openssl.ocsp.response.lua: -------------------------------------------------------------------------------- 1 | local ocsp_response = require "_openssl.ocsp.response" 2 | 3 | return ocsp_response 4 | -------------------------------------------------------------------------------- /src/openssl.pkcs12.lua: -------------------------------------------------------------------------------- 1 | return require('_openssl.pkcs12') 2 | -------------------------------------------------------------------------------- /src/openssl.pkey.lua: -------------------------------------------------------------------------------- 1 | local pkey = require"_openssl.pkey" 2 | 3 | return pkey 4 | 5 | -------------------------------------------------------------------------------- /src/openssl.pubkey.lua: -------------------------------------------------------------------------------- 1 | -- for backwards compatibility 2 | return require "openssl.pkey" 3 | -------------------------------------------------------------------------------- /src/openssl.rand.lua: -------------------------------------------------------------------------------- 1 | local ctx = require"_openssl.rand" 2 | 3 | return ctx 4 | -------------------------------------------------------------------------------- /src/openssl.ssl.context.lua: -------------------------------------------------------------------------------- 1 | local ctx = require"_openssl.ssl.context" 2 | 3 | local pack = table.pack or function(...) return { n = select("#", ...); ... } end 4 | 5 | -- Allow passing a vararg of ciphers, or an array 6 | local setCipherList; setCipherList = ctx.interpose("setCipherList", function (self, ciphers, ...) 7 | if (...) then 8 | local ciphers_t = pack(ciphers, ...) 9 | ciphers = table.concat(ciphers_t, ":", 1, ciphers_t.n) 10 | elseif type(ciphers) == "table" then 11 | ciphers = table.concat(ciphers, ":") 12 | end 13 | return setCipherList(self, ciphers) 14 | end) 15 | 16 | -- Allow passing a vararg of ciphersuites, or an array 17 | local setCipherSuites = ctx.interpose("setCipherSuites", nil) 18 | if setCipherSuites then 19 | ctx.interpose("setCipherSuites", function (self, ciphers, ...) 20 | if (...) then 21 | local ciphers_t = pack(ciphers, ...) 22 | ciphers = table.concat(ciphers_t, ":", 1, ciphers_t.n) 23 | elseif type(ciphers) == "table" then 24 | ciphers = table.concat(ciphers, ":") 25 | end 26 | return setCipherSuites(self, ciphers) 27 | end) 28 | end 29 | 30 | -- Allow passing a vararg of curves, or an array 31 | local setGroups = ctx.interpose("setGroups", nil) 32 | if setGroups then 33 | local function varargSetGroups(self, group, ...) 34 | if (...) then 35 | local group_t = pack(group, ...) 36 | group = table.concat(group_t, ":", 1, group_t.n) 37 | elseif type(group) == "table" then 38 | group = table.concat(group, ":") 39 | end 40 | return setGroups(self, group) 41 | end 42 | ctx.interpose("setGroups", varargSetGroups) 43 | ctx.interpose("setCurvesList", varargSetGroups) 44 | end 45 | 46 | return ctx 47 | -------------------------------------------------------------------------------- /src/openssl.ssl.lua: -------------------------------------------------------------------------------- 1 | local ssl = require"_openssl.ssl" 2 | 3 | local pack = table.pack or function(...) return { n = select("#", ...); ... } end 4 | 5 | ssl.interpose("setStore", function(self, store) 6 | self:setChainStore(store) 7 | self:setVerifyStore(store) 8 | return true 9 | end) 10 | 11 | -- Allow passing a vararg of ciphers, or an array 12 | local setCipherList; setCipherList = ssl.interpose("setCipherList", function (self, ciphers, ...) 13 | if (...) then 14 | local ciphers_t = pack(ciphers, ...) 15 | ciphers = table.concat(ciphers_t, ":", 1, ciphers_t.n) 16 | elseif type(ciphers) == "table" then 17 | ciphers = table.concat(ciphers, ":") 18 | end 19 | return setCipherList(self, ciphers) 20 | end) 21 | 22 | -- Allow passing a vararg of ciphersuites, or an array 23 | local setCipherSuites = ssl.interpose("setCipherSuites", nil) 24 | if setCipherSuites then 25 | ssl.interpose("setCipherSuites", function (self, ciphers, ...) 26 | if (...) then 27 | local ciphers_t = pack(ciphers, ...) 28 | ciphers = table.concat(ciphers_t, ":", 1, ciphers_t.n) 29 | elseif type(ciphers) == "table" then 30 | ciphers = table.concat(ciphers, ":") 31 | end 32 | return setCipherSuites(self, ciphers) 33 | end) 34 | end 35 | 36 | -- Allow passing a vararg of curves, or an array 37 | local setGroups = ssl.interpose("setGroups", nil) 38 | if setGroups then 39 | local function varargSetGroups(self, group, ...) 40 | if (...) then 41 | local group_t = pack(group, ...) 42 | group = table.concat(group_t, ":", 1, group_t.n) 43 | elseif type(group) == "table" then 44 | group = table.concat(group, ":") 45 | end 46 | return setGroups(self, group) 47 | end 48 | ssl.interpose("setGroups", varargSetGroups) 49 | ssl.interpose("setCurvesList", varargSetGroups) 50 | end 51 | 52 | return ssl 53 | -------------------------------------------------------------------------------- /src/openssl.x509.altname.lua: -------------------------------------------------------------------------------- 1 | local altname = require"_openssl.x509.altname" 2 | local auxlib = require"openssl.auxlib" 3 | 4 | altname.interpose("__tostring", function (self) 5 | local t = { } 6 | 7 | for k, v in auxlib.pairs(self) do 8 | t[#t + 1] = k .. ":" .. v 9 | end 10 | 11 | return table.concat(t, ", ") 12 | end) 13 | 14 | return altname 15 | -------------------------------------------------------------------------------- /src/openssl.x509.chain.lua: -------------------------------------------------------------------------------- 1 | local chain = require"_openssl.x509.chain" 2 | 3 | return chain 4 | -------------------------------------------------------------------------------- /src/openssl.x509.crl.lua: -------------------------------------------------------------------------------- 1 | return require('_openssl.x509.crl') 2 | -------------------------------------------------------------------------------- /src/openssl.x509.csr.lua: -------------------------------------------------------------------------------- 1 | return require('_openssl.x509.csr') 2 | -------------------------------------------------------------------------------- /src/openssl.x509.extension.lua: -------------------------------------------------------------------------------- 1 | return require('_openssl.x509.extension') 2 | -------------------------------------------------------------------------------- /src/openssl.x509.lua: -------------------------------------------------------------------------------- 1 | local x509 = require"_openssl.x509.cert" 2 | 3 | return x509 4 | -------------------------------------------------------------------------------- /src/openssl.x509.name.lua: -------------------------------------------------------------------------------- 1 | local name = require"_openssl.x509.name" 2 | local auxlib = require"openssl.auxlib" 3 | 4 | name.interpose("__tostring", function (self) 5 | local t = { } 6 | 7 | for k, v in auxlib.pairs(self) do 8 | t[#t + 1] = k .. "=" .. v 9 | end 10 | 11 | return table.concat(t, ", ") 12 | end) 13 | 14 | return name 15 | -------------------------------------------------------------------------------- /src/openssl.x509.store.lua: -------------------------------------------------------------------------------- 1 | local store = require"_openssl.x509.store" 2 | 3 | return store 4 | -------------------------------------------------------------------------------- /src/openssl.x509.verify_param.lua: -------------------------------------------------------------------------------- 1 | return require('_openssl.x509.verify_param') 2 | -------------------------------------------------------------------------------- /vendor/compat53/.gitignore: -------------------------------------------------------------------------------- 1 | # generated files 2 | *.so 3 | *.dll 4 | *.o 5 | *.obj 6 | HISTO 7 | 8 | # vim temporaries 9 | .*.swp 10 | 11 | -------------------------------------------------------------------------------- /vendor/compat53/.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | compiler: gcc 3 | 4 | sudo: false 5 | 6 | env: 7 | - LUA="lua=5.1" 8 | - LUA="lua=5.1" EXTERNAL=true 9 | - LUA="lua=5.1" COMPILER="g++" 10 | - LUA="lua=5.1" EXTERNAL=true COMPILER="g++" 11 | - LUA="luajit=@v2.1 --compat=none" 12 | - LUA="luajit=@v2.1 --compat=none" EXTERNAL=true 13 | - LUA="luajit=@v2.1 --compat=all" 14 | - LUA="luajit=@v2.1 --compat=all" EXTERNAL=true 15 | - LUA="lua=5.2" 16 | - LUA="lua=5.2" EXTERNAL=true 17 | - LUA="lua=5.2" COMPILER="g++" 18 | - LUA="lua=5.2" EXTERNAL=true COMPILER="g++" 19 | 20 | branches: 21 | only: 22 | - master 23 | 24 | git: 25 | depth: 3 26 | 27 | notifications: 28 | email: false 29 | 30 | before_install: 31 | - pip install --user hererocks 32 | - hererocks old --$LUA 33 | - test -e old/bin/lua || (cd old/bin && ln -s luajit* lua) 34 | - hererocks new --lua=5.3 35 | 36 | install: 37 | - export CC="${COMPILER:-gcc}" DEF="" SRC="" CFLAGS="-Wall -Wextra -Ic-api -O2 -fPIC" 38 | - if [ "x${EXTERNAL:-}" = xtrue ]; then DEF="-DCOMPAT53_PREFIX=compat53" SRC="c-api/compat-5.3.c"; fi 39 | - ${CC} ${CFLAGS} -Iold/include ${DEF} -shared -o old/testmod.so tests/testmod.c ${SRC} 40 | - ${CC} ${CFLAGS} -Inew/include ${DEF} -shared -o new/testmod.so tests/testmod.c ${SRC} 41 | - gcc ${CFLAGS} -Iold/include ${DEF} -shared -o old/compat53.so ltablib.c lutf8lib.c lstrlib.c ${SRC} 42 | 43 | script: 44 | - (cd old && bin/lua ../tests/test.lua) > old.txt 45 | - (cd new && bin/lua ../tests/test.lua) > new.txt 46 | - diff old.txt new.txt || true 47 | 48 | -------------------------------------------------------------------------------- /vendor/compat53/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Kepler Project. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /vendor/compat53/README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/keplerproject/lua-compat-5.3.svg?branch=master)](https://travis-ci.org/keplerproject/lua-compat-5.3) 2 | 3 | # lua-compat-5.3 4 | 5 | Lua-5.3-style APIs for Lua 5.2 and 5.1. 6 | 7 | ## What is it 8 | 9 | This is a small module that aims to make it easier to write code 10 | in a Lua-5.3-style that is compatible with Lua 5.1, Lua 5.2, and Lua 11 | 5.3. This does *not* make Lua 5.2 (or even Lua 5.1) entirely 12 | compatible with Lua 5.3, but it brings the API closer to that of Lua 13 | 5.3. 14 | 15 | It includes: 16 | 17 | * _For writing Lua_: The Lua module `compat53`, which can be require'd 18 | from Lua scripts and run in Lua 5.1, 5.2, and 5.3, including a 19 | backport of the `utf8` module, the 5.3 `table` module, and the 20 | string packing functions straight from the Lua 5.3 sources. 21 | * _For writing C_: A C header and file which can be linked to your 22 | Lua module written in C, providing some functions from the C API 23 | of Lua 5.3 that do not exist in Lua 5.2 or 5.1, making it easier to 24 | write C code that compiles with all three versions of liblua. 25 | 26 | ## How to use it 27 | 28 | ### Lua module 29 | 30 | ```lua 31 | require("compat53") 32 | ``` 33 | 34 | `compat53` makes changes to your global environment and does not return 35 | a meaningful return value, so the usual idiom of storing the return of 36 | `require` in a local variable makes no sense. 37 | 38 | When run under Lua 5.3+, this module does nothing. 39 | 40 | When run under Lua 5.2 or 5.1, it replaces some of your standard 41 | functions and adds new ones to bring your environment closer to that 42 | of Lua 5.3. It also tries to load the backported `utf8`, `table`, and 43 | string packing modules automatically. If unsuccessful, pure Lua 44 | versions of the new `table` functions are used as a fallback, and 45 | [Roberto's struct library][1] is tried for string packing. 46 | 47 | #### Lua submodules 48 | 49 | ```lua 50 | local _ENV = require("compat53.module") 51 | if setfenv then setfenv(1, _ENV) end 52 | ``` 53 | 54 | The `compat53.module` module does not modify the global environment, 55 | and so it is safe to use in modules without affecting other Lua files. 56 | It is supposed to be set as the current environment (see above), i.e. 57 | cherry picking individual functions from this module is expressly 58 | *not* supported!). Not all features are available when using this 59 | module (e.g. yieldable (x)pcall support, string/file methods, etc.), 60 | so it is recommended to use plain `require("compat53")` whenever 61 | possible. 62 | 63 | ### C code 64 | 65 | There are two ways of adding the C API compatibility functions/macros to 66 | your project: 67 | * If `COMPAT53_PREFIX` is *not* `#define`d, `compat-5.3.h` `#include`s 68 | `compat-5.3.c`, and all functions are made `static`. You don't have to 69 | compile/link/add `compat-5.3.c` yourself. This is useful for one-file 70 | projects. 71 | * If `COMPAT53_PREFIX` is `#define`d, all exported functions are renamed 72 | behind the scenes using this prefix to avoid linker conflicts with other 73 | code using this package. This doesn't change the way you call the 74 | compatibility functions in your code. You have to compile and link 75 | `compat-5.3.c` to your project yourself. You can change the way the 76 | functions are exported using the `COMPAT53_API` macro (e.g. if you need 77 | some `__declspec` magic). While it is technically possible to use 78 | the "lua" prefix (and it looks better in the debugger), this is 79 | discouraged because LuaJIT has started to implement its own Lua 5.2+ 80 | C API functions, and with the "lua" prefix you'd violate the 81 | one-definition rule with recent LuaJIT versions. 82 | 83 | ## What's implemented 84 | 85 | ### Lua 86 | 87 | * the `utf8` module backported from the Lua 5.3 sources 88 | * `string.pack`, `string.packsize`, and `string.unpack` from the Lua 89 | 5.3 sources or from the `struct` module. (`struct` is not 100% 90 | compatible to Lua 5.3's string packing!) (See [here][4]) 91 | * `math.maxinteger` and `math.mininteger`, `math.tointeger`, `math.type`, 92 | and `math.ult` (see [here][5]) 93 | * `assert` accepts non-string error messages 94 | * `ipairs` respects `__index` metamethod 95 | * `table.move` 96 | * `table` library respects metamethods 97 | 98 | For Lua 5.1 additionally: 99 | * `load` and `loadfile` accept `mode` and `env` parameters 100 | * `table.pack` and `table.unpack` 101 | * string patterns may contain embedded zeros (but see [here][6]) 102 | * `string.rep` accepts `sep` argument 103 | * `string.format` calls `tostring` on arguments for `%s` 104 | * `math.log` accepts base argument 105 | * `xpcall` takes additional arguments 106 | * `pcall` and `xpcall` can execute functions that yield (see 107 | [here][22] for a possible problem with `coroutine.running`) 108 | * `pairs` respects `__pairs` metamethod (see [here][7]) 109 | * `rawlen` (but `#` still doesn't respect `__len` for tables) 110 | * `package.searchers` as alias for `package.loaders` 111 | * `package.searchpath` (see [here][8]) 112 | * `coroutine` functions dealing with the main coroutine (see 113 | [here][22] for a possible problem with `coroutine.running`) 114 | * `coroutine.create` accepts functions written in C 115 | * return code of `os.execute` (see [here][9]) 116 | * `io.write` and `file:write` return file handle 117 | * `io.lines` and `file:lines` accept format arguments (like `io.read`) 118 | (see [here][10] and [here][11]) 119 | * `debug.setmetatable` returns object 120 | * `debug.getuservalue` (see [here][12]) 121 | * `debug.setuservalue` (see [here][13]) 122 | 123 | ### C 124 | 125 | * `lua_KContext` (see [here][14]) 126 | * `lua_KFunction` (see [here][14]) 127 | * `lua_dump` (extra `strip` parameter, ignored, see [here][15]) 128 | * `lua_getextraspace` (limited compatibilitiy, see [here][24]) 129 | * `lua_getfield` (return value) 130 | * `lua_geti` and `lua_seti` 131 | * `lua_getglobal` (return value) 132 | * `lua_getmetafield` (return value) 133 | * `lua_gettable` (return value) 134 | * `lua_getuservalue` (limited compatibility, see [here][16]) 135 | * `lua_setuservalue` (limited compatibility, see [here][17]) 136 | * `lua_isinteger` 137 | * `lua_numbertointeger` 138 | * `lua_callk` and `lua_pcallk` (limited compatibility, see [here][14]) 139 | * `lua_resume` 140 | * `lua_rawget` and `lua_rawgeti` (return values) 141 | * `lua_rawgetp` and `lua_rawsetp` 142 | * `luaL_requiref` (now checks `package.loaded` first) 143 | * `lua_rotate` 144 | * `lua_stringtonumber` (see [here][18]) 145 | 146 | For Lua 5.1 additionally: 147 | * `LUA_OK` 148 | * `LUA_ERRGCMM` 149 | * `LUA_OP*` macros for `lua_arith` and `lua_compare` 150 | * `LUA_FILEHANDLE` 151 | * `lua_Unsigned` 152 | * `luaL_Stream` (limited compatibility, see [here][19]) 153 | * `lua_absindex` 154 | * `lua_arith` (see [here][20]) 155 | * `lua_compare` 156 | * `lua_len`, `lua_rawlen`, and `luaL_len` 157 | * `lua_load` (mode argument) 158 | * `lua_pushstring`, `lua_pushlstring` (return value) 159 | * `lua_copy` 160 | * `lua_pushglobaltable` 161 | * `luaL_testudata` 162 | * `luaL_setfuncs`, `luaL_newlibtable`, and `luaL_newlib` 163 | * `luaL_setmetatable` 164 | * `luaL_getsubtable` 165 | * `luaL_traceback` 166 | * `luaL_execresult` 167 | * `luaL_fileresult` 168 | * `luaL_loadbufferx` 169 | * `luaL_loadfilex` 170 | * `luaL_checkversion` (with empty body, only to avoid compile errors, 171 | see [here][21]) 172 | * `luaL_tolstring` 173 | * `luaL_buffinitsize`, `luaL_prepbuffsize`, and `luaL_pushresultsize` 174 | (see [here][22]) 175 | * `lua_pushunsigned`, `lua_tounsignedx`, `lua_tounsigned`, 176 | `luaL_checkunsigned`, `luaL_optunsigned`, if 177 | `LUA_COMPAT_APIINTCASTS` is defined. 178 | 179 | ## What's not implemented 180 | 181 | * bit operators 182 | * integer division operator 183 | * utf8 escape sequences 184 | * 64 bit integers 185 | * `coroutine.isyieldable` 186 | * Lua 5.1: `_ENV`, `goto`, labels, ephemeron tables, etc. See 187 | [`lua-compat-5.2`][2] for a detailed list. 188 | * the following C API functions/macros: 189 | * `lua_isyieldable` 190 | * `lua_arith` (new operators missing) 191 | * `lua_push(v)fstring` (new formats missing) 192 | * `lua_upvalueid` (5.1) 193 | * `lua_upvaluejoin` (5.1) 194 | * `lua_version` (5.1) 195 | * `lua_yieldk` (5.1) 196 | 197 | ## See also 198 | 199 | * For Lua-5.2-style APIs under Lua 5.1, see [lua-compat-5.2][2], 200 | which also is the basis for most of the code in this project. 201 | * For Lua-5.1-style APIs under Lua 5.0, see [Compat-5.1][3] 202 | 203 | ## Credits 204 | 205 | This package contains code written by: 206 | 207 | * [The Lua Team](http://www.lua.org) 208 | * Philipp Janda ([@siffiejoe](http://github.com/siffiejoe)) 209 | * Tomás Guisasola Gorham ([@tomasguisasola](http://github.com/tomasguisasola)) 210 | * Hisham Muhammad ([@hishamhm](http://github.com/hishamhm)) 211 | * Renato Maia ([@renatomaia](http://github.com/renatomaia)) 212 | * [@ThePhD](http://github.com/ThePhD) 213 | * [@Daurnimator](http://github.com/Daurnimator) 214 | 215 | 216 | [1]: http://www.inf.puc-rio.br/~roberto/struct/ 217 | [2]: http://github.com/keplerproject/lua-compat-5.2/ 218 | [3]: http://keplerproject.org/compat/ 219 | [4]: https://github.com/keplerproject/lua-compat-5.3/wiki/string_packing 220 | [5]: https://github.com/keplerproject/lua-compat-5.3/wiki/math.type 221 | [6]: https://github.com/keplerproject/lua-compat-5.3/wiki/pattern_matching 222 | [7]: https://github.com/keplerproject/lua-compat-5.3/wiki/pairs 223 | [8]: https://github.com/keplerproject/lua-compat-5.3/wiki/package.searchpath 224 | [9]: https://github.com/keplerproject/lua-compat-5.3/wiki/os.execute 225 | [10]: https://github.com/keplerproject/lua-compat-5.3/wiki/io.lines 226 | [11]: https://github.com/keplerproject/lua-compat-5.3/wiki/file.lines 227 | [12]: https://github.com/keplerproject/lua-compat-5.3/wiki/debug.getuservalue 228 | [13]: https://github.com/keplerproject/lua-compat-5.3/wiki/debug.setuservalue 229 | [14]: https://github.com/keplerproject/lua-compat-5.3/wiki/yieldable_c_functions 230 | [15]: https://github.com/keplerproject/lua-compat-5.3/wiki/lua_dump 231 | [16]: https://github.com/keplerproject/lua-compat-5.3/wiki/lua_getuservalue 232 | [17]: https://github.com/keplerproject/lua-compat-5.3/wiki/lua_setuservalue 233 | [18]: https://github.com/keplerproject/lua-compat-5.3/wiki/lua_stringtonumber 234 | [19]: https://github.com/keplerproject/lua-compat-5.3/wiki/luaL_Stream 235 | [20]: https://github.com/keplerproject/lua-compat-5.3/wiki/lua_arith 236 | [21]: https://github.com/keplerproject/lua-compat-5.3/wiki/luaL_checkversion 237 | [22]: https://github.com/keplerproject/lua-compat-5.3/wiki/luaL_Buffer 238 | [23]: https://github.com/keplerproject/lua-compat-5.3/wiki/coroutine.running 239 | [24]: https://github.com/keplerproject/lua-compat-5.3/wiki/lua_getextraspace 240 | 241 | -------------------------------------------------------------------------------- /vendor/compat53/c-api/compat-5.3.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPAT53_H_ 2 | #define COMPAT53_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP) 8 | extern "C" { 9 | #endif 10 | #include 11 | #include 12 | #include 13 | #if defined(__cplusplus) && !defined(COMPAT53_LUA_CPP) 14 | } 15 | #endif 16 | 17 | 18 | #undef COMPAT53_INCLUDE_SOURCE 19 | #if defined(COMPAT53_PREFIX) 20 | /* - change the symbol names of functions to avoid linker conflicts 21 | * - compat-5.3.c needs to be compiled (and linked) separately 22 | */ 23 | # if !defined(COMPAT53_API) 24 | # define COMPAT53_API extern 25 | # endif 26 | #else /* COMPAT53_PREFIX */ 27 | /* - make all functions static and include the source. 28 | * - compat-5.3.c doesn't need to be compiled (and linked) separately 29 | */ 30 | # define COMPAT53_PREFIX compat53 31 | # undef COMPAT53_API 32 | # if defined(__GNUC__) || defined(__clang__) 33 | # define COMPAT53_API __attribute__((__unused__)) static 34 | # else 35 | # define COMPAT53_API static 36 | # endif 37 | # define COMPAT53_INCLUDE_SOURCE 38 | #endif /* COMPAT53_PREFIX */ 39 | 40 | #define COMPAT53_CONCAT_HELPER(a, b) a##b 41 | #define COMPAT53_CONCAT(a, b) COMPAT53_CONCAT_HELPER(a, b) 42 | 43 | 44 | 45 | /* declarations for Lua 5.1 */ 46 | #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 501 47 | 48 | /* XXX not implemented: 49 | * lua_arith (new operators) 50 | * lua_upvalueid 51 | * lua_upvaluejoin 52 | * lua_version 53 | * lua_yieldk 54 | */ 55 | 56 | #ifndef LUA_OK 57 | # define LUA_OK 0 58 | #endif 59 | #ifndef LUA_OPADD 60 | # define LUA_OPADD 0 61 | #endif 62 | #ifndef LUA_OPSUB 63 | # define LUA_OPSUB 1 64 | #endif 65 | #ifndef LUA_OPMUL 66 | # define LUA_OPMUL 2 67 | #endif 68 | #ifndef LUA_OPDIV 69 | # define LUA_OPDIV 3 70 | #endif 71 | #ifndef LUA_OPMOD 72 | # define LUA_OPMOD 4 73 | #endif 74 | #ifndef LUA_OPPOW 75 | # define LUA_OPPOW 5 76 | #endif 77 | #ifndef LUA_OPUNM 78 | # define LUA_OPUNM 6 79 | #endif 80 | #ifndef LUA_OPEQ 81 | # define LUA_OPEQ 0 82 | #endif 83 | #ifndef LUA_OPLT 84 | # define LUA_OPLT 1 85 | #endif 86 | #ifndef LUA_OPLE 87 | # define LUA_OPLE 2 88 | #endif 89 | 90 | /* LuaJIT/Lua 5.1 does not have the updated 91 | * error codes for thread status/function returns (but some patched versions do) 92 | * define it only if it's not found 93 | */ 94 | #if !defined(LUA_ERRGCMM) 95 | /* Use + 2 because in some versions of Lua (Lua 5.1) 96 | * LUA_ERRFILE is defined as (LUA_ERRERR+1) 97 | * so we need to avoid it (LuaJIT might have something at this 98 | * integer value too) 99 | */ 100 | # define LUA_ERRGCMM (LUA_ERRERR + 2) 101 | #endif /* LUA_ERRGCMM define */ 102 | 103 | typedef size_t lua_Unsigned; 104 | 105 | typedef struct luaL_Buffer_53 { 106 | luaL_Buffer b; /* make incorrect code crash! */ 107 | char *ptr; 108 | size_t nelems; 109 | size_t capacity; 110 | lua_State *L2; 111 | } luaL_Buffer_53; 112 | #define luaL_Buffer luaL_Buffer_53 113 | 114 | /* In PUC-Rio 5.1, userdata is a simple FILE* 115 | * In LuaJIT, it's a struct where the first member is a FILE* 116 | * We can't support the `closef` member 117 | */ 118 | typedef struct luaL_Stream { 119 | FILE *f; 120 | } luaL_Stream; 121 | 122 | #define lua_absindex COMPAT53_CONCAT(COMPAT53_PREFIX, _absindex) 123 | COMPAT53_API int lua_absindex (lua_State *L, int i); 124 | 125 | #define lua_arith COMPAT53_CONCAT(COMPAT53_PREFIX, _arith) 126 | COMPAT53_API void lua_arith (lua_State *L, int op); 127 | 128 | #define lua_compare COMPAT53_CONCAT(COMPAT53_PREFIX, _compare) 129 | COMPAT53_API int lua_compare (lua_State *L, int idx1, int idx2, int op); 130 | 131 | #define lua_copy COMPAT53_CONCAT(COMPAT53_PREFIX, _copy) 132 | COMPAT53_API void lua_copy (lua_State *L, int from, int to); 133 | 134 | #define lua_getuservalue(L, i) \ 135 | (lua_getfenv((L), (i)), lua_type((L), -1)) 136 | #define lua_setuservalue(L, i) \ 137 | (luaL_checktype((L), -1, LUA_TTABLE), lua_setfenv((L), (i))) 138 | 139 | #define lua_len COMPAT53_CONCAT(COMPAT53_PREFIX, _len) 140 | COMPAT53_API void lua_len (lua_State *L, int i); 141 | 142 | #define lua_pushstring(L, s) \ 143 | (lua_pushstring((L), (s)), lua_tostring((L), -1)) 144 | 145 | #define lua_pushlstring(L, s, len) \ 146 | ((((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len))), lua_tostring((L), -1)) 147 | 148 | #ifndef luaL_newlibtable 149 | # define luaL_newlibtable(L, l) \ 150 | (lua_createtable((L), 0, sizeof((l))/sizeof(*(l))-1)) 151 | #endif 152 | #ifndef luaL_newlib 153 | # define luaL_newlib(L, l) \ 154 | (luaL_newlibtable((L), (l)), luaL_register((L), NULL, (l))) 155 | #endif 156 | 157 | #define lua_pushglobaltable(L) \ 158 | lua_pushvalue((L), LUA_GLOBALSINDEX) 159 | 160 | #define lua_rawgetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawgetp) 161 | COMPAT53_API int lua_rawgetp (lua_State *L, int i, const void *p); 162 | 163 | #define lua_rawsetp COMPAT53_CONCAT(COMPAT53_PREFIX, _rawsetp) 164 | COMPAT53_API void lua_rawsetp(lua_State *L, int i, const void *p); 165 | 166 | #define lua_rawlen(L, i) lua_objlen((L), (i)) 167 | 168 | #define lua_tointeger(L, i) lua_tointegerx((L), (i), NULL) 169 | 170 | #define lua_tonumberx COMPAT53_CONCAT(COMPAT53_PREFIX, _tonumberx) 171 | COMPAT53_API lua_Number lua_tonumberx (lua_State *L, int i, int *isnum); 172 | 173 | #define luaL_checkversion COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkversion) 174 | COMPAT53_API void luaL_checkversion (lua_State *L); 175 | 176 | #define lua_load COMPAT53_CONCAT(COMPAT53_PREFIX, _load_53) 177 | COMPAT53_API int lua_load (lua_State *L, lua_Reader reader, void *data, const char* source, const char* mode); 178 | 179 | #define luaL_loadfilex COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadfilex) 180 | COMPAT53_API int luaL_loadfilex (lua_State *L, const char *filename, const char *mode); 181 | 182 | #define luaL_loadbufferx COMPAT53_CONCAT(COMPAT53_PREFIX, L_loadbufferx) 183 | COMPAT53_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t sz, const char *name, const char *mode); 184 | 185 | #define luaL_checkstack COMPAT53_CONCAT(COMPAT53_PREFIX, L_checkstack_53) 186 | COMPAT53_API void luaL_checkstack (lua_State *L, int sp, const char *msg); 187 | 188 | #define luaL_getsubtable COMPAT53_CONCAT(COMPAT53_PREFIX, L_getsubtable) 189 | COMPAT53_API int luaL_getsubtable (lua_State* L, int i, const char *name); 190 | 191 | #define luaL_len COMPAT53_CONCAT(COMPAT53_PREFIX, L_len) 192 | COMPAT53_API lua_Integer luaL_len (lua_State *L, int i); 193 | 194 | #define luaL_setfuncs COMPAT53_CONCAT(COMPAT53_PREFIX, L_setfuncs) 195 | COMPAT53_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup); 196 | 197 | #define luaL_setmetatable COMPAT53_CONCAT(COMPAT53_PREFIX, L_setmetatable) 198 | COMPAT53_API void luaL_setmetatable (lua_State *L, const char *tname); 199 | 200 | #define luaL_testudata COMPAT53_CONCAT(COMPAT53_PREFIX, L_testudata) 201 | COMPAT53_API void *luaL_testudata (lua_State *L, int i, const char *tname); 202 | 203 | #define luaL_traceback COMPAT53_CONCAT(COMPAT53_PREFIX, L_traceback) 204 | COMPAT53_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg, int level); 205 | 206 | #define luaL_fileresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_fileresult) 207 | COMPAT53_API int luaL_fileresult (lua_State *L, int stat, const char *fname); 208 | 209 | #define luaL_execresult COMPAT53_CONCAT(COMPAT53_PREFIX, L_execresult) 210 | COMPAT53_API int luaL_execresult (lua_State *L, int stat); 211 | 212 | #define lua_callk(L, na, nr, ctx, cont) \ 213 | ((void)(ctx), (void)(cont), lua_call((L), (na), (nr))) 214 | #define lua_pcallk(L, na, nr, err, ctx, cont) \ 215 | ((void)(ctx), (void)(cont), lua_pcall((L), (na), (nr), (err))) 216 | 217 | #define lua_resume(L, from, nargs) \ 218 | ((void)(from), lua_resume((L), (nargs))) 219 | 220 | #define luaL_buffinit COMPAT53_CONCAT(COMPAT53_PREFIX, _buffinit_53) 221 | COMPAT53_API void luaL_buffinit (lua_State *L, luaL_Buffer_53 *B); 222 | 223 | #define luaL_prepbuffsize COMPAT53_CONCAT(COMPAT53_PREFIX, _prepbufsize_53) 224 | COMPAT53_API char *luaL_prepbuffsize (luaL_Buffer_53 *B, size_t s); 225 | 226 | #define luaL_addlstring COMPAT53_CONCAT(COMPAT53_PREFIX, _addlstring_53) 227 | COMPAT53_API void luaL_addlstring (luaL_Buffer_53 *B, const char *s, size_t l); 228 | 229 | #define luaL_addvalue COMPAT53_CONCAT(COMPAT53_PREFIX, _addvalue_53) 230 | COMPAT53_API void luaL_addvalue (luaL_Buffer_53 *B); 231 | 232 | #define luaL_pushresult COMPAT53_CONCAT(COMPAT53_PREFIX, _pushresult_53) 233 | COMPAT53_API void luaL_pushresult (luaL_Buffer_53 *B); 234 | 235 | #undef luaL_buffinitsize 236 | #define luaL_buffinitsize(L, B, s) \ 237 | (luaL_buffinit((L), (B)), luaL_prepbuffsize((B), (s))) 238 | 239 | #undef luaL_prepbuffer 240 | #define luaL_prepbuffer(B) \ 241 | luaL_prepbuffsize((B), LUAL_BUFFERSIZE) 242 | 243 | #undef luaL_addchar 244 | #define luaL_addchar(B, c) \ 245 | ((void)((B)->nelems < (B)->capacity || luaL_prepbuffsize((B), 1)), \ 246 | ((B)->ptr[(B)->nelems++] = (c))) 247 | 248 | #undef luaL_addsize 249 | #define luaL_addsize(B, s) \ 250 | ((B)->nelems += (s)) 251 | 252 | #undef luaL_addstring 253 | #define luaL_addstring(B, s) \ 254 | luaL_addlstring((B), (s), strlen((s))) 255 | 256 | #undef luaL_pushresultsize 257 | #define luaL_pushresultsize(B, s) \ 258 | (luaL_addsize((B), (s)), luaL_pushresult((B))) 259 | 260 | #if defined(LUA_COMPAT_APIINTCASTS) 261 | #define lua_pushunsigned(L, n) \ 262 | lua_pushinteger((L), (lua_Integer)(n)) 263 | #define lua_tounsignedx(L, i, is) \ 264 | ((lua_Unsigned)lua_tointegerx((L), (i), (is))) 265 | #define lua_tounsigned(L, i) \ 266 | lua_tounsignedx((L), (i), NULL) 267 | #define luaL_checkunsigned(L, a) \ 268 | ((lua_Unsigned)luaL_checkinteger((L), (a))) 269 | #define luaL_optunsigned(L, a, d) \ 270 | ((lua_Unsigned)luaL_optinteger((L), (a), (lua_Integer)(d))) 271 | #endif 272 | 273 | #endif /* Lua 5.1 only */ 274 | 275 | 276 | 277 | /* declarations for Lua 5.1 and 5.2 */ 278 | #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM <= 502 279 | 280 | typedef int lua_KContext; 281 | 282 | typedef int (*lua_KFunction)(lua_State *L, int status, lua_KContext ctx); 283 | 284 | #define lua_dump(L, w, d, s) \ 285 | ((void)(s), lua_dump((L), (w), (d))) 286 | 287 | #define lua_getfield(L, i, k) \ 288 | (lua_getfield((L), (i), (k)), lua_type((L), -1)) 289 | 290 | #define lua_gettable(L, i) \ 291 | (lua_gettable((L), (i)), lua_type((L), -1)) 292 | 293 | #define lua_geti COMPAT53_CONCAT(COMPAT53_PREFIX, _geti) 294 | COMPAT53_API int lua_geti (lua_State *L, int index, lua_Integer i); 295 | 296 | #define lua_getextraspace COMPAT53_CONCAT(COMPAT53_PREFIX, _getextraspace) 297 | COMPAT53_API void *lua_getextraspace (lua_State *L); 298 | 299 | #define lua_isinteger COMPAT53_CONCAT(COMPAT53_PREFIX, _isinteger) 300 | COMPAT53_API int lua_isinteger (lua_State *L, int index); 301 | 302 | #define lua_tointegerx COMPAT53_CONCAT(COMPAT53_PREFIX, _tointegerx_53) 303 | COMPAT53_API lua_Integer lua_tointegerx (lua_State *L, int i, int *isnum); 304 | 305 | #define lua_numbertointeger(n, p) \ 306 | ((*(p) = (lua_Integer)(n)), 1) 307 | 308 | #define lua_rawget(L, i) \ 309 | (lua_rawget((L), (i)), lua_type((L), -1)) 310 | 311 | #define lua_rawgeti(L, i, n) \ 312 | (lua_rawgeti((L), (i), (n)), lua_type((L), -1)) 313 | 314 | #define lua_rotate COMPAT53_CONCAT(COMPAT53_PREFIX, _rotate) 315 | COMPAT53_API void lua_rotate (lua_State *L, int idx, int n); 316 | 317 | #define lua_seti COMPAT53_CONCAT(COMPAT53_PREFIX, _seti) 318 | COMPAT53_API void lua_seti (lua_State *L, int index, lua_Integer i); 319 | 320 | #define lua_stringtonumber COMPAT53_CONCAT(COMPAT53_PREFIX, _stringtonumber) 321 | COMPAT53_API size_t lua_stringtonumber (lua_State *L, const char *s); 322 | 323 | #define luaL_tolstring COMPAT53_CONCAT(COMPAT53_PREFIX, L_tolstring) 324 | COMPAT53_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len); 325 | 326 | #define luaL_getmetafield(L, o, e) \ 327 | (luaL_getmetafield((L), (o), (e)) ? lua_type((L), -1) : LUA_TNIL) 328 | 329 | #define luaL_newmetatable(L, tn) \ 330 | (luaL_newmetatable((L), (tn)) ? (lua_pushstring((L), (tn)), lua_setfield((L), -2, "__name"), 1) : 0) 331 | 332 | #define luaL_requiref COMPAT53_CONCAT(COMPAT53_PREFIX, L_requiref_53) 333 | COMPAT53_API void luaL_requiref (lua_State *L, const char *modname, 334 | lua_CFunction openf, int glb ); 335 | 336 | #endif /* Lua 5.1 and Lua 5.2 */ 337 | 338 | 339 | 340 | /* declarations for Lua 5.2 */ 341 | #if defined(LUA_VERSION_NUM) && LUA_VERSION_NUM == 502 342 | 343 | /* XXX not implemented: 344 | * lua_isyieldable 345 | * lua_arith (new operators) 346 | * lua_pushfstring (new formats) 347 | */ 348 | 349 | #define lua_getglobal(L, n) \ 350 | (lua_getglobal((L), (n)), lua_type((L), -1)) 351 | 352 | #define lua_getuservalue(L, i) \ 353 | (lua_getuservalue((L), (i)), lua_type((L), -1)) 354 | 355 | #define lua_pushlstring(L, s, len) \ 356 | (((len) == 0) ? lua_pushlstring((L), "", 0) : lua_pushlstring((L), (s), (len))) 357 | 358 | #define lua_rawgetp(L, i, p) \ 359 | (lua_rawgetp((L), (i), (p)), lua_type((L), -1)) 360 | 361 | #define LUA_KFUNCTION(_name) \ 362 | static int (_name)(lua_State *L, int status, lua_KContext ctx); \ 363 | static int (_name ## _52)(lua_State *L) { \ 364 | lua_KContext ctx; \ 365 | int status = lua_getctx(L, &ctx); \ 366 | return (_name)(L, status, ctx); \ 367 | } \ 368 | static int (_name)(lua_State *L, int status, lua_KContext ctx) 369 | 370 | #define lua_pcallk(L, na, nr, err, ctx, cont) \ 371 | lua_pcallk((L), (na), (nr), (err), (ctx), cont ## _52) 372 | 373 | #define lua_callk(L, na, nr, ctx, cont) \ 374 | lua_callk((L), (na), (nr), (ctx), cont ## _52) 375 | 376 | #define lua_yieldk(L, nr, ctx, cont) \ 377 | lua_yieldk((L), (nr), (ctx), cont ## _52) 378 | 379 | #ifdef lua_call 380 | # undef lua_call 381 | # define lua_call(L, na, nr) \ 382 | (lua_callk)((L), (na), (nr), 0, NULL) 383 | #endif 384 | 385 | #ifdef lua_pcall 386 | # undef lua_pcall 387 | # define lua_pcall(L, na, nr, err) \ 388 | (lua_pcallk)((L), (na), (nr), (err), 0, NULL) 389 | #endif 390 | 391 | #ifdef lua_yield 392 | # undef lua_yield 393 | # define lua_yield(L, nr) \ 394 | (lua_yieldk)((L), (nr), 0, NULL) 395 | #endif 396 | 397 | #endif /* Lua 5.2 only */ 398 | 399 | 400 | 401 | /* other Lua versions */ 402 | #if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501 || LUA_VERSION_NUM > 504 403 | 404 | # error "unsupported Lua version (i.e. not Lua 5.1, 5.2, 5.3, or 5.4)" 405 | 406 | #endif /* other Lua versions except 5.1, 5.2, 5.3, and 5.4 */ 407 | 408 | 409 | 410 | /* helper macro for defining continuation functions (for every version 411 | * *except* Lua 5.2) */ 412 | #ifndef LUA_KFUNCTION 413 | #define LUA_KFUNCTION(_name) \ 414 | static int (_name)(lua_State *L, int status, lua_KContext ctx) 415 | #endif 416 | 417 | 418 | #if defined(COMPAT53_INCLUDE_SOURCE) 419 | # include "compat-5.3.c" 420 | #endif 421 | 422 | 423 | #endif /* COMPAT53_H_ */ 424 | 425 | -------------------------------------------------------------------------------- /vendor/compat53/compat53/init.lua: -------------------------------------------------------------------------------- 1 | local lua_version = _VERSION:sub(-3) 2 | 3 | 4 | if lua_version < "5.3" then 5 | 6 | local _G, pairs, require, select, type = 7 | _G, pairs, require, select, type 8 | local debug, io = debug, io 9 | local unpack = lua_version == "5.1" and unpack or table.unpack 10 | 11 | local M = require("compat53.module") 12 | 13 | -- select the most powerful getmetatable function available 14 | local gmt = type(debug) == "table" and debug.getmetatable or 15 | getmetatable or function() return false end 16 | -- metatable for file objects from Lua's standard io library 17 | local file_meta = gmt(io.stdout) 18 | 19 | 20 | -- make '*' optional for file:read and file:lines 21 | if type(file_meta) == "table" and type(file_meta.__index) == "table" then 22 | 23 | local function addasterisk(fmt) 24 | if type(fmt) == "string" and fmt:sub(1, 1) ~= "*" then 25 | return "*"..fmt 26 | else 27 | return fmt 28 | end 29 | end 30 | 31 | local file_lines = file_meta.__index.lines 32 | file_meta.__index.lines = function(self, ...) 33 | local n = select('#', ...) 34 | for i = 1, n do 35 | local a = select(i, ...) 36 | local b = addasterisk(a) 37 | -- as an optimization we only allocate a table for the 38 | -- modified format arguments when we have a '*' somewhere 39 | if a ~= b then 40 | local args = { ... } 41 | args[i] = b 42 | for j = i+1, n do 43 | args[j] = addasterisk(args[j]) 44 | end 45 | return file_lines(self, unpack(args, 1, n)) 46 | end 47 | end 48 | return file_lines(self, ...) 49 | end 50 | 51 | local file_read = file_meta.__index.read 52 | file_meta.__index.read = function(self, ...) 53 | local n = select('#', ...) 54 | for i = 1, n do 55 | local a = select(i, ...) 56 | local b = addasterisk(a) 57 | -- as an optimization we only allocate a table for the 58 | -- modified format arguments when we have a '*' somewhere 59 | if a ~= b then 60 | local args = { ... } 61 | args[i] = b 62 | for j = i+1, n do 63 | args[j] = addasterisk(args[j]) 64 | end 65 | return file_read(self, unpack(args, 1, n)) 66 | end 67 | end 68 | return file_read(self, ...) 69 | end 70 | 71 | end -- got a valid metatable for file objects 72 | 73 | 74 | -- changes for Lua 5.1 only 75 | if lua_version == "5.1" then 76 | 77 | -- cache globals 78 | local error, pcall, rawset, setmetatable, tostring, xpcall = 79 | error, pcall, rawset, setmetatable, tostring, xpcall 80 | local coroutine, package, string = coroutine, package, string 81 | local coroutine_resume = coroutine.resume 82 | local coroutine_running = coroutine.running 83 | local coroutine_status = coroutine.status 84 | local coroutine_yield = coroutine.yield 85 | local io_type = io.type 86 | 87 | 88 | -- detect LuaJIT (including LUAJIT_ENABLE_LUA52COMPAT compilation flag) 89 | local is_luajit = (string.dump(function() end) or ""):sub(1, 3) == "\027LJ" 90 | local is_luajit52 = is_luajit and 91 | #setmetatable({}, { __len = function() return 1 end }) == 1 92 | 93 | 94 | -- make package.searchers available as an alias for package.loaders 95 | local p_index = { searchers = package.loaders } 96 | setmetatable(package, { 97 | __index = p_index, 98 | __newindex = function(p, k, v) 99 | if k == "searchers" then 100 | rawset(p, "loaders", v) 101 | p_index.searchers = v 102 | else 103 | rawset(p, k, v) 104 | end 105 | end 106 | }) 107 | 108 | 109 | if type(file_meta) == "table" and type(file_meta.__index) == "table" then 110 | if not is_luajit then 111 | local function helper(_, var_1, ...) 112 | if var_1 == nil then 113 | if (...) ~= nil then 114 | error((...), 2) 115 | end 116 | end 117 | return var_1, ... 118 | end 119 | 120 | local function lines_iterator(st) 121 | return helper(st, st.f:read(unpack(st, 1, st.n))) 122 | end 123 | 124 | local file_write = file_meta.__index.write 125 | file_meta.__index.write = function(self, ...) 126 | local res, msg, errno = file_write(self, ...) 127 | if res then 128 | return self 129 | else 130 | return nil, msg, errno 131 | end 132 | end 133 | 134 | file_meta.__index.lines = function(self, ...) 135 | if io_type(self) == "closed file" then 136 | error("attempt to use a closed file", 2) 137 | end 138 | local st = { f=self, n=select('#', ...), ... } 139 | for i = 1, st.n do 140 | local t = type(st[i]) 141 | if t == "string" then 142 | local fmt = st[i]:match("^*?([aln])") 143 | if not fmt then 144 | error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2) 145 | end 146 | st[i] = "*"..fmt 147 | elseif t ~= "number" then 148 | error("bad argument #"..(i+1).." to 'for iterator' (invalid format)", 2) 149 | end 150 | end 151 | return lines_iterator, st 152 | end 153 | end -- not luajit 154 | end -- file_meta valid 155 | 156 | 157 | -- the (x)pcall implementations start a new coroutine internally 158 | -- to allow yielding even in Lua 5.1. to allow for accurate 159 | -- stack traces we keep track of the nested coroutine activations 160 | -- in the weak tables below: 161 | local weak_meta = { __mode = "kv" } 162 | -- maps the internal pcall coroutines to the user coroutine that 163 | -- *should* be running if pcall didn't use coroutines internally 164 | local pcall_mainOf = setmetatable({}, weak_meta) 165 | -- table that maps each running coroutine started by pcall to 166 | -- the coroutine that resumed it (user coroutine *or* pcall 167 | -- coroutine!) 168 | local pcall_previous = setmetatable({}, weak_meta) 169 | -- reverse of `pcall_mainOf`. maps a user coroutine to the 170 | -- currently active pcall coroutine started within it 171 | local pcall_callOf = setmetatable({}, weak_meta) 172 | -- similar to `pcall_mainOf` but is used only while executing 173 | -- the error handler of xpcall (thus no nesting is necessary!) 174 | local xpcall_running = setmetatable({}, weak_meta) 175 | 176 | -- handle debug functions 177 | if type(debug) == "table" then 178 | local debug_getinfo = debug.getinfo 179 | local debug_traceback = debug.traceback 180 | 181 | if not is_luajit then 182 | local function calculate_trace_level(co, level) 183 | if level ~= nil then 184 | for out = 1, 1/0 do 185 | local info = (co==nil) and debug_getinfo(out, "") or debug_getinfo(co, out, "") 186 | if info == nil then 187 | local max = out-1 188 | if level <= max then 189 | return level 190 | end 191 | return nil, level-max 192 | end 193 | end 194 | end 195 | return 1 196 | end 197 | 198 | local stack_pattern = "\nstack traceback:" 199 | local stack_replace = "" 200 | function debug.traceback(co, msg, level) 201 | local lvl 202 | local nilmsg 203 | if type(co) ~= "thread" then 204 | co, msg, level = coroutine_running(), co, msg 205 | end 206 | if msg == nil then 207 | msg = "" 208 | nilmsg = true 209 | elseif type(msg) ~= "string" then 210 | return msg 211 | end 212 | if co == nil then 213 | msg = debug_traceback(msg, level or 1) 214 | else 215 | local xpco = xpcall_running[co] 216 | if xpco ~= nil then 217 | lvl, level = calculate_trace_level(xpco, level) 218 | if lvl then 219 | msg = debug_traceback(xpco, msg, lvl) 220 | else 221 | msg = msg..stack_pattern 222 | end 223 | lvl, level = calculate_trace_level(co, level) 224 | if lvl then 225 | local trace = debug_traceback(co, "", lvl) 226 | msg = msg..trace:gsub(stack_pattern, stack_replace) 227 | end 228 | else 229 | co = pcall_callOf[co] or co 230 | lvl, level = calculate_trace_level(co, level) 231 | if lvl then 232 | msg = debug_traceback(co, msg, lvl) 233 | else 234 | msg = msg..stack_pattern 235 | end 236 | end 237 | co = pcall_previous[co] 238 | while co ~= nil do 239 | lvl, level = calculate_trace_level(co, level) 240 | if lvl then 241 | local trace = debug_traceback(co, "", lvl) 242 | msg = msg..trace:gsub(stack_pattern, stack_replace) 243 | end 244 | co = pcall_previous[co] 245 | end 246 | end 247 | if nilmsg then 248 | msg = msg:gsub("^\n", "") 249 | end 250 | msg = msg:gsub("\n\t%(tail call%): %?", "\000") 251 | msg = msg:gsub("\n\t%.%.%.\n", "\001\n") 252 | msg = msg:gsub("\n\t%.%.%.$", "\001") 253 | msg = msg:gsub("(%z+)\001(%z+)", function(some, other) 254 | return "\n\t(..."..#some+#other.."+ tail call(s)...)" 255 | end) 256 | msg = msg:gsub("\001(%z+)", function(zeros) 257 | return "\n\t(..."..#zeros.."+ tail call(s)...)" 258 | end) 259 | msg = msg:gsub("(%z+)\001", function(zeros) 260 | return "\n\t(..."..#zeros.."+ tail call(s)...)" 261 | end) 262 | msg = msg:gsub("%z+", function(zeros) 263 | return "\n\t(..."..#zeros.." tail call(s)...)" 264 | end) 265 | msg = msg:gsub("\001", function() 266 | return "\n\t..." 267 | end) 268 | return msg 269 | end 270 | end -- is not luajit 271 | end -- debug table available 272 | 273 | 274 | if not is_luajit52 then 275 | local coroutine_running52 = M.coroutine.running 276 | function M.coroutine.running() 277 | local co, ismain = coroutine_running52() 278 | if ismain then 279 | return co, true 280 | else 281 | return pcall_mainOf[co] or co, false 282 | end 283 | end 284 | end 285 | 286 | if not is_luajit then 287 | local function pcall_results(current, call, success, ...) 288 | if coroutine_status(call) == "suspended" then 289 | return pcall_results(current, call, coroutine_resume(call, coroutine_yield(...))) 290 | end 291 | if pcall_previous then 292 | pcall_previous[call] = nil 293 | local main = pcall_mainOf[call] 294 | if main == current then current = nil end 295 | pcall_callOf[main] = current 296 | end 297 | pcall_mainOf[call] = nil 298 | return success, ... 299 | end 300 | 301 | local function pcall_exec(current, call, ...) 302 | local main = pcall_mainOf[current] or current 303 | pcall_mainOf[call] = main 304 | if pcall_previous then 305 | pcall_previous[call] = current 306 | pcall_callOf[main] = call 307 | end 308 | return pcall_results(current, call, coroutine_resume(call, ...)) 309 | end 310 | 311 | local coroutine_create52 = M.coroutine.create 312 | 313 | local function pcall_coroutine(func) 314 | if type(func) ~= "function" then 315 | local callable = func 316 | func = function (...) return callable(...) end 317 | end 318 | return coroutine_create52(func) 319 | end 320 | 321 | function M.pcall(func, ...) 322 | local current = coroutine_running() 323 | if not current then return pcall(func, ...) end 324 | return pcall_exec(current, pcall_coroutine(func), ...) 325 | end 326 | 327 | local function xpcall_catch(current, call, msgh, success, ...) 328 | if not success then 329 | xpcall_running[current] = call 330 | local ok, result = pcall(msgh, ...) 331 | xpcall_running[current] = nil 332 | if not ok then 333 | return false, "error in error handling ("..tostring(result)..")" 334 | end 335 | return false, result 336 | end 337 | return true, ... 338 | end 339 | 340 | function M.xpcall(f, msgh, ...) 341 | local current = coroutine_running() 342 | if not current then 343 | local args, n = { ... }, select('#', ...) 344 | return xpcall(function() return f(unpack(args, 1, n)) end, msgh) 345 | end 346 | local call = pcall_coroutine(f) 347 | return xpcall_catch(current, call, msgh, pcall_exec(current, call, ...)) 348 | end 349 | end -- not luajit 350 | 351 | end -- lua 5.1 352 | 353 | 354 | -- handle exporting to global scope 355 | local function extend_table(from, to) 356 | if from ~= to then 357 | for k,v in pairs(from) do 358 | if type(v) == "table" and 359 | type(to[k]) == "table" and 360 | v ~= to[k] then 361 | extend_table(v, to[k]) 362 | else 363 | to[k] = v 364 | end 365 | end 366 | end 367 | end 368 | 369 | extend_table(M, _G) 370 | 371 | end -- lua < 5.3 372 | 373 | -- vi: set expandtab softtabstop=3 shiftwidth=3 : 374 | -------------------------------------------------------------------------------- /vendor/compat53/lbitlib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lbitlib.c,v 1.30.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Standard library for bitwise operations 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lbitlib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include "lua.h" 14 | 15 | #include "lauxlib.h" 16 | #include "lualib.h" 17 | 18 | 19 | #if defined(LUA_COMPAT_BITLIB) /* { */ 20 | 21 | 22 | #define pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n)) 23 | #define checkunsigned(L,i) ((lua_Unsigned)luaL_checkinteger(L,i)) 24 | 25 | 26 | /* number of bits to consider in a number */ 27 | #if !defined(LUA_NBITS) 28 | #define LUA_NBITS 32 29 | #endif 30 | 31 | 32 | /* 33 | ** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must 34 | ** be made in two parts to avoid problems when LUA_NBITS is equal to the 35 | ** number of bits in a lua_Unsigned.) 36 | */ 37 | #define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) 38 | 39 | 40 | /* macro to trim extra bits */ 41 | #define trim(x) ((x) & ALLONES) 42 | 43 | 44 | /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ 45 | #define mask(n) (~((ALLONES << 1) << ((n) - 1))) 46 | 47 | 48 | 49 | static lua_Unsigned andaux (lua_State *L) { 50 | int i, n = lua_gettop(L); 51 | lua_Unsigned r = ~(lua_Unsigned)0; 52 | for (i = 1; i <= n; i++) 53 | r &= checkunsigned(L, i); 54 | return trim(r); 55 | } 56 | 57 | 58 | static int b_and (lua_State *L) { 59 | lua_Unsigned r = andaux(L); 60 | pushunsigned(L, r); 61 | return 1; 62 | } 63 | 64 | 65 | static int b_test (lua_State *L) { 66 | lua_Unsigned r = andaux(L); 67 | lua_pushboolean(L, r != 0); 68 | return 1; 69 | } 70 | 71 | 72 | static int b_or (lua_State *L) { 73 | int i, n = lua_gettop(L); 74 | lua_Unsigned r = 0; 75 | for (i = 1; i <= n; i++) 76 | r |= checkunsigned(L, i); 77 | pushunsigned(L, trim(r)); 78 | return 1; 79 | } 80 | 81 | 82 | static int b_xor (lua_State *L) { 83 | int i, n = lua_gettop(L); 84 | lua_Unsigned r = 0; 85 | for (i = 1; i <= n; i++) 86 | r ^= checkunsigned(L, i); 87 | pushunsigned(L, trim(r)); 88 | return 1; 89 | } 90 | 91 | 92 | static int b_not (lua_State *L) { 93 | lua_Unsigned r = ~checkunsigned(L, 1); 94 | pushunsigned(L, trim(r)); 95 | return 1; 96 | } 97 | 98 | 99 | static int b_shift (lua_State *L, lua_Unsigned r, lua_Integer i) { 100 | if (i < 0) { /* shift right? */ 101 | i = -i; 102 | r = trim(r); 103 | if (i >= LUA_NBITS) r = 0; 104 | else r >>= i; 105 | } 106 | else { /* shift left */ 107 | if (i >= LUA_NBITS) r = 0; 108 | else r <<= i; 109 | r = trim(r); 110 | } 111 | pushunsigned(L, r); 112 | return 1; 113 | } 114 | 115 | 116 | static int b_lshift (lua_State *L) { 117 | return b_shift(L, checkunsigned(L, 1), luaL_checkinteger(L, 2)); 118 | } 119 | 120 | 121 | static int b_rshift (lua_State *L) { 122 | return b_shift(L, checkunsigned(L, 1), -luaL_checkinteger(L, 2)); 123 | } 124 | 125 | 126 | static int b_arshift (lua_State *L) { 127 | lua_Unsigned r = checkunsigned(L, 1); 128 | lua_Integer i = luaL_checkinteger(L, 2); 129 | if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1)))) 130 | return b_shift(L, r, -i); 131 | else { /* arithmetic shift for 'negative' number */ 132 | if (i >= LUA_NBITS) r = ALLONES; 133 | else 134 | r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */ 135 | pushunsigned(L, r); 136 | return 1; 137 | } 138 | } 139 | 140 | 141 | static int b_rot (lua_State *L, lua_Integer d) { 142 | lua_Unsigned r = checkunsigned(L, 1); 143 | int i = d & (LUA_NBITS - 1); /* i = d % NBITS */ 144 | r = trim(r); 145 | if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ 146 | r = (r << i) | (r >> (LUA_NBITS - i)); 147 | pushunsigned(L, trim(r)); 148 | return 1; 149 | } 150 | 151 | 152 | static int b_lrot (lua_State *L) { 153 | return b_rot(L, luaL_checkinteger(L, 2)); 154 | } 155 | 156 | 157 | static int b_rrot (lua_State *L) { 158 | return b_rot(L, -luaL_checkinteger(L, 2)); 159 | } 160 | 161 | 162 | /* 163 | ** get field and width arguments for field-manipulation functions, 164 | ** checking whether they are valid. 165 | ** ('luaL_error' called without 'return' to avoid later warnings about 166 | ** 'width' being used uninitialized.) 167 | */ 168 | static int fieldargs (lua_State *L, int farg, int *width) { 169 | lua_Integer f = luaL_checkinteger(L, farg); 170 | lua_Integer w = luaL_optinteger(L, farg + 1, 1); 171 | luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); 172 | luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); 173 | if (f + w > LUA_NBITS) 174 | luaL_error(L, "trying to access non-existent bits"); 175 | *width = (int)w; 176 | return (int)f; 177 | } 178 | 179 | 180 | static int b_extract (lua_State *L) { 181 | int w; 182 | lua_Unsigned r = trim(checkunsigned(L, 1)); 183 | int f = fieldargs(L, 2, &w); 184 | r = (r >> f) & mask(w); 185 | pushunsigned(L, r); 186 | return 1; 187 | } 188 | 189 | 190 | static int b_replace (lua_State *L) { 191 | int w; 192 | lua_Unsigned r = trim(checkunsigned(L, 1)); 193 | lua_Unsigned v = trim(checkunsigned(L, 2)); 194 | int f = fieldargs(L, 3, &w); 195 | lua_Unsigned m = mask(w); 196 | r = (r & ~(m << f)) | ((v & m) << f); 197 | pushunsigned(L, r); 198 | return 1; 199 | } 200 | 201 | 202 | static const luaL_Reg bitlib[] = { 203 | {"arshift", b_arshift}, 204 | {"band", b_and}, 205 | {"bnot", b_not}, 206 | {"bor", b_or}, 207 | {"bxor", b_xor}, 208 | {"btest", b_test}, 209 | {"extract", b_extract}, 210 | {"lrotate", b_lrot}, 211 | {"lshift", b_lshift}, 212 | {"replace", b_replace}, 213 | {"rrotate", b_rrot}, 214 | {"rshift", b_rshift}, 215 | {NULL, NULL} 216 | }; 217 | 218 | 219 | 220 | LUAMOD_API int luaopen_bit32 (lua_State *L) { 221 | luaL_newlib(L, bitlib); 222 | return 1; 223 | } 224 | 225 | 226 | #else /* }{ */ 227 | 228 | 229 | LUAMOD_API int luaopen_bit32 (lua_State *L) { 230 | return luaL_error(L, "library 'bit32' has been deprecated"); 231 | } 232 | 233 | #endif /* } */ 234 | -------------------------------------------------------------------------------- /vendor/compat53/lprefix.h: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lprefix.h,v 1.2 2014/12/29 16:54:13 roberto Exp $ 3 | ** Definitions for Lua code that must come before any other header file 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #ifndef lprefix_h 8 | #define lprefix_h 9 | 10 | 11 | /* 12 | ** Allows POSIX/XSI stuff 13 | */ 14 | #if !defined(LUA_USE_C89) /* { */ 15 | 16 | #if !defined(_XOPEN_SOURCE) 17 | #define _XOPEN_SOURCE 600 18 | #elif _XOPEN_SOURCE == 0 19 | #undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ 20 | #endif 21 | 22 | /* 23 | ** Allows manipulation of large files in gcc and some other compilers 24 | */ 25 | #if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) 26 | #define _LARGEFILE_SOURCE 1 27 | #define _FILE_OFFSET_BITS 64 28 | #endif 29 | 30 | #endif /* } */ 31 | 32 | 33 | /* 34 | ** Windows stuff 35 | */ 36 | #if defined(_WIN32) /* { */ 37 | 38 | #if !defined(_CRT_SECURE_NO_WARNINGS) 39 | #define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ 40 | #endif 41 | 42 | #endif /* } */ 43 | 44 | 45 | /* COMPAT53 adaptation */ 46 | #include "c-api/compat-5.3.h" 47 | 48 | #undef LUAMOD_API 49 | #define LUAMOD_API extern 50 | 51 | 52 | #ifdef lutf8lib_c 53 | # define luaopen_utf8 luaopen_compat53_utf8 54 | /* we don't support the %U format string of lua_pushfstring! 55 | * code below adapted from the Lua 5.3 sources: 56 | */ 57 | static const char *compat53_utf8_escape (lua_State* L, long x) { 58 | if (x < 0x80) { /* ASCII */ 59 | char c = (char)x; 60 | lua_pushlstring(L, &c, 1); 61 | } else { 62 | char buff[8] = { 0 }; 63 | unsigned int mfb = 0x3f; 64 | int n = 1; 65 | do { 66 | buff[8 - (n++)] = (char)(0x80|(x & 0x3f)); 67 | x >>= 6; 68 | mfb >>= 1; 69 | } while (x > mfb); 70 | buff[8-n] = (char)((~mfb << 1) | x); 71 | lua_pushlstring(L, buff+8-n, n); 72 | } 73 | return lua_tostring(L, -1); 74 | } 75 | # define lua_pushfstring(L, fmt, l) \ 76 | compat53_utf8_escape(L, l) 77 | #endif 78 | 79 | 80 | #ifdef ltablib_c 81 | # define luaopen_table luaopen_compat53_table 82 | # ifndef LUA_MAXINTEGER 83 | /* conservative estimate: */ 84 | # define LUA_MAXINTEGER INT_MAX 85 | # endif 86 | #endif /* ltablib_c */ 87 | 88 | 89 | #ifdef lstrlib_c 90 | #include 91 | #include 92 | /* move the string library open function out of the way (we only take 93 | * the string packing functions)! 94 | */ 95 | # define luaopen_string luaopen_string_XXX 96 | /* used in string.format implementation, which we don't use: */ 97 | # ifndef LUA_INTEGER_FRMLEN 98 | # define LUA_INTEGER_FRMLEN "" 99 | # define LUA_NUMBER_FRMLEN "" 100 | # endif 101 | # ifndef LUA_MININTEGER 102 | # define LUA_MININTEGER 0 103 | # endif 104 | # ifndef LUA_INTEGER_FMT 105 | # define LUA_INTEGER_FMT "%d" 106 | # endif 107 | # ifndef LUAI_UACINT 108 | # define LUAI_UACINT lua_Integer 109 | # endif 110 | /* different Lua 5.3 versions have conflicting variants of this macro 111 | * in luaconf.h, there's a fallback implementation in lstrlib.c, and 112 | * the macro isn't used for string (un)packing anyway! 113 | * */ 114 | # undef lua_number2strx 115 | # if LUA_VERSION_NUM < 503 116 | /* lstrlib assumes that lua_Integer and lua_Unsigned have the same 117 | * size, so we use the unsigned equivalent of ptrdiff_t! */ 118 | # define lua_Unsigned size_t 119 | # endif 120 | # ifndef l_mathlim 121 | # ifdef LUA_NUMBER_DOUBLE 122 | # define l_mathlim(n) (DBL_##n) 123 | # else 124 | # define l_mathlim(n) (FLT_##n) 125 | # endif 126 | # endif 127 | # ifndef l_mathop 128 | # ifdef LUA_NUMBER_DOUBLE 129 | # define l_mathop(op) op 130 | # else 131 | # define l_mathop(op) op##f 132 | # endif 133 | # endif 134 | # ifndef lua_getlocaledecpoint 135 | # define lua_getlocaledecpoint() (localeconv()->decimal_point[0]) 136 | # endif 137 | # ifndef l_sprintf 138 | # if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L 139 | # define l_sprintf(s,sz,f,i) (snprintf(s, sz, f, i)) 140 | # else 141 | # define l_sprintf(s,sz,f,i) ((void)(sz), sprintf(s, f, i)) 142 | # endif 143 | # endif 144 | 145 | static int str_pack (lua_State *L); 146 | static int str_packsize (lua_State *L); 147 | static int str_unpack (lua_State *L); 148 | LUAMOD_API int luaopen_compat53_string (lua_State *L) { 149 | luaL_Reg const funcs[] = { 150 | { "pack", str_pack }, 151 | { "packsize", str_packsize }, 152 | { "unpack", str_unpack }, 153 | { NULL, NULL } 154 | }; 155 | luaL_newlib(L, funcs); 156 | return 1; 157 | } 158 | /* fake CLANG feature detection on other compilers */ 159 | # ifndef __has_attribute 160 | # define __has_attribute(x) 0 161 | # endif 162 | /* make luaopen_string(_XXX) static, so it (and all other referenced 163 | * string functions) won't be included in the resulting dll 164 | * (hopefully). 165 | */ 166 | # undef LUAMOD_API 167 | # if defined(__GNUC__) || __has_attribute(__unused__) 168 | # define LUAMOD_API __attribute__((__unused__)) static 169 | # else 170 | # define LUAMOD_API static 171 | # endif 172 | #endif /* lstrlib.c */ 173 | 174 | #endif 175 | 176 | -------------------------------------------------------------------------------- /vendor/compat53/ltablib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: ltablib.c,v 1.93.1.1 2017/04/19 17:20:42 roberto Exp $ 3 | ** Library for Table Manipulation 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define ltablib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | #include "lua.h" 18 | 19 | #include "lauxlib.h" 20 | #include "lualib.h" 21 | 22 | 23 | /* 24 | ** Operations that an object must define to mimic a table 25 | ** (some functions only need some of them) 26 | */ 27 | #define TAB_R 1 /* read */ 28 | #define TAB_W 2 /* write */ 29 | #define TAB_L 4 /* length */ 30 | #define TAB_RW (TAB_R | TAB_W) /* read/write */ 31 | 32 | 33 | #define aux_getn(L,n,w) (checktab(L, n, (w) | TAB_L), luaL_len(L, n)) 34 | 35 | 36 | static int checkfield (lua_State *L, const char *key, int n) { 37 | lua_pushstring(L, key); 38 | return (lua_rawget(L, -n) != LUA_TNIL); 39 | } 40 | 41 | 42 | /* 43 | ** Check that 'arg' either is a table or can behave like one (that is, 44 | ** has a metatable with the required metamethods) 45 | */ 46 | static void checktab (lua_State *L, int arg, int what) { 47 | if (lua_type(L, arg) != LUA_TTABLE) { /* is it not a table? */ 48 | int n = 1; /* number of elements to pop */ 49 | if (lua_getmetatable(L, arg) && /* must have metatable */ 50 | (!(what & TAB_R) || checkfield(L, "__index", ++n)) && 51 | (!(what & TAB_W) || checkfield(L, "__newindex", ++n)) && 52 | (!(what & TAB_L) || checkfield(L, "__len", ++n))) { 53 | lua_pop(L, n); /* pop metatable and tested metamethods */ 54 | } 55 | else 56 | luaL_checktype(L, arg, LUA_TTABLE); /* force an error */ 57 | } 58 | } 59 | 60 | 61 | #if defined(LUA_COMPAT_MAXN) 62 | static int maxn (lua_State *L) { 63 | lua_Number max = 0; 64 | luaL_checktype(L, 1, LUA_TTABLE); 65 | lua_pushnil(L); /* first key */ 66 | while (lua_next(L, 1)) { 67 | lua_pop(L, 1); /* remove value */ 68 | if (lua_type(L, -1) == LUA_TNUMBER) { 69 | lua_Number v = lua_tonumber(L, -1); 70 | if (v > max) max = v; 71 | } 72 | } 73 | lua_pushnumber(L, max); 74 | return 1; 75 | } 76 | #endif 77 | 78 | 79 | static int tinsert (lua_State *L) { 80 | lua_Integer e = aux_getn(L, 1, TAB_RW) + 1; /* first empty element */ 81 | lua_Integer pos; /* where to insert new element */ 82 | switch (lua_gettop(L)) { 83 | case 2: { /* called with only 2 arguments */ 84 | pos = e; /* insert new element at the end */ 85 | break; 86 | } 87 | case 3: { 88 | lua_Integer i; 89 | pos = luaL_checkinteger(L, 2); /* 2nd argument is the position */ 90 | luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); 91 | for (i = e; i > pos; i--) { /* move up elements */ 92 | lua_geti(L, 1, i - 1); 93 | lua_seti(L, 1, i); /* t[i] = t[i - 1] */ 94 | } 95 | break; 96 | } 97 | default: { 98 | return luaL_error(L, "wrong number of arguments to 'insert'"); 99 | } 100 | } 101 | lua_seti(L, 1, pos); /* t[pos] = v */ 102 | return 0; 103 | } 104 | 105 | 106 | static int tremove (lua_State *L) { 107 | lua_Integer size = aux_getn(L, 1, TAB_RW); 108 | lua_Integer pos = luaL_optinteger(L, 2, size); 109 | if (pos != size) /* validate 'pos' if given */ 110 | luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); 111 | lua_geti(L, 1, pos); /* result = t[pos] */ 112 | for ( ; pos < size; pos++) { 113 | lua_geti(L, 1, pos + 1); 114 | lua_seti(L, 1, pos); /* t[pos] = t[pos + 1] */ 115 | } 116 | lua_pushnil(L); 117 | lua_seti(L, 1, pos); /* t[pos] = nil */ 118 | return 1; 119 | } 120 | 121 | 122 | /* 123 | ** Copy elements (1[f], ..., 1[e]) into (tt[t], tt[t+1], ...). Whenever 124 | ** possible, copy in increasing order, which is better for rehashing. 125 | ** "possible" means destination after original range, or smaller 126 | ** than origin, or copying to another table. 127 | */ 128 | static int tmove (lua_State *L) { 129 | lua_Integer f = luaL_checkinteger(L, 2); 130 | lua_Integer e = luaL_checkinteger(L, 3); 131 | lua_Integer t = luaL_checkinteger(L, 4); 132 | int tt = !lua_isnoneornil(L, 5) ? 5 : 1; /* destination table */ 133 | checktab(L, 1, TAB_R); 134 | checktab(L, tt, TAB_W); 135 | if (e >= f) { /* otherwise, nothing to move */ 136 | lua_Integer n, i; 137 | luaL_argcheck(L, f > 0 || e < LUA_MAXINTEGER + f, 3, 138 | "too many elements to move"); 139 | n = e - f + 1; /* number of elements to move */ 140 | luaL_argcheck(L, t <= LUA_MAXINTEGER - n + 1, 4, 141 | "destination wrap around"); 142 | if (t > e || t <= f || (tt != 1 && !lua_compare(L, 1, tt, LUA_OPEQ))) { 143 | for (i = 0; i < n; i++) { 144 | lua_geti(L, 1, f + i); 145 | lua_seti(L, tt, t + i); 146 | } 147 | } 148 | else { 149 | for (i = n - 1; i >= 0; i--) { 150 | lua_geti(L, 1, f + i); 151 | lua_seti(L, tt, t + i); 152 | } 153 | } 154 | } 155 | lua_pushvalue(L, tt); /* return destination table */ 156 | return 1; 157 | } 158 | 159 | 160 | static void addfield (lua_State *L, luaL_Buffer *b, lua_Integer i) { 161 | lua_geti(L, 1, i); 162 | if (!lua_isstring(L, -1)) 163 | luaL_error(L, "invalid value (%s) at index %d in table for 'concat'", 164 | luaL_typename(L, -1), i); 165 | luaL_addvalue(b); 166 | } 167 | 168 | 169 | static int tconcat (lua_State *L) { 170 | luaL_Buffer b; 171 | lua_Integer last = aux_getn(L, 1, TAB_R); 172 | size_t lsep; 173 | const char *sep = luaL_optlstring(L, 2, "", &lsep); 174 | lua_Integer i = luaL_optinteger(L, 3, 1); 175 | last = luaL_optinteger(L, 4, last); 176 | luaL_buffinit(L, &b); 177 | for (; i < last; i++) { 178 | addfield(L, &b, i); 179 | luaL_addlstring(&b, sep, lsep); 180 | } 181 | if (i == last) /* add last value (if interval was not empty) */ 182 | addfield(L, &b, i); 183 | luaL_pushresult(&b); 184 | return 1; 185 | } 186 | 187 | 188 | /* 189 | ** {====================================================== 190 | ** Pack/unpack 191 | ** ======================================================= 192 | */ 193 | 194 | static int pack (lua_State *L) { 195 | int i; 196 | int n = lua_gettop(L); /* number of elements to pack */ 197 | lua_createtable(L, n, 1); /* create result table */ 198 | lua_insert(L, 1); /* put it at index 1 */ 199 | for (i = n; i >= 1; i--) /* assign elements */ 200 | lua_seti(L, 1, i); 201 | lua_pushinteger(L, n); 202 | lua_setfield(L, 1, "n"); /* t.n = number of elements */ 203 | return 1; /* return table */ 204 | } 205 | 206 | 207 | static int unpack (lua_State *L) { 208 | lua_Unsigned n; 209 | lua_Integer i = luaL_optinteger(L, 2, 1); 210 | lua_Integer e = luaL_opt(L, luaL_checkinteger, 3, luaL_len(L, 1)); 211 | if (i > e) return 0; /* empty range */ 212 | n = (lua_Unsigned)e - i; /* number of elements minus 1 (avoid overflows) */ 213 | if (n >= (unsigned int)INT_MAX || !lua_checkstack(L, (int)(++n))) 214 | return luaL_error(L, "too many results to unpack"); 215 | for (; i < e; i++) { /* push arg[i..e - 1] (to avoid overflows) */ 216 | lua_geti(L, 1, i); 217 | } 218 | lua_geti(L, 1, e); /* push last element */ 219 | return (int)n; 220 | } 221 | 222 | /* }====================================================== */ 223 | 224 | 225 | 226 | /* 227 | ** {====================================================== 228 | ** Quicksort 229 | ** (based on 'Algorithms in MODULA-3', Robert Sedgewick; 230 | ** Addison-Wesley, 1993.) 231 | ** ======================================================= 232 | */ 233 | 234 | 235 | /* type for array indices */ 236 | typedef unsigned int IdxT; 237 | 238 | 239 | /* 240 | ** Produce a "random" 'unsigned int' to randomize pivot choice. This 241 | ** macro is used only when 'sort' detects a big imbalance in the result 242 | ** of a partition. (If you don't want/need this "randomness", ~0 is a 243 | ** good choice.) 244 | */ 245 | #if !defined(l_randomizePivot) /* { */ 246 | 247 | #include 248 | 249 | /* size of 'e' measured in number of 'unsigned int's */ 250 | #define sof(e) (sizeof(e) / sizeof(unsigned int)) 251 | 252 | /* 253 | ** Use 'time' and 'clock' as sources of "randomness". Because we don't 254 | ** know the types 'clock_t' and 'time_t', we cannot cast them to 255 | ** anything without risking overflows. A safe way to use their values 256 | ** is to copy them to an array of a known type and use the array values. 257 | */ 258 | static unsigned int l_randomizePivot (void) { 259 | clock_t c = clock(); 260 | time_t t = time(NULL); 261 | unsigned int buff[sof(c) + sof(t)]; 262 | unsigned int i, rnd = 0; 263 | memcpy(buff, &c, sof(c) * sizeof(unsigned int)); 264 | memcpy(buff + sof(c), &t, sof(t) * sizeof(unsigned int)); 265 | for (i = 0; i < sof(buff); i++) 266 | rnd += buff[i]; 267 | return rnd; 268 | } 269 | 270 | #endif /* } */ 271 | 272 | 273 | /* arrays larger than 'RANLIMIT' may use randomized pivots */ 274 | #define RANLIMIT 100u 275 | 276 | 277 | static void set2 (lua_State *L, IdxT i, IdxT j) { 278 | lua_seti(L, 1, i); 279 | lua_seti(L, 1, j); 280 | } 281 | 282 | 283 | /* 284 | ** Return true iff value at stack index 'a' is less than the value at 285 | ** index 'b' (according to the order of the sort). 286 | */ 287 | static int sort_comp (lua_State *L, int a, int b) { 288 | if (lua_isnil(L, 2)) /* no function? */ 289 | return lua_compare(L, a, b, LUA_OPLT); /* a < b */ 290 | else { /* function */ 291 | int res; 292 | lua_pushvalue(L, 2); /* push function */ 293 | lua_pushvalue(L, a-1); /* -1 to compensate function */ 294 | lua_pushvalue(L, b-2); /* -2 to compensate function and 'a' */ 295 | lua_call(L, 2, 1); /* call function */ 296 | res = lua_toboolean(L, -1); /* get result */ 297 | lua_pop(L, 1); /* pop result */ 298 | return res; 299 | } 300 | } 301 | 302 | 303 | /* 304 | ** Does the partition: Pivot P is at the top of the stack. 305 | ** precondition: a[lo] <= P == a[up-1] <= a[up], 306 | ** so it only needs to do the partition from lo + 1 to up - 2. 307 | ** Pos-condition: a[lo .. i - 1] <= a[i] == P <= a[i + 1 .. up] 308 | ** returns 'i'. 309 | */ 310 | static IdxT partition (lua_State *L, IdxT lo, IdxT up) { 311 | IdxT i = lo; /* will be incremented before first use */ 312 | IdxT j = up - 1; /* will be decremented before first use */ 313 | /* loop invariant: a[lo .. i] <= P <= a[j .. up] */ 314 | for (;;) { 315 | /* next loop: repeat ++i while a[i] < P */ 316 | while (lua_geti(L, 1, ++i), sort_comp(L, -1, -2)) { 317 | if (i == up - 1) /* a[i] < P but a[up - 1] == P ?? */ 318 | luaL_error(L, "invalid order function for sorting"); 319 | lua_pop(L, 1); /* remove a[i] */ 320 | } 321 | /* after the loop, a[i] >= P and a[lo .. i - 1] < P */ 322 | /* next loop: repeat --j while P < a[j] */ 323 | while (lua_geti(L, 1, --j), sort_comp(L, -3, -1)) { 324 | if (j < i) /* j < i but a[j] > P ?? */ 325 | luaL_error(L, "invalid order function for sorting"); 326 | lua_pop(L, 1); /* remove a[j] */ 327 | } 328 | /* after the loop, a[j] <= P and a[j + 1 .. up] >= P */ 329 | if (j < i) { /* no elements out of place? */ 330 | /* a[lo .. i - 1] <= P <= a[j + 1 .. i .. up] */ 331 | lua_pop(L, 1); /* pop a[j] */ 332 | /* swap pivot (a[up - 1]) with a[i] to satisfy pos-condition */ 333 | set2(L, up - 1, i); 334 | return i; 335 | } 336 | /* otherwise, swap a[i] - a[j] to restore invariant and repeat */ 337 | set2(L, i, j); 338 | } 339 | } 340 | 341 | 342 | /* 343 | ** Choose an element in the middle (2nd-3th quarters) of [lo,up] 344 | ** "randomized" by 'rnd' 345 | */ 346 | static IdxT choosePivot (IdxT lo, IdxT up, unsigned int rnd) { 347 | IdxT r4 = (up - lo) / 4; /* range/4 */ 348 | IdxT p = rnd % (r4 * 2) + (lo + r4); 349 | lua_assert(lo + r4 <= p && p <= up - r4); 350 | return p; 351 | } 352 | 353 | 354 | /* 355 | ** QuickSort algorithm (recursive function) 356 | */ 357 | static void auxsort (lua_State *L, IdxT lo, IdxT up, 358 | unsigned int rnd) { 359 | while (lo < up) { /* loop for tail recursion */ 360 | IdxT p; /* Pivot index */ 361 | IdxT n; /* to be used later */ 362 | /* sort elements 'lo', 'p', and 'up' */ 363 | lua_geti(L, 1, lo); 364 | lua_geti(L, 1, up); 365 | if (sort_comp(L, -1, -2)) /* a[up] < a[lo]? */ 366 | set2(L, lo, up); /* swap a[lo] - a[up] */ 367 | else 368 | lua_pop(L, 2); /* remove both values */ 369 | if (up - lo == 1) /* only 2 elements? */ 370 | return; /* already sorted */ 371 | if (up - lo < RANLIMIT || rnd == 0) /* small interval or no randomize? */ 372 | p = (lo + up)/2; /* middle element is a good pivot */ 373 | else /* for larger intervals, it is worth a random pivot */ 374 | p = choosePivot(lo, up, rnd); 375 | lua_geti(L, 1, p); 376 | lua_geti(L, 1, lo); 377 | if (sort_comp(L, -2, -1)) /* a[p] < a[lo]? */ 378 | set2(L, p, lo); /* swap a[p] - a[lo] */ 379 | else { 380 | lua_pop(L, 1); /* remove a[lo] */ 381 | lua_geti(L, 1, up); 382 | if (sort_comp(L, -1, -2)) /* a[up] < a[p]? */ 383 | set2(L, p, up); /* swap a[up] - a[p] */ 384 | else 385 | lua_pop(L, 2); 386 | } 387 | if (up - lo == 2) /* only 3 elements? */ 388 | return; /* already sorted */ 389 | lua_geti(L, 1, p); /* get middle element (Pivot) */ 390 | lua_pushvalue(L, -1); /* push Pivot */ 391 | lua_geti(L, 1, up - 1); /* push a[up - 1] */ 392 | set2(L, p, up - 1); /* swap Pivot (a[p]) with a[up - 1] */ 393 | p = partition(L, lo, up); 394 | /* a[lo .. p - 1] <= a[p] == P <= a[p + 1 .. up] */ 395 | if (p - lo < up - p) { /* lower interval is smaller? */ 396 | auxsort(L, lo, p - 1, rnd); /* call recursively for lower interval */ 397 | n = p - lo; /* size of smaller interval */ 398 | lo = p + 1; /* tail call for [p + 1 .. up] (upper interval) */ 399 | } 400 | else { 401 | auxsort(L, p + 1, up, rnd); /* call recursively for upper interval */ 402 | n = up - p; /* size of smaller interval */ 403 | up = p - 1; /* tail call for [lo .. p - 1] (lower interval) */ 404 | } 405 | if ((up - lo) / 128 > n) /* partition too imbalanced? */ 406 | rnd = l_randomizePivot(); /* try a new randomization */ 407 | } /* tail call auxsort(L, lo, up, rnd) */ 408 | } 409 | 410 | 411 | static int sort (lua_State *L) { 412 | lua_Integer n = aux_getn(L, 1, TAB_RW); 413 | if (n > 1) { /* non-trivial interval? */ 414 | luaL_argcheck(L, n < INT_MAX, 1, "array too big"); 415 | if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ 416 | luaL_checktype(L, 2, LUA_TFUNCTION); /* must be a function */ 417 | lua_settop(L, 2); /* make sure there are two arguments */ 418 | auxsort(L, 1, (IdxT)n, 0); 419 | } 420 | return 0; 421 | } 422 | 423 | /* }====================================================== */ 424 | 425 | 426 | static const luaL_Reg tab_funcs[] = { 427 | {"concat", tconcat}, 428 | #if defined(LUA_COMPAT_MAXN) 429 | {"maxn", maxn}, 430 | #endif 431 | {"insert", tinsert}, 432 | {"pack", pack}, 433 | {"unpack", unpack}, 434 | {"remove", tremove}, 435 | {"move", tmove}, 436 | {"sort", sort}, 437 | {NULL, NULL} 438 | }; 439 | 440 | 441 | LUAMOD_API int luaopen_table (lua_State *L) { 442 | luaL_newlib(L, tab_funcs); 443 | #if defined(LUA_COMPAT_UNPACK) 444 | /* _G.unpack = table.unpack */ 445 | lua_getfield(L, -1, "unpack"); 446 | lua_setglobal(L, "unpack"); 447 | #endif 448 | return 1; 449 | } 450 | 451 | -------------------------------------------------------------------------------- /vendor/compat53/lutf8lib.c: -------------------------------------------------------------------------------- 1 | /* 2 | ** $Id: lutf8lib.c,v 1.16.1.1 2017/04/19 17:29:57 roberto Exp $ 3 | ** Standard library for UTF-8 manipulation 4 | ** See Copyright Notice in lua.h 5 | */ 6 | 7 | #define lutf8lib_c 8 | #define LUA_LIB 9 | 10 | #include "lprefix.h" 11 | 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include "lua.h" 19 | 20 | #include "lauxlib.h" 21 | #include "lualib.h" 22 | 23 | #define MAXUNICODE 0x10FFFF 24 | 25 | #define iscont(p) ((*(p) & 0xC0) == 0x80) 26 | 27 | 28 | /* from strlib */ 29 | /* translate a relative string position: negative means back from end */ 30 | static lua_Integer u_posrelat (lua_Integer pos, size_t len) { 31 | if (pos >= 0) return pos; 32 | else if (0u - (size_t)pos > len) return 0; 33 | else return (lua_Integer)len + pos + 1; 34 | } 35 | 36 | 37 | /* 38 | ** Decode one UTF-8 sequence, returning NULL if byte sequence is invalid. 39 | */ 40 | static const char *utf8_decode (const char *o, int *val) { 41 | static const unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF}; 42 | const unsigned char *s = (const unsigned char *)o; 43 | unsigned int c = s[0]; 44 | unsigned int res = 0; /* final result */ 45 | if (c < 0x80) /* ascii? */ 46 | res = c; 47 | else { 48 | int count = 0; /* to count number of continuation bytes */ 49 | while (c & 0x40) { /* still have continuation bytes? */ 50 | int cc = s[++count]; /* read next byte */ 51 | if ((cc & 0xC0) != 0x80) /* not a continuation byte? */ 52 | return NULL; /* invalid byte sequence */ 53 | res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */ 54 | c <<= 1; /* to test next bit */ 55 | } 56 | res |= ((c & 0x7F) << (count * 5)); /* add first byte */ 57 | if (count > 3 || res > MAXUNICODE || res <= limits[count]) 58 | return NULL; /* invalid byte sequence */ 59 | s += count; /* skip continuation bytes read */ 60 | } 61 | if (val) *val = res; 62 | return (const char *)s + 1; /* +1 to include first byte */ 63 | } 64 | 65 | 66 | /* 67 | ** utf8len(s [, i [, j]]) --> number of characters that start in the 68 | ** range [i,j], or nil + current position if 's' is not well formed in 69 | ** that interval 70 | */ 71 | static int utflen (lua_State *L) { 72 | int n = 0; 73 | size_t len; 74 | const char *s = luaL_checklstring(L, 1, &len); 75 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 76 | lua_Integer posj = u_posrelat(luaL_optinteger(L, 3, -1), len); 77 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 2, 78 | "initial position out of string"); 79 | luaL_argcheck(L, --posj < (lua_Integer)len, 3, 80 | "final position out of string"); 81 | while (posi <= posj) { 82 | const char *s1 = utf8_decode(s + posi, NULL); 83 | if (s1 == NULL) { /* conversion error? */ 84 | lua_pushnil(L); /* return nil ... */ 85 | lua_pushinteger(L, posi + 1); /* ... and current position */ 86 | return 2; 87 | } 88 | posi = s1 - s; 89 | n++; 90 | } 91 | lua_pushinteger(L, n); 92 | return 1; 93 | } 94 | 95 | 96 | /* 97 | ** codepoint(s, [i, [j]]) -> returns codepoints for all characters 98 | ** that start in the range [i,j] 99 | */ 100 | static int codepoint (lua_State *L) { 101 | size_t len; 102 | const char *s = luaL_checklstring(L, 1, &len); 103 | lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len); 104 | lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len); 105 | int n; 106 | const char *se; 107 | luaL_argcheck(L, posi >= 1, 2, "out of range"); 108 | luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range"); 109 | if (posi > pose) return 0; /* empty interval; return no values */ 110 | if (pose - posi >= INT_MAX) /* (lua_Integer -> int) overflow? */ 111 | return luaL_error(L, "string slice too long"); 112 | n = (int)(pose - posi) + 1; 113 | luaL_checkstack(L, n, "string slice too long"); 114 | n = 0; 115 | se = s + pose; 116 | for (s += posi - 1; s < se;) { 117 | int code; 118 | s = utf8_decode(s, &code); 119 | if (s == NULL) 120 | return luaL_error(L, "invalid UTF-8 code"); 121 | lua_pushinteger(L, code); 122 | n++; 123 | } 124 | return n; 125 | } 126 | 127 | 128 | static void pushutfchar (lua_State *L, int arg) { 129 | lua_Integer code = luaL_checkinteger(L, arg); 130 | luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range"); 131 | lua_pushfstring(L, "%U", (long)code); 132 | } 133 | 134 | 135 | /* 136 | ** utfchar(n1, n2, ...) -> char(n1)..char(n2)... 137 | */ 138 | static int utfchar (lua_State *L) { 139 | int n = lua_gettop(L); /* number of arguments */ 140 | if (n == 1) /* optimize common case of single char */ 141 | pushutfchar(L, 1); 142 | else { 143 | int i; 144 | luaL_Buffer b; 145 | luaL_buffinit(L, &b); 146 | for (i = 1; i <= n; i++) { 147 | pushutfchar(L, i); 148 | luaL_addvalue(&b); 149 | } 150 | luaL_pushresult(&b); 151 | } 152 | return 1; 153 | } 154 | 155 | 156 | /* 157 | ** offset(s, n, [i]) -> index where n-th character counting from 158 | ** position 'i' starts; 0 means character at 'i'. 159 | */ 160 | static int byteoffset (lua_State *L) { 161 | size_t len; 162 | const char *s = luaL_checklstring(L, 1, &len); 163 | lua_Integer n = luaL_checkinteger(L, 2); 164 | lua_Integer posi = (n >= 0) ? 1 : len + 1; 165 | posi = u_posrelat(luaL_optinteger(L, 3, posi), len); 166 | luaL_argcheck(L, 1 <= posi && --posi <= (lua_Integer)len, 3, 167 | "position out of range"); 168 | if (n == 0) { 169 | /* find beginning of current byte sequence */ 170 | while (posi > 0 && iscont(s + posi)) posi--; 171 | } 172 | else { 173 | if (iscont(s + posi)) 174 | return luaL_error(L, "initial position is a continuation byte"); 175 | if (n < 0) { 176 | while (n < 0 && posi > 0) { /* move back */ 177 | do { /* find beginning of previous character */ 178 | posi--; 179 | } while (posi > 0 && iscont(s + posi)); 180 | n++; 181 | } 182 | } 183 | else { 184 | n--; /* do not move for 1st character */ 185 | while (n > 0 && posi < (lua_Integer)len) { 186 | do { /* find beginning of next character */ 187 | posi++; 188 | } while (iscont(s + posi)); /* (cannot pass final '\0') */ 189 | n--; 190 | } 191 | } 192 | } 193 | if (n == 0) /* did it find given character? */ 194 | lua_pushinteger(L, posi + 1); 195 | else /* no such character */ 196 | lua_pushnil(L); 197 | return 1; 198 | } 199 | 200 | 201 | static int iter_aux (lua_State *L) { 202 | size_t len; 203 | const char *s = luaL_checklstring(L, 1, &len); 204 | lua_Integer n = lua_tointeger(L, 2) - 1; 205 | if (n < 0) /* first iteration? */ 206 | n = 0; /* start from here */ 207 | else if (n < (lua_Integer)len) { 208 | n++; /* skip current byte */ 209 | while (iscont(s + n)) n++; /* and its continuations */ 210 | } 211 | if (n >= (lua_Integer)len) 212 | return 0; /* no more codepoints */ 213 | else { 214 | int code; 215 | const char *next = utf8_decode(s + n, &code); 216 | if (next == NULL || iscont(next)) 217 | return luaL_error(L, "invalid UTF-8 code"); 218 | lua_pushinteger(L, n + 1); 219 | lua_pushinteger(L, code); 220 | return 2; 221 | } 222 | } 223 | 224 | 225 | static int iter_codes (lua_State *L) { 226 | luaL_checkstring(L, 1); 227 | lua_pushcfunction(L, iter_aux); 228 | lua_pushvalue(L, 1); 229 | lua_pushinteger(L, 0); 230 | return 3; 231 | } 232 | 233 | 234 | /* pattern to match a single UTF-8 character */ 235 | #define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*" 236 | 237 | 238 | static const luaL_Reg funcs[] = { 239 | {"offset", byteoffset}, 240 | {"codepoint", codepoint}, 241 | {"char", utfchar}, 242 | {"len", utflen}, 243 | {"codes", iter_codes}, 244 | /* placeholders */ 245 | {"charpattern", NULL}, 246 | {NULL, NULL} 247 | }; 248 | 249 | 250 | LUAMOD_API int luaopen_utf8 (lua_State *L) { 251 | luaL_newlib(L, funcs); 252 | lua_pushlstring(L, UTF8PATT, sizeof(UTF8PATT)/sizeof(char) - 1); 253 | lua_setfield(L, -2, "charpattern"); 254 | return 1; 255 | } 256 | 257 | -------------------------------------------------------------------------------- /vendor/compat53/rockspecs/bit32-5.3.5-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "bit32" 2 | version = "5.3.5-1" 3 | source = { 4 | url = "https://github.com/keplerproject/lua-compat-5.3/archive/v0.9.zip", 5 | dir = "lua-compat-5.3-0.9", 6 | } 7 | description = { 8 | summary = "Lua 5.2 bit manipulation library", 9 | detailed = [[ 10 | bit32 is the native Lua 5.2 bit manipulation library, in the version 11 | from Lua 5.3; it is compatible with Lua 5.1, 5.2 and 5.3. 12 | ]], 13 | homepage = "http://www.lua.org/manual/5.2/manual.html#6.7", 14 | license = "MIT" 15 | } 16 | dependencies = { 17 | "lua >= 5.1, < 5.5" 18 | } 19 | build = { 20 | type = "builtin", 21 | modules = { 22 | bit32 = { 23 | sources = { "lbitlib.c" }, 24 | defines = { "LUA_COMPAT_BITLIB" }, 25 | incdirs = { "c-api" }, 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /vendor/compat53/rockspecs/bit32-scm-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "bit32" 2 | version = "scm-1" 3 | source = { 4 | url = "https://github.com/keplerproject/lua-compat-5.3/archive/master.zip", 5 | branch = "lua-compat-5.3-master", 6 | } 7 | description = { 8 | summary = "Lua 5.2 bit manipulation library", 9 | detailed = [[ 10 | bit32 is the native Lua 5.2 bit manipulation library, in the version 11 | from Lua 5.3; it is compatible with Lua 5.1, 5.2 and 5.3. 12 | ]], 13 | homepage = "http://www.lua.org/manual/5.2/manual.html#6.7", 14 | license = "MIT" 15 | } 16 | dependencies = { 17 | "lua >= 5.1, < 5.5" 18 | } 19 | build = { 20 | type = "builtin", 21 | modules = { 22 | bit32 = { 23 | sources = { "lbitlib.c" }, 24 | defines = { "LUA_COMPAT_BITLIB" }, 25 | incdirs = { "c-api" }, 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /vendor/compat53/rockspecs/compat53-0.1-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "compat53" 2 | version = "0.1-1" 3 | source = { 4 | url = "https://github.com/keplerproject/lua-compat-5.3/archive/v0.1.zip", 5 | dir = "lua-compat-5.3-0.1", 6 | } 7 | description = { 8 | summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", 9 | detailed = [[ 10 | This is a small module that aims to make it easier to write Lua 11 | code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. 12 | It does *not* make Lua 5.2 (or even 5.1) entirely compatible 13 | with Lua 5.3, but it brings the API closer to that of Lua 5.3. 14 | ]], 15 | homepage = "https://github.com/keplerproject/lua-compat-5.3", 16 | license = "MIT" 17 | } 18 | dependencies = { 19 | "lua >= 5.1, < 5.4", 20 | --"struct" -- make Roberto's struct module optional 21 | } 22 | build = { 23 | type = "builtin", 24 | modules = { 25 | ["compat53"] = "compat53.lua", 26 | ["compat53.utf8"] = "lutf8lib.c", 27 | ["compat53.table"] = "ltablib.c", 28 | ["compat53.string"] = "lstrlib.c", 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /vendor/compat53/rockspecs/compat53-0.2-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "compat53" 2 | version = "0.2-1" 3 | source = { 4 | url = "https://github.com/keplerproject/lua-compat-5.3/archive/v0.2.zip", 5 | dir = "lua-compat-5.3-0.2", 6 | } 7 | description = { 8 | summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", 9 | detailed = [[ 10 | This is a small module that aims to make it easier to write Lua 11 | code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. 12 | It does *not* make Lua 5.2 (or even 5.1) entirely compatible 13 | with Lua 5.3, but it brings the API closer to that of Lua 5.3. 14 | ]], 15 | homepage = "https://github.com/keplerproject/lua-compat-5.3", 16 | license = "MIT" 17 | } 18 | dependencies = { 19 | "lua >= 5.1, < 5.4", 20 | --"struct" -- make Roberto's struct module optional 21 | } 22 | build = { 23 | type = "builtin", 24 | modules = { 25 | ["compat53.init"] = "compat53/init.lua", 26 | ["compat53.module"] = "compat53/module.lua", 27 | ["compat53.utf8"] = "lutf8lib.c", 28 | ["compat53.table"] = "ltablib.c", 29 | ["compat53.string"] = "lstrlib.c", 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /vendor/compat53/rockspecs/compat53-0.3-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "compat53" 2 | version = "0.3-1" 3 | source = { 4 | url = "https://github.com/keplerproject/lua-compat-5.3/archive/v0.3.zip", 5 | dir = "lua-compat-5.3-0.3", 6 | } 7 | description = { 8 | summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", 9 | detailed = [[ 10 | This is a small module that aims to make it easier to write Lua 11 | code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. 12 | It does *not* make Lua 5.2 (or even 5.1) entirely compatible 13 | with Lua 5.3, but it brings the API closer to that of Lua 5.3. 14 | ]], 15 | homepage = "https://github.com/keplerproject/lua-compat-5.3", 16 | license = "MIT" 17 | } 18 | dependencies = { 19 | "lua >= 5.1, < 5.4", 20 | --"struct" -- make Roberto's struct module optional 21 | } 22 | build = { 23 | type = "builtin", 24 | modules = { 25 | ["compat53.init"] = "compat53/init.lua", 26 | ["compat53.module"] = "compat53/module.lua", 27 | ["compat53.utf8"] = "lutf8lib.c", 28 | ["compat53.table"] = "ltablib.c", 29 | ["compat53.string"] = "lstrlib.c", 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /vendor/compat53/rockspecs/compat53-0.4-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "compat53" 2 | version = "0.4-1" 3 | source = { 4 | url = "https://github.com/keplerproject/lua-compat-5.3/archive/v0.4.zip", 5 | dir = "lua-compat-5.3-0.4", 6 | } 7 | description = { 8 | summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", 9 | detailed = [[ 10 | This is a small module that aims to make it easier to write Lua 11 | code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. 12 | It does *not* make Lua 5.2 (or even 5.1) entirely compatible 13 | with Lua 5.3, but it brings the API closer to that of Lua 5.3. 14 | ]], 15 | homepage = "https://github.com/keplerproject/lua-compat-5.3", 16 | license = "MIT" 17 | } 18 | dependencies = { 19 | "lua >= 5.1, < 5.4", 20 | --"struct" -- make Roberto's struct module optional 21 | } 22 | build = { 23 | type = "builtin", 24 | modules = { 25 | ["compat53.init"] = "compat53/init.lua", 26 | ["compat53.module"] = "compat53/module.lua", 27 | ["compat53.utf8"] = "lutf8lib.c", 28 | ["compat53.table"] = "ltablib.c", 29 | ["compat53.string"] = "lstrlib.c", 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /vendor/compat53/rockspecs/compat53-0.5-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "compat53" 2 | version = "0.5-1" 3 | source = { 4 | url = "https://github.com/keplerproject/lua-compat-5.3/archive/v0.5.zip", 5 | dir = "lua-compat-5.3-0.5", 6 | } 7 | description = { 8 | summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", 9 | detailed = [[ 10 | This is a small module that aims to make it easier to write Lua 11 | code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. 12 | It does *not* make Lua 5.2 (or even 5.1) entirely compatible 13 | with Lua 5.3, but it brings the API closer to that of Lua 5.3. 14 | ]], 15 | homepage = "https://github.com/keplerproject/lua-compat-5.3", 16 | license = "MIT" 17 | } 18 | dependencies = { 19 | "lua >= 5.1, < 5.4", 20 | --"struct" -- make Roberto's struct module optional 21 | } 22 | build = { 23 | type = "builtin", 24 | modules = { 25 | ["compat53.init"] = "compat53/init.lua", 26 | ["compat53.module"] = "compat53/module.lua", 27 | ["compat53.utf8"] = "lutf8lib.c", 28 | ["compat53.table"] = "ltablib.c", 29 | ["compat53.string"] = "lstrlib.c", 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /vendor/compat53/rockspecs/compat53-0.7-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "compat53" 2 | version = "0.7-1" 3 | source = { 4 | url = "https://github.com/keplerproject/lua-compat-5.3/archive/v0.7.zip", 5 | dir = "lua-compat-5.3-0.7", 6 | } 7 | description = { 8 | summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", 9 | detailed = [[ 10 | This is a small module that aims to make it easier to write Lua 11 | code in a Lua-5.3-style that runs on Lua 5.3, 5.2, and 5.1. 12 | It does *not* make Lua 5.2 (or even 5.1) entirely compatible 13 | with Lua 5.3, but it brings the API closer to that of Lua 5.3. 14 | ]], 15 | homepage = "https://github.com/keplerproject/lua-compat-5.3", 16 | license = "MIT" 17 | } 18 | dependencies = { 19 | "lua >= 5.1, < 5.4", 20 | --"struct" -- make Roberto's struct module optional 21 | } 22 | build = { 23 | type = "builtin", 24 | modules = { 25 | ["compat53.init"] = "compat53/init.lua", 26 | ["compat53.module"] = "compat53/module.lua", 27 | ["compat53.utf8"] = "lutf8lib.c", 28 | ["compat53.table"] = "ltablib.c", 29 | ["compat53.string"] = "lstrlib.c", 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /vendor/compat53/rockspecs/compat53-0.8-1.rockspec: -------------------------------------------------------------------------------- 1 | package = "compat53" 2 | version = "0.8-1" 3 | source = { 4 | url = "https://github.com/keplerproject/lua-compat-5.3/archive/v0.8.zip", 5 | dir = "lua-compat-5.3-0.8", 6 | } 7 | description = { 8 | summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", 9 | detailed = [[ 10 | This is a small module that aims to make it easier to write Lua 11 | code in a Lua-5.3-style that runs on Lua 5.1+. 12 | It does *not* make Lua 5.2 (or even 5.1) entirely compatible 13 | with Lua 5.3, but it brings the API closer to that of Lua 5.3. 14 | ]], 15 | homepage = "https://github.com/keplerproject/lua-compat-5.3", 16 | license = "MIT" 17 | } 18 | dependencies = { 19 | "lua >= 5.1, < 5.5", 20 | --"struct" -- make Roberto's struct module optional 21 | } 22 | build = { 23 | type = "builtin", 24 | modules = { 25 | ["compat53.init"] = "compat53/init.lua", 26 | ["compat53.module"] = "compat53/module.lua", 27 | ["compat53.utf8"] = "lutf8lib.c", 28 | ["compat53.table"] = "ltablib.c", 29 | ["compat53.string"] = "lstrlib.c", 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /vendor/compat53/rockspecs/compat53-scm-0.rockspec: -------------------------------------------------------------------------------- 1 | package = "compat53" 2 | version = "scm-0" 3 | source = { 4 | url = "https://github.com/keplerproject/lua-compat-5.3/archive/master.zip", 5 | dir = "lua-compat-5.3-master", 6 | } 7 | description = { 8 | summary = "Compatibility module providing Lua-5.3-style APIs for Lua 5.2 and 5.1", 9 | detailed = [[ 10 | This is a small module that aims to make it easier to write Lua 11 | code in a Lua-5.3-style that runs on Lua 5.1+. 12 | It does *not* make Lua 5.2 (or even 5.1) entirely compatible 13 | with Lua 5.3, but it brings the API closer to that of Lua 5.3. 14 | ]], 15 | homepage = "https://github.com/keplerproject/lua-compat-5.3", 16 | license = "MIT" 17 | } 18 | dependencies = { 19 | "lua >= 5.1, < 5.5", 20 | --"struct" -- make Roberto's struct module optional 21 | } 22 | build = { 23 | type = "builtin", 24 | modules = { 25 | ["compat53.init"] = "compat53/init.lua", 26 | ["compat53.module"] = "compat53/module.lua", 27 | ["compat53.utf8"] = "lutf8lib.c", 28 | ["compat53.table"] = "ltablib.c", 29 | ["compat53.string"] = "lstrlib.c", 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /vendor/compat53/tests/test-bit32.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local bit32 = require("bit32") 4 | 5 | 6 | assert(bit32.bnot(0) == 2^32-1) 7 | assert(bit32.band(1, 3, 5) == 1) 8 | assert(bit32.bor(1, 3, 5) == 7) 9 | 10 | -------------------------------------------------------------------------------- /vendor/compat53/tests/test.lua: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env lua 2 | 3 | local F, tproxy, writefile, noprint, ___ 4 | do 5 | local type, unpack = type, table.unpack or unpack 6 | local assert, io = assert, io 7 | function F(...) 8 | local args, n = { ... }, select('#', ...) 9 | for i = 1, n do 10 | local t = type(args[i]) 11 | if t ~= "string" and t ~= "number" and t ~= "boolean" then 12 | args[i] = t 13 | end 14 | end 15 | return unpack(args, 1, n) 16 | end 17 | function tproxy(t) 18 | return setmetatable({}, { 19 | __index = t, 20 | __newindex = t, 21 | __len = function() return #t end, 22 | }), t 23 | end 24 | function writefile(name, contents, bin) 25 | local f = assert(io.open(name, bin and "wb" or "w")) 26 | f:write(contents) 27 | f:close() 28 | end 29 | function noprint() end 30 | local sep = ("="):rep(70) 31 | function ___() 32 | print(sep) 33 | end 34 | end 35 | 36 | local V = _VERSION:gsub("^.*(%d+)%.(%d+)$", "%1%2") 37 | if jit then V = "jit" end 38 | 39 | local mode = "global" 40 | if arg[1] == "module" then 41 | mode = "module" 42 | end 43 | local self = arg[0] 44 | 45 | package.path = "../?.lua;../?/init.lua" 46 | package.cpath = "./?-"..V..".so;./?-"..V..".dll;./?.so;./?.dll" 47 | if mode == "module" then 48 | print("testing Lua API using `compat53.module` ...") 49 | _ENV = require("compat53.module") 50 | if setfenv then setfenv(1, _ENV) end 51 | else 52 | print("testing Lua API using `compat53` ...") 53 | require("compat53") 54 | end 55 | 56 | 57 | ___'' 58 | do 59 | print("assert", F(pcall(assert, false))) 60 | print("assert", F(pcall(assert, false, nil))) 61 | print("assert", F(pcall(assert, false, "error msg"))) 62 | print("assert", F(pcall(assert, nil, {}))) 63 | print("assert", F(pcall(assert, 1, 2, 3))) 64 | end 65 | 66 | 67 | ___'' 68 | do 69 | local t = setmetatable({}, { __index = { 1, false, "three" } }) 70 | for i,v in ipairs(t) do 71 | print("ipairs", i, v) 72 | end 73 | end 74 | 75 | 76 | ___'' 77 | do 78 | local p, t = tproxy{ "a", "b", "c" } 79 | print("table.concat", table.concat(p)) 80 | print("table.concat", table.concat(p, ",", 2)) 81 | print("table.concat", table.concat(p, ".", 1, 2)) 82 | print("table.concat", table.concat(t)) 83 | print("table.concat", table.concat(t, ",", 2)) 84 | print("table.concat", table.concat(t, ".", 1, 2)) 85 | end 86 | 87 | 88 | ___'' 89 | do 90 | local p, t = tproxy{ "a", "b", "c" } 91 | table.insert(p, "d") 92 | print("table.insert", next(p), t[4]) 93 | table.insert(p, 1, "z") 94 | print("table.insert", next(p), t[1], t[2]) 95 | table.insert(p, 2, "y") 96 | print("table.insert", next(p), t[1], t[2], p[3]) 97 | t = { "a", "b", "c" } 98 | table.insert(t, "d") 99 | print("table.insert", t[1], t[2], t[3], t[4]) 100 | table.insert(t, 1, "z") 101 | print("table.insert", t[1], t[2], t[3], t[4], t[5]) 102 | table.insert(t, 2, "y") 103 | print("table.insert", t[1], t[2], t[3], t[4], t[5]) 104 | end 105 | 106 | 107 | ___'' 108 | do 109 | local ps, s = tproxy{ "a", "b", "c", "d" } 110 | local pd, d = tproxy{ "A", "B", "C", "D" } 111 | table.move(ps, 1, 4, 1, pd) 112 | print("table.move", next(pd), d[1], d[2], d[3], d[4]) 113 | pd, d = tproxy{ "A", "B", "C", "D" } 114 | table.move(ps, 2, 4, 1, pd) 115 | print("table.move", next(pd), d[1], d[2], d[3], d[4]) 116 | pd, d = tproxy{ "A", "B", "C", "D" } 117 | table.move(ps, 2, 3, 4, pd) 118 | print("table.move", next(pd), d[1], d[2], d[3], d[4], d[5]) 119 | table.move(ps, 2, 4, 1) 120 | print("table.move", next(ps), s[1], s[2], s[3], s[4]) 121 | ps, s = tproxy{ "a", "b", "c", "d" } 122 | table.move(ps, 2, 3, 4) 123 | print("table.move", next(ps), s[1], s[2], s[3], s[4], s[5]) 124 | s = { "a", "b", "c", "d" } 125 | d = { "A", "B", "C", "D" } 126 | table.move(s, 1, 4, 1, d) 127 | print("table.move", d[1], d[2], d[3], d[4]) 128 | d = { "A", "B", "C", "D" } 129 | table.move(s, 2, 4, 1, d) 130 | print("table.move", d[1], d[2], d[3], d[4]) 131 | d = { "A", "B", "C", "D" } 132 | table.move(s, 2, 3, 4, d) 133 | print("table.move", d[1], d[2], d[3], d[4], d[5]) 134 | table.move(s, 2, 4, 1) 135 | print("table.move", s[1], s[2], s[3], s[4]) 136 | s = { "a", "b", "c", "d" } 137 | table.move(s, 2, 3, 4) 138 | print("table.move", s[1], s[2], s[3], s[4], s[5]) 139 | end 140 | 141 | 142 | ___'' 143 | do 144 | local p, t = tproxy{ "a", "b", "c", "d", "e" } 145 | print("table.remove", table.remove(p)) 146 | print("table.remove", next(p), t[1], t[2], t[3], t[4], t[5]) 147 | print("table.remove", table.remove(p, 1)) 148 | print("table.remove", next(p), t[1], t[2], t[3], t[4]) 149 | print("table.remove", table.remove(p, 2)) 150 | print("table.remove", next(p), t[1], t[2], t[3]) 151 | print("table.remove", table.remove(p, 3)) 152 | print("table.remove", next(p), t[1], t[2], t[3]) 153 | p, t = tproxy{} 154 | print("table.remove", table.remove(p)) 155 | print("table.remove", next(p), next(t)) 156 | t = { "a", "b", "c", "d", "e" } 157 | print("table.remove", table.remove(t)) 158 | print("table.remove", t[1], t[2], t[3], t[4], t[5]) 159 | print("table.remove", table.remove(t, 1)) 160 | print("table.remove", t[1], t[2], t[3], t[4]) 161 | print("table.remove", table.remove(t, 2)) 162 | print("table.remove", t[1], t[2], t[3]) 163 | print("table.remove", table.remove(t, 3)) 164 | print("table.remove", t[1], t[2], t[3]) 165 | t = {} 166 | print("table.remove", table.remove(t)) 167 | print("table.remove", next(t)) 168 | end 169 | 170 | ___'' 171 | do 172 | local p, t = tproxy{ 3, 1, 5, 2, 8, 5, 2, 9, 7, 4 } 173 | table.sort(p) 174 | print("table.sort", next(p)) 175 | for i,v in ipairs(t) do 176 | print("table.sort", i, v) 177 | end 178 | table.sort(p) 179 | print("table.sort", next(p)) 180 | for i,v in ipairs(t) do 181 | print("table.sort", i, v) 182 | end 183 | p, t = tproxy{ 9, 8, 7, 6, 5, 4, 3, 2, 1 } 184 | table.sort(p) 185 | print("table.sort", next(p)) 186 | for i,v in ipairs(t) do 187 | print("table.sort", i, v) 188 | end 189 | table.sort(p, function(a, b) return a > b end) 190 | print("table.sort", next(p)) 191 | for i,v in ipairs(t) do 192 | print("table.sort", i, v) 193 | end 194 | p, t = tproxy{ 1, 1, 1, 1, 1 } 195 | print("table.sort", next(p)) 196 | for i,v in ipairs(t) do 197 | print("table.sort", i, v) 198 | end 199 | t = { 3, 1, 5, 2, 8, 5, 2, 9, 7, 4 } 200 | table.sort(t) 201 | for i,v in ipairs(t) do 202 | print("table.sort", i, v) 203 | end 204 | table.sort(t, function(a, b) return a > b end) 205 | for i,v in ipairs(t) do 206 | print("table.sort", i, v) 207 | end 208 | end 209 | 210 | 211 | ___'' 212 | do 213 | local p, t = tproxy{ "a", "b", "c" } 214 | print("table.unpack", table.unpack(p)) 215 | print("table.unpack", table.unpack(p, 2)) 216 | print("table.unpack", table.unpack(p, 1, 2)) 217 | print("table.unpack", table.unpack(t)) 218 | print("table.unpack", table.unpack(t, 2)) 219 | print("table.unpack", table.unpack(t, 1, 2)) 220 | end 221 | 222 | 223 | ___'' 224 | print("math.maxinteger", math.maxinteger+1 > math.maxinteger) 225 | print("math.mininteger", math.mininteger-1 < math.mininteger) 226 | 227 | 228 | ___'' 229 | print("math.tointeger", math.tointeger(0)) 230 | print("math.tointeger", math.tointeger(math.pi)) 231 | print("math.tointeger", math.tointeger("hello")) 232 | print("math.tointeger", math.tointeger(math.maxinteger+2.0)) 233 | print("math.tointeger", math.tointeger(math.mininteger*2.0)) 234 | 235 | 236 | ___'' 237 | print("math.type", math.type(0)) 238 | print("math.type", math.type(math.pi)) 239 | print("math.type", math.type("hello")) 240 | 241 | 242 | ___'' 243 | print("math.ult", math.ult(1, 2), math.ult(2, 1)) 244 | print("math.ult", math.ult(-1, 2), math.ult(2, -1)) 245 | print("math.ult", math.ult(-1, -2), math.ult(-2, -1)) 246 | print("math.ult", pcall(math.ult, "x", 2)) 247 | print("math.ult", pcall(math.ult, 1, 2.1)) 248 | ___'' 249 | 250 | 251 | if utf8.len then 252 | local unpack = table.unpack or unpack 253 | local function utf8rt(s) 254 | local t = { utf8.codepoint(s, 1, #s) } 255 | local ps, cs = {}, {} 256 | for p,c in utf8.codes(s) do 257 | ps[#ps+1], cs[#cs+1] = p, c 258 | end 259 | print("utf8.codes", unpack(ps)) 260 | print("utf8.codes", unpack(cs)) 261 | print("utf8.codepoint", unpack(t)) 262 | print("utf8.len", utf8.len(s), #t, #s) 263 | print("utf8.char", utf8.char(unpack(t))) 264 | end 265 | utf8rt("äöüßÄÖÜ") 266 | utf8rt("abcdefg") 267 | ___'' 268 | local s = "äöüßÄÖÜ" 269 | print("utf8.offset", utf8.offset(s, 1, 1)) 270 | print("utf8.offset", utf8.offset(s, 2, 1)) 271 | print("utf8.offset", utf8.offset(s, 3, 1)) 272 | print("utf8.offset", pcall(utf8.offset, s, 3, 2)) 273 | print("utf8.offset", utf8.offset(s, 3, 3)) 274 | print("utf8.offset", utf8.offset(s, -1, 7)) 275 | print("utf8.offset", utf8.offset(s, -2, 7)) 276 | print("utf8.offset", utf8.offset(s, -3, 7)) 277 | print("utf8.offset", utf8.offset(s, -1)) 278 | ___'' 279 | else 280 | print("XXX: utf8 module not available") 281 | end 282 | 283 | 284 | if string.pack then 285 | local format = "bBhHlLjJdc3z" 286 | local s = string.pack(format, -128, 255, -32768, 65535, -2147483648, 4294967295, -32768, 65536, 1.25, "abc", "defgh") 287 | print("string.unpack", string.unpack(format, s)) 288 | ___'' 289 | else 290 | print("XXX: string packing not available") 291 | end 292 | 293 | 294 | print("testing Lua API for Lua 5.1 ...") 295 | 296 | ___'' 297 | print("debug.getuservalue()", F(debug.getuservalue(false))) 298 | print("debug.setuservalue()", pcall(function() 299 | debug.setuservalue(false, {}) 300 | end)) 301 | print("debug.setmetatable()", F(debug.setmetatable({}, {}))) 302 | 303 | 304 | ___'' 305 | do 306 | local t = setmetatable({}, { 307 | __pairs = function() return pairs({ a = "a" }) end, 308 | }) 309 | for k,v in pairs(t) do 310 | print("pairs()", k, v) 311 | end 312 | end 313 | 314 | 315 | ___'' 316 | do 317 | local code = "print('hello world')\n" 318 | local badcode = "print('blub\n" 319 | print("load()", pcall(function() load(true) end)) 320 | print("load()", F(load(badcode))) 321 | print("load()", F(load(code))) 322 | print("load()", F(load(code, "[L]"))) 323 | print("load()", F(load(code, "[L]", "b"))) 324 | print("load()", F(load(code, "[L]", "t"))) 325 | print("load()", F(load(code, "[L]", "bt"))) 326 | local f = load(code, "[L]", "bt", {}) 327 | print("load()", pcall(f)) 328 | f = load(code, "[L]", "bt", { print = noprint }) 329 | print("load()", pcall(f)) 330 | local bytecode = string.dump(f) 331 | print("load()", F(load(bytecode))) 332 | print("load()", F(load(bytecode, "[L]"))) 333 | print("load()", F(load(bytecode, "[L]", "b"))) 334 | print("load()", F(load(bytecode, "[L]", "t"))) 335 | print("load()", F(load(bytecode, "[L]", "bt"))) 336 | f = load(bytecode, "[L]", "bt", {}) 337 | print("load()", pcall(f)) 338 | f = load(bytecode, "[L]", "bt", { print = noprint }) 339 | print("load()", pcall(f)) 340 | local function make_loader(code) 341 | local mid = math.floor( #code/2 ) 342 | local array = { code:sub(1, mid), code:sub(mid+1) } 343 | local i = 0 344 | return function() 345 | i = i + 1 346 | return array[i] 347 | end 348 | end 349 | print("load()", F(load(make_loader(badcode)))) 350 | print("load()", F(load(make_loader(code)))) 351 | print("load()", F(load(make_loader(code), "[L]"))) 352 | print("load()", F(load(make_loader(code), "[L]", "b"))) 353 | print("load()", F(load(make_loader(code), "[L]", "t"))) 354 | print("load()", F(load(make_loader(code), "[L]", "bt"))) 355 | f = load(make_loader(code), "[L]", "bt", {}) 356 | print("load()", pcall(f)) 357 | f = load(make_loader(code), "[L]", "bt", { print = noprint }) 358 | print("load()", pcall(f)) 359 | print("load()", F(load(make_loader(bytecode)))) 360 | print("load()", F(load(make_loader(bytecode), "[L]"))) 361 | print("load()", F(load(make_loader(bytecode), "[L]", "b"))) 362 | print("load()", F(load(make_loader(bytecode), "[L]", "t"))) 363 | print("load()", F(load(make_loader(bytecode), "[L]", "bt"))) 364 | f = load(make_loader(bytecode), "[L]", "bt", {}) 365 | print("load()", pcall(f)) 366 | f = load(make_loader(bytecode), "[L]", "bt", { print = noprint }) 367 | print("load()", pcall(f)) 368 | writefile("good.lua", code) 369 | writefile("bad.lua", badcode) 370 | writefile("good.luac", bytecode, true) 371 | print("loadfile()", F(loadfile("bad.lua"))) 372 | print("loadfile()", F(loadfile("good.lua"))) 373 | print("loadfile()", F(loadfile("good.lua", "b"))) 374 | print("loadfile()", F(loadfile("good.lua", "t"))) 375 | print("loadfile()", F(loadfile("good.lua", "bt"))) 376 | f = loadfile("good.lua", "bt", {}) 377 | print("loadfile()", pcall(f)) 378 | f = loadfile("good.lua", "bt", { print = noprint }) 379 | print("loadfile()", pcall(f)) 380 | print("loadfile()", F(loadfile("good.luac"))) 381 | print("loadfile()", F(loadfile("good.luac", "b"))) 382 | print("loadfile()", F(loadfile("good.luac", "t"))) 383 | print("loadfile()", F(loadfile("good.luac", "bt"))) 384 | f = loadfile("good.luac", "bt", {}) 385 | print("loadfile()", pcall(f)) 386 | f = loadfile("good.luac", "bt", { print = noprint }) 387 | print("loadfile()", pcall(f)) 388 | os.remove("good.lua") 389 | os.remove("bad.lua") 390 | os.remove("good.luac") 391 | end 392 | 393 | 394 | ___'' 395 | do 396 | local function func(throw) 397 | if throw then 398 | error("argh") 399 | else 400 | return 1, 2, 3 401 | end 402 | end 403 | local function tb(err) return "|"..err.."|" end 404 | print("xpcall()", xpcall(func, debug.traceback, false)) 405 | print("xpcall()", xpcall(func, debug.traceback, true)) 406 | print("xpcall()", xpcall(func, tb, true)) 407 | if mode ~= "module" then 408 | local function func2(cb) 409 | print("xpcall()", xpcall(cb, debug.traceback, "str")) 410 | end 411 | local function func3(cb) 412 | print("pcall()", pcall(cb, "str")) 413 | end 414 | local function cb(arg) 415 | coroutine.yield(2) 416 | return arg 417 | end 418 | local c = coroutine.wrap(func2) 419 | print("xpcall()", c(cb)) 420 | print("xpcall()", c()) 421 | local c = coroutine.wrap(func3) 422 | print("pcall()", c(cb)) 423 | print("pcall()", c()) 424 | end 425 | end 426 | 427 | 428 | ___'' 429 | do 430 | local t = setmetatable({ 1 }, { __len = function() return 5 end }) 431 | print("rawlen()", rawlen(t), rawlen("123")) 432 | end 433 | 434 | 435 | ___'' 436 | print("os.execute()", os.execute("exit 1")) 437 | io.flush() 438 | print("os.execute()", os.execute("echo 'hello world!'")) 439 | io.flush() 440 | print("os.execute()", os.execute("no_such_file")) 441 | 442 | 443 | ___'' 444 | do 445 | local t = table.pack("a", nil, "b", nil) 446 | print("table.(un)pack()", t.n, table.unpack(t, 1, t.n)) 447 | end 448 | 449 | 450 | ___'' 451 | do 452 | print("coroutine.running()", F(coroutine.wrap(function() 453 | return coroutine.running() 454 | end)())) 455 | print("coroutine.running()", F(coroutine.running())) 456 | local main_co, co1, co2 = coroutine.running() 457 | -- coroutine.yield 458 | if mode ~= "module" then 459 | print("coroutine.yield()", pcall(function() 460 | coroutine.yield(1, 2, 3) 461 | end)) 462 | end 463 | print("coroutine.yield()", coroutine.wrap(function() 464 | coroutine.yield(1, 2, 3) 465 | end)()) 466 | print("coroutine.resume()", coroutine.resume(main_co, 1, 2, 3)) 467 | co1 = coroutine.create(function(a, b, c) 468 | print("coroutine.resume()", a, b, c) 469 | return a, b, c 470 | end) 471 | print("coroutine.resume()", coroutine.resume(co1, 1, 2, 3)) 472 | co1 = coroutine.create(function() 473 | print("coroutine.status()", "[co1] main is", coroutine.status(main_co)) 474 | print("coroutine.status()", "[co1] co2 is", coroutine.status(co2)) 475 | end) 476 | co2 = coroutine.create(function() 477 | print("coroutine.status()", "[co2] main is", coroutine.status(main_co)) 478 | print("coroutine.status()", "[co2] co2 is", coroutine.status(co2)) 479 | coroutine.yield() 480 | coroutine.resume(co1) 481 | end) 482 | print("coroutine.status()", coroutine.status(main_co)) 483 | print("coroutine.status()", coroutine.status(co2)) 484 | coroutine.resume(co2) 485 | print("coroutine.status()", F(coroutine.status(co2))) 486 | coroutine.resume(co2) 487 | print("coroutine.status()", F(coroutine.status(co2))) 488 | end 489 | 490 | 491 | ___'' 492 | print("math.log()", math.log(1000)) 493 | print("math.log()", math.log(1000, 10)) 494 | 495 | 496 | ___'' 497 | do 498 | local path, prefix = "./?.lua;?/init.lua;../?.lua", "package.searchpath()" 499 | print(prefix, package.searchpath("no.such.module", path)) 500 | print(prefix, package.searchpath("no.such.module", "")) 501 | print(prefix, package.searchpath("compat53", path)) 502 | print(prefix, package.searchpath("no:such:module", path, ":", "|")) 503 | end 504 | 505 | 506 | ___'' 507 | if mode ~= "module" then 508 | local function mod_func() return {} end 509 | local function my_searcher(name) 510 | if name == "my.module" then 511 | print("package.searchers", "my.module found") 512 | return mod_func 513 | end 514 | end 515 | local function my_searcher2(name) 516 | if name == "my.module" then 517 | print("package.searchers", "my.module found 2") 518 | return mod_func 519 | end 520 | end 521 | table.insert(package.searchers, my_searcher) 522 | require("my.module") 523 | package.loaded["my.module"] = nil 524 | local new_s = { my_searcher2 } 525 | for i,f in ipairs(package.searchers) do 526 | new_s[i+1] = f 527 | end 528 | package.searchers = new_s 529 | require("my.module") 530 | end 531 | 532 | 533 | ___'' 534 | do 535 | print("string.find()", string.find("abc\0abc\0abc", "[^a\0]+")) 536 | print("string.find()", string.find("abc\0abc\0abc", "%w+\0", 5)) 537 | for x in string.gmatch("abc\0def\0ghi", "[^\0]+") do 538 | print("string.gmatch()", x) 539 | end 540 | for x in string.gmatch("abc\0def\0ghi", "%w*\0") do 541 | print("string.gmatch()", #x) 542 | end 543 | print("string.gsub()", string.gsub("abc\0def\0ghi", "[\0]", "X")) 544 | print("string.gsub()", string.gsub("abc\0def\0ghi", "%w*\0", "X")) 545 | print("string.gsub()", string.gsub("abc\0def\0ghi", "%A", "X")) 546 | print("string.match()", string.match("abc\0abc\0abc", "([^\0a]+)")) 547 | print("string.match()", #string.match("abc\0abc\0abc", ".*\0")) 548 | print("string.rep()", string.rep("a", 0)) 549 | print("string.rep()", string.rep("b", 1)) 550 | print("string.rep()", string.rep("c", 4)) 551 | print("string.rep()", string.rep("a", 0, "|")) 552 | print("string.rep()", string.rep("b", 1, "|")) 553 | print("string.rep()", string.rep("c", 4, "|")) 554 | local _tostring = tostring 555 | function tostring(v) 556 | if type(v) == "number" then 557 | return "(".._tostring(v)..")" 558 | else 559 | return _tostring(v) 560 | end 561 | end 562 | print("string.format()", string.format("%q", "\"\\\0000\0010\002\r\n0\t0\"")) 563 | print("string.format()", string.format("%12.3fx%%sxx%.6s", 3.1, {})) 564 | print("string.format()", string.format("%-3f %%%s %%s", 3.1, true)) 565 | print("string.format()", string.format("% 3.2g %%d %%%s", 3.1, nil)) 566 | print("string.format()", string.format("%+3d %%d %%%%%10.6s", 3, io.stdout)) 567 | print("string.format()", pcall(function() 568 | print("string.format()", string.format("%d %%s", {})) 569 | end)) 570 | tostring = _tostring 571 | end 572 | 573 | 574 | ___'' 575 | do 576 | print("io.write()", io.type(io.write("hello world\n"))) 577 | local f = assert(io.tmpfile()) 578 | print("file:write()", io.type(f:write("hello world\n"))) 579 | f:close() 580 | end 581 | 582 | 583 | ___'' 584 | do 585 | writefile("data.txt", "123 18.8 hello world\ni'm here\n") 586 | io.input("data.txt") 587 | print("io.read()", io.read("*n", "*number", "*l", "*a")) 588 | io.input("data.txt") 589 | print("io.read()", io.read("n", "number", "l", "a")) 590 | io.input(io.stdin) 591 | if mode ~= "module" then 592 | local f = assert(io.open("data.txt", "r")) 593 | print("file:read()", f:read("*n", "*number", "*l", "*a")) 594 | f:close() 595 | f = assert(io.open("data.txt", "r")) 596 | print("file:read()", f:read("n", "number", "l", "a")) 597 | f:close() 598 | end 599 | os.remove("data.txt") 600 | end 601 | 602 | 603 | ___'' 604 | do 605 | writefile("data.txt", "123 18.8 hello world\ni'm here\n") 606 | for a,b in io.lines(self, 2, "*l") do 607 | print("io.lines()", a, b) 608 | break 609 | end 610 | for l in io.lines(self) do 611 | print("io.lines()", l) 612 | break 613 | end 614 | for n1,n2,rest in io.lines("data.txt", "*n", "n", "*a") do 615 | print("io.lines()", n1, n2, rest) 616 | end 617 | for l in io.lines("data.txt") do 618 | print("io.lines()", l) 619 | end 620 | print("io.lines()", pcall(function() 621 | for l in io.lines("data.txt", "*x") do print(l) end 622 | end)) 623 | print("io.lines()", pcall(function() 624 | for l in io.lines("no_such_file.txt") do print(l) end 625 | end)) 626 | if mode ~= "module" then 627 | local f = assert(io.open(self, "r")) 628 | for a,b in f:lines(2, "*l") do 629 | print("file:lines()", a, b) 630 | break 631 | end 632 | f:close() 633 | f = assert(io.open("data.txt", "r")) 634 | for n1,n2,rest in f:lines("*n", "n", "*a") do 635 | print("file:lines()", n1, n2, rest) 636 | end 637 | f:close() 638 | f = assert(io.open("data.txt", "r")) 639 | for l in f:lines() do 640 | print("file:lines()", l) 641 | end 642 | f:close() 643 | print("file:lines()", pcall(function() 644 | for l in f:lines() do print(l) end 645 | end)) 646 | print("file:lines()", pcall(function() 647 | local f = assert(io.open("data.txt", "r")) 648 | for l in f:lines("*l", "*x") do print(l) end 649 | f:close() 650 | end)) 651 | end 652 | os.remove("data.txt") 653 | end 654 | ___'' 655 | 656 | 657 | print("testing C API ...") 658 | local mod = require("testmod") 659 | ___'' 660 | print("isinteger", mod.isinteger(1)) 661 | print("isinteger", mod.isinteger(0)) 662 | print("isinteger", mod.isinteger(1234567)) 663 | print("isinteger", mod.isinteger(12.3)) 664 | print("isinteger", mod.isinteger(math.huge)) 665 | print("isinteger", mod.isinteger(math.sqrt(-1))) 666 | 667 | ___'' 668 | print("rotate", mod.rotate(1, 1, 2, 3, 4, 5, 6)) 669 | print("rotate", mod.rotate(-1, 1, 2, 3, 4, 5, 6)) 670 | print("rotate", mod.rotate(4, 1, 2, 3, 4, 5, 6)) 671 | print("rotate", mod.rotate(-4, 1, 2, 3, 4, 5, 6)) 672 | 673 | ___'' 674 | print("strtonum", mod.strtonum("+123")) 675 | print("strtonum", mod.strtonum(" 123 ")) 676 | print("strtonum", mod.strtonum("-1.23")) 677 | print("strtonum", mod.strtonum(" 123 abc")) 678 | print("strtonum", mod.strtonum("jkl")) 679 | 680 | ___'' 681 | local a, b, c = mod.requiref() 682 | print("requiref", type(a), type(b), type(c), 683 | a.boolean, b.boolean, c.boolean, 684 | type(requiref1), type(requiref2), type(requiref3)) 685 | 686 | ___'' 687 | local c = coroutine.wrap(function() 688 | mod.extraspace("uvw") 689 | print("getextraspace", mod.extraspace()) 690 | coroutine.yield() 691 | print("getextraspace", mod.extraspace()) 692 | coroutine.yield() 693 | print("getextraspace", mod.extraspace()) 694 | end) 695 | c() 696 | mod.extraspace("abc") 697 | print("getextraspace", mod.extraspace()) 698 | c() 699 | local d = coroutine.wrap(function() 700 | print("getextraspace", mod.extraspace()) 701 | mod.extraspace("xyz") 702 | print("getextraspace", mod.extraspace()) 703 | coroutine.yield() 704 | print("getextraspace", mod.extraspace()) 705 | coroutine.yield() 706 | print("getextraspace", mod.extraspace()) 707 | end) 708 | d() 709 | print("getextraspace", mod.extraspace()) 710 | mod.extraspace("123") 711 | c() 712 | d() 713 | 714 | ___'' 715 | local proxy, backend = {}, {} 716 | setmetatable(proxy, { __index = backend, __newindex = backend }) 717 | print("geti/seti", rawget(proxy, 1), rawget(backend, 1)) 718 | print("geti/seti", mod.getseti(proxy, 1)) 719 | print("geti/seti", rawget(proxy, 1), rawget(backend, 1)) 720 | print("geti/seti", mod.getseti(proxy, 1)) 721 | print("geti/seti", rawget(proxy, 1), rawget(backend, 1)) 722 | 723 | -- tests for Lua 5.1 724 | ___'' 725 | print("tonumber", mod.tonumber(12)) 726 | print("tonumber", mod.tonumber("12")) 727 | print("tonumber", mod.tonumber("0")) 728 | print("tonumber", mod.tonumber(false)) 729 | print("tonumber", mod.tonumber("error")) 730 | 731 | ___'' 732 | print("tointeger", mod.tointeger(12)) 733 | print("tointeger", mod.tointeger(12)) 734 | print("tointeger", mod.tointeger(12.1)) 735 | print("tointeger", mod.tointeger(12.9)) 736 | print("tointeger", mod.tointeger(-12.1)) 737 | print("tointeger", mod.tointeger(-12.9)) 738 | print("tointeger", mod.tointeger("12")) 739 | print("tointeger", mod.tointeger("0")) 740 | print("tointeger", mod.tointeger(math.pi)) 741 | print("tointeger", mod.tointeger(false)) 742 | print("tointeger", mod.tointeger("error")) 743 | 744 | ___'' 745 | print("len", mod.len("123")) 746 | print("len", mod.len({ 1, 2, 3})) 747 | print("len", pcall(mod.len, true)) 748 | local ud, meta = mod.newproxy() 749 | meta.__len = function() return 5 end 750 | print("len", mod.len(ud)) 751 | meta.__len = function() return true end 752 | print("len", pcall(mod.len, ud)) 753 | 754 | ___'' 755 | print("copy", mod.copy(true, "string", {}, 1)) 756 | 757 | ___'' 758 | print("rawgetp/rawsetp", mod.rawxetp()) 759 | print("rawgetp/rawsetp", mod.rawxetp("I'm back")) 760 | 761 | ___'' 762 | print("globals", F(mod.globals()), mod.globals() == _G) 763 | 764 | ___'' 765 | local t = {} 766 | print("getsubtable", F(mod.subtable(t))) 767 | local x, msg = mod.subtable(t) 768 | print("getsubtable", F(x, msg, x == t.xxx)) 769 | 770 | ___'' 771 | print("udata", F(mod.udata())) 772 | print("udata", mod.udata("nosuchtype")) 773 | 774 | ___'' 775 | print("uservalue", F(mod.uservalue())) 776 | 777 | ___'' 778 | print("upvalues", mod.getupvalues()) 779 | 780 | ___'' 781 | print("absindex", mod.absindex("hi", true)) 782 | 783 | ___'' 784 | print("arith", mod.arith(2, 1)) 785 | print("arith", mod.arith(3, 5)) 786 | 787 | ___'' 788 | print("compare", mod.compare(1, 1)) 789 | print("compare", mod.compare(2, 1)) 790 | print("compare", mod.compare(1, 2)) 791 | 792 | ___'' 793 | print("tolstring", mod.tolstring("string")) 794 | local t = setmetatable({}, { 795 | __tostring = function(v) return "mytable" end 796 | }) 797 | print("tolstring", mod.tolstring(t)) 798 | local t = setmetatable({}, { 799 | __tostring = function(v) return nil end 800 | }) 801 | print("tolstring", pcall(mod.tolstring, t)) 802 | local ud, meta = mod.newproxy() 803 | meta.__name = "XXX" 804 | print("tolstring", mod.tolstring(ud):gsub(":.*$", ": yyy")) 805 | 806 | ___'' 807 | print("pushstring", mod.pushstring()) 808 | 809 | ___'' 810 | print("Buffer", mod.buffer()) 811 | 812 | ___'' 813 | print("execresult", mod.exec("exit 0")) 814 | print("execresult", mod.exec("exit 1")) 815 | print("execresult", mod.exec("exit 25")) 816 | 817 | ___'' 818 | do 819 | local bin = string.dump(function() end) 820 | local modes = { "t", "b", "bt" } 821 | local codes = { 822 | "", "return true", bin, "invalidsource", "\27invalidbinary" 823 | } 824 | for _,m in ipairs(modes) do 825 | for i,c in ipairs(codes) do 826 | print("loadbufferx", m, i, F(mod.loadstring(c, m))) 827 | end 828 | end 829 | 830 | ___'' 831 | local bom = "\239\187\191" 832 | local shebang = "#!/usr/bin/env lua\n" 833 | codes[#codes+1] = bom .. shebang .. "return true" 834 | codes[#codes+1] = bom .. shebang .. bin 835 | codes[#codes+1] = bom .. shebang .. "invalidsource" 836 | codes[#codes+1] = bom .. shebang .. "\027invalidbinary" 837 | for _,m in ipairs(modes) do 838 | for i,c in ipairs(codes) do 839 | print("loadfilex", m, i, F(mod.loadfile(c, m))) 840 | end 841 | end 842 | end 843 | ___'' 844 | 845 | -------------------------------------------------------------------------------- /vendor/compat53/tests/testmod.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "compat-5.3.h" 5 | 6 | 7 | static int test_isinteger (lua_State *L) { 8 | lua_pushboolean(L, lua_isinteger(L, 1)); 9 | return 1; 10 | } 11 | 12 | 13 | static int test_rotate (lua_State *L) { 14 | int r = (int)luaL_checkinteger(L, 1); 15 | int n = lua_gettop(L)-1; 16 | luaL_argcheck(L, (r < 0 ? -r : r) <= n, 1, "not enough arguments"); 17 | lua_rotate(L, 2, r); 18 | return n; 19 | } 20 | 21 | 22 | static int test_str2num (lua_State *L) { 23 | const char *s = luaL_checkstring(L, 1); 24 | size_t len = lua_stringtonumber(L, s); 25 | if (len == 0) 26 | lua_pushnumber(L, 0); 27 | lua_pushinteger(L, (lua_Integer)len); 28 | return 2; 29 | } 30 | 31 | 32 | static int my_mod (lua_State *L ) { 33 | lua_newtable(L); 34 | lua_pushboolean(L, 1); 35 | lua_setfield(L, -2, "boolean"); 36 | return 1; 37 | } 38 | 39 | static int test_requiref (lua_State *L) { 40 | lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); 41 | lua_newtable(L); 42 | lua_pushboolean(L, 0); 43 | lua_setfield(L, -2, "boolean"); 44 | lua_setfield(L, -2, "requiref3"); 45 | lua_pop(L, 1); 46 | luaL_requiref(L, "requiref1", my_mod, 0); 47 | luaL_requiref(L, "requiref2", my_mod, 1); 48 | luaL_requiref(L, "requiref3", my_mod, 1); 49 | return 3; 50 | } 51 | 52 | static int test_getseti (lua_State *L) { 53 | lua_Integer k = luaL_checkinteger(L, 2); 54 | lua_Integer n = 0; 55 | if (lua_geti(L, 1, k) == LUA_TNUMBER) { 56 | n = lua_tointeger(L, -1); 57 | } else { 58 | lua_pop(L, 1); 59 | lua_pushinteger(L, n); 60 | } 61 | lua_pushinteger(L, n+1); 62 | lua_seti(L, 1, k); 63 | return 1; 64 | } 65 | 66 | 67 | #ifndef LUA_EXTRASPACE 68 | #define LUA_EXTRASPACE (sizeof(void*)) 69 | #endif 70 | 71 | static int test_getextraspace (lua_State *L) { 72 | size_t len = 0; 73 | char const* s = luaL_optlstring(L, 1, NULL, &len); 74 | char* p = (char*)lua_getextraspace(L); 75 | lua_pushstring(L, p); 76 | if (s) 77 | memcpy(p, s, len > LUA_EXTRASPACE-1 ? LUA_EXTRASPACE-1 : len+1); 78 | return 1; 79 | } 80 | 81 | 82 | /* additional tests for Lua5.1 */ 83 | #define NUP 3 84 | 85 | static int test_newproxy (lua_State *L) { 86 | lua_settop(L, 0); 87 | lua_newuserdata(L, 0); 88 | lua_newtable(L); 89 | lua_pushvalue(L, -1); 90 | lua_pushboolean(L, 1); 91 | lua_setfield(L, -2, "__gc"); 92 | lua_setmetatable(L, -3); 93 | return 2; 94 | } 95 | 96 | static int test_absindex (lua_State *L) { 97 | int i = 1; 98 | for (i = 1; i <= NUP; ++i) 99 | lua_pushvalue(L, lua_absindex(L, lua_upvalueindex(i))); 100 | lua_pushvalue(L, lua_absindex(L, LUA_REGISTRYINDEX)); 101 | lua_pushstring(L, lua_typename(L, lua_type(L, lua_absindex(L, -1)))); 102 | lua_replace(L, lua_absindex(L, -2)); 103 | lua_pushvalue(L, lua_absindex(L, -2)); 104 | lua_pushvalue(L, lua_absindex(L, -4)); 105 | lua_pushvalue(L, lua_absindex(L, -6)); 106 | i += 3; 107 | lua_pushvalue(L, lua_absindex(L, 1)); 108 | lua_pushvalue(L, lua_absindex(L, 2)); 109 | lua_pushvalue(L, lua_absindex(L, 3)); 110 | i += 3; 111 | return i; 112 | } 113 | 114 | static int test_arith (lua_State *L) { 115 | lua_settop(L, 2); 116 | lua_pushvalue(L, 1); 117 | lua_pushvalue(L, 2); 118 | lua_arith(L, LUA_OPADD); 119 | lua_pushvalue(L, 1); 120 | lua_pushvalue(L, 2); 121 | lua_arith(L, LUA_OPSUB); 122 | lua_pushvalue(L, 1); 123 | lua_pushvalue(L, 2); 124 | lua_arith(L, LUA_OPMUL); 125 | lua_pushvalue(L, 1); 126 | lua_pushvalue(L, 2); 127 | lua_arith(L, LUA_OPDIV); 128 | lua_pushvalue(L, 1); 129 | lua_pushvalue(L, 2); 130 | lua_arith(L, LUA_OPMOD); 131 | lua_pushvalue(L, 1); 132 | lua_pushvalue(L, 2); 133 | lua_arith(L, LUA_OPPOW); 134 | lua_pushvalue(L, 1); 135 | lua_arith(L, LUA_OPUNM); 136 | return lua_gettop(L)-2; 137 | } 138 | 139 | static int test_compare (lua_State *L) { 140 | luaL_checknumber(L, 1); 141 | luaL_checknumber(L, 2); 142 | lua_settop(L, 2); 143 | lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPEQ)); 144 | lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPLT)); 145 | lua_pushboolean(L, lua_compare(L, 1, 2, LUA_OPLE)); 146 | return 3; 147 | } 148 | 149 | static int test_globals (lua_State *L) { 150 | lua_pushglobaltable(L); 151 | return 1; 152 | } 153 | 154 | static int test_tonumber (lua_State *L) { 155 | int isnum = 0; 156 | lua_Number n = lua_tonumberx(L, 1, &isnum); 157 | if (!isnum) 158 | lua_pushnil(L); 159 | else 160 | lua_pushnumber(L, n); 161 | return 1; 162 | } 163 | 164 | static int test_tointeger (lua_State *L) { 165 | int isnum = 0; 166 | lua_Integer n = lua_tointegerx(L, 1, &isnum); 167 | if (!isnum) 168 | lua_pushnil(L); 169 | else 170 | lua_pushinteger(L, n); 171 | lua_pushinteger(L, lua_tointeger(L, 1)); 172 | return 2; 173 | } 174 | 175 | static int test_len (lua_State *L) { 176 | luaL_checkany(L, 1); 177 | lua_len(L, 1); 178 | lua_pushinteger(L, luaL_len(L, 1)); 179 | return 2; 180 | } 181 | 182 | static int test_copy (lua_State *L) { 183 | int args = lua_gettop(L); 184 | if (args >= 2) { 185 | int i = 0; 186 | for (i = args-1; i > 0; --i) 187 | lua_copy(L, args, i); 188 | } 189 | return args; 190 | } 191 | 192 | /* need an address */ 193 | static char const dummy = 0; 194 | 195 | static int test_rawxetp (lua_State *L) { 196 | if (lua_gettop(L) > 0) 197 | lua_pushvalue(L, 1); 198 | else 199 | lua_pushliteral(L, "hello again"); 200 | lua_rawsetp(L, LUA_REGISTRYINDEX, &dummy); 201 | lua_settop(L, 0); 202 | lua_rawgetp(L, LUA_REGISTRYINDEX, &dummy); 203 | return 1; 204 | } 205 | 206 | static int test_udata (lua_State *L) { 207 | const char *tname = luaL_optstring(L, 1, "utype1"); 208 | void *u1 = lua_newuserdata(L, 1); 209 | int u1pos = lua_gettop(L); 210 | void *u2 = lua_newuserdata(L, 1); 211 | int u2pos = lua_gettop(L); 212 | luaL_newmetatable(L, "utype1"); 213 | luaL_newmetatable(L, "utype2"); 214 | lua_pop(L, 2); 215 | luaL_setmetatable(L, "utype2"); 216 | lua_pushvalue(L, u1pos); 217 | luaL_setmetatable(L, "utype1"); 218 | lua_pop(L, 1); 219 | (void)u1; 220 | (void)u2; 221 | lua_pushlightuserdata(L, luaL_testudata(L, u1pos, tname)); 222 | lua_pushlightuserdata(L, luaL_testudata(L, u2pos, tname)); 223 | luaL_getmetatable(L, "utype1"); 224 | lua_getfield(L, -1, "__name"); 225 | lua_replace(L, -2); 226 | return 3; 227 | } 228 | 229 | static int test_subtable (lua_State *L) { 230 | luaL_checktype(L, 1, LUA_TTABLE); 231 | lua_settop(L, 1); 232 | if (luaL_getsubtable(L, 1, "xxx")) { 233 | lua_pushliteral(L, "oldtable"); 234 | } else { 235 | lua_pushliteral(L, "newtable"); 236 | } 237 | return 2; 238 | } 239 | 240 | static int test_uservalue (lua_State *L) { 241 | void *udata = lua_newuserdata(L, 1); 242 | int ui = lua_gettop(L); 243 | lua_newtable(L); 244 | lua_setuservalue(L, ui); 245 | lua_pushinteger(L, lua_getuservalue(L, ui)); 246 | (void)udata; 247 | return 2; 248 | } 249 | 250 | static int test_upvalues (lua_State *L) { 251 | int i = 1; 252 | for (i = 1; i <= NUP; ++i) 253 | lua_pushvalue(L, lua_upvalueindex(i)); 254 | return NUP; 255 | } 256 | 257 | static int test_tolstring (lua_State *L) { 258 | size_t len = 0; 259 | luaL_tolstring(L, 1, &len); 260 | lua_pushinteger(L, (int)len); 261 | return 2; 262 | } 263 | 264 | static int test_pushstring (lua_State *L) { 265 | lua_pushstring(L, lua_pushliteral(L, "abc")); 266 | lua_pushstring(L, lua_pushlstring(L, "abc", 2)); 267 | lua_pushstring(L, lua_pushlstring(L, NULL, 0)); 268 | lua_pushstring(L, lua_pushstring(L, "abc")); 269 | lua_pushboolean(L, NULL == lua_pushstring(L, NULL)); 270 | return 10; 271 | } 272 | 273 | static int test_buffer (lua_State *L) { 274 | luaL_Buffer b; 275 | char *p = luaL_buffinitsize(L, &b, LUAL_BUFFERSIZE+1); 276 | p[0] = 'a'; 277 | p[1] = 'b'; 278 | luaL_addsize(&b, 2); 279 | luaL_addstring(&b, "c"); 280 | lua_pushliteral(L, "d"); 281 | luaL_addvalue(&b); 282 | luaL_addchar(&b, 'e'); 283 | luaL_pushresult(&b); 284 | return 1; 285 | } 286 | 287 | static int test_exec (lua_State *L) { 288 | const char *cmd = luaL_checkstring(L, 1); 289 | errno = 0; 290 | return luaL_execresult(L, system(cmd)); 291 | } 292 | 293 | static int test_loadstring (lua_State *L) { 294 | size_t len = 0; 295 | char const* s = luaL_checklstring(L, 1, &len); 296 | char const* mode = luaL_optstring(L, 2, "bt"); 297 | lua_pushinteger(L, luaL_loadbufferx(L, s, len, s, mode)); 298 | return 2; 299 | } 300 | 301 | static int test_loadfile (lua_State *L) { 302 | char filename[L_tmpnam+1] = { 0 }; 303 | size_t len = 0; 304 | char const* s = luaL_checklstring(L, 1, &len); 305 | char const* mode = luaL_optstring(L, 2, "bt"); 306 | if (tmpnam(filename)) { 307 | FILE* f = fopen(filename, "wb"); 308 | if (f) { 309 | fwrite(s, 1, len, f); 310 | fclose(f); 311 | lua_pushinteger(L, luaL_loadfilex(L, filename, mode)); 312 | remove(filename); 313 | return 2; 314 | } else 315 | remove(filename); 316 | } 317 | return 0; 318 | } 319 | 320 | 321 | static const luaL_Reg funcs[] = { 322 | { "isinteger", test_isinteger }, 323 | { "rotate", test_rotate }, 324 | { "strtonum", test_str2num }, 325 | { "requiref", test_requiref }, 326 | { "getseti", test_getseti }, 327 | { "extraspace", test_getextraspace }, 328 | { "newproxy", test_newproxy }, 329 | { "arith", test_arith }, 330 | { "compare", test_compare }, 331 | { "tonumber", test_tonumber }, 332 | { "tointeger", test_tointeger }, 333 | { "len", test_len }, 334 | { "copy", test_copy }, 335 | { "rawxetp", test_rawxetp }, 336 | { "subtable", test_subtable }, 337 | { "udata", test_udata }, 338 | { "uservalue", test_uservalue }, 339 | { "globals", test_globals }, 340 | { "tolstring", test_tolstring }, 341 | { "pushstring", test_pushstring }, 342 | { "buffer", test_buffer }, 343 | { "exec", test_exec }, 344 | { "loadstring", test_loadstring }, 345 | { "loadfile", test_loadfile }, 346 | { NULL, NULL } 347 | }; 348 | 349 | static const luaL_Reg more_funcs[] = { 350 | { "getupvalues", test_upvalues }, 351 | { "absindex", test_absindex }, 352 | { NULL, NULL } 353 | }; 354 | 355 | 356 | #ifdef __cplusplus 357 | extern "C" { 358 | #endif 359 | int luaopen_testmod (lua_State *L) { 360 | int i = 1; 361 | luaL_newlib(L, funcs); 362 | for (i = 1; i <= NUP; ++i) 363 | lua_pushnumber(L, i); 364 | luaL_setfuncs(L, more_funcs, NUP); 365 | return 1; 366 | } 367 | #ifdef __cplusplus 368 | } 369 | #endif 370 | 371 | --------------------------------------------------------------------------------