• use BAFH for hash ipv NZAAT

• prep for release
• fix minor nits in manpage and tests
This commit is contained in:
tg 2014-01-11 18:09:43 +00:00
parent c1c0b997fe
commit 270a86f895
8 changed files with 121 additions and 158 deletions

19
check.t
View File

@ -1,4 +1,4 @@
# $MirOS: src/bin/mksh/check.t,v 1.639 2014/01/05 21:57:22 tg Exp $ # $MirOS: src/bin/mksh/check.t,v 1.640 2014/01/11 18:09:37 tg Exp $
# OpenBSD src/regress/bin/ksh updated: 2013/12/02 20:39:44 # OpenBSD src/regress/bin/ksh updated: 2013/12/02 20:39:44
#- #-
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
@ -27,7 +27,7 @@
# http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD # http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
expected-stdout: expected-stdout:
@(#)MIRBSD KSH R49 2014/01/05 @(#)MIRBSD KSH R49 2014/01/11
description: description:
Check version of shell. Check version of shell.
stdin: stdin:
@ -36,7 +36,7 @@ name: KSH_VERSION
category: shell:legacy-no category: shell:legacy-no
--- ---
expected-stdout: expected-stdout:
@(#)LEGACY KSH R49 2014/01/05 @(#)LEGACY KSH R49 2014/01/11
description: description:
Check version of legacy shell. Check version of legacy shell.
stdin: stdin:
@ -2075,12 +2075,18 @@ stdin:
echo [!-ab]* echo [!-ab]*
echo [!ab]* echo [!ab]*
echo []ab]* echo []ab]*
:>'./!bc'
:>'./^bc'
echo [^ab]*
echo [!ab]*
expected-stdout: expected-stdout:
-bc abc bbc -bc abc bbc
-bc abc bbc -bc abc bbc
cbc cbc
-bc cbc -bc cbc
abc bbc abc bbc
^bc abc bbc
!bc -bc ^bc cbc
--- ---
name: glob-range-2 name: glob-range-2
description: description:
@ -7685,14 +7691,9 @@ stdin:
typeset -i8 foo=10 typeset -i8 foo=10
bar=baz bar=baz
unset baz unset baz
bla=foo
print ${foo@#} ${bar@#} ${baz@#} . print ${foo@#} ${bar@#} ${baz@#} .
print ${foo@#123} ${bar@#456} ${baz@#789} .
print ${foo@#bla} ${bar@#bar} ${baz@#OPTIND} .
expected-stdout: expected-stdout:
D50219A0 20E5DB5B 00000000 . 9B15FBFB CFBDD32B 00000000 .
554A1C76 004A212E CB209562 .
6B21CF91 20E5DB5B 124EA49D .
--- ---
name: varexpand-special-quote name: varexpand-special-quote
description: description:

View File

@ -1,5 +1,5 @@
# $Id$ # $Id$
# $MirOS: src/bin/mksh/dot.mkshrc,v 1.87 2014/01/05 22:17:57 tg Exp $ # $MirOS: src/bin/mksh/dot.mkshrc,v 1.88 2014/01/11 18:09:39 tg Exp $
#- #-
# Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010, # Copyright (c) 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2010,
# 2011, 2012, 2013, 2014 # 2011, 2012, 2013, 2014
@ -333,9 +333,12 @@ function Lb64encode {
(( u )) || set -U (( u )) || set -U
} }
# mksh NUL counting, never zero # Better Avalanche for the Jenkins Hash
typeset -Z11 -Uui16 Lnzathash_v typeset -Z11 -Uui16 Lbafh_v
function Lnzathash_add { function Lbafh_init {
Lbafh_v=0
}
function Lbafh_add {
[[ -o utf8-mode ]]; local u=$? [[ -o utf8-mode ]]; local u=$?
set +U set +U
local s local s
@ -348,45 +351,19 @@ function Lnzathash_add {
local -i i=0 n=${#s[*]} local -i i=0 n=${#s[*]}
while (( i < n )); do while (( i < n )); do
((# Lnzathash_v = (Lnzathash_v + s[i++] + 1) * 1025 )) ((# Lbafh_v = (Lbafh_v + s[i++] + 1) * 1025 ))
((# Lnzathash_v ^= Lnzathash_v >> 6 )) ((# Lbafh_v ^= Lbafh_v >> 6 ))
done done
(( u )) || set -U (( u )) || set -U
} }
function Lnzaathash_end { function Lbafh_finish {
((# Lnzathash_v *= 1025 )) local -Ui t
((# Lnzathash_v ^= Lnzathash_v >> 6 ))
((# Lnzathash_v += Lnzathash_v << 3 ))
((# Lnzathash_v = (Lnzathash_v ^
(Lnzathash_v >> 11)) * 32769 ))
print ${Lnzathash_v#16#}
}
function Lnzaathash {
Lnzathash_v=0
Lnzathash_add "$@"
Lnzaathash_end
}
function Lnzathash {
Lnzathash_v=0
Lnzathash_add "$@"
Lnzathash_end
}
function Lnzathash_end {
if (( Lnzathash_v )); then
Lnzaathash_end
else
Lnzathash_v=1
print ${Lnzathash_v#16#}
fi
}
function Lnzathash_mix {
local -Uui16 t
((# t = ((Lnzathash_v >> 7) & 0x01010101) * 0x1B )) ((# t = (((Lbafh_v >> 7) & 0x01010101) * 0x1B) ^ \
((# t ^= (Lnzathash_v << 1) & 0xFEFEFEFE )) ((Lbafh_v << 1) & 0xFEFEFEFE) ))
((# Lnzathash_v = t ^ (t <<< 24) ^ (Lnzathash_v <<< 8) ^ \ ((# Lbafh_v = t ^ (t >>> 8) ^ (Lbafh_v >>> 8) ^ \
(Lnzathash_v <<< 16) ^ (Lnzathash_v <<< 24) )) (Lbafh_v >>> 16) ^ (Lbafh_v >>> 24) ))
: :
} }

23
eval.c
View File

@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/eval.c,v 1.146 2014/01/05 21:57:25 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/eval.c,v 1.147 2014/01/11 18:09:39 tg Exp $");
/* /*
* string expansion * string expansion
@ -412,27 +412,10 @@ expand(
if (stype) if (stype)
sp += slen; sp += slen;
switch (stype & 0x17F) { switch (stype & 0x17F) {
case 0x100 | '#': { case 0x100 | '#':
char *beg, *end;
mksh_ari_t seed;
register uint32_t h;
beg = wdcopy(sp, ATEMP);
end = beg + (wdscan(sp, CSUBST) - sp);
end[-2] = EOS;
end = wdstrip(beg, 0);
afree(beg, ATEMP);
evaluate(substitute(end, 0),
&seed, KSH_UNWIND_ERROR, true);
/* hash with seed, for now */
h = seed;
NZATUpdateString(h,
str_val(st->var));
NZAATFinish(h);
x.str = shf_smprintf("%08X", x.str = shf_smprintf("%08X",
(unsigned int)h); (unsigned int)hash(str_val(st->var)));
break; break;
}
case 0x100 | 'Q': { case 0x100 | 'Q': {
struct shf shf; struct shf shf;

5
lex.c
View File

@ -2,7 +2,7 @@
/*- /*-
* Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
* 2011, 2012, 2013 * 2011, 2012, 2013, 2014
* Thorsten Glaser <tg@mirbsd.org> * Thorsten Glaser <tg@mirbsd.org>
* *
* Provided that these terms and disclaimer and all copyright notices * Provided that these terms and disclaimer and all copyright notices
@ -23,7 +23,7 @@
#include "sh.h" #include "sh.h"
__RCSID("$MirOS: src/bin/mksh/lex.c,v 1.191 2014/01/05 19:11:45 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/lex.c,v 1.192 2014/01/11 18:09:40 tg Exp $");
/* /*
* states while lexing word * states while lexing word
@ -1440,6 +1440,7 @@ getsc_line(Source *s)
alarm(0); alarm(0);
} }
cp = Xstring(s->xs, xp); cp = Xstring(s->xs, xp);
rndpush(cp);
s->start = s->str = cp; s->start = s->str = cp;
strip_nuls(Xstring(s->xs, xp), Xlength(s->xs, xp)); strip_nuls(Xstring(s->xs, xp), Xlength(s->xs, xp));
/* Note: if input is all nulls, this is not eof */ /* Note: if input is all nulls, this is not eof */

26
main.c
View File

@ -34,7 +34,7 @@
#include <locale.h> #include <locale.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/main.c,v 1.276 2014/01/11 16:26:28 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/main.c,v 1.277 2014/01/11 18:09:40 tg Exp $");
extern char **environ; extern char **environ;
@ -142,21 +142,6 @@ rndsetup(void)
return ((mksh_uari_t)h); return ((mksh_uari_t)h);
} }
uint32_t
chvt_rndsetup(const void *bp, size_t sz)
{
register uint32_t h;
NZATInit(h);
/* variation through pid, ppid, and the works */
NZATUpdateMem(h, &rndsetupstate, sizeof(rndsetupstate));
/* some variation, some possibly entropy, depending on OE */
NZATUpdateMem(h, bp, sz);
NZAATFinish(h);
return (h);
}
void void
chvt_reinit(void) chvt_reinit(void)
{ {
@ -359,9 +344,14 @@ main_init(int argc, const char *argv[], Source **sp, struct block **lp)
#endif #endif
/* import environment */ /* import environment */
if (environ != NULL) if (environ != NULL) {
for (wp = (const char **)environ; *wp != NULL; wp++) wp = (const char **)environ;
while (*wp != NULL) {
rndpush(*wp);
typeset(*wp, IMPORT | EXPORT, 0, 0, 0); typeset(*wp, IMPORT | EXPORT, 0, 0, 0);
++wp;
}
}
/* for security */ /* for security */
typeset(initifs, 0, 0, 0, 0); typeset(initifs, 0, 0, 0, 0);

21
mksh.1
View File

@ -1,4 +1,4 @@
.\" $MirOS: src/bin/mksh/mksh.1,v 1.328 2014/01/05 21:57:27 tg Exp $ .\" $MirOS: src/bin/mksh/mksh.1,v 1.329 2014/01/11 18:09:41 tg Exp $
.\" $OpenBSD: ksh.1,v 1.149 2013/12/18 13:53:11 millert Exp $ .\" $OpenBSD: ksh.1,v 1.149 2013/12/18 13:53:11 millert Exp $
.\"- .\"-
.\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, .\" Copyright © 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
@ -74,7 +74,7 @@
.\" with -mandoc, it might implement .Mx itself, but we want to .\" with -mandoc, it might implement .Mx itself, but we want to
.\" use our own definition. And .Dd must come *first*, always. .\" use our own definition. And .Dd must come *first*, always.
.\" .\"
.Dd $Mdocdate: January 5 2014 $ .Dd $Mdocdate: January 11 2014 $
.\" .\"
.\" Check which macro package we use, and do other -mdoc setup. .\" Check which macro package we use, and do other -mdoc setup.
.\" .\"
@ -1693,17 +1693,10 @@ Currently,
must start with a space, opening parenthesis or digit to be recognised. must start with a space, opening parenthesis or digit to be recognised.
Cannot be applied to a vector. Cannot be applied to a vector.
.Pp .Pp
.It Xo .It Pf ${ Ns Ar name Ns @#}
.Pf ${ Ar name The hash (using the BAFH algorithm) of the expansion of
.Pf @# Ns Oo Ar seed Oc Ns } .Ar name .
.Xc This is also used internally for the shell's hashtables.
The internal hash of the expansion of
.Ar name ,
with an optional (defaulting to zero)
.Op Ar seed .
At the moment, this is NZAAT (a 32-bit hash based on
Bob Jenkins' one-at-a-time hash), but this is not set.
This is the hash the shell uses internally for its associative arrays.
.Pp .Pp
.It Pf ${ Ns Ar name Ns @Q} .It Pf ${ Ns Ar name Ns @Q}
A quoted expression safe for re-entry, whose value is the value of the A quoted expression safe for re-entry, whose value is the value of the
@ -3633,7 +3626,7 @@ Since expressions may need to be quoted,
is syntactic sugar for is syntactic sugar for
.No let \&" Ns Ar expr Ns \&" . .No let \&" Ns Ar expr Ns \&" .
.Pp .Pp
.It let] .It Ic let]
Internally used alias for Internally used alias for
.Ic let . .Ic let .
.Pp .Pp

49
sh.h
View File

@ -169,9 +169,9 @@
#endif #endif
#ifdef EXTERN #ifdef EXTERN
__RCSID("$MirOS: src/bin/mksh/sh.h,v 1.683 2014/01/11 16:26:28 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/sh.h,v 1.684 2014/01/11 18:09:42 tg Exp $");
#endif #endif
#define MKSH_VERSION "R49 2014/01/05" #define MKSH_VERSION "R49 2014/01/11"
/* arithmetic types: C implementation */ /* arithmetic types: C implementation */
#if !HAVE_CAN_INTTYPES #if !HAVE_CAN_INTTYPES
@ -1616,48 +1616,6 @@ EXTERN struct timeval j_usrtime, j_systime;
} while (/* CONSTCOND */ 0) } while (/* CONSTCOND */ 0)
/* NZAAT hash based on Bob Jenkins' one-at-a-time hash */
/* From: src/kern/include/nzat.h,v 1.2 2011/07/18 00:35:40 tg Exp $ */
#define NZATInit(h) do { \
(h) = 0; \
} while (/* CONSTCOND */ 0)
#define NZATUpdateByte(h,b) do { \
(h) += (uint8_t)(b); \
++(h); \
(h) += (h) << 10; \
(h) ^= (h) >> 6; \
} while (/* CONSTCOND */ 0)
#define NZATUpdateMem(h,p,z) do { \
register const uint8_t *NZATUpdateMem_p; \
register size_t NZATUpdateMem_z = (z); \
\
NZATUpdateMem_p = (const void *)(p); \
while (NZATUpdateMem_z--) \
NZATUpdateByte((h), *NZATUpdateMem_p++); \
} while (/* CONSTCOND */ 0)
#define NZATUpdateString(h,s) do { \
register const char *NZATUpdateString_s; \
register uint8_t NZATUpdateString_c; \
\
NZATUpdateString_s = (const void *)(s); \
while ((NZATUpdateString_c = *NZATUpdateString_s++)) \
NZATUpdateByte((h), NZATUpdateString_c); \
} while (/* CONSTCOND */ 0)
#define NZAATFinish(h) do { \
(h) += (h) << 10; \
(h) ^= (h) >> 6; \
(h) += (h) << 3; \
(h) ^= (h) >> 11; \
(h) += (h) << 15; \
} while (/* CONSTCOND */ 0)
/* lalloc.c */ /* lalloc.c */
void ainit(Area *); void ainit(Area *);
void afreeall(Area *); void afreeall(Area *);
@ -1895,7 +1853,6 @@ struct tbl **ktsort(struct table *);
void DF(const char *, ...) void DF(const char *, ...)
MKSH_A_FORMAT(__printf__, 1, 2); MKSH_A_FORMAT(__printf__, 1, 2);
#endif #endif
uint32_t chvt_rndsetup(const void *, size_t) MKSH_A_PURE;
/* misc.c */ /* misc.c */
void setctypes(const char *, int); void setctypes(const char *, int);
void initctypes(void); void initctypes(void);
@ -2010,8 +1967,10 @@ size_t array_ref_len(const char *) MKSH_A_PURE;
char *arrayname(const char *); char *arrayname(const char *);
mksh_uari_t set_array(const char *, bool, const char **); mksh_uari_t set_array(const char *, bool, const char **);
uint32_t hash(const void *) MKSH_A_PURE; uint32_t hash(const void *) MKSH_A_PURE;
uint32_t chvt_rndsetup(const void *, size_t) MKSH_A_PURE;
mksh_ari_t rndget(void); mksh_ari_t rndget(void);
void rndset(unsigned long); void rndset(unsigned long);
void rndpush(const void *);
enum Test_op { enum Test_op {
/* non-operator */ /* non-operator */

83
var.c
View File

@ -22,12 +22,13 @@
*/ */
#include "sh.h" #include "sh.h"
#include "mirhash.h"
#if defined(__OpenBSD__) #if defined(__OpenBSD__)
#include <sys/sysctl.h> #include <sys/sysctl.h>
#endif #endif
__RCSID("$MirOS: src/bin/mksh/var.c,v 1.176 2014/01/05 21:57:29 tg Exp $"); __RCSID("$MirOS: src/bin/mksh/var.c,v 1.177 2014/01/11 18:09:43 tg Exp $");
/*- /*-
* Variables * Variables
@ -40,7 +41,7 @@ __RCSID("$MirOS: src/bin/mksh/var.c,v 1.176 2014/01/05 21:57:29 tg Exp $");
*/ */
static struct table specials; static struct table specials;
static uint32_t lcg_state = 5381; static uint32_t lcg_state = 5381, qh_state = 4711;
static char *formatstr(struct tbl *, const char *); static char *formatstr(struct tbl *, const char *);
static void exportprep(struct tbl *, const char *); static void exportprep(struct tbl *, const char *);
@ -1490,6 +1491,11 @@ set_array(const char *var, bool reset, const char **vals)
void void
change_winsz(void) change_winsz(void)
{ {
struct timeval tv;
mksh_TIME(tv);
BAFHUpdateMem_mem(qh_state, &tv, sizeof(tv));
#ifdef TIOCGWINSZ #ifdef TIOCGWINSZ
/* check if window size has changed */ /* check if window size has changed */
if (tty_init_fd() < 2) { if (tty_init_fd() < 2) {
@ -1520,9 +1526,28 @@ hash(const void *s)
{ {
register uint32_t h; register uint32_t h;
NZATInit(h); BAFHInit(h);
NZATUpdateString(h, s); BAFHUpdateStr_reg(h, s);
NZAATFinish(h); BAFHFinish_reg(h);
return (h);
}
uint32_t
chvt_rndsetup(const void *bp, size_t sz)
{
register uint32_t h;
/* use LCG as seed but try to get them to deviate immediately */
h = lcg_state;
(void)rndget();
BAFHFinish_reg(h);
/* variation through pid, ppid, and the works */
BAFHUpdateMem_reg(h, &rndsetupstate, sizeof(rndsetupstate));
/* some variation, some possibly entropy, depending on OE */
BAFHUpdateMem_reg(h, bp, sz);
/* mix them all up */
BAFHFinish_reg(h);
return (h); return (h);
} }
@ -1540,28 +1565,62 @@ void
rndset(unsigned long v) rndset(unsigned long v)
{ {
register uint32_t h; register uint32_t h;
#if defined(arc4random_pushb_fast) || defined(MKSH_A4PB)
register uint32_t t;
#endif
struct {
struct timeval tv;
void *sp;
uint32_t qh;
pid_t pp;
short r;
} z;
NZATInit(h); h = lcg_state;
NZATUpdateMem(h, &lcg_state, sizeof(lcg_state)); BAFHFinish_reg(h);
NZATUpdateMem(h, &v, sizeof(v)); BAFHUpdateMem_reg(h, &v, sizeof(v));
mksh_TIME(z.tv);
z.sp = &lcg_state;
z.pp = procpid;
z.r = (short)rndget();
#if defined(arc4random_pushb_fast) || defined(MKSH_A4PB) #if defined(arc4random_pushb_fast) || defined(MKSH_A4PB)
t = qh_state;
BAFHFinish_reg(t);
z.qh = (t & 0xFFFF8000) | rndget();
lcg_state = (t << 15) | rndget();
/* /*
* either we have very chap entropy get and push available, * either we have very chap entropy get and push available,
* with malloc() pulling in this code already anyway, or the * with malloc() pulling in this code already anyway, or the
* user requested us to use the old functions * user requested us to use the old functions
*/ */
lcg_state = h; t = h;
NZAATFinish(lcg_state); BAFHUpdateMem_reg(t, &lcg_state, sizeof(lcg_state));
BAFHFinish_reg(t);
lcg_state = t;
#if defined(arc4random_pushb_fast) #if defined(arc4random_pushb_fast)
arc4random_pushb_fast(&lcg_state, sizeof(lcg_state)); arc4random_pushb_fast(&lcg_state, sizeof(lcg_state));
lcg_state = arc4random(); lcg_state = arc4random();
#else #else
lcg_state = arc4random_pushb(&lcg_state, sizeof(lcg_state)); lcg_state = arc4random_pushb(&lcg_state, sizeof(lcg_state));
#endif #endif
NZATUpdateMem(h, &lcg_state, sizeof(lcg_state)); BAFHUpdateMem_reg(h, &lcg_state, sizeof(lcg_state));
#else
z.qh = qh_state;
#endif #endif
NZAATFinish(h); BAFHUpdateMem_reg(h, &z, sizeof(z));
BAFHFinish_reg(h);
lcg_state = h; lcg_state = h;
} }
void
rndpush(const void *s)
{
register uint32_t h = qh_state;
BAFHUpdateStr_reg(h, s);
BAFHUpdateOctet_reg(h, 0);
qh_state = h;
}