Commit 252f2eee by Patrick Steinhardt

parse: implement and use `git_parse_advance_digit`

The patch parsing code has multiple recurring patterns where we want to
parse an actual number. Create a new function `git_parse_advance_digit`
and use it to avoid code duplication.
parent 65dcb645
...@@ -79,3 +79,18 @@ int git_parse_advance_nl(git_parse_ctx *ctx) ...@@ -79,3 +79,18 @@ int git_parse_advance_nl(git_parse_ctx *ctx)
git_parse_advance_line(ctx); git_parse_advance_line(ctx);
return 0; return 0;
} }
int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base)
{
const char *end;
int ret;
if (ctx->line_len < 1 || !git__isdigit(ctx->line[0]))
return -1;
if ((ret = git__strntol64(out, ctx->line, ctx->line_len, &end, base)) < 0)
return -1;
git_parse_advance_chars(ctx, (end - ctx->line));
return 0;
}
...@@ -47,3 +47,4 @@ int git_parse_advance_expected( ...@@ -47,3 +47,4 @@ int git_parse_advance_expected(
int git_parse_advance_ws(git_parse_ctx *ctx); int git_parse_advance_ws(git_parse_ctx *ctx);
int git_parse_advance_nl(git_parse_ctx *ctx); int git_parse_advance_nl(git_parse_ctx *ctx);
int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base);
...@@ -102,24 +102,17 @@ static int parse_header_git_newpath( ...@@ -102,24 +102,17 @@ static int parse_header_git_newpath(
static int parse_header_mode(uint16_t *mode, git_patch_parse_ctx *ctx) static int parse_header_mode(uint16_t *mode, git_patch_parse_ctx *ctx)
{ {
const char *end; int64_t m;
int32_t m;
int ret;
if (ctx->parse_ctx.line_len < 1 || !git__isdigit(ctx->parse_ctx.line[0])) if ((git_parse_advance_digit(&m, &ctx->parse_ctx, 8)) < 0)
return git_parse_err("invalid file mode at line %"PRIuZ, ctx->parse_ctx.line_num); return git_parse_err("invalid file mode at line %"PRIuZ, ctx->parse_ctx.line_num);
if ((ret = git__strntol32(&m, ctx->parse_ctx.line, ctx->parse_ctx.line_len, &end, 8)) < 0)
return ret;
if (m > UINT16_MAX) if (m > UINT16_MAX)
return -1; return -1;
*mode = (uint16_t)m; *mode = (uint16_t)m;
git_parse_advance_chars(&ctx->parse_ctx, (end - ctx->parse_ctx.line)); return 0;
return ret;
} }
static int parse_header_oid( static int parse_header_oid(
...@@ -258,19 +251,15 @@ static int parse_header_copyto( ...@@ -258,19 +251,15 @@ static int parse_header_copyto(
static int parse_header_percent(uint16_t *out, git_patch_parse_ctx *ctx) static int parse_header_percent(uint16_t *out, git_patch_parse_ctx *ctx)
{ {
int32_t val; int64_t val;
const char *end;
if (ctx->parse_ctx.line_len < 1 || !git__isdigit(ctx->parse_ctx.line[0]) || if (git_parse_advance_digit(&val, &ctx->parse_ctx, 10) < 0)
git__strntol32(&val, ctx->parse_ctx.line, ctx->parse_ctx.line_len, &end, 10) < 0)
return -1; return -1;
git_parse_advance_chars(&ctx->parse_ctx, (end - ctx->parse_ctx.line));
if (git_parse_advance_expected_str(&ctx->parse_ctx, "%") < 0) if (git_parse_advance_expected_str(&ctx->parse_ctx, "%") < 0)
return -1; return -1;
if (val > 100) if (val < 0 || val > 100)
return -1; return -1;
*out = val; *out = val;
...@@ -457,7 +446,7 @@ static int parse_int(int *out, git_patch_parse_ctx *ctx) ...@@ -457,7 +446,7 @@ static int parse_int(int *out, git_patch_parse_ctx *ctx)
{ {
git_off_t num; git_off_t num;
if (parse_number(&num, ctx) < 0 || !git__is_int(num)) if (git_parse_advance_digit(&num, &ctx->parse_ctx, 10) < 0 || !git__is_int(num))
return -1; return -1;
*out = (int)num; *out = (int)num;
...@@ -687,7 +676,8 @@ static int parse_patch_binary_side( ...@@ -687,7 +676,8 @@ static int parse_patch_binary_side(
goto done; goto done;
} }
if (parse_number(&len, ctx) < 0 || git_parse_advance_nl(&ctx->parse_ctx) < 0 || len < 0) { if (git_parse_advance_digit(&len, &ctx->parse_ctx, 10) < 0 ||
git_parse_advance_nl(&ctx->parse_ctx) < 0 || len < 0) {
error = git_parse_err("invalid binary size at line %"PRIuZ, ctx->parse_ctx.line_num); error = git_parse_err("invalid binary size at line %"PRIuZ, ctx->parse_ctx.line_num);
goto done; goto done;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment