From 4c439b1e8a450639424cbb3a79e5c8f8f7700a75 Mon Sep 17 00:00:00 2001 From: Tommy Hofmann Date: Tue, 15 Aug 2023 16:12:58 +0200 Subject: [PATCH] Stop degree(::MPoly,...) from overflowing --- src/flint/fmpq_mpoly.jl | 16 +++++++++++++--- src/flint/fmpz_mod_mpoly.jl | 14 ++++++++++++-- src/flint/fmpz_mpoly.jl | 16 +++++++++++++--- src/flint/fq_nmod_mpoly.jl | 14 ++++++++++++-- src/flint/nmod_mpoly.jl | 13 +++++++++++-- test/flint/fmpq_mpoly-test.jl | 6 ++++++ test/flint/fmpz_mpoly-test.jl | 6 ++++++ test/flint/fq_nmod_mpoly-test.jl | 6 ++++++ test/flint/gfp_fmpz_mpoly-test.jl | 6 ++++++ test/flint/nmod_mpoly-test.jl | 6 ++++++ 10 files changed, 91 insertions(+), 12 deletions(-) diff --git a/src/flint/fmpq_mpoly.jl b/src/flint/fmpq_mpoly.jl index ad2c08666..786c856b4 100644 --- a/src/flint/fmpq_mpoly.jl +++ b/src/flint/fmpq_mpoly.jl @@ -200,9 +200,13 @@ end function degree(a::QQMPolyRingElem, i::Int) n = nvars(parent(a)) (i <= 0 || i > n) && error("Index must be between 1 and $n") - d = ccall((:fmpq_mpoly_degree_si, libflint), Int, - (Ref{QQMPolyRingElem}, Int, Ref{QQMPolyRing}), a, i - 1, a.parent) - return d + if degrees_fit_int(a) + d = ccall((:fmpq_mpoly_degree_si, libflint), Int, + (Ref{QQMPolyRingElem}, Int, Ref{QQMPolyRing}), a, i - 1, a.parent) + return d + else + return Int(degree_fmpz(a, i)) + end end # Degree in the i-th variable as an ZZRingElem @@ -225,6 +229,9 @@ end # Return an array of the max degrees in each variable function degrees(a::QQMPolyRingElem) + if !degrees_fit_int(a) + throw(OverflowError("degrees of polynomial do not fit into Int")) + end degs = Vector{Int}(undef, nvars(parent(a))) ccall((:fmpq_mpoly_degrees_si, libflint), Nothing, (Ptr{Int}, Ref{QQMPolyRingElem}, Ref{QQMPolyRing}), @@ -254,6 +261,9 @@ function total_degree_fits_int(a::QQMPolyRingElem) # Total degree as an Int function total_degree(a::QQMPolyRingElem) + if !total_degree_fits_int(a) + throw(OverflowError("Total degree of polynomial does not fit into Int")) + end d = ccall((:fmpq_mpoly_total_degree_si, libflint), Int, (Ref{QQMPolyRingElem}, Ref{QQMPolyRing}), a, a.parent) return d diff --git a/src/flint/fmpz_mod_mpoly.jl b/src/flint/fmpz_mod_mpoly.jl index 477079745..3b21affa0 100644 --- a/src/flint/fmpz_mod_mpoly.jl +++ b/src/flint/fmpz_mod_mpoly.jl @@ -208,10 +208,14 @@ end function degree(a::($etype), i::Int) n = nvars(parent(a)) (i <= 0 || i > n) && error("Index must be between 1 and $n") - d = ccall((:fmpz_mod_mpoly_degree_si, libflint), Int, + if degrees_fit_int(a) + d = ccall((:fmpz_mod_mpoly_degree_si, libflint), Int, (Ref{($etype)}, Int, Ref{($rtype)}), a, i - 1, parent(a)) - return d + return d + else + return Int(degree_fmpz(a, i)) + end end # Degree in the i-th variable as an ZZRingElem @@ -234,6 +238,9 @@ end # Return an array of the max degrees in each variable function degrees(a::($etype)) + if !degrees_fit_int(a) + throw(OverflowError("degrees of polynomial do not fit into Int")) + end degs = Vector{Int}(undef, nvars(parent(a))) ccall((:fmpz_mod_mpoly_degrees_si, libflint), Nothing, (Ptr{Int}, Ref{($etype)}, Ref{($rtype)}), @@ -263,6 +270,9 @@ end # Total degree as an Int function total_degree(a::($etype)) + if !total_degree_fits_int(a) + throw(OverflowError("Total degree of polynomial does not fit into Int")) + end d = ccall((:fmpz_mod_mpoly_total_degree_si, libflint), Int, (Ref{($etype)}, Ref{($rtype)}), a, a.parent) diff --git a/src/flint/fmpz_mpoly.jl b/src/flint/fmpz_mpoly.jl index cb89710d8..3cda8dc14 100644 --- a/src/flint/fmpz_mpoly.jl +++ b/src/flint/fmpz_mpoly.jl @@ -180,9 +180,13 @@ end function degree(a::ZZMPolyRingElem, i::Int) n = nvars(parent(a)) (i <= 0 || i > n) && error("Index must be between 1 and $n") - d = ccall((:fmpz_mpoly_degree_si, libflint), Int, - (Ref{ZZMPolyRingElem}, Int, Ref{ZZMPolyRing}), a, i - 1, a.parent) - return d + if degrees_fit_int(a) + d = ccall((:fmpz_mpoly_degree_si, libflint), Int, + (Ref{ZZMPolyRingElem}, Int, Ref{ZZMPolyRing}), a, i - 1, a.parent) + return d + else + return Int(degree_fmpz(a, i)) + end end # Degree in the i-th variable as an ZZRingElem @@ -205,6 +209,9 @@ end # Return an array of the max degrees in each variable function degrees(a::ZZMPolyRingElem) + if !degrees_fit_int(a) + throw(OverflowError("degrees of polynomial do not fit into Int")) + end degs = Vector{Int}(undef, nvars(parent(a))) ccall((:fmpz_mpoly_degrees_si, libflint), Nothing, (Ptr{Int}, Ref{ZZMPolyRingElem}, Ref{ZZMPolyRing}), @@ -234,6 +241,9 @@ function total_degree_fits_int(a::ZZMPolyRingElem) # Total degree as an Int function total_degree(a::ZZMPolyRingElem) + if !total_degree_fits_int(a) + throw(OverflowError("Total degree of polynomial does not fit into Int")) + end d = ccall((:fmpz_mpoly_total_degree_si, libflint), Int, (Ref{ZZMPolyRingElem}, Ref{ZZMPolyRing}), a, a.parent) return d diff --git a/src/flint/fq_nmod_mpoly.jl b/src/flint/fq_nmod_mpoly.jl index a2b99ef1f..e7fad5bd5 100644 --- a/src/flint/fq_nmod_mpoly.jl +++ b/src/flint/fq_nmod_mpoly.jl @@ -188,10 +188,14 @@ end function degree(a::fqPolyRepMPolyRingElem, i::Int) n = nvars(parent(a)) !(1 <= i <= n) && error("Index must be between 1 and $n") - d = ccall((:fq_nmod_mpoly_degree_si, libflint), Int, + if degrees_fit_int(a) + d = ccall((:fq_nmod_mpoly_degree_si, libflint), Int, (Ref{fqPolyRepMPolyRingElem}, Int, Ref{fqPolyRepMPolyRing}), a, i - 1, a.parent) - return d + return d + else + return Int(degree_fmpz(a, i)) + end end # Degree in the i-th variable as an ZZRingElem @@ -215,6 +219,9 @@ end # Return an array of the max degrees in each variable function degrees(a::fqPolyRepMPolyRingElem) + if !degrees_fit_int(a) + throw(OverflowError("degrees of polynomial do not fit into Int")) + end degs = Vector{Int}(undef, nvars(parent(a))) ccall((:fq_nmod_mpoly_degrees_si, libflint), Nothing, (Ptr{Int}, Ref{fqPolyRepMPolyRingElem}, Ref{fqPolyRepMPolyRing}), @@ -245,6 +252,9 @@ end # Total degree as an Int function total_degree(a::fqPolyRepMPolyRingElem) + if !total_degree_fits_int(a) + throw(OverflowError("Total degree of polynomial does not fit into Int")) + end d = ccall((:fq_nmod_mpoly_total_degree_si, libflint), Int, (Ref{fqPolyRepMPolyRingElem}, Ref{fqPolyRepMPolyRing}), a, a.parent) diff --git a/src/flint/nmod_mpoly.jl b/src/flint/nmod_mpoly.jl index 6d7d2e7e7..ed69398e6 100644 --- a/src/flint/nmod_mpoly.jl +++ b/src/flint/nmod_mpoly.jl @@ -193,10 +193,13 @@ end function degree(a::($etype), i::Int) n = nvars(parent(a)) (i <= 0 || i > n) && error("Index must be between 1 and $n") - d = ccall((:nmod_mpoly_degree_si, libflint), Int, + if degrees_fit_int(a) + d = ccall((:nmod_mpoly_degree_si, libflint), Int, (Ref{($etype)}, Int, Ref{($rtype)}), a, i - 1, parent(a)) - return d + else + return Int(degree_fmpz(a, i)) + end end # Degree in the i-th variable as an ZZRingElem @@ -219,6 +222,9 @@ end # Return an array of the max degrees in each variable function degrees(a::($etype)) + if !degrees_fit_int(a) + throw(OverflowError("degrees of polynomial do not fit into Int")) + end degs = Vector{Int}(undef, nvars(parent(a))) ccall((:nmod_mpoly_degrees_si, libflint), Nothing, (Ptr{Int}, Ref{($etype)}, Ref{($rtype)}), @@ -248,6 +254,9 @@ end # Total degree as an Int function total_degree(a::($etype)) + if !total_degree_fits_int(a) + throw(OverflowError("Total degree of polynomial does not fit into Int")) + end d = ccall((:nmod_mpoly_total_degree_si, libflint), Int, (Ref{($etype)}, Ref{($rtype)}), a, a.parent) diff --git a/test/flint/fmpq_mpoly-test.jl b/test/flint/fmpq_mpoly-test.jl index e5ec2f72e..b5594a45a 100644 --- a/test/flint/fmpq_mpoly-test.jl +++ b/test/flint/fmpq_mpoly-test.jl @@ -224,6 +224,12 @@ end @test trailing_coefficient(x) == 1 @test trailing_coefficient(S(2)) == 2 @test trailing_coefficient(S()) == 0 + + f = x^(ZZ(2)^100) * y^100 + @test_throws InexactError degree(f, 1) + @test degree(f, 2) == 100 + @test_throws OverflowError degrees(f) + @test_throws OverflowError total_degree(f) end @testset "QQMPolyRingElem.multivariate_coeff" begin diff --git a/test/flint/fmpz_mpoly-test.jl b/test/flint/fmpz_mpoly-test.jl index 5afeef4cd..cb92dd0a0 100644 --- a/test/flint/fmpz_mpoly-test.jl +++ b/test/flint/fmpz_mpoly-test.jl @@ -213,6 +213,12 @@ end @test trailing_coefficient(x) == 1 @test trailing_coefficient(S(2)) == 2 @test trailing_coefficient(S()) == 0 + + f = x^(ZZ(2)^100) * y^100 + @test_throws InexactError degree(f, 1) + @test degree(f, 2) == 100 + @test_throws OverflowError degrees(f) + @test_throws OverflowError total_degree(f) end @testset "ZZMPolyRingElem.multivariate_coeff" begin diff --git a/test/flint/fq_nmod_mpoly-test.jl b/test/flint/fq_nmod_mpoly-test.jl index 9fa1d6c5e..3f3b8257a 100644 --- a/test/flint/fq_nmod_mpoly-test.jl +++ b/test/flint/fq_nmod_mpoly-test.jl @@ -241,6 +241,12 @@ end @test trailing_coefficient(x) == 1 @test trailing_coefficient(S(2)) == 2 @test trailing_coefficient(S()) == 0 + + f = x^(ZZ(2)^100) * y^100 + @test_throws InexactError degree(f, 1) + @test degree(f, 2) == 100 + @test_throws OverflowError degrees(f) + @test_throws OverflowError total_degree(f) end @testset "fqPolyRepMPolyRingElem.multivariate_coeff" begin diff --git a/test/flint/gfp_fmpz_mpoly-test.jl b/test/flint/gfp_fmpz_mpoly-test.jl index 9ee22ca31..799db2660 100644 --- a/test/flint/gfp_fmpz_mpoly-test.jl +++ b/test/flint/gfp_fmpz_mpoly-test.jl @@ -201,6 +201,12 @@ end @test trailing_coefficient(x) == 1 @test trailing_coefficient(S(2)) == 2 @test trailing_coefficient(S()) == 0 + + f = x^(ZZ(2)^100) * y^100 + @test_throws InexactError degree(f, 1) + @test degree(f, 2) == 100 + @test_throws OverflowError degrees(f) + @test_throws OverflowError total_degree(f) end @testset "FpMPolyRingElem.multivariate_coeff" begin diff --git a/test/flint/nmod_mpoly-test.jl b/test/flint/nmod_mpoly-test.jl index 321e15a60..a897975c0 100644 --- a/test/flint/nmod_mpoly-test.jl +++ b/test/flint/nmod_mpoly-test.jl @@ -241,6 +241,12 @@ end @test trailing_coefficient(x) == 1 @test trailing_coefficient(S(2)) == 2 @test trailing_coefficient(S()) == 0 + + f = x^(ZZ(2)^100) * y^100 + @test_throws InexactError degree(f, 1) + @test degree(f, 2) == 100 + @test_throws OverflowError degrees(f) + @test_throws OverflowError total_degree(f) end @testset "zzModMPolyRingElem.multivariate_coeff" begin