From 307da60bb9be05e618fa47a707613623726dcaee Mon Sep 17 00:00:00 2001 From: Cosmos Nicolaou Date: Mon, 19 Oct 2020 19:45:08 -0700 Subject: [PATCH 1/2] x/ref/{cmd,lib}/vdl: changes to work with overlapping module paths --- v23/security/openssl.c | 62 ------------------------------------ x/ref/cmd/vdl/main.go | 35 +++++++++++++++----- x/ref/lib/vdl/build/build.go | 17 +++------- 3 files changed, 32 insertions(+), 82 deletions(-) delete mode 100644 v23/security/openssl.c diff --git a/v23/security/openssl.c b/v23/security/openssl.c deleted file mode 100644 index d5a0b164c..000000000 --- a/v23/security/openssl.c +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2015 The Vanadium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build openssl - -#include -#include -#include -#include -#include - -// d2i_ECPrivateKey + ERR_get_error in a single function. -// This is to ensure that the call to ERR_get_error happens in the same thread -// as the call to d2i_ECPrivateKey. If the two were called from Go, the goroutine -// might be pre-empted and rescheduled on another thread leading to an -// inconsistent error. -EC_KEY *openssl_d2i_ECPrivateKey(const unsigned char *data, long len, unsigned long *e) -{ - EC_KEY *k = d2i_ECPrivateKey(NULL, &data, len); - if (k != NULL) - { - *e = 0; - return k; - } - *e = ERR_get_error(); - return NULL; -} - -// d2i_EC_PUBKEY + ERR_get_error in a single function. -// This is to ensure that the call to ERR_get_error happens in the same thread -// as the call to d2i_EC_PUBKEY. If the two were called from Go, the goroutine -// might be pre-empted and rescheduled on another thread leading to an -// inconsistent error. -EC_KEY *openssl_d2i_EC_PUBKEY(const unsigned char *data, long len, unsigned long *e) -{ - EC_KEY *k = d2i_EC_PUBKEY(NULL, &data, len); - if (k != NULL) - { - *e = 0; - return k; - } - *e = ERR_get_error(); - return NULL; -} - -// ECDSA_do_sign + ERR_get_error in a single function. -// This is to ensure that the call to ERR_get_error happens in the same thread -// as the call to ECDSA_do_sign. If the two were called from Go, the goroutine -// might be pre-empted and rescheduled on another thread leading to an -// inconsistent error. -ECDSA_SIG *openssl_ECDSA_do_sign(const unsigned char *digest, int len, EC_KEY *key, unsigned long *e) -{ - ECDSA_SIG *sig = ECDSA_do_sign(digest, len, key); - if (sig != NULL) - { - *e = 0; - return sig; - } - *e = ERR_get_error(); - return NULL; -} diff --git a/x/ref/cmd/vdl/main.go b/x/ref/cmd/vdl/main.go index 2f934c725..42f02dab0 100644 --- a/x/ref/cmd/vdl/main.go +++ b/x/ref/cmd/vdl/main.go @@ -691,25 +691,44 @@ func handleErrorOrSkip(prefix string, err error, env *compile.Env) bool { var errSkip = fmt.Errorf("SKIP") +// returns the dir componets in suffix descending order, ie. +// for /a/b/c return [a, b, c]. +func dirsFromPath(suffix string, dirs []string) []string { + if suffix == "." { + return dirs + } + return append(dirsFromPath(filepath.Dir(suffix), dirs), filepath.Base(suffix)) +} + // Handle the case where go modules are used and the directory structure // on the local filesystem omits the portion of the package path represented // by the module definition in the go.mod file. For vanadium, the code is // hosted as github.com/vanadium/core/... but the go.mod defines the packages // as v.io/... with the v.io portion not appearing in the local filesystem. +// It's also possible for the 'missing portion' to be overlap with package +// paths. For example, github.com/grailbio/base can be cloned into a directory +// /some/path/base, and hence the path to write vdl output for package /a/b +// would be: /some/path/base/a/b. func goModulePath(dir, path, outPkgPath string) (string, error) { prefix, module, suffix := build.PackagePathSplit(dir, path) if len(suffix) == 0 { return "", fmt.Errorf("package dir %q doesn't share a common suffix with package path %q", dir, path) } - gomod, err := build.GoModuleName(prefix) - if err != nil { - return "", err - } - if len(gomod) > 0 { - if gomod != module { - return "", fmt.Errorf("package dir %q and package %q do not match go module path %q != %q", dir, path, gomod, module) + goModRelative := "" + // Look for go.mod file anywhere on starting at . + for _, dir := range dirsFromPath(suffix, nil) { + goModDir := filepath.Join(prefix, goModRelative) + gomod, err := build.GoModuleName(goModDir) + if err != nil { + return "", err + } + if len(gomod) > 0 { + if got, want := filepath.Join(module, goModRelative), gomod; got != want { + return "", fmt.Errorf("package dir %q and package %q do not match go module path %q != %q", dir, path, got, want) + } + return filepath.Join(prefix, filepath.Join(goModRelative, strings.TrimPrefix(outPkgPath, gomod))), nil } - return filepath.Join(prefix, strings.TrimPrefix(outPkgPath, gomod)), nil + goModRelative = filepath.Join(goModRelative, dir) } return filepath.Join(dir, outPkgPath), nil } diff --git a/x/ref/lib/vdl/build/build.go b/x/ref/lib/vdl/build/build.go index 484befd83..16a80a826 100644 --- a/x/ref/lib/vdl/build/build.go +++ b/x/ref/lib/vdl/build/build.go @@ -41,7 +41,6 @@ package build import ( - "bufio" "bytes" "fmt" "io" @@ -54,6 +53,7 @@ import ( "sort" "strings" + "golang.org/x/mod/modfile" "v.io/v23/vdl" "v.io/v23/vdlroot/vdltool" "v.io/x/lib/toposort" @@ -323,17 +323,11 @@ func GoModuleName(path string) (string, error) { } return "", err } - sc := bufio.NewScanner(bytes.NewBuffer(buf)) - for sc.Scan() { - parts := strings.Fields(sc.Text()) - if len(parts) != 2 { - continue - } - if parts[0] == "module" { - return parts[1], nil - } + module := modfile.ModulePath(buf) + if len(module) == 0 { + return "", fmt.Errorf("failed to find module statement in %v", gomod) } - return "", fmt.Errorf("failed to find module statement in %v", gomod) + return module, nil } // PackagePathSplit returns the longest common suffix in dir and path, @@ -838,7 +832,6 @@ func (ds *depSorter) resolveImportPath(pkgPath string, mode UnknownPathMode, pre vdlutil.Vlog.Printf("%s: resolved import path %q using go.mod to %v", pkg.Dir, pkgPath, dir) return pkg } - return nil } } // We can't find a valid dir corresponding to this import path. From 14c13299f99fedeb2a2f1567933023ee54e865b4 Mon Sep 17 00:00:00 2001 From: Cosmos Nicolaou Date: Mon, 19 Oct 2020 21:54:26 -0700 Subject: [PATCH 2/2] add back missing file --- v23/security/openssl.c | 62 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 v23/security/openssl.c diff --git a/v23/security/openssl.c b/v23/security/openssl.c new file mode 100644 index 000000000..d5a0b164c --- /dev/null +++ b/v23/security/openssl.c @@ -0,0 +1,62 @@ +// Copyright 2015 The Vanadium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build openssl + +#include +#include +#include +#include +#include + +// d2i_ECPrivateKey + ERR_get_error in a single function. +// This is to ensure that the call to ERR_get_error happens in the same thread +// as the call to d2i_ECPrivateKey. If the two were called from Go, the goroutine +// might be pre-empted and rescheduled on another thread leading to an +// inconsistent error. +EC_KEY *openssl_d2i_ECPrivateKey(const unsigned char *data, long len, unsigned long *e) +{ + EC_KEY *k = d2i_ECPrivateKey(NULL, &data, len); + if (k != NULL) + { + *e = 0; + return k; + } + *e = ERR_get_error(); + return NULL; +} + +// d2i_EC_PUBKEY + ERR_get_error in a single function. +// This is to ensure that the call to ERR_get_error happens in the same thread +// as the call to d2i_EC_PUBKEY. If the two were called from Go, the goroutine +// might be pre-empted and rescheduled on another thread leading to an +// inconsistent error. +EC_KEY *openssl_d2i_EC_PUBKEY(const unsigned char *data, long len, unsigned long *e) +{ + EC_KEY *k = d2i_EC_PUBKEY(NULL, &data, len); + if (k != NULL) + { + *e = 0; + return k; + } + *e = ERR_get_error(); + return NULL; +} + +// ECDSA_do_sign + ERR_get_error in a single function. +// This is to ensure that the call to ERR_get_error happens in the same thread +// as the call to ECDSA_do_sign. If the two were called from Go, the goroutine +// might be pre-empted and rescheduled on another thread leading to an +// inconsistent error. +ECDSA_SIG *openssl_ECDSA_do_sign(const unsigned char *digest, int len, EC_KEY *key, unsigned long *e) +{ + ECDSA_SIG *sig = ECDSA_do_sign(digest, len, key); + if (sig != NULL) + { + *e = 0; + return sig; + } + *e = ERR_get_error(); + return NULL; +}