Merge branch 'ua/os-version-capability'
The value of "uname -s" is by default sent over the wire as a part of the "version" capability. * ua/os-version-capability: agent: advertise OS name via agent capability t5701: add setup test to remove side-effect dependency version: extend get_uname_info() to hide system details version: refactor get_uname_info() version: refactor redact_non_printables() version: replace manual ASCII checks with isprint() for claritymaint
commit
9d8cce051a
|
@ -184,9 +184,13 @@ form `agent=X`) to notify the client that the server is running version
|
|||
the `agent` capability with a value `Y` (in the form `agent=Y`) in its
|
||||
request to the server (but it MUST NOT do so if the server did not
|
||||
advertise the agent capability). The `X` and `Y` strings may contain any
|
||||
printable ASCII characters except space (i.e., the byte range 32 < x <
|
||||
127), and are typically of the form "package/version" (e.g.,
|
||||
"git/1.8.3.1"). The agent strings are purely informative for statistics
|
||||
printable ASCII characters except space (i.e., the byte range 33 <= x <=
|
||||
126), and are typically of the form "package/version-os" (e.g.,
|
||||
"git/1.8.3.1-Linux") where `os` is the operating system name (e.g.,
|
||||
"Linux"). `X` and `Y` can be configured using the GIT_USER_AGENT
|
||||
environment variable and it takes priority. The `os` is
|
||||
retrieved using the 'sysname' field of the `uname(2)` system call
|
||||
or its equivalent. The agent strings are purely informative for statistics
|
||||
and debugging purposes, and MUST NOT be used to programmatically assume
|
||||
the presence or absence of particular features.
|
||||
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
#include "diagnose.h"
|
||||
#include "object-file.h"
|
||||
#include "setup.h"
|
||||
#include "version.h"
|
||||
|
||||
static void get_system_info(struct strbuf *sys_info)
|
||||
{
|
||||
struct utsname uname_info;
|
||||
char *shell = NULL;
|
||||
|
||||
/* get git version from native cmd */
|
||||
|
@ -24,16 +24,7 @@ static void get_system_info(struct strbuf *sys_info)
|
|||
|
||||
/* system call for other version info */
|
||||
strbuf_addstr(sys_info, "uname: ");
|
||||
if (uname(&uname_info))
|
||||
strbuf_addf(sys_info, _("uname() failed with error '%s' (%d)\n"),
|
||||
strerror(errno),
|
||||
errno);
|
||||
else
|
||||
strbuf_addf(sys_info, "%s %s %s %s\n",
|
||||
uname_info.sysname,
|
||||
uname_info.release,
|
||||
uname_info.version,
|
||||
uname_info.machine);
|
||||
get_uname_info(sys_info, 1);
|
||||
|
||||
strbuf_addstr(sys_info, _("compiler info: "));
|
||||
get_compiler_info(sys_info);
|
||||
|
|
|
@ -624,7 +624,7 @@ const char *parse_feature_value(const char *feature_list, const char *feature, s
|
|||
*offset = found + len - orig_start;
|
||||
return value;
|
||||
}
|
||||
/* feature with a value (e.g., "agent=git/1.2.3") */
|
||||
/* feature with a value (e.g., "agent=git/1.2.3-Linux") */
|
||||
else if (*value == '=') {
|
||||
size_t end;
|
||||
|
||||
|
|
|
@ -7,24 +7,40 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|||
|
||||
. ./test-lib.sh
|
||||
|
||||
test_expect_success 'test capability advertisement' '
|
||||
test_expect_success 'setup to generate files with expected content' '
|
||||
printf "agent=git/%s" "$(git version | cut -d" " -f3)" >agent_capability &&
|
||||
|
||||
test_oid_cache <<-EOF &&
|
||||
wrong_algo sha1:sha256
|
||||
wrong_algo sha256:sha1
|
||||
EOF
|
||||
|
||||
if test_have_prereq WINDOWS
|
||||
then
|
||||
printf "agent=FAKE\n" >agent_capability
|
||||
else
|
||||
printf -- "-%s\n" $(uname -s | test_redact_non_printables) >>agent_capability
|
||||
fi &&
|
||||
cat >expect.base <<-EOF &&
|
||||
version 2
|
||||
agent=git/$(git version | cut -d" " -f3)
|
||||
$(cat agent_capability)
|
||||
ls-refs=unborn
|
||||
fetch=shallow wait-for-done
|
||||
server-option
|
||||
object-format=$(test_oid algo)
|
||||
EOF
|
||||
cat >expect.trailer <<-EOF &&
|
||||
cat >expect.trailer <<-EOF
|
||||
0000
|
||||
EOF
|
||||
'
|
||||
|
||||
test_expect_success 'test capability advertisement' '
|
||||
cat expect.base expect.trailer >expect &&
|
||||
|
||||
if test_have_prereq WINDOWS
|
||||
then
|
||||
GIT_USER_AGENT=FAKE && export GIT_USER_AGENT
|
||||
fi &&
|
||||
GIT_TEST_SIDEBAND_ALL=0 test-tool serve-v2 \
|
||||
--advertise-capabilities >out &&
|
||||
test-tool pkt-line unpack <out >actual &&
|
||||
|
@ -355,6 +371,10 @@ test_expect_success 'test capability advertisement with uploadpack.advertiseBund
|
|||
expect.extra \
|
||||
expect.trailer >expect &&
|
||||
|
||||
if test_have_prereq WINDOWS
|
||||
then
|
||||
GIT_USER_AGENT=FAKE && export GIT_USER_AGENT
|
||||
fi &&
|
||||
GIT_TEST_SIDEBAND_ALL=0 test-tool serve-v2 \
|
||||
--advertise-capabilities >out &&
|
||||
test-tool pkt-line unpack <out >actual &&
|
||||
|
|
|
@ -2043,3 +2043,11 @@ test_trailing_hash () {
|
|||
test-tool hexdump |
|
||||
sed "s/ //g"
|
||||
}
|
||||
|
||||
# Trim and replace each character with ascii code below 32 or above
|
||||
# 127 (included) using a dot '.' character.
|
||||
# Octal intervals \001-\040 and \177-\377
|
||||
# correspond to decimal intervals 1-32 and 127-255
|
||||
test_redact_non_printables () {
|
||||
tr -d "\n\r" | tr "[\001-\040][\177-\377]" "."
|
||||
}
|
||||
|
|
69
version.c
69
version.c
|
@ -1,6 +1,9 @@
|
|||
#define USE_THE_REPOSITORY_VARIABLE
|
||||
|
||||
#include "git-compat-util.h"
|
||||
#include "version.h"
|
||||
#include "strbuf.h"
|
||||
#include "gettext.h"
|
||||
|
||||
#ifndef GIT_VERSION_H
|
||||
# include "version-def.h"
|
||||
|
@ -11,6 +14,19 @@
|
|||
const char git_version_string[] = GIT_VERSION;
|
||||
const char git_built_from_commit_string[] = GIT_BUILT_FROM_COMMIT;
|
||||
|
||||
/*
|
||||
* Trim and replace each character with ascii code below 32 or above
|
||||
* 127 (included) using a dot '.' character.
|
||||
*/
|
||||
static void redact_non_printables(struct strbuf *buf)
|
||||
{
|
||||
strbuf_trim(buf);
|
||||
for (size_t i = 0; i < buf->len; i++) {
|
||||
if (!isprint(buf->buf[i]) || buf->buf[i] == ' ')
|
||||
buf->buf[i] = '.';
|
||||
}
|
||||
}
|
||||
|
||||
const char *git_user_agent(void)
|
||||
{
|
||||
static const char *agent = NULL;
|
||||
|
@ -24,6 +40,27 @@ const char *git_user_agent(void)
|
|||
return agent;
|
||||
}
|
||||
|
||||
/*
|
||||
Retrieve, sanitize and cache operating system info for subsequent
|
||||
calls. Return a pointer to the sanitized operating system info
|
||||
string.
|
||||
*/
|
||||
static const char *os_info(void)
|
||||
{
|
||||
static const char *os = NULL;
|
||||
|
||||
if (!os) {
|
||||
struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
get_uname_info(&buf, 0);
|
||||
/* Sanitize the os information immediately */
|
||||
redact_non_printables(&buf);
|
||||
os = strbuf_detach(&buf, NULL);
|
||||
}
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
const char *git_user_agent_sanitized(void)
|
||||
{
|
||||
static const char *agent = NULL;
|
||||
|
@ -32,13 +69,35 @@ const char *git_user_agent_sanitized(void)
|
|||
struct strbuf buf = STRBUF_INIT;
|
||||
|
||||
strbuf_addstr(&buf, git_user_agent());
|
||||
strbuf_trim(&buf);
|
||||
for (size_t i = 0; i < buf.len; i++) {
|
||||
if (buf.buf[i] <= 32 || buf.buf[i] >= 127)
|
||||
buf.buf[i] = '.';
|
||||
|
||||
if (!getenv("GIT_USER_AGENT")) {
|
||||
strbuf_addch(&buf, '-');
|
||||
strbuf_addstr(&buf, os_info());
|
||||
}
|
||||
agent = buf.buf;
|
||||
redact_non_printables(&buf);
|
||||
agent = strbuf_detach(&buf, NULL);
|
||||
}
|
||||
|
||||
return agent;
|
||||
}
|
||||
|
||||
int get_uname_info(struct strbuf *buf, unsigned int full)
|
||||
{
|
||||
struct utsname uname_info;
|
||||
|
||||
if (uname(&uname_info)) {
|
||||
strbuf_addf(buf, _("uname() failed with error '%s' (%d)\n"),
|
||||
strerror(errno),
|
||||
errno);
|
||||
return -1;
|
||||
}
|
||||
if (full)
|
||||
strbuf_addf(buf, "%s %s %s %s\n",
|
||||
uname_info.sysname,
|
||||
uname_info.release,
|
||||
uname_info.version,
|
||||
uname_info.machine);
|
||||
else
|
||||
strbuf_addf(buf, "%s\n", uname_info.sysname);
|
||||
return 0;
|
||||
}
|
||||
|
|
10
version.h
10
version.h
|
@ -1,10 +1,20 @@
|
|||
#ifndef VERSION_H
|
||||
#define VERSION_H
|
||||
|
||||
struct repository;
|
||||
|
||||
extern const char git_version_string[];
|
||||
extern const char git_built_from_commit_string[];
|
||||
|
||||
const char *git_user_agent(void);
|
||||
const char *git_user_agent_sanitized(void);
|
||||
|
||||
/*
|
||||
Try to get information about the system using uname(2).
|
||||
Return -1 and put an error message into 'buf' in case of uname()
|
||||
error. Return 0 and put uname info into 'buf' otherwise.
|
||||
*/
|
||||
int get_uname_info(struct strbuf *buf, unsigned int full);
|
||||
|
||||
|
||||
#endif /* VERSION_H */
|
||||
|
|
Loading…
Reference in New Issue