Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:Update
libgit2
libgit2-boo1114729.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File libgit2-boo1114729.patch of Package libgit2
diff -urpN libgit2-0.24.1.orig/src/commit.c libgit2-0.24.1/src/commit.c --- libgit2-0.24.1.orig/src/commit.c 2018-11-30 12:33:48.857715432 -0600 +++ libgit2-0.24.1/src/commit.c 2018-12-03 16:48:07.486679807 -0600 @@ -390,7 +390,7 @@ int git_commit__parse(void *_commit, git while (eoln < buffer_end && *eoln != '\n') ++eoln; - if (git__prefixcmp(buffer, "encoding ") == 0) { + if (git__prefixncmp(buffer, buffer_end - buffer, "encoding ") == 0) { buffer += strlen("encoding "); commit->message_encoding = git__strndup(buffer, eoln - buffer); diff -urpN libgit2-0.24.1.orig/src/commit_list.c libgit2-0.24.1/src/commit_list.c --- libgit2-0.24.1.orig/src/commit_list.c 2016-04-11 17:18:17.000000000 -0500 +++ libgit2-0.24.1/src/commit_list.c 2018-11-30 17:57:07.753226873 -0600 @@ -166,7 +166,9 @@ static int commit_quick_parse( buffer--; } - if ((buffer == committer_start) || (git__strtol64(&commit_time, (char *)(buffer + 1), NULL, 10) < 0)) + if ((buffer == committer_start) || + (git__strntol64(&commit_time, (char *)(buffer + 1), + buffer_end - buffer + 1, NULL, 10) < 0)) return commit_error(commit, "cannot parse commit time"); commit->time = commit_time; diff -urpN libgit2-0.24.1.orig/src/config.c libgit2-0.24.1/src/config.c --- libgit2-0.24.1.orig/src/config.c 2016-04-11 17:18:17.000000000 -0500 +++ libgit2-0.24.1/src/config.c 2018-11-30 18:09:06.077051245 -0600 @@ -1279,7 +1279,7 @@ int git_config_parse_int64(int64_t *out, const char *num_end; int64_t num; - if (!value || git__strtol64(&num, value, &num_end, 0) < 0) + if (!value || git__strntol64(&num, value, strlen(value), &num_end, 0) < 0) goto fail_parse; switch (*num_end) { diff -urpN libgit2-0.24.1.orig/src/curl_stream.c libgit2-0.24.1/src/curl_stream.c --- libgit2-0.24.1.orig/src/curl_stream.c 2016-04-11 17:18:17.000000000 -0500 +++ libgit2-0.24.1/src/curl_stream.c 2018-12-03 15:55:59.292894819 -0600 @@ -212,7 +212,7 @@ int git_curl_stream_new(git_stream **out return -1; } - if ((error = git__strtol32(&iport, port, NULL, 10)) < 0) { + if ((error = git__strntol32(&iport, port, strlen(port), NULL, 10)) < 0) { git__free(st); return error; } diff -urpN libgit2-0.24.1.orig/src/index.c libgit2-0.24.1/src/index.c --- libgit2-0.24.1.orig/src/index.c 2018-11-30 13:50:00.592636745 -0600 +++ libgit2-0.24.1/src/index.c 2018-11-30 17:58:02.081515708 -0600 @@ -2181,7 +2181,7 @@ static int read_reuc(git_index *index, c for (i = 0; i < 3; i++) { int64_t tmp; - if (git__strtol64(&tmp, buffer, &endptr, 8) < 0 || + if (git__strntol64(&tmp, buffer, size, &endptr, 8) < 0 || !endptr || endptr == buffer || *endptr || tmp < 0) { index_entry_reuc_free(lost); diff -urpN libgit2-0.24.1.orig/src/rebase.c libgit2-0.24.1/src/rebase.c --- libgit2-0.24.1.orig/src/rebase.c 2016-04-11 17:18:17.000000000 -0500 +++ libgit2-0.24.1/src/rebase.c 2018-12-03 16:23:13.063866526 -0600 @@ -151,7 +151,7 @@ GIT_INLINE(int) rebase_readint( if ((error = rebase_readfile(asc_out, state_path, filename)) < 0) return error; - if (git__strtol32(&num, asc_out->ptr, &eol, 10) < 0 || num < 0 || *eol) { + if (git__strntol32(&num, asc_out->ptr, asc_out->size, &eol, 10) < 0 || num < 0 || *eol) { giterr_set(GITERR_REBASE, "The file '%s' contains an invalid numeric value", filename); return -1; } diff -urpN libgit2-0.24.1.orig/src/revparse.c libgit2-0.24.1/src/revparse.c --- libgit2-0.24.1.orig/src/revparse.c 2016-04-11 17:18:17.000000000 -0500 +++ libgit2-0.24.1/src/revparse.c 2018-12-03 15:55:59.292894819 -0600 @@ -127,7 +127,8 @@ static int try_parse_numeric(int *n, con int32_t content; const char *end_ptr; - if (git__strtol32(&content, curly_braces_content, &end_ptr, 10) < 0) + if (git__strntol32(&content, curly_braces_content, strlen(curly_braces_content), + &end_ptr, 10) < 0) return -1; if (*end_ptr != '\0') @@ -577,7 +578,7 @@ static int extract_how_many(int *n, cons } while (spec[(*pos)] == kind && kind == '~'); if (git__isdigit(spec[*pos])) { - if (git__strtol32(&parsed, spec + *pos, &end_ptr, 10) < 0) + if (git__strntol32(&parsed, spec + *pos, strlen(spec + *pos), &end_ptr, 10) < 0) return GIT_EINVALIDSPEC; accumulated += (parsed - 1); diff -urpN libgit2-0.24.1.orig/src/signature.c libgit2-0.24.1/src/signature.c --- libgit2-0.24.1.orig/src/signature.c 2016-04-11 17:18:17.000000000 -0500 +++ libgit2-0.24.1/src/signature.c 2018-12-04 09:45:16.286494537 -0600 @@ -227,7 +227,8 @@ int git_signature__parse(git_signature * const char *time_start = email_end + 2; const char *time_end; - if (git__strtol64(&sig->when.time, time_start, &time_end, 10) < 0) + if (git__strntol64(&sig->when.time, time_start, + buffer_end - time_start, &time_end, 10) < 0) return signature_error("invalid Unix timestamp"); /* do we have a timezone? */ @@ -238,8 +239,9 @@ int git_signature__parse(git_signature * tz_start = time_end + 1; if ((tz_start[0] != '-' && tz_start[0] != '+') || - git__strtol32(&offset, tz_start + 1, &tz_end, 10) < 0) { - //malformed timezone, just assume it's zero + git__strntol32(&offset, tz_start + 1, + buffer_end - tz_start + 1, &tz_end, 10) < 0) { + /* malformed timezone, just assume it's zero */ offset = 0; } diff -urpN libgit2-0.24.1.orig/src/tag.c libgit2-0.24.1/src/tag.c --- libgit2-0.24.1.orig/src/tag.c 2016-04-11 17:18:17.000000000 -0500 +++ libgit2-0.24.1/src/tag.c 2018-12-03 16:29:43.489577620 -0600 @@ -70,10 +70,9 @@ static int tag_parse(git_tag *tag, const static const char *tag_types[] = { NULL, "commit\n", "tree\n", "blob\n", "tag\n" }; - - unsigned int i; size_t text_len, alloc_len; - char *search; + const char *search; + unsigned int i; if (git_oid__parse(&tag->target, &buffer, buffer_end, "object ") < 0) return tag_error("Object field invalid"); diff -urpN libgit2-0.24.1.orig/src/transports/http.c.orig libgit2-0.24.1/src/transports/http.c.orig --- libgit2-0.24.1.orig/src/transports/http.c.orig 2016-04-11 17:18:17.000000000 -0500 +++ libgit2-0.24.1/src/transports/http.c.orig 1969-12-31 18:00:00.000000000 -0600 @@ -1,1082 +0,0 @@ -/* - * Copyright (C) the libgit2 contributors. All rights reserved. - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef GIT_WINHTTP - -#include "git2.h" -#include "http_parser.h" -#include "buffer.h" -#include "netops.h" -#include "global.h" -#include "remote.h" -#include "smart.h" -#include "auth.h" -#include "auth_negotiate.h" -#include "tls_stream.h" -#include "socket_stream.h" -#include "curl_stream.h" - -git_http_auth_scheme auth_schemes[] = { - { GIT_AUTHTYPE_NEGOTIATE, "Negotiate", GIT_CREDTYPE_DEFAULT, git_http_auth_negotiate }, - { GIT_AUTHTYPE_BASIC, "Basic", GIT_CREDTYPE_USERPASS_PLAINTEXT, git_http_auth_basic }, -}; - -static const char *upload_pack_service = "upload-pack"; -static const char *upload_pack_ls_service_url = "/info/refs?service=git-upload-pack"; -static const char *upload_pack_service_url = "/git-upload-pack"; -static const char *receive_pack_service = "receive-pack"; -static const char *receive_pack_ls_service_url = "/info/refs?service=git-receive-pack"; -static const char *receive_pack_service_url = "/git-receive-pack"; -static const char *get_verb = "GET"; -static const char *post_verb = "POST"; - -#define OWNING_SUBTRANSPORT(s) ((http_subtransport *)(s)->parent.subtransport) - -#define PARSE_ERROR_GENERIC -1 -#define PARSE_ERROR_REPLAY -2 -/** Look at the user field */ -#define PARSE_ERROR_EXT -3 - -#define CHUNK_SIZE 4096 - -enum last_cb { - NONE, - FIELD, - VALUE -}; - -typedef struct { - git_smart_subtransport_stream parent; - const char *service; - const char *service_url; - char *redirect_url; - const char *verb; - char *chunk_buffer; - unsigned chunk_buffer_len; - unsigned sent_request : 1, - received_response : 1, - chunked : 1, - redirect_count : 3; -} http_stream; - -typedef struct { - git_smart_subtransport parent; - transport_smart *owner; - git_stream *io; - gitno_connection_data connection_data; - bool connected; - - /* Parser structures */ - http_parser parser; - http_parser_settings settings; - gitno_buffer parse_buffer; - git_buf parse_header_name; - git_buf parse_header_value; - char parse_buffer_data[NETIO_BUFSIZE]; - char *content_type; - char *location; - git_vector www_authenticate; - enum last_cb last_cb; - int parse_error; - int error; - unsigned parse_finished : 1; - - /* Authentication */ - git_cred *cred; - git_cred *url_cred; - git_vector auth_contexts; -} http_subtransport; - -typedef struct { - http_stream *s; - http_subtransport *t; - - /* Target buffer details from read() */ - char *buffer; - size_t buf_size; - size_t *bytes_read; -} parser_context; - -static bool credtype_match(git_http_auth_scheme *scheme, void *data) -{ - unsigned int credtype = *(unsigned int *)data; - - return !!(scheme->credtypes & credtype); -} - -static bool challenge_match(git_http_auth_scheme *scheme, void *data) -{ - const char *scheme_name = scheme->name; - const char *challenge = (const char *)data; - size_t scheme_len; - - scheme_len = strlen(scheme_name); - return (strncmp(challenge, scheme_name, scheme_len) == 0 && - (challenge[scheme_len] == '\0' || challenge[scheme_len] == ' ')); -} - -static int auth_context_match( - git_http_auth_context **out, - http_subtransport *t, - bool (*scheme_match)(git_http_auth_scheme *scheme, void *data), - void *data) -{ - git_http_auth_scheme *scheme = NULL; - git_http_auth_context *context = NULL, *c; - size_t i; - - *out = NULL; - - for (i = 0; i < ARRAY_SIZE(auth_schemes); i++) { - if (scheme_match(&auth_schemes[i], data)) { - scheme = &auth_schemes[i]; - break; - } - } - - if (!scheme) - return 0; - - /* See if authentication has already started for this scheme */ - git_vector_foreach(&t->auth_contexts, i, c) { - if (c->type == scheme->type) { - context = c; - break; - } - } - - if (!context) { - if (scheme->init_context(&context, &t->connection_data) < 0) - return -1; - else if (!context) - return 0; - else if (git_vector_insert(&t->auth_contexts, context) < 0) - return -1; - } - - *out = context; - - return 0; -} - -static int apply_credentials(git_buf *buf, http_subtransport *t) -{ - git_cred *cred = t->cred; - git_http_auth_context *context; - - /* Apply the credentials given to us in the URL */ - if (!cred && t->connection_data.user && t->connection_data.pass) { - if (!t->url_cred && - git_cred_userpass_plaintext_new(&t->url_cred, - t->connection_data.user, t->connection_data.pass) < 0) - return -1; - - cred = t->url_cred; - } - - if (!cred) - return 0; - - /* Get or create a context for the best scheme for this cred type */ - if (auth_context_match(&context, t, credtype_match, &cred->credtype) < 0) - return -1; - - return context->next_token(buf, context, cred); -} - -static const char *user_agent(void) -{ - const char *custom = git_libgit2__user_agent(); - - if (custom) - return custom; - - return "libgit2 " LIBGIT2_VERSION; -} - -static int gen_request( - git_buf *buf, - http_stream *s, - size_t content_length) -{ - http_subtransport *t = OWNING_SUBTRANSPORT(s); - const char *path = t->connection_data.path ? t->connection_data.path : "/"; - size_t i; - - git_buf_printf(buf, "%s %s%s HTTP/1.1\r\n", s->verb, path, s->service_url); - - git_buf_printf(buf, "User-Agent: git/1.0 (%s)\r\n", user_agent()); - git_buf_printf(buf, "Host: %s\r\n", t->connection_data.host); - - if (s->chunked || content_length > 0) { - git_buf_printf(buf, "Accept: application/x-git-%s-result\r\n", s->service); - git_buf_printf(buf, "Content-Type: application/x-git-%s-request\r\n", s->service); - - if (s->chunked) - git_buf_puts(buf, "Transfer-Encoding: chunked\r\n"); - else - git_buf_printf(buf, "Content-Length: %"PRIuZ "\r\n", content_length); - } else - git_buf_puts(buf, "Accept: */*\r\n"); - - for (i = 0; i < t->owner->custom_headers.count; i++) { - if (t->owner->custom_headers.strings[i]) - git_buf_printf(buf, "%s\r\n", t->owner->custom_headers.strings[i]); - } - - /* Apply credentials to the request */ - if (apply_credentials(buf, t) < 0) - return -1; - - git_buf_puts(buf, "\r\n"); - - if (git_buf_oom(buf)) - return -1; - - return 0; -} - -static int parse_authenticate_response( - git_vector *www_authenticate, - http_subtransport *t, - int *allowed_types) -{ - git_http_auth_context *context; - char *challenge; - size_t i; - - git_vector_foreach(www_authenticate, i, challenge) { - if (auth_context_match(&context, t, challenge_match, challenge) < 0) - return -1; - else if (!context) - continue; - - if (context->set_challenge && - context->set_challenge(context, challenge) < 0) - return -1; - - *allowed_types |= context->credtypes; - } - - return 0; -} - -static int on_header_ready(http_subtransport *t) -{ - git_buf *name = &t->parse_header_name; - git_buf *value = &t->parse_header_value; - - if (!strcasecmp("Content-Type", git_buf_cstr(name))) { - if (!t->content_type) { - t->content_type = git__strdup(git_buf_cstr(value)); - GITERR_CHECK_ALLOC(t->content_type); - } - } - else if (!strcasecmp("WWW-Authenticate", git_buf_cstr(name))) { - char *dup = git__strdup(git_buf_cstr(value)); - GITERR_CHECK_ALLOC(dup); - - git_vector_insert(&t->www_authenticate, dup); - } - else if (!strcasecmp("Location", git_buf_cstr(name))) { - if (!t->location) { - t->location = git__strdup(git_buf_cstr(value)); - GITERR_CHECK_ALLOC(t->location); - } - } - - return 0; -} - -static int on_header_field(http_parser *parser, const char *str, size_t len) -{ - parser_context *ctx = (parser_context *) parser->data; - http_subtransport *t = ctx->t; - - /* Both parse_header_name and parse_header_value are populated - * and ready for consumption */ - if (VALUE == t->last_cb) - if (on_header_ready(t) < 0) - return t->parse_error = PARSE_ERROR_GENERIC; - - if (NONE == t->last_cb || VALUE == t->last_cb) - git_buf_clear(&t->parse_header_name); - - if (git_buf_put(&t->parse_header_name, str, len) < 0) - return t->parse_error = PARSE_ERROR_GENERIC; - - t->last_cb = FIELD; - return 0; -} - -static int on_header_value(http_parser *parser, const char *str, size_t len) -{ - parser_context *ctx = (parser_context *) parser->data; - http_subtransport *t = ctx->t; - - assert(NONE != t->last_cb); - - if (FIELD == t->last_cb) - git_buf_clear(&t->parse_header_value); - - if (git_buf_put(&t->parse_header_value, str, len) < 0) - return t->parse_error = PARSE_ERROR_GENERIC; - - t->last_cb = VALUE; - return 0; -} - -static int on_headers_complete(http_parser *parser) -{ - parser_context *ctx = (parser_context *) parser->data; - http_subtransport *t = ctx->t; - http_stream *s = ctx->s; - git_buf buf = GIT_BUF_INIT; - int error = 0, no_callback = 0, allowed_auth_types = 0; - - /* Both parse_header_name and parse_header_value are populated - * and ready for consumption. */ - if (VALUE == t->last_cb) - if (on_header_ready(t) < 0) - return t->parse_error = PARSE_ERROR_GENERIC; - - /* Capture authentication headers which may be a 401 (authentication - * is not complete) or a 200 (simply informing us that auth *is* - * complete.) - */ - if (parse_authenticate_response(&t->www_authenticate, t, - &allowed_auth_types) < 0) - return t->parse_error = PARSE_ERROR_GENERIC; - - /* Check for an authentication failure. */ - if (parser->status_code == 401 && get_verb == s->verb) { - if (!t->owner->cred_acquire_cb) { - no_callback = 1; - } else { - if (allowed_auth_types) { - if (t->cred) { - t->cred->free(t->cred); - t->cred = NULL; - } - - error = t->owner->cred_acquire_cb(&t->cred, - t->owner->url, - t->connection_data.user, - allowed_auth_types, - t->owner->cred_acquire_payload); - - if (error == GIT_PASSTHROUGH) { - no_callback = 1; - } else if (error < 0) { - t->error = error; - return t->parse_error = PARSE_ERROR_EXT; - } else { - assert(t->cred); - - if (!(t->cred->credtype & allowed_auth_types)) { - giterr_set(GITERR_NET, "credentials callback returned an invalid cred type"); - return t->parse_error = PARSE_ERROR_GENERIC; - } - - /* Successfully acquired a credential. */ - t->parse_error = PARSE_ERROR_REPLAY; - return 0; - } - } - } - - if (no_callback) { - giterr_set(GITERR_NET, "authentication required but no callback set"); - return t->parse_error = PARSE_ERROR_GENERIC; - } - } - - /* Check for a redirect. - * Right now we only permit a redirect to the same hostname. */ - if ((parser->status_code == 301 || - parser->status_code == 302 || - (parser->status_code == 303 && get_verb == s->verb) || - parser->status_code == 307) && - t->location) { - - if (s->redirect_count >= 7) { - giterr_set(GITERR_NET, "Too many redirects"); - return t->parse_error = PARSE_ERROR_GENERIC; - } - - if (gitno_connection_data_from_url(&t->connection_data, t->location, s->service_url) < 0) - return t->parse_error = PARSE_ERROR_GENERIC; - - /* Set the redirect URL on the stream. This is a transfer of - * ownership of the memory. */ - if (s->redirect_url) - git__free(s->redirect_url); - - s->redirect_url = t->location; - t->location = NULL; - - t->connected = 0; - s->redirect_count++; - - t->parse_error = PARSE_ERROR_REPLAY; - return 0; - } - - /* Check for a 200 HTTP status code. */ - if (parser->status_code != 200) { - giterr_set(GITERR_NET, - "Unexpected HTTP status code: %d", - parser->status_code); - return t->parse_error = PARSE_ERROR_GENERIC; - } - - /* The response must contain a Content-Type header. */ - if (!t->content_type) { - giterr_set(GITERR_NET, "No Content-Type header in response"); - return t->parse_error = PARSE_ERROR_GENERIC; - } - - /* The Content-Type header must match our expectation. */ - if (get_verb == s->verb) - git_buf_printf(&buf, - "application/x-git-%s-advertisement", - ctx->s->service); - else - git_buf_printf(&buf, - "application/x-git-%s-result", - ctx->s->service); - - if (git_buf_oom(&buf)) - return t->parse_error = PARSE_ERROR_GENERIC; - - if (strcmp(t->content_type, git_buf_cstr(&buf))) { - git_buf_free(&buf); - giterr_set(GITERR_NET, - "Invalid Content-Type: %s", - t->content_type); - return t->parse_error = PARSE_ERROR_GENERIC; - } - - git_buf_free(&buf); - - return 0; -} - -static int on_message_complete(http_parser *parser) -{ - parser_context *ctx = (parser_context *) parser->data; - http_subtransport *t = ctx->t; - - t->parse_finished = 1; - - return 0; -} - -static int on_body_fill_buffer(http_parser *parser, const char *str, size_t len) -{ - parser_context *ctx = (parser_context *) parser->data; - http_subtransport *t = ctx->t; - - /* If our goal is to replay the request (either an auth failure or - * a redirect) then don't bother buffering since we're ignoring the - * content anyway. - */ - if (t->parse_error == PARSE_ERROR_REPLAY) - return 0; - - if (ctx->buf_size < len) { - giterr_set(GITERR_NET, "Can't fit data in the buffer"); - return t->parse_error = PARSE_ERROR_GENERIC; - } - - memcpy(ctx->buffer, str, len); - *(ctx->bytes_read) += len; - ctx->buffer += len; - ctx->buf_size -= len; - - return 0; -} - -static void clear_parser_state(http_subtransport *t) -{ - http_parser_init(&t->parser, HTTP_RESPONSE); - gitno_buffer_setup_fromstream(t->io, - &t->parse_buffer, - t->parse_buffer_data, - sizeof(t->parse_buffer_data)); - - t->last_cb = NONE; - t->parse_error = 0; - t->parse_finished = 0; - - git_buf_free(&t->parse_header_name); - git_buf_init(&t->parse_header_name, 0); - - git_buf_free(&t->parse_header_value); - git_buf_init(&t->parse_header_value, 0); - - git__free(t->content_type); - t->content_type = NULL; - - git__free(t->location); - t->location = NULL; - - git_vector_free_deep(&t->www_authenticate); -} - -static int write_chunk(git_stream *io, const char *buffer, size_t len) -{ - git_buf buf = GIT_BUF_INIT; - - /* Chunk header */ - git_buf_printf(&buf, "%" PRIxZ "\r\n", len); - - if (git_buf_oom(&buf)) - return -1; - - if (git_stream_write(io, buf.ptr, buf.size, 0) < 0) { - git_buf_free(&buf); - return -1; - } - - git_buf_free(&buf); - - /* Chunk body */ - if (len > 0 && git_stream_write(io, buffer, len, 0) < 0) - return -1; - - /* Chunk footer */ - if (git_stream_write(io, "\r\n", 2, 0) < 0) - return -1; - - return 0; -} - -static int http_connect(http_subtransport *t) -{ - int error; - char *proxy_url; - - if (t->connected && - http_should_keep_alive(&t->parser) && - t->parse_finished) - return 0; - - if (t->io) { - git_stream_close(t->io); - git_stream_free(t->io); - t->io = NULL; - } - - if (t->connection_data.use_ssl) { - error = git_tls_stream_new(&t->io, t->connection_data.host, t->connection_data.port); - } else { -#ifdef GIT_CURL - error = git_curl_stream_new(&t->io, t->connection_data.host, t->connection_data.port); -#else - error = git_socket_stream_new(&t->io, t->connection_data.host, t->connection_data.port); -#endif - } - - if (error < 0) - return error; - - GITERR_CHECK_VERSION(t->io, GIT_STREAM_VERSION, "git_stream"); - - if (git_stream_supports_proxy(t->io) && - !git_remote__get_http_proxy(t->owner->owner, !!t->connection_data.use_ssl, &proxy_url)) { - error = git_stream_set_proxy(t->io, proxy_url); - git__free(proxy_url); - - if (error < 0) - return error; - } - - error = git_stream_connect(t->io); - -#if defined(GIT_OPENSSL) || defined(GIT_SECURE_TRANSPORT) || defined(GIT_CURL) - if ((!error || error == GIT_ECERTIFICATE) && t->owner->certificate_check_cb != NULL && - git_stream_is_encrypted(t->io)) { - git_cert *cert; - int is_valid; - - if ((error = git_stream_certificate(&cert, t->io)) < 0) - return error; - - giterr_clear(); - is_valid = error != GIT_ECERTIFICATE; - error = t->owner->certificate_check_cb(cert, is_valid, t->connection_data.host, t->owner->message_cb_payload); - - if (error < 0) { - if (!giterr_last()) - giterr_set(GITERR_NET, "user cancelled certificate check"); - - return error; - } - } -#endif - if (error < 0) - return error; - - t->connected = 1; - return 0; -} - -static int http_stream_read( - git_smart_subtransport_stream *stream, - char *buffer, - size_t buf_size, - size_t *bytes_read) -{ - http_stream *s = (http_stream *)stream; - http_subtransport *t = OWNING_SUBTRANSPORT(s); - parser_context ctx; - size_t bytes_parsed; - -replay: - *bytes_read = 0; - - assert(t->connected); - - if (!s->sent_request) { - git_buf request = GIT_BUF_INIT; - - clear_parser_state(t); - - if (gen_request(&request, s, 0) < 0) - return -1; - - if (git_stream_write(t->io, request.ptr, request.size, 0) < 0) { - git_buf_free(&request); - return -1; - } - - git_buf_free(&request); - - s->sent_request = 1; - } - - if (!s->received_response) { - if (s->chunked) { - assert(s->verb == post_verb); - - /* Flush, if necessary */ - if (s->chunk_buffer_len > 0 && - write_chunk(t->io, s->chunk_buffer, s->chunk_buffer_len) < 0) - return -1; - - s->chunk_buffer_len = 0; - - /* Write the final chunk. */ - if (git_stream_write(t->io, "0\r\n\r\n", 5, 0) < 0) - return -1; - } - - s->received_response = 1; - } - - while (!*bytes_read && !t->parse_finished) { - size_t data_offset; - int error; - - /* - * Make the parse_buffer think it's as full of data as - * the buffer, so it won't try to recv more data than - * we can put into it. - * - * data_offset is the actual data offset from which we - * should tell the parser to start reading. - */ - if (buf_size >= t->parse_buffer.len) { - t->parse_buffer.offset = 0; - } else { - t->parse_buffer.offset = t->parse_buffer.len - buf_size; - } - - data_offset = t->parse_buffer.offset; - - if (gitno_recv(&t->parse_buffer) < 0) - return -1; - - /* This call to http_parser_execute will result in invocations of the - * on_* family of callbacks. The most interesting of these is - * on_body_fill_buffer, which is called when data is ready to be copied - * into the target buffer. We need to marshal the buffer, buf_size, and - * bytes_read parameters to this callback. */ - ctx.t = t; - ctx.s = s; - ctx.buffer = buffer; - ctx.buf_size = buf_size; - ctx.bytes_read = bytes_read; - - /* Set the context, call the parser, then unset the context. */ - t->parser.data = &ctx; - - bytes_parsed = http_parser_execute(&t->parser, - &t->settings, - t->parse_buffer.data + data_offset, - t->parse_buffer.offset - data_offset); - - t->parser.data = NULL; - - /* If there was a handled authentication failure, then parse_error - * will have signaled us that we should replay the request. */ - if (PARSE_ERROR_REPLAY == t->parse_error) { - s->sent_request = 0; - - if ((error = http_connect(t)) < 0) - return error; - - goto replay; - } - - if (t->parse_error == PARSE_ERROR_EXT) { - return t->error; - } - - if (t->parse_error < 0) - return -1; - - if (bytes_parsed != t->parse_buffer.offset - data_offset) { - giterr_set(GITERR_NET, - "HTTP parser error: %s", - http_errno_description((enum http_errno)t->parser.http_errno)); - return -1; - } - } - - return 0; -} - -static int http_stream_write_chunked( - git_smart_subtransport_stream *stream, - const char *buffer, - size_t len) -{ - http_stream *s = (http_stream *)stream; - http_subtransport *t = OWNING_SUBTRANSPORT(s); - - assert(t->connected); - - /* Send the request, if necessary */ - if (!s->sent_request) { - git_buf request = GIT_BUF_INIT; - - clear_parser_state(t); - - if (gen_request(&request, s, 0) < 0) - return -1; - - if (git_stream_write(t->io, request.ptr, request.size, 0) < 0) { - git_buf_free(&request); - return -1; - } - - git_buf_free(&request); - - s->sent_request = 1; - } - - if (len > CHUNK_SIZE) { - /* Flush, if necessary */ - if (s->chunk_buffer_len > 0) { - if (write_chunk(t->io, s->chunk_buffer, s->chunk_buffer_len) < 0) - return -1; - - s->chunk_buffer_len = 0; - } - - /* Write chunk directly */ - if (write_chunk(t->io, buffer, len) < 0) - return -1; - } - else { - /* Append as much to the buffer as we can */ - int count = min(CHUNK_SIZE - s->chunk_buffer_len, len); - - if (!s->chunk_buffer) - s->chunk_buffer = git__malloc(CHUNK_SIZE); - - memcpy(s->chunk_buffer + s->chunk_buffer_len, buffer, count); - s->chunk_buffer_len += count; - buffer += count; - len -= count; - - /* Is the buffer full? If so, then flush */ - if (CHUNK_SIZE == s->chunk_buffer_len) { - if (write_chunk(t->io, s->chunk_buffer, s->chunk_buffer_len) < 0) - return -1; - - s->chunk_buffer_len = 0; - - if (len > 0) { - memcpy(s->chunk_buffer, buffer, len); - s->chunk_buffer_len = len; - } - } - } - - return 0; -} - -static int http_stream_write_single( - git_smart_subtransport_stream *stream, - const char *buffer, - size_t len) -{ - http_stream *s = (http_stream *)stream; - http_subtransport *t = OWNING_SUBTRANSPORT(s); - git_buf request = GIT_BUF_INIT; - - assert(t->connected); - - if (s->sent_request) { - giterr_set(GITERR_NET, "Subtransport configured for only one write"); - return -1; - } - - clear_parser_state(t); - - if (gen_request(&request, s, len) < 0) - return -1; - - if (git_stream_write(t->io, request.ptr, request.size, 0) < 0) - goto on_error; - - if (len && git_stream_write(t->io, buffer, len, 0) < 0) - goto on_error; - - git_buf_free(&request); - s->sent_request = 1; - - return 0; - -on_error: - git_buf_free(&request); - return -1; -} - -static void http_stream_free(git_smart_subtransport_stream *stream) -{ - http_stream *s = (http_stream *)stream; - - if (s->chunk_buffer) - git__free(s->chunk_buffer); - - if (s->redirect_url) - git__free(s->redirect_url); - - git__free(s); -} - -static int http_stream_alloc(http_subtransport *t, - git_smart_subtransport_stream **stream) -{ - http_stream *s; - - if (!stream) - return -1; - - s = git__calloc(sizeof(http_stream), 1); - GITERR_CHECK_ALLOC(s); - - s->parent.subtransport = &t->parent; - s->parent.read = http_stream_read; - s->parent.write = http_stream_write_single; - s->parent.free = http_stream_free; - - *stream = (git_smart_subtransport_stream *)s; - return 0; -} - -static int http_uploadpack_ls( - http_subtransport *t, - git_smart_subtransport_stream **stream) -{ - http_stream *s; - - if (http_stream_alloc(t, stream) < 0) - return -1; - - s = (http_stream *)*stream; - - s->service = upload_pack_service; - s->service_url = upload_pack_ls_service_url; - s->verb = get_verb; - - return 0; -} - -static int http_uploadpack( - http_subtransport *t, - git_smart_subtransport_stream **stream) -{ - http_stream *s; - - if (http_stream_alloc(t, stream) < 0) - return -1; - - s = (http_stream *)*stream; - - s->service = upload_pack_service; - s->service_url = upload_pack_service_url; - s->verb = post_verb; - - return 0; -} - -static int http_receivepack_ls( - http_subtransport *t, - git_smart_subtransport_stream **stream) -{ - http_stream *s; - - if (http_stream_alloc(t, stream) < 0) - return -1; - - s = (http_stream *)*stream; - - s->service = receive_pack_service; - s->service_url = receive_pack_ls_service_url; - s->verb = get_verb; - - return 0; -} - -static int http_receivepack( - http_subtransport *t, - git_smart_subtransport_stream **stream) -{ - http_stream *s; - - if (http_stream_alloc(t, stream) < 0) - return -1; - - s = (http_stream *)*stream; - - /* Use Transfer-Encoding: chunked for this request */ - s->chunked = 1; - s->parent.write = http_stream_write_chunked; - - s->service = receive_pack_service; - s->service_url = receive_pack_service_url; - s->verb = post_verb; - - return 0; -} - -static int http_action( - git_smart_subtransport_stream **stream, - git_smart_subtransport *subtransport, - const char *url, - git_smart_service_t action) -{ - http_subtransport *t = (http_subtransport *)subtransport; - int ret; - - if (!stream) - return -1; - - if ((!t->connection_data.host || !t->connection_data.port || !t->connection_data.path) && - (ret = gitno_connection_data_from_url(&t->connection_data, url, NULL)) < 0) - return ret; - - if ((ret = http_connect(t)) < 0) - return ret; - - switch (action) { - case GIT_SERVICE_UPLOADPACK_LS: - return http_uploadpack_ls(t, stream); - - case GIT_SERVICE_UPLOADPACK: - return http_uploadpack(t, stream); - - case GIT_SERVICE_RECEIVEPACK_LS: - return http_receivepack_ls(t, stream); - - case GIT_SERVICE_RECEIVEPACK: - return http_receivepack(t, stream); - } - - *stream = NULL; - return -1; -} - -static int http_close(git_smart_subtransport *subtransport) -{ - http_subtransport *t = (http_subtransport *) subtransport; - git_http_auth_context *context; - size_t i; - - clear_parser_state(t); - - if (t->io) { - git_stream_close(t->io); - git_stream_free(t->io); - t->io = NULL; - } - - if (t->cred) { - t->cred->free(t->cred); - t->cred = NULL; - } - - if (t->url_cred) { - t->url_cred->free(t->url_cred); - t->url_cred = NULL; - } - - git_vector_foreach(&t->auth_contexts, i, context) { - if (context->free) - context->free(context); - } - - git_vector_clear(&t->auth_contexts); - - gitno_connection_data_free_ptrs(&t->connection_data); - memset(&t->connection_data, 0x0, sizeof(gitno_connection_data)); - - return 0; -} - -static void http_free(git_smart_subtransport *subtransport) -{ - http_subtransport *t = (http_subtransport *) subtransport; - - http_close(subtransport); - - git_vector_free(&t->auth_contexts); - git__free(t); -} - -int git_smart_subtransport_http(git_smart_subtransport **out, git_transport *owner, void *param) -{ - http_subtransport *t; - - GIT_UNUSED(param); - - if (!out) - return -1; - - t = git__calloc(sizeof(http_subtransport), 1); - GITERR_CHECK_ALLOC(t); - - t->owner = (transport_smart *)owner; - t->parent.action = http_action; - t->parent.close = http_close; - t->parent.free = http_free; - - t->settings.on_header_field = on_header_field; - t->settings.on_header_value = on_header_value; - t->settings.on_headers_complete = on_headers_complete; - t->settings.on_body = on_body_fill_buffer; - t->settings.on_message_complete = on_message_complete; - - *out = (git_smart_subtransport *) t; - return 0; -} - -#endif /* !GIT_WINHTTP */ diff -urpN libgit2-0.24.1.orig/src/transports/smart_pkt.c libgit2-0.24.1/src/transports/smart_pkt.c --- libgit2-0.24.1.orig/src/transports/smart_pkt.c 2018-11-30 13:50:30.312789191 -0600 +++ libgit2-0.24.1/src/transports/smart_pkt.c 2018-12-03 15:55:59.292894819 -0600 @@ -382,7 +382,7 @@ static int32_t parse_len(const char *lin } } - if ((error = git__strtol32(&len, num, &num_end, 16)) < 0) + if ((error = git__strntol32(&len, num, PKT_LEN_SIZE, &num_end, 16)) < 0) return error; return len; diff -urpN libgit2-0.24.1.orig/src/transports/winhttp.c libgit2-0.24.1/src/transports/winhttp.c --- libgit2-0.24.1.orig/src/transports/winhttp.c 2016-04-11 17:18:17.000000000 -0500 +++ libgit2-0.24.1/src/transports/winhttp.c 2018-12-03 15:55:59.292894819 -0600 @@ -603,7 +603,8 @@ static int winhttp_connect( t->connection = NULL; /* Prepare port */ - if (git__strtol32(&port, t->connection_data.port, NULL, 10) < 0) + if (git__strntol32(&port, t->connection_data.port, + strlen(t->connection_data.port), NULL, 10) < 0) return -1; /* Prepare host */ diff -urpN libgit2-0.24.1.orig/src/tree-cache.c libgit2-0.24.1/src/tree-cache.c --- libgit2-0.24.1.orig/src/tree-cache.c 2016-04-11 17:18:17.000000000 -0500 +++ libgit2-0.24.1/src/tree-cache.c 2018-12-03 15:52:12.747962464 -0600 @@ -90,7 +90,7 @@ static int read_tree_internal(git_tree_c return -1; /* Blank-terminated ASCII decimal number of entries in this tree */ - if (git__strtol32(&count, buffer, &buffer, 10) < 0) + if (git__strntol32(&count, buffer, buffer_end - buffer, &buffer, 10) < 0) goto corrupted; tree->entry_count = count; @@ -99,7 +99,7 @@ static int read_tree_internal(git_tree_c goto corrupted; /* Number of children of the tree, newline-terminated */ - if (git__strtol32(&count, buffer, &buffer, 10) < 0 || count < 0) + if (git__strntol32(&count, buffer, buffer_end - buffer, &buffer, 10) < 0 || count < 0) goto corrupted; tree->children_count = count; diff -urpN libgit2-0.24.1.orig/src/util.c libgit2-0.24.1/src/util.c --- libgit2-0.24.1.orig/src/util.c 2016-04-11 17:18:17.000000000 -0500 +++ libgit2-0.24.1/src/util.c 2018-12-10 11:59:37.398310363 -0600 @@ -64,7 +64,7 @@ int git_strarray_copy(git_strarray *tgt, return 0; } -int git__strtol64(int64_t *result, const char *nptr, const char **endptr, int base) +int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const char **endptr, int base) { const char *p; int64_t n, nn; @@ -111,7 +111,7 @@ int git__strtol64(int64_t *result, const /* * Non-empty sequence of digits */ - for (;; p++,ndig++) { + for (; nptr_len > 0; p++,ndig++,nptr_len--) { c = *p; v = base; if ('0'<=c && c<='9') @@ -122,15 +122,25 @@ int git__strtol64(int64_t *result, const v = c - 'A' + 10; if (v >= base) break; - nn = n*base + v; - if (nn < n) + v = neg ? -v : v; + if (n > INT64_MAX / base || n < INT64_MIN / base) { ovfl = 1; - n = nn; + /* Keep on iterating until the end of this number */ + continue; + } + nn = n * base; + if ((v > 0 && nn > INT64_MAX - v) || + (v < 0 && nn < INT64_MIN - v)) { + ovfl = 1; + /* Keep on iterating until the end of this number */ + continue; + } + n = nn + v; } Return: if (ndig == 0) { - giterr_set(GITERR_INVALID, "Failed to convert string to long. Not a number"); + giterr_set(GITERR_INVALID, "failed to convert string to long: not a number"); return -1; } @@ -138,30 +148,34 @@ Return: *endptr = p; if (ovfl) { - giterr_set(GITERR_INVALID, "Failed to convert string to long. Overflow error"); + giterr_set(GITERR_INVALID, "failed to convert string to long: overflow error"); return -1; } - *result = neg ? -n : n; + *result = n; return 0; } -int git__strtol32(int32_t *result, const char *nptr, const char **endptr, int base) +int git__strntol32(int32_t *result, const char *nptr, size_t nptr_len, const char **endptr, int base) { - int error; + const char *tmp_endptr; int32_t tmp_int; int64_t tmp_long; + int error; - if ((error = git__strtol64(&tmp_long, nptr, endptr, base)) < 0) + if ((error = git__strntol64(&tmp_long, nptr, nptr_len, &tmp_endptr, base)) < 0) return error; tmp_int = tmp_long & 0xFFFFFFFF; if (tmp_int != tmp_long) { - giterr_set(GITERR_INVALID, "Failed to convert. '%s' is too large", nptr); + int len = tmp_endptr - nptr; + giterr_set(GITERR_INVALID, "failed to convert: '%.*s' is too large", len, nptr); return -1; } *result = tmp_int; + if (endptr) + *endptr = tmp_endptr; return error; } @@ -238,35 +252,47 @@ void git__strtolower(char *str) git__strntolower(str, strlen(str)); } -int git__prefixcmp(const char *str, const char *prefix) +GIT_INLINE(int) prefixcmp(const char *str, size_t str_n, const char *prefix, bool icase) { - for (;;) { - unsigned char p = *(prefix++), s; + int s, p; + + while (str_n--) { + s = (unsigned char)*str++; + p = (unsigned char)*prefix++; + + if (icase) { + s = git__tolower(s); + p = git__tolower(p); + } + if (!p) return 0; - if ((s = *(str++)) != p) + + if (s != p) return s - p; } + + return (0 - *prefix); } -int git__prefixcmp_icase(const char *str, const char *prefix) +int git__prefixcmp(const char *str, const char *prefix) { - return strncasecmp(str, prefix, strlen(prefix)); + return prefixcmp(str, SIZE_MAX, prefix, false); } -int git__prefixncmp_icase(const char *str, size_t str_n, const char *prefix) +int git__prefixncmp(const char *str, size_t str_n, const char *prefix) { - int s, p; - - while(str_n--) { - s = (unsigned char)git__tolower(*str++); - p = (unsigned char)git__tolower(*prefix++); + return prefixcmp(str, str_n, prefix, false); +} - if (s != p) - return s - p; - } +int git__prefixcmp_icase(const char *str, const char *prefix) +{ + return prefixcmp(str, SIZE_MAX, prefix, true); +} - return (0 - *prefix); +int git__prefixncmp_icase(const char *str, size_t str_n, const char *prefix) +{ + return prefixcmp(str, str_n, prefix, true); } int git__suffixcmp(const char *str, const char *suffix) @@ -319,6 +345,47 @@ char *git__strsep(char **end, const char } return NULL; +} + +/* + * Adapted Not So Naive algorithm from http://www-igm.univ-mlv.fr/~lecroq/string/ + */ +const void * git__memmem(const void *haystack, size_t haystacklen, + const void *needle, size_t needlelen) +{ + const char *h, *n; + size_t j, k, l; + + if (needlelen > haystacklen || !haystacklen || !needlelen) + return NULL; + + h = (const char *) haystack, + n = (const char *) needle; + + if (needlelen == 1) + return memchr(haystack, *n, haystacklen); + + if (n[0] == n[1]) { + k = 2; + l = 1; + } else { + k = 1; + l = 2; + } + + j = 0; + while (j <= haystacklen - needlelen) { + if (n[1] != h[j + 1]) { + j += k; + } else { + if (memcmp(n + 2, h + j + 2, needlelen - 2) == 0 && + n[0] == h[j]) + return h + j; + j += l; + } + } + + return NULL; } void git__hexdump(const char *buffer, size_t len) diff -urpN libgit2-0.24.1.orig/src/util.h libgit2-0.24.1/src/util.h --- libgit2-0.24.1.orig/src/util.h 2016-04-11 17:18:17.000000000 -0500 +++ libgit2-0.24.1/src/util.h 2018-12-10 11:57:01.735357451 -0600 @@ -254,6 +254,7 @@ GIT_INLINE(void) git__free(void *ptr) extern int git__prefixcmp(const char *str, const char *prefix); extern int git__prefixcmp_icase(const char *str, const char *prefix); +extern int git__prefixncmp(const char *str, size_t str_n, const char *prefix); extern int git__prefixncmp_icase(const char *str, size_t str_n, const char *prefix); extern int git__suffixcmp(const char *str, const char *suffix); @@ -262,8 +263,9 @@ GIT_INLINE(int) git__signum(int val) return ((val > 0) - (val < 0)); } -extern int git__strtol32(int32_t *n, const char *buff, const char **end_buf, int base); -extern int git__strtol64(int64_t *n, const char *buff, const char **end_buf, int base); +extern int git__strntol32(int32_t *n, const char *buff, size_t buff_len, const char **end_buf, int base); +extern int git__strntol64(int64_t *n, const char *buff, size_t buff_len, const char **end_buf, int base); + extern void git__hexdump(const char *buffer, size_t n); extern uint32_t git__hash(const void *key, int len, uint32_t seed); @@ -312,6 +314,9 @@ GIT_INLINE(const void *) git__memrchr(co return NULL; } +extern const void * git__memmem(const void *haystack, size_t haystacklen, + const void *needle, size_t needlelen); + typedef int (*git__tsort_cmp)(const void *a, const void *b); extern void git__tsort(void **dst, size_t size, git__tsort_cmp cmp); diff -urpN libgit2-0.24.1.orig/tests/core/memmem.c libgit2-0.24.1/tests/core/memmem.c --- libgit2-0.24.1.orig/tests/core/memmem.c 1969-12-31 18:00:00.000000000 -0600 +++ libgit2-0.24.1/tests/core/memmem.c 2018-12-03 16:29:09.245427048 -0600 @@ -0,0 +1,46 @@ +#include "clar_libgit2.h" + +static void assert_found(const char *haystack, const char *needle, size_t expected_pos) +{ + cl_assert_equal_p(git__memmem(haystack, haystack ? strlen(haystack) : 0, + needle, needle ? strlen(needle) : 0), + haystack + expected_pos); +} + +static void assert_absent(const char *haystack, const char *needle) +{ + cl_assert_equal_p(git__memmem(haystack, haystack ? strlen(haystack) : 0, + needle, needle ? strlen(needle) : 0), + NULL); +} + +void test_core_memmem__found(void) +{ + assert_found("a", "a", 0); + assert_found("ab", "a", 0); + assert_found("ba", "a", 1); + assert_found("aa", "a", 0); + assert_found("aab", "aa", 0); + assert_found("baa", "aa", 1); + assert_found("dabc", "abc", 1); + assert_found("abababc", "abc", 4); +} + +void test_core_memmem__absent(void) +{ + assert_absent("a", "b"); + assert_absent("a", "aa"); + assert_absent("ba", "ab"); + assert_absent("ba", "ab"); + assert_absent("abc", "abcd"); + assert_absent("abcabcabc", "bcac"); +} + +void test_core_memmem__edgecases(void) +{ + assert_absent(NULL, NULL); + assert_absent("a", NULL); + assert_absent(NULL, "a"); + assert_absent("", "a"); + assert_absent("a", ""); +} diff -urpN libgit2-0.24.1.orig/tests/core/strtol.c libgit2-0.24.1/tests/core/strtol.c --- libgit2-0.24.1.orig/tests/core/strtol.c 2016-04-11 17:18:17.000000000 -0500 +++ libgit2-0.24.1/tests/core/strtol.c 2018-12-10 11:47:08.871232203 -0600 @@ -1,37 +1,84 @@ #include "clar_libgit2.h" -void test_core_strtol__int32(void) +static void assert_l32_parses(const char *string, int32_t expected, int base) { int32_t i; + cl_git_pass(git__strntol32(&i, string, strlen(string), NULL, base)); + cl_assert_equal_i(i, expected); +} - cl_git_pass(git__strtol32(&i, "123", NULL, 10)); - cl_assert(i == 123); - cl_git_pass(git__strtol32(&i, " +123 ", NULL, 10)); - cl_assert(i == 123); - cl_git_pass(git__strtol32(&i, " +2147483647 ", NULL, 10)); - cl_assert(i == 2147483647); - cl_git_pass(git__strtol32(&i, " -2147483648 ", NULL, 10)); - cl_assert(i == -2147483648LL); - - cl_git_fail(git__strtol32(&i, " 2147483657 ", NULL, 10)); - cl_git_fail(git__strtol32(&i, " -2147483657 ", NULL, 10)); +static void assert_l32_fails(const char *string, int base) +{ + int32_t i; + cl_git_fail(git__strntol32(&i, string, strlen(string), NULL, base)); } -void test_core_strtol__int64(void) +static void assert_l64_parses(const char *string, int64_t expected, int base) { int64_t i; + cl_git_pass(git__strntol64(&i, string, strlen(string), NULL, base)); + cl_assert_equal_i(i, expected); +} + +static void assert_l64_fails(const char *string, int base) +{ + int64_t i; + cl_git_fail(git__strntol64(&i, string, strlen(string), NULL, base)); +} + +void test_core_strtol__int32(void) +{ + assert_l32_parses("123", 123, 10); + assert_l32_parses(" +123 ", 123, 10); + assert_l32_parses(" +2147483647 ", 2147483647, 10); + assert_l32_parses(" -2147483648 ", -2147483648LL, 10); + assert_l32_parses("A", 10, 16); + assert_l32_parses("1x1", 1, 10); - cl_git_pass(git__strtol64(&i, "123", NULL, 10)); - cl_assert(i == 123); - cl_git_pass(git__strtol64(&i, " +123 ", NULL, 10)); - cl_assert(i == 123); - cl_git_pass(git__strtol64(&i, " +2147483647 ", NULL, 10)); - cl_assert(i == 2147483647); - cl_git_pass(git__strtol64(&i, " -2147483648 ", NULL, 10)); - cl_assert(i == -2147483648LL); - cl_git_pass(git__strtol64(&i, " 2147483657 ", NULL, 10)); - cl_assert(i == 2147483657LL); - cl_git_pass(git__strtol64(&i, " -2147483657 ", NULL, 10)); - cl_assert(i == -2147483657LL); + assert_l32_fails("", 10); + assert_l32_fails("a", 10); + assert_l32_fails("x10x", 10); + assert_l32_fails(" 2147483657 ", 10); + assert_l32_fails(" -2147483657 ", 10); } +void test_core_strtol__int64(void) +{ + assert_l64_parses("123", 123, 10); + assert_l64_parses(" +123 ", 123, 10); + assert_l64_parses(" +2147483647 ", 2147483647, 10); + assert_l64_parses(" -2147483648 ", -2147483648LL, 10); + assert_l64_parses(" 2147483657 ", 2147483657LL, 10); + assert_l64_parses(" -2147483657 ", -2147483657LL, 10); + assert_l64_parses(" 9223372036854775807 ", INT64_MAX, 10); + assert_l64_parses(" -9223372036854775808 ", INT64_MIN, 10); + assert_l64_parses(" 0x7fffffffffffffff ", INT64_MAX, 16); + assert_l64_parses(" -0x8000000000000000 ", INT64_MIN, 16); + assert_l64_parses("1a", 26, 16); + assert_l64_parses("1A", 26, 16); + + assert_l64_fails("", 10); + assert_l64_fails("a", 10); + assert_l64_fails("x10x", 10); + assert_l64_fails("0x8000000000000000", 16); + assert_l64_fails("-0x8000000000000001", 16); +} + +void test_core_strtol__buffer_length_truncates(void) +{ + int32_t i32; + int64_t i64; + + cl_git_pass(git__strntol32(&i32, "11", 1, NULL, 10)); + cl_assert_equal_i(i32, 1); + + cl_git_pass(git__strntol64(&i64, "11", 1, NULL, 10)); + cl_assert_equal_i(i64, 1); +} + +void test_core_strtol__error_message_cuts_off(void) +{ + assert_l32_fails("2147483657foobar", 10); + cl_assert(strstr(giterr_last()->message, "2147483657") != NULL); + cl_assert(strstr(giterr_last()->message, "foobar") == NULL); +}
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor