mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 07:29:23 +00:00
Introduce testlib_extract() helper
This commit is contained in:
parent
ecb2ef7c39
commit
27b5deefb1
7 changed files with 53 additions and 54 deletions
40
libc/testlib/extract.c
Normal file
40
libc/testlib/extract.c
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||||
|
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||||
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||||
|
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||||
|
│ │
|
||||||
|
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||||
|
│ any purpose with or without fee is hereby granted, provided that the │
|
||||||
|
│ above copyright notice and this permission notice appear in all copies. │
|
||||||
|
│ │
|
||||||
|
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||||
|
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||||
|
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||||
|
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||||
|
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||||
|
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||||
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/mem/copyfd.internal.h"
|
||||||
|
#include "libc/sysv/consts/o.h"
|
||||||
|
#include "libc/testlib/testlib.h"
|
||||||
|
|
||||||
|
STATIC_YOINK("zip_uri_support");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts zip asset to filesystem.
|
||||||
|
*
|
||||||
|
* @param zip is name of asset in zip executable central directory
|
||||||
|
* @param to is local filesystem path to which it's extracted
|
||||||
|
* @param mode is file mode used for `to`
|
||||||
|
*/
|
||||||
|
void testlib_extract(const char *zip, const char *to, int mode) {
|
||||||
|
int fdin, fdout;
|
||||||
|
ASSERT_NE(-1, (fdin = open(zip, O_RDONLY)));
|
||||||
|
ASSERT_NE(-1, (fdout = creat(to, mode)));
|
||||||
|
ASSERT_NE(-1, _copyfd(fdin, fdout, -1));
|
||||||
|
ASSERT_NE(-1, close(fdout));
|
||||||
|
ASSERT_NE(-1, close(fdin));
|
||||||
|
}
|
|
@ -398,6 +398,7 @@ bool testlib_strcaseequals(size_t, const void *, const void *) nosideeffect;
|
||||||
bool testlib_strncaseequals(size_t, const void *, const void *,
|
bool testlib_strncaseequals(size_t, const void *, const void *,
|
||||||
size_t) nosideeffect;
|
size_t) nosideeffect;
|
||||||
void testlib_free(void *);
|
void testlib_free(void *);
|
||||||
|
void testlib_extract(const char *, const char *, int);
|
||||||
bool testlib_binequals(const char16_t *, const void *, size_t) nosideeffect;
|
bool testlib_binequals(const char16_t *, const void *, size_t) nosideeffect;
|
||||||
bool testlib_hexequals(const char *, const void *, size_t) nosideeffect;
|
bool testlib_hexequals(const char *, const void *, size_t) nosideeffect;
|
||||||
bool testlib_startswith(size_t, const void *, const void *) nosideeffect;
|
bool testlib_startswith(size_t, const void *, const void *) nosideeffect;
|
||||||
|
|
|
@ -59,6 +59,7 @@ LIBC_TESTLIB_A_SRCS_C = \
|
||||||
libc/testlib/comborunner.c \
|
libc/testlib/comborunner.c \
|
||||||
libc/testlib/contains.c \
|
libc/testlib/contains.c \
|
||||||
libc/testlib/endswith.c \
|
libc/testlib/endswith.c \
|
||||||
|
libc/testlib/extract.c \
|
||||||
libc/testlib/ezbenchcontrol.c \
|
libc/testlib/ezbenchcontrol.c \
|
||||||
libc/testlib/ezbenchreport.c \
|
libc/testlib/ezbenchreport.c \
|
||||||
libc/testlib/ezbenchwarn.c \
|
libc/testlib/ezbenchwarn.c \
|
||||||
|
|
|
@ -61,8 +61,6 @@
|
||||||
#include "libc/time/time.h"
|
#include "libc/time/time.h"
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
|
|
||||||
STATIC_YOINK("zip_uri_support");
|
|
||||||
|
|
||||||
char testlib_enable_tmp_setup_teardown;
|
char testlib_enable_tmp_setup_teardown;
|
||||||
|
|
||||||
void OnSig(int sig) {
|
void OnSig(int sig) {
|
||||||
|
@ -71,26 +69,11 @@ void OnSig(int sig) {
|
||||||
|
|
||||||
int sys_memfd_secret(unsigned int); // our ENOSYS threshold
|
int sys_memfd_secret(unsigned int); // our ENOSYS threshold
|
||||||
|
|
||||||
int extract(const char *from, const char *to, int mode) {
|
|
||||||
int fdin, fdout;
|
|
||||||
if ((fdin = open(from, O_RDONLY)) == -1) return -1;
|
|
||||||
if ((fdout = creat(to, mode)) == -1) {
|
|
||||||
close(fdin);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (_copyfd(fdin, fdout, -1) == -1) {
|
|
||||||
close(fdout);
|
|
||||||
close(fdin);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return close(fdout) | close(fdin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetUp(void) {
|
void SetUp(void) {
|
||||||
__enable_threads();
|
__enable_threads();
|
||||||
if (!__is_linux_2_6_23() && !IsOpenbsd()) exit(0);
|
if (!__is_linux_2_6_23() && !IsOpenbsd()) exit(0);
|
||||||
ASSERT_SYS(0, 0, extract("/zip/life.elf", "life.elf", 0755));
|
testlib_extract("/zip/life.elf", "life.elf", 0755);
|
||||||
ASSERT_SYS(0, 0, extract("/zip/sock.elf", "sock.elf", 0755));
|
testlib_extract("/zip/sock.elf", "sock.elf", 0755);
|
||||||
__pledge_mode = PLEDGE_PENALTY_RETURN_EPERM;
|
__pledge_mode = PLEDGE_PENALTY_RETURN_EPERM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/mem/copyfd.internal.h"
|
|
||||||
#include "libc/calls/landlock.h"
|
#include "libc/calls/landlock.h"
|
||||||
#include "libc/calls/struct/dirent.h"
|
#include "libc/calls/struct/dirent.h"
|
||||||
#include "libc/calls/struct/stat.h"
|
#include "libc/calls/struct/stat.h"
|
||||||
|
@ -25,6 +24,7 @@
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/intrin/kprintf.h"
|
#include "libc/intrin/kprintf.h"
|
||||||
|
#include "libc/mem/copyfd.internal.h"
|
||||||
#include "libc/mem/gc.h"
|
#include "libc/mem/gc.h"
|
||||||
#include "libc/runtime/internal.h"
|
#include "libc/runtime/internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
@ -45,8 +45,6 @@
|
||||||
#include "libc/x/x.h"
|
#include "libc/x/x.h"
|
||||||
#include "libc/x/xasprintf.h"
|
#include "libc/x/xasprintf.h"
|
||||||
|
|
||||||
STATIC_YOINK("zip_uri_support");
|
|
||||||
|
|
||||||
#define EACCES_OR_ENOENT (IsOpenbsd() ? ENOENT : EACCES)
|
#define EACCES_OR_ENOENT (IsOpenbsd() ? ENOENT : EACCES)
|
||||||
|
|
||||||
char testlib_enable_tmp_setup_teardown;
|
char testlib_enable_tmp_setup_teardown;
|
||||||
|
@ -70,21 +68,6 @@ void SetUp(void) {
|
||||||
ASSERT_SYS(0, 0, stat("/zip/life.elf", &st));
|
ASSERT_SYS(0, 0, stat("/zip/life.elf", &st));
|
||||||
}
|
}
|
||||||
|
|
||||||
int extract(const char *from, const char *to, int mode) {
|
|
||||||
int fdin, fdout;
|
|
||||||
if ((fdin = open(from, O_RDONLY)) == -1) return -1;
|
|
||||||
if ((fdout = creat(to, mode)) == -1) {
|
|
||||||
close(fdin);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (_copyfd(fdin, fdout, -1) == -1) {
|
|
||||||
close(fdout);
|
|
||||||
close(fdin);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return close(fdout) | close(fdin);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST(unveil, api_differences) {
|
TEST(unveil, api_differences) {
|
||||||
SPAWN(fork);
|
SPAWN(fork);
|
||||||
ASSERT_SYS(0, 0, mkdir("foo", 0755));
|
ASSERT_SYS(0, 0, mkdir("foo", 0755));
|
||||||
|
@ -111,7 +94,7 @@ TEST(unveil, api_differences) {
|
||||||
TEST(unveil, rx_readOnlyPreexistingExecutable_worksFine) {
|
TEST(unveil, rx_readOnlyPreexistingExecutable_worksFine) {
|
||||||
SPAWN(fork);
|
SPAWN(fork);
|
||||||
ASSERT_SYS(0, 0, mkdir("folder", 0755));
|
ASSERT_SYS(0, 0, mkdir("folder", 0755));
|
||||||
ASSERT_SYS(0, 0, extract("/zip/life.elf", "folder/life.elf", 0755));
|
testlib_extract("/zip/life.elf", "folder/life.elf", 0755);
|
||||||
ASSERT_SYS(0, 0, unveil("folder", "rx"));
|
ASSERT_SYS(0, 0, unveil("folder", "rx"));
|
||||||
ASSERT_SYS(0, 0, unveil(0, 0));
|
ASSERT_SYS(0, 0, unveil(0, 0));
|
||||||
SPAWN(fork);
|
SPAWN(fork);
|
||||||
|
@ -125,7 +108,7 @@ TEST(unveil, rx_readOnlyPreexistingExecutable_worksFine) {
|
||||||
TEST(unveil, r_noExecutePreexistingExecutable_raisesEacces) {
|
TEST(unveil, r_noExecutePreexistingExecutable_raisesEacces) {
|
||||||
SPAWN(fork);
|
SPAWN(fork);
|
||||||
ASSERT_SYS(0, 0, mkdir("folder", 0755));
|
ASSERT_SYS(0, 0, mkdir("folder", 0755));
|
||||||
ASSERT_SYS(0, 0, extract("/zip/life.elf", "folder/life.elf", 0755));
|
testlib_extract("/zip/life.elf", "folder/life.elf", 0755);
|
||||||
ASSERT_SYS(0, 0, unveil("folder", "r"));
|
ASSERT_SYS(0, 0, unveil("folder", "r"));
|
||||||
ASSERT_SYS(0, 0, unveil(0, 0));
|
ASSERT_SYS(0, 0, unveil(0, 0));
|
||||||
SPAWN(fork);
|
SPAWN(fork);
|
||||||
|
@ -156,7 +139,7 @@ TEST(unveil, rwc_createExecutableFile_isAllowedButCantBeRun) {
|
||||||
ASSERT_SYS(0, 0, mkdir("folder", 0755));
|
ASSERT_SYS(0, 0, mkdir("folder", 0755));
|
||||||
ASSERT_SYS(0, 0, unveil("folder", "rwc"));
|
ASSERT_SYS(0, 0, unveil("folder", "rwc"));
|
||||||
ASSERT_SYS(0, 0, unveil(0, 0));
|
ASSERT_SYS(0, 0, unveil(0, 0));
|
||||||
ASSERT_SYS(0, 0, extract("/zip/life.elf", "folder/life.elf", 0755));
|
testlib_extract("/zip/life.elf", "folder/life.elf", 0755);
|
||||||
SPAWN(fork);
|
SPAWN(fork);
|
||||||
ASSERT_SYS(0, 0, stat("folder/life.elf", &st));
|
ASSERT_SYS(0, 0, stat("folder/life.elf", &st));
|
||||||
ASSERT_SYS(EACCES, -1, execl("folder/life.elf", "folder/life.elf", 0));
|
ASSERT_SYS(EACCES, -1, execl("folder/life.elf", "folder/life.elf", 0));
|
||||||
|
@ -169,7 +152,7 @@ TEST(unveil, rwcx_createExecutableFile_canAlsoBeRun) {
|
||||||
ASSERT_SYS(0, 0, mkdir("folder", 0755));
|
ASSERT_SYS(0, 0, mkdir("folder", 0755));
|
||||||
ASSERT_SYS(0, 0, unveil("folder", "rwcx"));
|
ASSERT_SYS(0, 0, unveil("folder", "rwcx"));
|
||||||
ASSERT_SYS(0, 0, unveil(0, 0));
|
ASSERT_SYS(0, 0, unveil(0, 0));
|
||||||
ASSERT_SYS(0, 0, extract("/zip/life.elf", "folder/life.elf", 0755));
|
testlib_extract("/zip/life.elf", "folder/life.elf", 0755);
|
||||||
SPAWN(fork);
|
SPAWN(fork);
|
||||||
ASSERT_SYS(0, 0, stat("folder/life.elf", &st));
|
ASSERT_SYS(0, 0, stat("folder/life.elf", &st));
|
||||||
execl("folder/life.elf", "folder/life.elf", 0);
|
execl("folder/life.elf", "folder/life.elf", 0);
|
||||||
|
@ -206,7 +189,7 @@ TEST(unveil, mostRestrictivePolicy) {
|
||||||
TEST(unveil, overlappingDirectories_inconsistentBehavior) {
|
TEST(unveil, overlappingDirectories_inconsistentBehavior) {
|
||||||
SPAWN(fork);
|
SPAWN(fork);
|
||||||
ASSERT_SYS(0, 0, makedirs("f1/f2", 0755));
|
ASSERT_SYS(0, 0, makedirs("f1/f2", 0755));
|
||||||
ASSERT_SYS(0, 0, extract("/zip/life.elf", "f1/f2/life.elf", 0755));
|
testlib_extract("/zip/life.elf", "f1/f2/life.elf", 0755);
|
||||||
ASSERT_SYS(0, 0, unveil("f1", "x"));
|
ASSERT_SYS(0, 0, unveil("f1", "x"));
|
||||||
ASSERT_SYS(0, 0, unveil("f1/f2", "r"));
|
ASSERT_SYS(0, 0, unveil("f1/f2", "r"));
|
||||||
ASSERT_SYS(0, 0, unveil(0, 0));
|
ASSERT_SYS(0, 0, unveil(0, 0));
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/mem/copyfd.internal.h"
|
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/fmt/conv.h"
|
#include "libc/fmt/conv.h"
|
||||||
|
@ -26,6 +25,7 @@
|
||||||
#include "libc/limits.h"
|
#include "libc/limits.h"
|
||||||
#include "libc/log/libfatal.internal.h"
|
#include "libc/log/libfatal.internal.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
|
#include "libc/mem/copyfd.internal.h"
|
||||||
#include "libc/mem/gc.h"
|
#include "libc/mem/gc.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/runtime/internal.h"
|
#include "libc/runtime/internal.h"
|
||||||
|
@ -40,24 +40,15 @@
|
||||||
#include "libc/x/xasprintf.h"
|
#include "libc/x/xasprintf.h"
|
||||||
#include "net/http/escape.h"
|
#include "net/http/escape.h"
|
||||||
|
|
||||||
STATIC_YOINK("zip_uri_support");
|
|
||||||
STATIC_YOINK("backtrace.com");
|
STATIC_YOINK("backtrace.com");
|
||||||
STATIC_YOINK("backtrace.com.dbg");
|
STATIC_YOINK("backtrace.com.dbg");
|
||||||
|
|
||||||
char testlib_enable_tmp_setup_teardown_once;
|
char testlib_enable_tmp_setup_teardown_once;
|
||||||
|
|
||||||
void Extract(const char *from, const char *to, int mode) {
|
|
||||||
ASSERT_SYS(0, 3, open(from, O_RDONLY));
|
|
||||||
ASSERT_SYS(0, 4, creat(to, mode));
|
|
||||||
ASSERT_NE(-1, _copyfd(3, 4, -1));
|
|
||||||
EXPECT_SYS(0, 0, close(4));
|
|
||||||
EXPECT_SYS(0, 0, close(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetUpOnce(void) {
|
void SetUpOnce(void) {
|
||||||
ASSERT_NE(-1, mkdir("bin", 0755));
|
ASSERT_NE(-1, mkdir("bin", 0755));
|
||||||
Extract("/zip/backtrace.com", "bin/backtrace.com", 0755);
|
testlib_extract("/zip/backtrace.com", "bin/backtrace.com", 0755);
|
||||||
Extract("/zip/backtrace.com.dbg", "bin/backtrace.com.dbg", 0755);
|
testlib_extract("/zip/backtrace.com.dbg", "bin/backtrace.com.dbg", 0755);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool OutputHasSymbol(const char *output, const char *s) {
|
static bool OutputHasSymbol(const char *output, const char *s) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue